从零开始使用docker搭建wordpress博客

  • 之前已经写了一个建站日记了Ubuntu 16.04 & Docker 搭建 WordPress,不过之前的版本有点像记流水账一样,现在有时间想重新组织语言,记录一下wordpress博客的搭建流程。
  • 这篇文章适用于那些不希望无脑搭建博客,但又希望以最简单的方式明明白白搭一个博客的读者取用。

本博客是由Wordpress搭建而成,如果你感兴趣的话,可以在博客中四处逛逛,看看这是不是可以解决你的需求的东西。实际上,Wordpress不仅仅可以搭建个人博客,而且还可以设计为公司主页,产品展示页面。接下来,我将从原理上介绍搭建Wordpress的流程。

WordPress博客的组成部分

PHP编写的后端逻辑

WordPress博客是一个使用PHP编写而成的博客系统,Wordpress使用PHP这个世界上最好的语言实现了网站的内部逻辑,诸如用户登录,插件管理等功能。至于PHP为什么是世界上最好的语言,有图为证↓。

至于PHP本身在Wordpress里面好用的一点,就是我们可以比较方便得修改它。比如这篇文章末尾的转载标签,就是通过手工修改PHP代码实现的(当然这里的手工也是通过博客页面上面的工具实现的),即使你不会PHP,只要知道在PHP语言中 <?php ... ?> 这个代码块内部实现的是程序逻辑,而代码块外面是我们需要显示的HTML代码就好了,也就是说,我们将希望修改的内容放在 <?php ... ?> 外面,就可以很轻松在程序母版上实现内容的添加。

搭载在Nginx服务器上

在PHP语言实现的站点逻辑的更上一层,是可以搭载该逻辑的服务器,由于服务器独立于实现逻辑(PHP程序和Nginx服务器的关系有点像C++语言和Linux系统一样)。主流的服务器有Nginx和Apache,在这里,我们使用Nginx,服务器本身的功能是监听端口,响应请求。

对于一个没有经过特殊设置的Wordpress博客系统,Nginx服务器将监听80端口(也就是我们使用HTTP访问IP没有指定端口时的默认端口)。网页访问者在该端口上的任何请求都会由Nginx解析,并调用指定的PHP程序渲染出我们希望的页面。

Mysql数据库储存网站数据

在结构上和Nginx服务端并列的,是数据库。数据库是一个为了实现数据的查询和储存设计出来的高性能系统,其功能也仅仅限于提供数据的储存于查询接口。诸如注册用户列表,文章内容等都是存在于数据库中的。Wordpress使用了Mysql数据库,这是一个基于表的关系型数据库,就效率上来说比其他数据库会好一些。

正在执行的一个PHP代码,在特定时候需要访问网站的数据(例如处理用户登录时,需要从数据库拉取指定用户的密码用以检验。)。这时,PHP程序将访问数据库,查询指定用户名对应的密码。

一个未经特殊设置的Mysql数据库,监听端口3306,而本机的其他程序,可以通过向该端口发送消息来与数据库交互。

多模块结合工作

在一般的情况下,打在了PHP网页逻辑的Nginx服务器是一个单一模块,Mysql是另一个模块。Nginx服务器在运行时会时不时地向3306端口发送请求以实现对数据库的查询。

两个模块力求尽可能的独立,这样,倘若因为错误的插件安装,你的网站逻辑部分崩了,你只需要重装Nginx-PHP模块,而不会丢失任何的用户数据。同理,对于数据库的修改也不会影响网站本身。

Docker是什么

Docker的原理

WordPress包含两个模块,他们各自的卸载与重装都不会对另一个模块产生影响。当你的服务器上不仅仅有Wordpress,还部署了其他的网站(这个情况实际上非常常见,谁也不能保证你的服务器永远只有一个博客),情况就不一样了。比如多个网站依赖于不同版本的服务端,或者网站各自的模块重装会互相影响等等…..

这时,我们就开始想Linux下面是否有类似于Python中的Anaconda一样的虚拟环境。倘若将这些模块装在互不影响的虚拟环境中,就可以实现相互独立了。或者说,有没有一个像虚拟机一样的东西,将Wordpress需要的两个模块分别运行在不同的虚拟机中,并使用一定的机制将它们关联在一起?这不,还真是有这么样一个虚拟环境,那就是Docker。

Docker在Linux中充当了虚拟机的角色,但是比虚拟机拥有更高的效率。也许是机智的Linux设计者早就预料好了有今天的需求,Linux的诸多设计使得在Docker这样的虚拟环境成为可能。在Docker中,一个虚拟环境的进程可以和主机进程并行运行(没有一个虚拟机一样的机器做翻译),并且从进程内部看,好像在一个与外界隔离的虚拟机中运行一样。

为了尝试说明Docker的原理,你只要知道下面的事实就好了——

  • Linux中有一个chroot指令,这条指令可以将接下来派生进程的根目录设置为主机的某一个目录,考虑如果有一个目录下有完备的/bin、/etc等Linux必备文件(本身Linux的就有Everything is Files的说法),那么我们使用了chroot将一个进程根目录设置为这个目录,那么看起来,这个进程接下来的运行就好像在一个全新的系统中运行一样!
  • 机智的Linux设计者还提供了其他东西,来解决诸如IP地址冲突,端口冲突的问题,总之,一个“虚拟机”中的进程可以实际运行在主机中而不干扰主机的任何工作。
  • Linux有文件映射与可持久化的机制,可以在一个固定文件版本的基础上,通过增量的方式快速构造另一个只有少量修改的文件版本(比如我有一个Ubuntu系统,我可以同时构造出一个安装了Wordpress的Ubuntu系统和安装了Mysql的Ubuntu系统,而总共占据了1个Ubuntu系统多一点的空间)。

确定了解了上述事实后,我们就很容易理解Docker究竟在干什么了——

Docker中存在两个概念,镜像与容器,镜像是一系列静态的文件打包,比如Ubuntu镜像,里面包含了所有Ubuntu运行需要的文件(也就是我们平常所看到的新的Ubuntu系统从根目录向下的所有文件);而容器则可以理解为可以运行、停止镜像,比如运行着的Ubuntu容器,在镜像的基础上,由于容器自身的运行,其内部的一些文件必然发生改变,Docker以花费极少的空间,用可持久化的方式追踪这些文件。而镜像和容器的关系是:一个镜像可以派生出多个容器,容器在运行并修改了自身后,又可以由特定docker命令固化为镜像。倘若之后读者成功建立了Docker容器,不妨到 /var/lib/docker/aufs/mnt 目录看看,你就知道容器是什么东西了。

在使用Docker建立出的纯净的系统中,我们可以从零开始搭建自己想要搭建的东西,自然而然就会有人建立一些常用环境的镜像并开源。这些镜像都收录于DockerHub中。比较著名的是Ubuntu镜像Mysql镜像以及WordPress镜像。当然,如果将整个系统镜像上传打包实际上是不妥的,用户并不能知晓这个镜像是如何制造出来的,故存在一个称之为Dockerfile的文件可以将生成这些镜像的方法“开源”,Dockerfile内部指名了这个镜像是基于什么镜像,并在该镜像基础上执行了哪些Bash命令得到的。比如我们需要基于Ubuntu镜像生成Mysql镜像可以理解为在Ubuntu镜像的文件系统中执行一条Mysql安装语句(当然,实际的实现可能会复杂一些)得到的新的文件系统。

使用Docker搭建一个博客

下面将介绍如何使用docker的原生命令建立一个Wordpress,该方法也可以在Wordpress的DockerHub镜像页面找到。不过这个方法可以被下一节中的Docker-Compose方法取代——

首先,我们先拉取我们需要的wordpress,以及mysql镜像

这里已经可以看到Docker镜像的文件系统的分层性质了,每一个十六进制的Tag都表示一个文件系统的版本。在生成mysql镜像的时候复用了wordpress镜像的一部分文件。这些文件就是这两个镜像所共有的Linux内核。

在DockerHub的Mysql页面,我们可以找到生成Mysql的容器的命令——

这里,输出结果 5f99a8d32f88f047da392fc764a5bf247a2b07440416a13942fb02891c0ce550 是新建出的容器ID,之后可以使用 docker ps 查看。在这一个步骤,我们建立了名为some-mysql的数据库容器,其密码为my-secret-pw,是基于mysql镜像建立的。

同理,在DockerHub的Wordpress页面,我们可以找到生成Wordpress容器的命令——

这里,我们新建了一个名为some-wordpress的Wordpress容器,依赖于名为wordpress的镜像。单独讲解一下–link参数的意义:由于两个容器互不干扰,可以理解为两个独立的主机,那么他们的通讯方法之一就是使用IP+端口通讯,那么这个参数的意义就是将some-mysql容器的IP地址储存在新建的some-wordpress容器的hosts文件中的一个名为mysql的项中,换句话说,之后再some-wordpress中,访问mysql:3306就能够访问到some-mysql的主机3306端口,进而建立起不同容器的通讯。而-p参数则代表将容器内部的80端口暴露为主机的8080端口。

更多细节有,docker常用的命令还有:

  • docker build :自己写一个Dockerfile,并让docker依照该Dockerfile新建一个镜像
  • docker ps -A :同时打印出由于各种错误导致停止的容器,而非正在运行的容器
  • docker stop :停止容器
  • docker restart :运行一个之前停止的容器

倘若之前的步骤没有任何问题的话,使用 docker ps 可以看到刚刚建立的两个进程正在运行。而如果有问题的话,也可以使用 docker ps -A 看到已经停止运行的容器,并用 docker logs <Container ID> 查看运行日志。

而访问主机的127.0.0.1:8080可以进入Wordpress的初始欢迎页面——

剩余部分就可以自由发挥啦~

Docker-Compose

Docker-Compose是一个可以将之前执行的一系列安装命令自动化的脚本。安装Compose可以按照官方文档的指示安装,由于这个依赖于平台,就不细讲了,如Linux可使用如下命令安装。

安装一个Wordpress使用Docker-Compose只需要在一个自定义的目录中,写一个如下的 Wordpress/docker-compose.yml 文件——

实际上,这个文件中的每一行,都是用来提供之前命令中需要的参数,而与上一节的内容对应,读者应该很容易了解每一行都在干什么——

  • 第一行是新建容器标识,仅仅用于内部的解析使用
  • 第二行是容器基于的镜像名称
  • 第三行、第四行表示内部端口和外部端口的映射
  • 第五行表示一些内部的设置,比如数据库密码等
  • 第六行用于连接mysql容器
  • 第七行是容器名
  • 后面mysql的部分相似

接着,使用 docker-compose -f Wordpress/docker-compose.yml up -d 命令启动。这一个命令可以得到上一节的相同结果。

更多细节是,docker-compose的up参数可以替换为stop、rm等命令。

注意事项

在本文中,我们将内部wordpress的80端口映射到了外部的8022端口,读者倘若希望仅仅建立博客的话,应该映射到外部80端口(因为80端口是HTTP请求的默认端口)。我这样做的原因是我的服务器上面搭载了不同的网站,而这些网站需要通过判断用户访问的域名来决定究竟将请求分发到那个处理容器中,因此在我的处理中,我还有一个外部的nginx服务器,用于域名的分发,将mhy12345.xyz这个域名下的所有访问都映射到8022端口上去,进而被容器截获。

原创文章地址:【从零开始使用docker搭建wordpress博客】转载时请注明出处mhy12345.xyz

新加坡NExT实践日记

 

2018年7月19日到2018年7月26日,我在新加坡参加NExT大数据时代调研实践。这次实践的核心就是深入新加坡的大数据实验室以及业界,了解大数据的前景。而NExT(NUS Extreme Tsinghua)是NUS和Tsinghua合办的基于大数据的研究中心。

我们住的地方是新加坡国立大学(NUS),说实话,NUS的住宿真的很好了(虽然没有空调,但是新加坡的气候整体上挺好的)。特别是窗边的景色~

和NUS相似,南洋理工大学的教学楼也设计精巧,环境与建筑融为一体。

并不是只有校园才是这样和谐,城市中,随处可见的大厦也非常震撼【感觉在新加坡,没有设计好的大楼是不允许动工的==】,有种乡下人进城的感觉。

在参观过程中,恰好遇到了新加坡的国庆彩排,有战斗机飞过,那种音爆下面,整个人都快聋了的感觉,すごいですね。

 

再po几张自己照的植物

当然,回到正事,我们在新加坡听了很多博士生的报告,以及在业界公司的访问——

最后,放一些合照

 

原创文章地址:【新加坡NExT实践日记】转载时请注明出处mhy12345.xyz

学习无锁编程

无锁编程非常有意思,大约在高三的时候我第一次接触多线程、锁这些概念,并系统性学习了这些东西。

《深入理解计算机系统》这本书中,我对于缓存,计算机流水线等概念有了一些初步了解,接下来,在网络上一些基础教程中,我知道了什么是锁,临界区等。不过锁,信号量这些手段都存在一些比较大的开销。例如维护一个链表,并对于链表每一个节点加一个读写锁会使程序变得非常非常慢。

后来接了一个外边的工作,大体目标是通过无锁数据结构来优化高频交易系统的信息传递。由于在这种情形下,普通的信息交互手段(如socket等)过于缓慢,但是若干两个进程同时申请了一块共享内存,并在共享内存上实现一个消息队列,就可以纳秒级实现消息的传输。借此机会,我开始研究无锁数据类型

在《C++ Concurrency in Action》这本书中,学习了无锁队列,栈的写法。借助C++的原子CAS操作,我们可以模拟一个锁,已达到更高的运行效率。再到后连,原子操作中的内存顺序(Memory Order)开始困扰我,不过有幸阅读到了 http://preshing.com/ 这个博客,生动的讲述了本来非常深奥的概念。网络上已经有一些这个博客的翻译,不过质量都不怎么高,因此希望能够静下心,翻译这个博客的一系列博文,并打造出一个真真意义上有教学意义的系列文章

原创文章地址:【学习无锁编程】转载时请注明出处mhy12345.xyz

WordPress速度优化

网站访问速度是搜索引擎衡量一个网站的核心因素,因为这在另一方面意味着用户点选这个词条的用户体验。因此,我们十分有必要优化Wordpress的速度。这里,我使用了WP Super Cache和Jetpack插件,WP Super Cache可以缓存你的博客页面,特别是对于匿名用户,不论如何,网站对匿名用户返回的始终是同一个页面,因此将他们缓存下来可以达到很好的效果(从原来的2s变成了几乎看不到延迟)。同时Jetpack插件提供了免费的CDN服务。也可以优化图片以及视频的加载速度。

原创文章地址:【WordPress速度优化】转载时请注明出处mhy12345.xyz

我是如何和搜索引擎斗智斗勇的.要有一个固定的域名

要有一个固定的域名

之前曾经提到百度将我的博客列为“用户不友好网站”,追溯其原因。回想之前对网站做的危险操作,不外乎变更子域名了。最初我的博客使用的是blog.mhy12345.xyz,提交了百度收录之后,我又心血来潮将站点的域名改变成了mhy12345.xyz。当时的想仅仅是,也许我改变了域名,搜索引擎自己会直接迁移过去blablabla,但是可能并不是这样。

从搜索引擎视角来看,首先出现了一个blog.mhy12345.xyz网站,接着有出现了一个冒充blog.mhy12345.xyz网站的另一个网站,内容完全相似。直接判定为抄袭站点。接下来发生的事情就更好解释了,百度只收录blog.mhy12345.xyz,我一怒之下,删去了对于blog.mhy12345.xyz的解析,剩下了一个mhy12345.xyz,而这个网站已经被搜索引擎判定为了恶意站点。然后……就没有然后了……(等等,为啥google就没有判断出错呢? 唔,毕竟百度不是世界一流互联网公司吧)

原创文章地址:【我是如何和搜索引擎斗智斗勇的.要有一个固定的域名】转载时请注明出处mhy12345.xyz

我的网站

自己写博客,特别是技术类博客,当然希望能够有其他人能够看到。我的第一篇正式文章Ubuntu 16.04 & Docker 搭建 WordPress 写于2017年4月,而到现在已经一年多了。大大小小杂文有七十于篇(怎么会那么多!?)自己认为很有用的也有大约10篇了。

有了足够的干货,当然希望更多人能够看到,这就依赖于搜索引擎了。然而搜索引擎却貌似并不买我的账。怎么说呢,google是个好公司啊,因为至少在我一点一点写博客这个时间段,google索引量在逐渐增加的,google给我带来了95%的搜索引擎索引量。而百度,甚至将我的博客列为了“用户不友好网站”==。想一想其实不无道理,google面向国外,有非常多的优质个人站点,所以理所当然赋予了个人站点更高的权值,反观百度的用户主体,国内,随随便便点开一个小站,各种广告网站满天飞,是我也想一枪毙掉所有的个人网站了。

 

原创文章地址:【我的网站】转载时请注明出处mhy12345.xyz

往事:大学物理,一门感触深刻的课程

之前常问,计算机这个专业根本和大学物理不沾边,学校怎么会将大学物理设为必修课呢?现在看来,最期末结课时间,最令我感触深刻的,竟然就是这个曾经最看不起的课程了。

老毕,毕楷杰,选课的时候还真以为是中国人呢,通过幽默,细腻的教学方式,深深感动了一个班的学生。

每次专门回答Zero等奇怪问题的Zero Position,专门抽最后一排回答问题的有趣规则,每逢节日的奇装异服,还有家庭表演,这就是用心吧。

课程中的点点滴滴越发模糊,但是每节课,总会有那么一些无法忘记的经典。诸如“企鹅与中国人”这个我现在都不知道要表达什么意思的梗,短波杀手“鸽子pupu”,物理学之精粹“Parsimony”,不知道已经说错多少年的“广义双节棍”。

课程人数从上学期的7-8排,缩减了2/3左右,但是这个的原因,大概仅仅是现在GPA至上的产物吧。否则完全无法理解为什么这样一个老师会导致学生的净流出?不过我并不在意,即使这次考试没有能够及格,我也绝不会后悔。而且最后留下的都是真爱了吧。

在薛定谔那只奇奇怪怪的猫的注视下,课程走到了尾声,故写下文章用于记忆~

原创文章地址:【往事:大学物理,一门感触深刻的课程】转载时请注明出处mhy12345.xyz

Docker通过Nginx容器实现域名转发

有些时候一台服务器上面需要架设多个网站,而同一个服务器又只有一个80端口,所以这是一个非常麻烦的事……

我在docker里面架设了两个wordpress,希望分别通过a.com和b.com转发到不同的容器中。

首先大致介绍一下nginx的转发配置

监听blog.mhy12345.xyz:80,对于任意的路径,转发到地址:http://wordpress_wordpress,后面那几行都在转发过程中修改header,具体是不是有用我也不知道。这个内容复制两遍,放入Nginx对应位置(/etc/nginx/conf.d/default.conf),就可以实现对于两个容器的转发了。

顺便给一下docker-compose.yml的写法

这里解释了为什么之前的URL是http://wordpress_wordpress,这是由于docker内部容器链接的dns设置了wordpress_wordpress的ip地址。

参考:http://www.cnblogs.com/Jarvin/p/5796193.html

当然,这一部分相当糟糕,原因是:

缓存!

是的,就是这东西,缓存!

docker的image创建有缓存,这个可以直接通过添加–no-cache参数

解决。

还有更可怕的是“浏览器缓存”

谁tm想得到浏览器会把跳转页面缓存下来啊……

每次输入 http://blog.mhy12345.xyz ,自动重定向到 https://blog.mhy12345.xyz:8022 ,根本找不出哪里有问题……

最后吐槽腾讯云学生机真是坑,一个G内存,5个docker容器就撑爆了……之后扩成两个G,然后月租上百了……

原创文章地址:【Docker通过Nginx容器实现域名转发】转载时请注明出处mhy12345.xyz

Ubuntu 16.04 & Docker 搭建 WordPress

我承认在半期考试前搭博客是非常颓,不过,whatever……

有尝试下载apache2+php+mysql的标准安装包安装方式,最后还是放弃了。大概原因是服务器上本身已经装了一些东西,各种安装包依赖关系炸了,最后直接把服务器整挂了>_<

之后突然想到,docker不就是用来隔离环境,解决各种冲突的么,是不是wordpress可以在docker里面搭?事实证明,在外部包爆炸后,docker内部也会受影响,在docker里面pull了mysql竟然都运行不了。各种调错未果之后,果断重装了服务器。果真在新系统下一切ok……

之后就相当简单,在dockerhub上面我们可以发现已经有一个叫做wordpress的镜像,而且有详细的安装说明,其中使用到了一个叫做的docker-compose工具,可以一键创建多个容器:

大概就是建立两个容器,分别是数据库mysql和wordpress,然后wordpress连接mysql

由于实在太简单,也没啥好说的了

原创文章地址:【Ubuntu 16.04 & Docker 搭建 WordPress】转载时请注明出处mhy12345.xyz