原文来自 How to Manually Build Docker Containers for WordPressphp
前中本专栏已经介绍过 Docker 的基础知识,本文开始进行 Docker 实战:手动使用 Docker 构建 WordPress 容器。同时介绍一下 Docker 官方 MySQL 镜像的爬坑方法,同时演示 Docker 生产中常见的问题以及解决办法。html
在我之前的文章中,咱们已经介绍了 Docker 的基础知识和基础命令。固然,虽然咱们已经介绍了这些知识,咱们尚未使用它们作出有价值的东西。构建 WordPress 的 Docker 容器有多种方法,本文将会介绍手动构建容器。若是你尚未认识 Docker,能够戳这里。mysql
数据库是 WordPress 的基础,本文使用 Docker Hub 来获取 MySQL 镜像。sql
Docker 官方已经构建了 MySQL 镜像。在使用 MySQL 镜像以前,请先读镜像手册。在写本文时,镜像的最新版本是 5.7。docker
按照一般的方法,使用 MySQL 镜像的方法以下:数据库
docker run --name wordpressdb -d mysql:5.7
执行这条命令的时候,若是本机没有 MySQL 镜像,那么 Docker 会从 Docker Pull 先下载镜像。使用 --name
参数指定容器运行时的名字,使用 -d
参数指定再后台运行。apache
使用 docker ps
命令能够发现,并无名叫 wordpressdb
的容器在后台运行,可是不该该这样啊。使用 docker logs wordpressdb
查看镜像日志:bash
error: database is uninitialized and MYSQL_ROOT_PASSWORD not set Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?
那么问题出在哪儿?架构
咱们运行了 MySQL,可是没有指明数据库的 root 密码,因此容器并不能运行。因此为了修正这个错误,咱们须要删除容器 wordpressdb
,而后从新创建容器。Docker 不容许两个容器使用相同的名字。ide
再次运行容器的时候咱们用 -e
参数指定容器内的环境变量MYSQL_ROOT_PASSWORD
:
docker run --name wordpressdb -e MYSQL_ROOT_PASSWORD=password -d mysql:5.7
再次运行 docker logs wordpressdb
的时候,咱们会看到很是长的信息。实际上 MySQL 容器已经在后台运行了,运行 docker ps
也能够看到正在运行的容器 wordpressdb
。
固然你也可使用 MYSQL_DATABASE
参数指定运行容器以前就建立名为 wordpress
的数据库:
docker run --name wordpressdb -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress -d mysql:5.7
固然,MySQL 数据库还有其余的参数,例如指定建立用户和密码。固然,更多的用法就须要参考他们 官方的文档 了。
容器的 IP 会随启动而变化,须要使用 docker inspect --format='{{.NetworkSettings.IPAddress}}' wordpressdb
获取容器的 IP。
固然,Dockerfile 中有不少的容器构建信息。MySQL 基于 debian wheezy 镜像构建,而后启动 mysqld
命令。当使用这个容器的时候,其实只启动了 mysqld
命令。
如今咱们已经有了 MySQL 容器,用户名 root
,密码 password
,数据库名称 wordpress
。下一步就是构建 WordPress 了。
这一步咱们使用PHP 镜像,PHP 镜像镜像也有不少,咱们使用官方提供的带有 Apache 的 php 镜像。
docker run --name wordpress php:5.6-apache
不加 -d
参数,容器便会在前台运行,也能看到应该由 docker logs
输出的数据。
使用 docker inspect --format='{{.NetworkSettings.IPAddress}}' wordpress
命令获取 wordpress
容器的 IP。本文是 172.17.0.35
。
若是你直接访问这个 IP,会获得一个 403 的错误。由于容器中的网站目录在 /var/www/html,可是实际上目录中没有东西,因此 403 forbidden。
那么怎么将文件放入容器的那个文件夹?
第一步:宿主机建立文件夹,而后进入文件夹。
第二部:进入这个文件夹,建立 index.php 文件,文件内容是 <?php phpinfo(); ?>
第三部:使用命令启动容器:docker run --name wordpress -v "$PWD/":/var/www/html php:5.6-apache
。
这样访问 wordpress 容器的 IP(由于是新容器,因此 IP 有变化),便会获得经典的 phpinfo 页面。
测试完成,咱们的容器能够执行 php 文件。
将 wordpress 文件放入本文件夹,chmod 777
,而后从新启动 wordpress
容器,可是会这么提示:
您的PHP彷佛没有安装运行WordPress所必需的MySQL扩展。
官方 php 镜像并未提供 mysql 扩展,因此咱们必需要本身手动写 Dockerfile 安装扩展:
FROM php:5.6-apache # 使用 php:5.6-apache 镜像 RUN docker-php-ext-install mysqli # 使用 docker-php-ext-install 命令安装 mysqli 扩展 CMD ["apache2-foreground"] # 默认启动 apache2-foreground 命令
而后咱们构建这个镜像,镜像名为 phpwithmysql。
docker build -t phpwithmysql .
-t
参数指定构建出的镜像的名称。.
表示使用本目录的 Dockerfile
。
构建完成,便会得 phpwithmysql 镜像,tag 名为 latest。
再次启动 WordPress:
docker run --name wordpress -v "$PWD/":/var/www/html phpwithmysql
此次再使用 IP 访问你的 wordpress:
走到这一步,大部分的事情咱们都作的差很少了,只有一个问题:
万一重启 wordpressdb 容器,数据库容器的 IP 变了怎么办?
Docker 提供了链接参数,让咱们能够将一个容器链接到另外一个容器。
docker run --name wordpress --link wordpressdb:mysql -v "$PWD/":/var/www/html phpwithmysql
新参数是 --link
,做用是将 wordpressdb
链接到 wordpress
容器内,具体为在 wordpress
容器内的 hosts 文件中增长 mysql 172.17.0.X
。172.17.0.X
为 wordpressdb
的 IP。
除此以外,还会修改 wordpress
的环境变量。
所以,安装的时候只需指定数据库主机为 mysql
便可。
可是还有点蛋疼的问题:
wordpress 并不能上传文件,也不能安装主题。由于 wordpress
容器内的 apache
对文件系统没有写权限,因此咱们还得调整 phpwithmysql
镜像的 Dockerfile:
FROM php:5.6-apache RUN docker-php-ext-install mysqli COPY entrypoint.sh /entrypoint.sh RUN chmod 777 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] CMD ["apache2-foreground"]
接下来建立 encrypting.sh 文件:
#!/bin/bash chown -R www-data:www-data . exec "$@"
这是官方 WordPress 镜像构建方法的简化版,可是已经解决了文件系统的写权限问题。
如今构建新的镜像:
docker build -t phpwithmysql:v2 .
删除旧容器并重启:
docker rm -f wordpress docker rm -f wordpressdb docker run --name wordpressdb -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress -d mysql:5.7 docker run --name wordpress --link wordpressdb:mysql -v "$PWD/":/var/www/html phpwithmysql:v2
最后,删除 wp-config.php
文件。
这一次访问 wordpress
的 IP,从新安装 WordPress,即可构建完成。
构建过程可能有些麻烦,因此 WordPress 有官方的各类语言的 Docker 镜像。Docker 不容许容器内的应用对宿主机文件系统有写权限,这究竟是好是坏?我以为应该是好事。咱们能够创立一个数据容器专门负责放文件,这样能够实现架构的多样化。可是对于现有架构的应用例如 WordPress,咱们只能如此变通。
最后一步大概不少人猜获得,就是万一关机了怎么办?wordpress
容器 IP 变化了怎么办?要知道,WordPress 没有配置的状况下爱,是使用 IP 保存站点 URL 的,因此咱们必需要这样修改 wp-config.php
文件:
define('WP_HOME',$_SERVER['SERVER_ADDR']); define('WP_SITEURL',$_SERVER['SERVER_ADDR']);
要注意的是,在 wp-config.php
文件中改变的设置,是没法再在 WordPress 的仪表盘中再改动的。
本文中咱们手动使用 Docker 构建了 WordPress 镜像,可是使用了一个很是曲折的方法。固然,还有更简便的方法,由于 Docker 官方已经构建了 WordPress 镜像。有了官方镜像,咱们手动构建的镜像其实意义不大了。不过,经过调试,咱们演示了 Docker 可能出现的常见问题,例如 IP 变化,以及解决办法(--link)等。