手动构建 WordPress 的 Docker 容器

原文来自 How to Manually Build Docker Containers for WordPressphp

前中本专栏已经介绍过 Docker 的基础知识,本文开始进行 Docker 实战:手动使用 Docker 构建 WordPress 容器。同时介绍一下 Docker 官方 MySQL 镜像的爬坑方法,同时演示 Docker 生产中常见的问题以及解决办法。html

在我之前的文章中,咱们已经介绍了 Docker 的基础知识和基础命令。固然,虽然咱们已经介绍了这些知识,咱们尚未使用它们作出有价值的东西。构建 WordPress 的 Docker 容器有多种方法,本文将会介绍手动构建容器。若是你尚未认识 Docker,能够戳这里mysql

设置 MySQL

数据库是 WordPress 的基础,本文使用 Docker Hub 来获取 MySQL 镜像。sql

Docker 官方已经构建了 MySQL 镜像。在使用 MySQL 镜像以前,请先读镜像手册。在写本文时,镜像的最新版本是 5.7。docker

clipboard.png

按照一般的方法,使用 MySQL 镜像的方法以下:数据库

docker run --name wordpressdb -d mysql:5.7

clipboard.png

执行这条命令的时候,若是本机没有 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 命令。

clipboard.png

如今咱们已经有了 MySQL 容器,用户名 root,密码 password,数据库名称 wordpress。下一步就是构建 WordPress 了。

构建 WorePress 容器

这一步咱们使用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:

clipboard.png

走到这一步,大部分的事情咱们都作的差很少了,只有一个问题:
万一重启 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.Xwordpressdb 的 IP。
除此以外,还会修改 wordpress 的环境变量。

所以,安装的时候只需指定数据库主机为 mysql 便可。

clipboard.png

可是还有点蛋疼的问题:

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)等。

相关文章
相关标签/搜索