Published on

使用 Docker 来部署 Wordpress

Authors
  • avatar
    作者
    老麦

最近一个现实中的朋友不知从哪里知道了我有在网上搭建博客,便找到了我。他的意思是想请我帮他搭建一个简单的博客,然后将他多年在新浪博客上记录的文字转到新的博客上即可。

在博客系统上我综合考虑了很久,认为 Wordpress 更适合我朋友的需求。不得不承认,这么多年过去了,期间哪怕诞生过很多出色的博客系统,但是在博客这个领域中,Wordpress 仍然是最受欢迎的。

我也借此机会记录一下如何使用 Docker 来从零去搭建一个 Wordpress 博客。

前期准备

环境说明

使用全新的 Debian12 系统,并以 root 用户来进行全程操作。

开户 root 用户登陆方法:

  1. 使用具有管理员权限的普通用户登录到系统。

  2. 打开终端或控制台窗口。

  3. 运行以下命令以切换到 root 用户:

sudo su -

这将要求您输入当前用户的密码。

  1. 编辑 /etc/ssh/sshd_config 文件,可以使用任何文本编辑器打开,比如 nano:
nano /etc/ssh/sshd_config

找到文件中的 PermitRootLogin 行,并将其更改为 yes

PermitRootLogin yes

保存并关闭文件。

  1. 重新启动 SSH 服务,以使更改生效。运行以下命令:
systemctl restart sshd

安装 Docker

我选择使用官方的脚本来安装,并通过添加 --mirror Aliyun 来使用阿里云的镜像,更多安装方法可自行查阅官方安装文档。

https://docs.docker.com/

root@Debian12:~# curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

……

Client: Docker Engine - Community
 Version:           24.0.4
 API version:       1.43
 Go version:        go1.20.5
 Git commit:        3713ee1
 Built:             Fri Jul  7 14:51:00 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.4
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.5
  Git commit:       4ffc614
  Built:            Fri Jul  7 14:51:00 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
 runc:
  Version:          1.1.7
  GitCommit:        v1.1.7-0-g860f061
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

================================================================================

当看到上面信息证明已经安装成功,如果需要使用非 root 用户来运行,请依照提示信息查阅相关的文档。

安装成功后的提示信息意思如下:

如果您想以非特权用户身份运行 Docker,请考虑为您的用户设置无根模式 (rootless mode)的 Docker 守护程序:

dockerd-rootless-setuptool.sh install

您可以访问 https://docs.docker.com/go/rootless/ 了解有关无根模式的详细信息。

如果您希望将 Docker 守护程序作为完全特权服务运行,同时授予非 root 用户访问权限,请参考 https://docs.docker.com/go/daemon-access/

警告:在特权 Docker 守护程序上访问远程 API 等效于对主机拥有 root 访问权限。请参阅“Docker 守护程序攻击面”文档了解详情: https://docs.docker.com/go/attack-surface/

Docker 的基础使用

个人认为一般使用者的话,Docker 的使用了解个基础就可以完成大部分的操作了。如果要深一阶的使用可以找相关的系列教程来学,B 站上就有很多这方面的优秀课程视频。

以下是整理好的一些常用的基础命令:

思维导图地址链接:https://www.processon.com/view/link/60aa447b7d9c081691888211

数据目录

按照个人习惯来演示说明:

  1. 在用户目录下创建一个 docker 目录用来保存相关的数据;
mkdir -p ~/docker

这时我们要在 Docker 上运行容器项目的话,一些相关的配置项是要保存起来的,方便以后迁移或者修改配置。我们以 Wordpress 为例,这里我们就可以在 docker 目录再新建一个 wordpress 目录用来存放一些相关的配置。

mkdir -p ~/docker/wordpress
  1. 在 docker 目录下新建一个 data 目录用来保存与各个容器内绑定的数据目录;

使用容器项目时经常需要将容器内的目录绑定到宿主机上,这样子下次启动或者迁移容器时就可以使用之前的数据与文件了。

mkdir -p ~/docker/data

同样以 Wordpress 为例,启动容器命令中的绑定目录指令为:

-v ~/docker/data/wordpress/html:/var/www/html

/var/www/html 为 Wordpress 在容器内存放的目录,这时我们将其绑定到 ~/docker/data/wordpress/html 下,这样子就方便备份与修改相关的文件了。

说明:以上仅仅只是我个人习惯,数据目录存放在什么目录下可随自己习惯而定。

部署 Wordpress

在正式使用 Docker 来部署 Wordpress 之前我想先说明一下,因为我朋友需要使用 redis,因此这个时候需要在 Wordpress 运行的 PHP 环境里安装 redis 这个扩展。

构建自定义镜像

个人认为解决上述需要自定义安装扩展的需求最好的办法就是使用 Dockertfile 来自定义一个镜像。

# 进入docker目录下的wordpress目录
cd ~/docker/wordpress

# 创建并编辑Dockerfile文件
vim Dockerfile

然后按 i 进入编辑模式,将以下内容复制进去后按 ESC 退出编辑模式并输入 :wq 保存退出。

FROM wordpress:php8.2

RUN set -ex; \
    pecl install redis; \
    docker-php-ext-enable redis

接下来使用命令进行构建一个全新的镜像。

docker build -t wordpress-redis .

当构建结束后我们就可以查看本地的镜像库里是否存在刚才构建的库。

docker image ls

REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
wordpress-redis   latest    8e73295d2cad   38 seconds ago   740MB

自定义 PHP 配置参数

主要是解锁上传文件的最大大小,这里请根据自己的实际需求来设定。

~/docker/wordpress 目录下新建一个 custom-config.ini 文件,并将以下配置复制进去后保存退出即可。

upload_max_filesize = 128M
post_max_size = 128M

在 Docker 里创建一个网络

因为我们不单单要运行 Wordpress 的容器,我们还要运行 Mysql、Redis、Phpmyadmin 这些容器来配合 Wordpress,因此事先创建一个网络让这些容器跑在同一个网段里,以达到顺利进行交互的目的。

# 创建一个名为wp的网络
docker network create wp

f7c021110fdeea8a7711d3a87fa613392d022895938ad4e2a04a9c1379b632ee

# 查看网络列表
docker network ls

NETWORK ID     NAME      DRIVER    SCOPE
74a19e0c4a54   bridge    bridge    local
5b5d233ef64d   host      host      local
500123cf3291   none      null      local
f7c021110fde   wp        bridge    local

运行容器

这里要注意的点是 Wordpress 和 Mysql 的用户、密码、数据库一定要一一对应。

Mysql

docker run \
--name mysql \
--network wp \
-e MYSQL_ROOT_PASSWORD=ROOT密码 \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wordpress \
-e MYSQL_PASSWORD=wordpress \
-v ~/docker/data/mysql:/var/lib/mysql \
--restart=unless-stopped \
-d mysql:latest

就这样我们创建了一个名为 mysql 的容器,并加入到之前我们创建好并命名为 wp 的网络里,同时我们加入了四个变量以用作设置对应的 root 用户密码,并分别创建了数据库、用户名和密码,最后还绑定了存放数据的目录到宿主机的 ~/docker/data/mysql

Redis

docker run -d \
  --name redis \
  --network wp \
  -p 6379:6379 \
  -v ~/docker/data/redis:/data \
  --restart=unless-stopped \
  redis:latest \
  redis-server --requirepass redis密码

Phpmyadmin

docker run \
--name phpmyadmin \
--network wp \
-e PMA_HOST=mysql \
-e MYSQL_ROOT_PASSWORD=ROOT密码 \
-p 802:80 \
--restart=unless-stopped \
-d phpmyadmin:latest
注意:这里的 ROOT 密码要与 Mysql 里的一致。

Wordpress

docker run \
--name wordpress \
--network wp \
-e WORDPRESS_DB_NAME=wordpress \
-e WORDPRESS_DB_USER=wordpress \
-e WORDPRESS_DB_PASSWORD=wordpress \
-e WORDPRESS_DB_HOST=mysql \
-v ~/docker/data/wordpress/html:/var/www/html \
-v ~/docker/wordpress/custom-config.ini:/usr/local/etc/php/conf.d/custom-config.ini \
-p 801:80 \
--restart=unless-stopped \
-d wordpress-redis

就这样我们要运行的容器都已经跑起来了,查看运行情况。

# 查看正在运行的容器
docker ps -a

CONTAINER ID   IMAGE               COMMAND                  CREATED              STATUS              PORTS                                       NAMES
a4b4b79721e4   wordpress-redis     "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:801->80/tcp, :::801->80/tcp         wordpress
69fc5a6efb8c   phpmyadmin:latest   "/docker-entrypoint.…"   4 minutes ago        Up 4 minutes        0.0.0.0:802->80/tcp, :::802->80/tcp         phpmyadmin
82fc27949c85   redis:latest        "docker-entrypoint.s…"   6 minutes ago        Up 6 minutes        0.0.0.0:6379->6379/tcp, :::6379->6379/tcp   redis
c98d1031bb49   mysql:latest        "docker-entrypoint.s…"   15 minutes ago       Up 15 minutes       3306/tcp, 33060/tcp                         mysql

# 查看容器是否在我们创建的网络里
docker network inspect wp

[
    {
        "Name": "wp",
        "Id": "f7c021110fdeea8a7711d3a87fa613392d022895938ad4e2a04a9c1379b632ee",
        "Created": "2023-07-25T03:38:23.102986883-04:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "69fc5a6efb8cda9aaf57ab93b4ce77d3a8a63601f45734e447e0c5478d28ce84": {
                "Name": "phpmyadmin",
                "EndpointID": "bd414a7605d850c0762d29c6a8460e882cbc7e73061fe7c7cb65b4ea0bf69d2c",
                "MacAddress": "02:42:ac:12:00:04",
                "IPv4Address": "172.18.0.4/16",
                "IPv6Address": ""
            },
            "82fc27949c8593712eb7c2bf1f78b197dedc049822e588c6eb9d084226142b5b": {
                "Name": "redis",
                "EndpointID": "037a5f6087cbc41f6b7c1967eee3bef1bd06929cdabc179caf5bc9841443ace1",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "a4b4b79721e418bac0d49257d5840dbe76d6d4960c912d968df0cf20b7a50b52": {
                "Name": "wordpress",
                "EndpointID": "d746134b544c2f41dd569e7b68e4053e1c777edb8dfa292df921d29f5150d35b",
                "MacAddress": "02:42:ac:12:00:05",
                "IPv4Address": "172.18.0.5/16",
                "IPv6Address": ""
            },
            "c98d1031bb49531f0acbffa6e5f5da405ae13a8cdddbfb131dfe6bb4e2703f81": {
                "Name": "mysql",
                "EndpointID": "2288d06448dfe42b7653be561d209c92eed6f8169c431bf3fc98f1374ec671d6",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

可以看到我们跑的四个容器都在名为 wp 的网络里,这样子容器之间的交互就打通了。

接下来我们就可以服务 IP 加上 801 这个端口来访问我们的 Wordpress 站点了。

使用 docker-compose 来快速部署 Wordpress

虽然使用上述方法已经非常方便地将 Wordpress 运行起来了,但是因为我们需要跑 4 个容器,因此一个个容器去启动的话还是有点不够优雅的。接下来这个方法更加快捷,只需要一行命令即可完成所有部署。

因为我们是主题是部署 Wordpress,因此 docker-compose.yml 文件我选择存放在 ~/docker/wordpress 这个目录里。

# 首先进入配置目录
cd ~/docker/wordpress

# 新建docker-compose.yml
vim docker-compose.yml

将以下内容复制进去后保存退出即可。

version: '3.8'
services:
  wordpress:
    image: wordpress-redis
    restart: always
    ports:
      - 801:80
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ~/docker/data/wordpress:/var/www/html
      - ~/docker/wordpress/custom-config.ini:/usr/local/etc/php/conf.d/custom-config.ini
    depends_on:
      - redis
    networks:
      - wp
  mysql:
    image: mysql:latest
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
      MYSQL_RANDOM_ROOT_PASSWORD: ROOT密码
    volumes:
      - ~/docker/data/mysql:/var/lib/mysql
    networks:
      - wp
  phpmyadmin:
    image: phpmyadmin:latest
    restart: always
    ports:
      - 802:80
    environment:
      PMA_HOST: mysql
      MYSQL_ROOT_PASSWORD: ROOT密码
    networks:
      - wp
  redis:
    image: redis:latest
    restart: always
    ports:
      - 6379:6379
    volumes:
      - ~/docker/data/redis:/data
    command: ['redis-server', '--requirepass', 'redis密码'] # 如果不设置密码请注释或删除此行
    networks:
      - wp
networks:
  wp:

接下来我们尝试运行一下这个 compose;

root@Debian12:~/docker/wordpress# docker compose up -d
[+] Running 5/5
 ✔ Network wordpress_wp              Created                                                                                        0.0s
 ✔ Container wordpress-redis-1       Started                                                                                        0.6s
 ✔ Container wordpress-mysql-1       Started                                                                                        0.5s
 ✔ Container wordpress-phpmyadmin-1  Started                                                                                        0.5s
 ✔ Container wordpress-wordpress-1   Started

我们可以看到输出的结果就是创建了一个 Network,并且启动了四个容器。这跟我们之前一个一个启动的效果是一样的,只是对应的网络和容器名字有所变化而已,这是因为 docker-compose.yml 文件所在的目录名为 wordpress,因此项目里的容器名字都带有这样的前缀,但实际使用上是没有任何区别的。

关闭 compose;

docker compose down
注意:运行 compose 命令时一定要在 docker-compose.yml 这个文件所在的目录下。

总结

以前将项目直接部署在服务器或者宝塔面板上时,每做一次迁移我都会头皮发麻,单单安装各种环境都要花费大量时间,现在使用 Docker 后一切都变得轻松了起来。

至于上述场景选择单独部署还是选择使用 docker compose 的方式就请按照自己的实际情况来出发,如果你还有项目容器需要连接到 Redis 和 Mysql 上的话,那么单独部署可能会是更好的选择,否则一起打包会更加方便一些。当然,这并不是强制的,灵活配置一下达到你想要的效果即可。