资讯专栏INFORMATION COLUMN

手动构建 WordPress 的 Docker 容器

UsherChen / 2418人阅读

摘要:原文来自前中本专栏已经介绍过的基础知识,本文开始进行实战手动使用构建容器。构建的容器有多种方法,本文将会介绍手动构建容器。表示使用本目录的。有了官方镜像,我们手动构建的镜像其实意义不大了。

  

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

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

在我以前的文章中,我们已经介绍了 Docker 的基础知识和基础命令。当然,虽然我们已经介绍了这些知识,我们还没有使用它们做出有价值的东西。构建 WordPress 的 Docker 容器有多种方法,本文将会介绍手动构建容器。如果你还没有认识 Docker,可以戳这里。

设置 MySQL

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

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

按照通常的方法,使用 MySQL 镜像的方法如下:

docker run --name wordpressdb -d mysql:5.7

执行这条命令的时候,如果本机没有 MySQL 镜像,那么 Docker 会从 Docker Pull 先下载镜像。使用 --name 参数指定容器运行时的名字,使用 -d 参数指定再后台运行。

使用 docker ps 命令可以发现,并没有名叫 wordpressdb 的容器在后台运行,但是不应该这样啊。使用 docker logs wordpressdb 查看镜像日志:

error: database is uninitialized and MYSQL_ROOT_PASSWORD not set
  Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?

那么问题出在哪儿?

我们运行了 MySQL,但是没有指明数据库的 root 密码,所以容器并不能运行。所以为了修正这个错误,我们需要删除容器 wordpressdb,然后重新建立容器。Docker 不允许两个容器使用相同的名字。

再次运行容器的时候我们用 -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 了。

构建 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 文件,文件内容是
第三部:使用命令启动容器: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.Xwordpressdb 的 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)等。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/26406.html

相关文章

  • Dokku和Docker完美配合

    摘要:我并没有直接在另外一个容器中安装客户端,而是直接在服务器上安装之前的代码是用来获取指派给数据库服务容器的地址,以便连接。现在我们需要添加配置到现在我们可以启动我们的新服务。原文链接译文原文和的完美配合,一起来辩翻译钟最龙校对李颖杰 看到一篇不错的文章,收藏一下: 【编者的话】本文作者介绍了如何在单机上将Dokku和Docker结合。Dokku是一个小型的PaaS平台,只需使用Git将...

    Aldous 评论0 收藏0
  • Linux运维:docker(2)-镜像与容器

    摘要:用于系统引导的文件系统,包括和容器启动完成后会被卸载以节约内存资源位于之上,表现为容器的根文件系统镜像原理镜像的文件系统被设计为分层存储的架构。分层存储的特征使得镜像的复用,定制变得更加容易。 docker镜像概述 操作系统分为内核kernel和用户空间。对于Linux而言,内核(bootfs)启动后会挂载root文件系统为其提供用户空间支持。而docker镜像,就相当于是一个root...

    wuyumin 评论0 收藏0
  • Docker部署WordPress LNMP(Nginx PHP MySQL)环境实践

    摘要:为了能只使用一个文件就能快速部署环境,我们把及环境的相关配置保存到阿里云的代码托管,然后使用阿里云的镜像仓库从拉取自动构建镜像。编写以上在阿里云创建的镜像到本地,在此项目中创建然后在目录分别创建目录,用于存放它们各自及配置文件。 Docker基于LXC实现了把软件封装到一个完整的文件系统,可以在docker容器中运行所需的一切代码,运行环境,系统工具和系统库。由于docker使用独立于...

    Aklman 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<