Open eyasliu opened 7 years ago
我想要运行WordPress程序,启动一个展示类的简单网站,但是我不想在我机器上安装php运行环境,也不想装mysql,因为在我看来他们的安装过程都是很繁琐,配置多,升级困难,不好维护。如果用docker 容器则不会有这些问题。
那问题来了,既然WordPress依赖php和mysql,那么运行在docker里面和运行在主机不是一样的占用资源吗?对于这个问题,我的回答是,php是必须的,但是mysql并不是必须的,我可以使用sqlite替代mysql。sqlite是一种非常轻量级关系型数据库,他的资源占用非常的低,而且目前Linux所有发行版都默认附带sqlite,所以是不需要安装的。所以结果就是 只需要php,不需要mysql。
既然需要php运行环境,那就需要php镜像。但是在 dockerhub 能搜到 WordPress 镜像和 php 镜像,怎么选呢?
所以很明显,当然是选择 WordPress 镜像。
我想到了这个方法,肯定别人也早就想到了,早在几年前就有人做好了,如果觉得下面的方法太麻烦太难懂,想速成,就这样:
docker run -d -p 80:80 dorwardv/wordpress-sqlite-nginx-docker
这样就启动了一个基于 nginx 的 wordpress ,使用的 sqlite 插件。
这个项目的地址: https://github.com/dorwardv/wordpress-sqlite-nginx-docker
如果你要用这个方法,那下文的那么多内容其实不用看了。如果你想学到更多的东西,请继续看下文。
在 WordPress 的默认镜像(latest)中,是使用php的默认镜像,php的默认镜像,是使用的debian系统,加上apache,暴露出 80 端口。所以在docker运行WordPress最快的方式就是
docker run -p 80:80 wordpress
命令运行完,就可以使用浏览器打开 http://localhost 应该就能看到WordPress安装界面了。 注:运行前请确定80端口没有被占用,如果被占用,可以使用另外的端口,在-p参数指定即可,如 -p 8080:80
-p 8080:80
上面是可以正常的运行,但是资源占用可能比在主机中运行更耗资源,要使php占用资源尽可能的小,首选alpine镜像。alpine镜像只提供了最小化系统运行所需。WordPress的alpine镜像tag为 4.8.1-fpm-alpine,没错,php的 alpine 镜像只有fpm版本。
4.8.1-fpm-alpine
php:alpine镜像只启动了php-fpm,fpm监听9000端口(php服务都是监听9000端口),但是这个端口并不是web端口,而是 unix 端口,具体怎么用,我们要先从php的运行流程说起。
php:alpine
先看一段nginx 的 php 配置
server { // 其他配置 // ...... // ...... location ~ [^/]\.php(/|$) { fastcgi_split_path_info ^(.+?\.php)(/.*)$; if (!-f $document_root$fastcgi_script_name) { return 404; } include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; } }
当浏览器访问一个url时,访问的是nginx或者apache的web服务器,web服务器根据url匹配到这个请求应该给 fastcgi 处理,这个时候fastcgi 会把匹配到的php文件给 127.0.0.1:9000 处理,这个9000端口就是php启动的cgi服务,php服务接收到fastcgi 的请求后执行php文件,然后把执行的结果返回给fastcgi,fastcgi在给回 web服务器,web服务器再响应给用户,用户就能看到php代码执行的结果了。
fastcgi
127.0.0.1:9000
写了那么长,其实可以简单地概括成:web服务器接收到请求后,让php服务执行,然后把执行结果返回。
再回到php:alpine镜像,其实这个镜像启动的9000端口就是php服务,WordPress的alpine镜像是基于php:alpine,只是在原本镜像基础上增加了php扩展和把wp源码放在了镜像中。所以说启动WordPress镜像的结果就只是启动了一个php服务罢了,这个php服务本身不接收不处理任何web请求。所以,我们还是需要一个apache或者nginx。
由于nginx比apache更轻量级,所以我选择了nginx,当然,是docker的nginx:alpine镜像。
另一个问题,WordPress源码是在WordPress镜像的/usr/src/wordpress里面,运行的时候会把 /usr/src/wordpress复制到 /var/www/html,然后定义了/var/www/html为挂载目录。这个过程可以在这里看到。这里就需要用到docker的volumes-from参数了,用这个参数指定一个容器启动一个新容器,会让新容器直接使用被指定的容器挂载目录。所以使用这个特性就可以让nginx使用到WordPress镜像的源码了。
/usr/src/wordpress
/var/www/html
先启动wordpress镜像,并暴露出端口
docker run -p 9000:9000 --name wordpress-fpm wordpress:4-fpm-alpine
第二部,新建一个nginx配置文件vhost.conf,内容如下
vhost.conf
server { listen 80; server_name localhost; root /var/www/html; index index.php; location / { try_files $uri $uri/ /index.php?$args; } rewrite /wp-admin$ $scheme://$host$uri/ permanent; location ~ [^/]\.php(/|$) { fastcgi_split_path_info ^(.+?\.php)(/.*)$; if (!-f $document_root$fastcgi_script_name) { return 404; } include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; } }
第三部,启动nginx容器
docker run -p 80:80 -v `pwd`/vhost.conf:/etc/nginx/conf.d/default.conf --volumes-from wordpress-fpm nginx:alpine
就这样,访问http://localhost 就能到吗wordpress安装界面了
wordpress总算是开始安装了,不过说好的不用mysql而转用sqlite呢。
官方镜像中,在docker-entrypoint.sh 有mysql数据库的检查代码,我们要先去掉它,先把文件提取出来,删除 TERM=dumb php -- <<'EOPHP' ........ $mysql->close(); EOPHP 的这大段php代码即可,改好后留着备用,待会定制镜像时会放进新镜像中
TERM=dumb php -- <<'EOPHP' ........ $mysql->close(); EOPHP
wordpress 使用sqlite 需要用到一个插件: SQLite Integration
插件的使用方法是,把插件解压放到plugins目录,然后把该插件目录的 db.php 放到 wp-content 目录下,在执行安装过程,就能发现跳过了输入数据库信息的过程。
db.php
把插件也放在镜像里面,每次启动就不用重新复制插件了。这样需要使用 Dockerfile 定制镜像。我们基于wordpress:4-fpm-alpine 镜像去定制
FROM wordpress:4-fpm-alpine MAINTAINER eyasliu@163.com COPY docker-entrypoint.sh /usr/local/bin/ RUN curl -o sqlite-plugin.zip https://downloads.wordpress.org/plugin/sqlite-integration.1.8.1.zip && \ unzip sqlite-plugin.zip -d /usr/src/wordpress/wp-content/plugins/ && \ cp /usr/src/wordpress/wp-content/plugins/sqlite-integration/db.php /usr/src/wordpress/wp-content && \ chmod +x /usr/local/bin/docker-entrypoint.sh && \ rm -rf sqlite-plugin.zip
Dockerfile 有了,构建一下新的镜像
docker build -t fpm-sqlite-wp:latest .
构建好后就可以启动了
docker run -d -p 9000:9000 --name fpm-wp fpm-sqlite-wp docker run -d -p 80:80 --name nginx --volumes-from fpm-wp nginx:alpine
到此为止,镜像定制完成。
如果使用docker-compose,配置可以这样写
version: '2' services: fpm-wp: image: fpm-sqlite-wp networks: - mywp expose: - '9000' nginx: image: nginx:1.11.10-alpine depends_on: - fpm-wp volumes: - ./nginx.conf:/etc/nginx/nginx.conf volumes_from: - fpm-wp networks: - mywp ports: - '80:80'
整个过程是很繁琐,但是这种定制在一个稍微复杂项目中我觉得不算什么,我的项目中nginx是做了很多事情的,所以是必须的,而且结果的确达到了节省资源的目的。
背景
我想要运行WordPress程序,启动一个展示类的简单网站,但是我不想在我机器上安装php运行环境,也不想装mysql,因为在我看来他们的安装过程都是很繁琐,配置多,升级困难,不好维护。如果用docker 容器则不会有这些问题。
需求分析
那问题来了,既然WordPress依赖php和mysql,那么运行在docker里面和运行在主机不是一样的占用资源吗?对于这个问题,我的回答是,php是必须的,但是mysql并不是必须的,我可以使用sqlite替代mysql。sqlite是一种非常轻量级关系型数据库,他的资源占用非常的低,而且目前Linux所有发行版都默认附带sqlite,所以是不需要安装的。所以结果就是 只需要php,不需要mysql。
镜像选择
既然需要php运行环境,那就需要php镜像。但是在 dockerhub 能搜到 WordPress 镜像和 php 镜像,怎么选呢?
所以很明显,当然是选择 WordPress 镜像。
最简操作
我想到了这个方法,肯定别人也早就想到了,早在几年前就有人做好了,如果觉得下面的方法太麻烦太难懂,想速成,就这样:
这样就启动了一个基于 nginx 的 wordpress ,使用的 sqlite 插件。
这个项目的地址: https://github.com/dorwardv/wordpress-sqlite-nginx-docker
如果你要用这个方法,那下文的那么多内容其实不用看了。如果你想学到更多的东西,请继续看下文。
启动 WordPress 容器
默认镜像
在 WordPress 的默认镜像(latest)中,是使用php的默认镜像,php的默认镜像,是使用的debian系统,加上apache,暴露出 80 端口。所以在docker运行WordPress最快的方式就是
命令运行完,就可以使用浏览器打开 http://localhost 应该就能看到WordPress安装界面了。 注:运行前请确定80端口没有被占用,如果被占用,可以使用另外的端口,在-p参数指定即可,如
-p 8080:80
alpine 镜像
上面是可以正常的运行,但是资源占用可能比在主机中运行更耗资源,要使php占用资源尽可能的小,首选alpine镜像。alpine镜像只提供了最小化系统运行所需。WordPress的alpine镜像tag为
4.8.1-fpm-alpine
,没错,php的 alpine 镜像只有fpm版本。php的 alpine 镜像使用
php:alpine
镜像只启动了php-fpm,fpm监听9000端口(php服务都是监听9000端口),但是这个端口并不是web端口,而是 unix 端口,具体怎么用,我们要先从php的运行流程说起。先看一段nginx 的 php 配置
当浏览器访问一个url时,访问的是nginx或者apache的web服务器,web服务器根据url匹配到这个请求应该给
fastcgi
处理,这个时候fastcgi 会把匹配到的php文件给127.0.0.1:9000
处理,这个9000端口就是php启动的cgi服务,php服务接收到fastcgi 的请求后执行php文件,然后把执行的结果返回给fastcgi,fastcgi在给回 web服务器,web服务器再响应给用户,用户就能看到php代码执行的结果了。写了那么长,其实可以简单地概括成:web服务器接收到请求后,让php服务执行,然后把执行结果返回。
再回到php:alpine镜像,其实这个镜像启动的9000端口就是php服务,WordPress的alpine镜像是基于php:alpine,只是在原本镜像基础上增加了php扩展和把wp源码放在了镜像中。所以说启动WordPress镜像的结果就只是启动了一个php服务罢了,这个php服务本身不接收不处理任何web请求。所以,我们还是需要一个apache或者nginx。
由于nginx比apache更轻量级,所以我选择了nginx,当然,是docker的nginx:alpine镜像。
另一个问题,WordPress源码是在WordPress镜像的
/usr/src/wordpress
里面,运行的时候会把/usr/src/wordpress
复制到/var/www/html
,然后定义了/var/www/html
为挂载目录。这个过程可以在这里看到。这里就需要用到docker的volumes-from参数了,用这个参数指定一个容器启动一个新容器,会让新容器直接使用被指定的容器挂载目录。所以使用这个特性就可以让nginx使用到WordPress镜像的源码了。先启动wordpress镜像,并暴露出端口
第二部,新建一个nginx配置文件
vhost.conf
,内容如下第三部,启动nginx容器
就这样,访问http://localhost 就能到吗wordpress安装界面了
数据库
wordpress总算是开始安装了,不过说好的不用mysql而转用sqlite呢。
官方镜像中,在docker-entrypoint.sh 有mysql数据库的检查代码,我们要先去掉它,先把文件提取出来,删除
TERM=dumb php -- <<'EOPHP' ........ $mysql->close(); EOPHP
的这大段php代码即可,改好后留着备用,待会定制镜像时会放进新镜像中wordpress 使用sqlite 需要用到一个插件: SQLite Integration
插件的使用方法是,把插件解压放到plugins目录,然后把该插件目录的
db.php
放到 wp-content 目录下,在执行安装过程,就能发现跳过了输入数据库信息的过程。定制镜像
把插件也放在镜像里面,每次启动就不用重新复制插件了。这样需要使用 Dockerfile 定制镜像。我们基于wordpress:4-fpm-alpine 镜像去定制
Dockerfile 有了,构建一下新的镜像
构建好后就可以启动了
到此为止,镜像定制完成。
如果使用docker-compose,配置可以这样写
结语
整个过程是很繁琐,但是这种定制在一个稍微复杂项目中我觉得不算什么,我的项目中nginx是做了很多事情的,所以是必须的,而且结果的确达到了节省资源的目的。