Docker Compose快速安装WordPress完整教程:详细步骤与配置指南
介绍
WordPress是一个基于MySQL数据库和PHP处理的免费开源内容管理系统(CMS)。由于其可扩展的插件架构和模板系统,大部分的管理工作可以通过Web界面完成。这就是为什么WordPress在创建各种类型的网站时都是一个受欢迎的选择,从博客到产品页面再到电子商务网站。
运行WordPress通常涉及安装LAMP(Linux、Apache、MySQL和PHP)或LEMP(Linux、Nginx、MySQL和PHP)堆栈,这可能需要花费很多时间。然而,通过使用Docker和Docker Compose等工具,您可以简化设置您所偏好的堆栈和安装WordPress的过程。与手动安装各个组件不同,您可以使用镜像,这些镜像标准化了库、配置文件和环境变量等内容。然后,在容器中运行这些镜像,容器是运行在共享操作系统上的隔离进程。此外,通过使用Compose,您可以协调多个容器之间的通信,例如应用程序和数据库。
在本教程中,您将建立一个多容器的WordPress安装。您的容器将包括一个MySQL数据库、一个Nginx Web服务器和WordPress本身。您还将通过使用Let’s Encrypt获取与您网站相关联的域名的TLS/SSL证书来保护您的安装。最后,您将设置一个定时任务来更新您的证书,以保证您的域名保持安全。
先决条件
为了按照这个教程操作,你需要准备以下物品:
- 一台运行Ubuntu 20.04的服务器,以及一个具有sudo权限的非root用户和活动的防火墙。有关如何设置这些的指导,请阅读我们的《初始服务器设置》指南。
- 在你的服务器上安装Docker,遵循《如何在Ubuntu 20.04上安装和使用Docker》的第1步和第2步。
- 在你的服务器上安装Docker Compose,遵循《如何在Ubuntu 20.04上安装Docker Compose》的第1步。
- 一个注册的域名。本教程将全程使用your_domain作为示例。你可以在Freenom免费获取一个,或使用你选择的域名注册商。
- 为你的服务器设置以下两个DNS记录。你可以按照《硅云DNS简介》了解如何将它们添加到硅云账户的详细信息:
一个将your_domain指向你服务器公网IP地址的A记录。
一个将www.your_domain指向你服务器公网IP地址的A记录。
一旦你把一切都准备好了,你就可以开始第一步了。
第一步——定义Web服务器配置
在运行任何容器之前,你的第一步是为你的Nginx Web服务器定义配置。你的配置文件将包括一些WordPress特定的位置块,以及一个位置块,用于将Let’s Encrypt的验证请求指向Certbot客户端,以实现自动证书续订。
首先,为您的WordPress设置创建一个项目目录。在这个例子中,它被称为wordpress。如果您愿意,您可以给这个目录取一个不同的名字。
- mkdir wordpress
然后导航到目录。
- cd wordpress
接下来,创建一个用于存放配置文件的目录。
- mkdir nginx-conf
用nano或你最喜欢的编辑器打开文件。
- nano nginx-conf/nginx.conf
在这个文件中,添加一个服务器块,包含服务器名称和文档根目录的指令,以及用于指导Certbot客户端请求证书、PHP处理和静态资源请求的位置块。
请将以下代码添加到文件中。请确保将your_domain替换为您自己的域名。
~/wordpress/nginx-conf/nginx.conf 可以被简化为 ~/wp/nginx.conf。
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
index index.php index.html index.htm;
root /var/www/html;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}
我们的服务器区块包括以下信息:
- listen:这告诉Nginx监听端口80,这将允许您使用Certbot的webroot插件进行证书请求。请注意,您尚未包含端口443 — 在成功获取证书后,您将更新配置以包含SSL。
- server_name:这定义了您的服务器名称和应该用于服务器请求的服务器块。请确保将此行中的your_domain替换为您自己的域名。
- index:该指令定义了在处理服务器请求时将用作索引的文件。您在此处修改了默认的优先级顺序,将index.php移到index.html之前,以便Nginx在可能的情况下优先处理名为index.php的文件。
- root:该指令指定服务器请求的根目录。这个目录/var/www/html是由WordPress Dockerfile中的指令在构建时创建的挂载点。这些Dockerfile指令还确保WordPress发行版中的文件被挂载到该卷。
位置区块
- location ~ /.well-known/acme-challenge:此位置块将处理对.well-known目录的请求,Certbot将在该目录中放置临时文件以验证您域名的DNS是否解析到您的服务器。有了此配置,您将能够使用Certbot的webroot插件获取域名的证书。
- location /:在此位置块中,使用try_files指令来检查与单个URI请求匹配的文件。但是,与默认返回404未找到状态不同,您将控制权传递给WordPress的index.php文件,并附带请求参数。
- location ~ \.php$:此位置块将处理PHP处理并将这些请求代理到您的wordpress容器。因为您的WordPress Docker镜像将基于php:fpm镜像,您还将在此块中包含特定于FastCGI协议的配置选项。Nginx需要独立的PHP处理器来处理PHP请求。在这种情况下,这些请求将由php:fpm镜像中包含的php-fpm处理器处理。
此外,此位置块还包括特定于FastCGI的指令、变量和选项,这些选项将请求代理到在wordpress容器中运行的WordPress应用程序,为解析的请求URI设置首选索引,并解析URI请求。 - location ~ /\.ht:此块将处理.htaccess文件,因为Nginx不会提供这些文件。deny_all指令确保.htaccess文件永远不会提供给用户。
- location = /favicon.ico, location = /robots.txt:这些块确保对/favicon.ico和/robots.txt的请求不会被记录。
- location ~* \.(css|gif|ico|jpeg|jpg|js|png)$:此块关闭静态资源请求的日志记录,并确保这些资源具有高度可缓存性,因为它们通常服务成本较高。
关于FastCGI代理的更多信息,请阅读《理解和实现Nginx中的FastCGI代理》。关于服务器和位置块的信息,请查阅《理解Nginx服务器和位置块选择算法》。
在编辑完成后保存并关闭文件。如果您使用的是nano,可以通过按下CTRL+X,然后按Y,最后按下ENTER键来完成操作。
通过设置Nginx配置,您可以继续创建运行时传递给应用程序和数据库容器的环境变量。
步骤2 – 定义环境变量
第三步 – 配置环境变量保护敏感信息
在运行WordPress和数据库容器时,需要配置特定的环境变量以确保应用程序数据的持久化和可访问性。这些变量包含敏感信息(如MySQL root密码、数据库用户和密码)以及非敏感信息(如数据库名称和主机)。
为了避免在Docker Compose主文件中直接设置这些值,最佳实践是将敏感信息存储在单独的.env文件中并限制其访问权限。这种方法可以有效防止敏感数据被意外提交到项目存储库中,从而避免安全风险。
创建.env文件
在您的主项目目录~/wordpress
中,创建一个名为.env的文件:
nano .env
在此文件中,您需要设置MySQL root用户的密码以及WordPress用于访问数据库的用户名和密码。请添加以下变量,并记得为每个变量提供您自己的安全值:
MYSQL_ROOT_PASSWORD=您的root密码
MYSQL_USER=您的WordPress数据库用户名
MYSQL_PASSWORD=您的WordPress数据库密码
编辑完成后,保存并关闭文件。
保护敏感文件
由于.env文件包含敏感信息,您需要确保它被包含在项目的.gitignore和.dockerignore文件中。这样Git和Docker就不会将这些文件复制到您的Git仓库和Docker镜像中。
配置Git忽略文件
如果您计划使用Git进行版本控制,首先将当前工作目录初始化为Git仓库:
git init
然后创建并打开.gitignore文件:
nano .gitignore
将.env文件添加到.gitignore中:
.env
编辑完成后,保存并关闭文件。
配置Docker忽略文件
同样,将.env添加到.dockerignore文件中是一个很好的安全措施,这样在将该目录作为构建上下文时,敏感文件就不会出现在您的容器中。
打开.dockerignore文件:
nano .dockerignore
将.env文件添加到.dockerignore中:
.env
您还可以根据需要添加其他与应用程序开发相关的文件和目录:
.env
.git
docker-compose.yml
.dockerignore
编辑完成后,保存并关闭文件。
第四步 – 使用Docker Compose定义服务
您的docker-compose.yml文件将包含所有服务定义。在Docker Compose中,服务代表运行的容器,而服务定义则指定每个容器的运行配置。
通过使用Compose,您可以定义不同的服务来运行多容器应用程序,因为Compose允许您通过共享网络和卷将这些服务连接在一起。这对您的WordPress设置非常有帮助,因为您将为数据库、WordPress应用程序和Web服务器创建不同的容器。您还将创建一个容器来运行Certbot客户端,以获取用于Web服务器的SSL证书。
首先,在项目目录中创建并打开docker-compose.yml文件:
nano docker-compose.yml
将以下代码添加到您的Compose文件中,包括版本信息和db数据库服务的定义:
version: '3'
services:
db:
image: mysql:8.0
container_name: db
restart: unless-stopped
env_file: .env
environment:
MYSQL_DATABASE: wordpress
volumes:
- dbdata:/var/lib/mysql
command: '--default-authentication-plugin=mysql_native_password'
networks:
- app-network
volumes:
dbdata:
networks:
app-network:
driver: bridge
version: '3'
services:
db:
image: mysql:8.0
container_name: db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_DATABASE=wordpress
volumes:
- dbdata:/var/lib/mysql
command: '--default-authentication-plugin=mysql_native_password'
networks:
- app-network
数据库服务定义包含以下选项:
- image:这告诉Compose要拉取哪个镜像来创建容器。这里你固定使用mysql:8.0镜像,以避免随着mysql:latest镜像不断更新而产生未来的冲突。有关版本固定和避免依赖冲突的更多信息,请阅读Docker文档中关于Dockerfile最佳实践的内容。
- container_name:这为容器指定一个名称。
- restart:这定义了容器的重启策略。默认是no,但你已将容器设置为除非手动停止,否则会重启。
- env_file:这个选项告诉Compose,你希望从位于构建上下文中的名为.env的文件添加环境变量。在这种情况下,构建上下文是你当前的目录。
- environment:这个选项允许你添加额外的环境变量,超出.env文件中定义的那些。你将MYSQL_DATABASE变量设置为wordpress,为你的应用程序数据库提供一个名称。因为这是非敏感信息,你可以直接将其包含在docker-compose.yml文件中。
- volumes:在这里,你将一个名为dbdata的命名卷挂载到容器上的/var/lib/mysql目录。这是大多数发行版上MySQL的标准数据目录。
- command:这个选项指定一个命令来覆盖镜像的默认CMD指令。在这种特定情况下,你将向Docker镜像的标准mysqld命令添加一个选项,该命令在容器上启动MySQL服务器。这个选项–default-authentication-plugin=mysql_native_password将–default-authentication-plugin系统变量设置为mysql_native_password,指定哪种身份验证机制应该管理对服务器的新身份验证请求。由于PHP以及你的WordPress镜像不支持MySQL的较新身份验证默认值,你必须进行此调整以验证你的应用程序数据库用户。
- networks:这指定你的应用程序服务将加入app-network网络,你将在文件底部定义该网络。
接下来,在数据库服务定义下方,增加你的WordPress应用程序服务的定义。
~/wordpress/docker-compose.yml 文件的中文意思是:
...
wordpress:
depends_on:
- db
image: wordpress:5.1.1-fpm-alpine
container_name: wordpress
restart: unless-stopped
env_file: .env
environment:
- WORDPRESS_DB_HOST=db:3306
- WORDPRESS_DB_USER=$MYSQL_USER
- WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
- WORDPRESS_DB_NAME=wordpress
volumes:
- wordpress:/var/www/html
networks:
- app-network
在此服务定义中,您正在命名容器并定义重启策略,就像您在数据库服务中所做的一样。您还添加了一些特定于该容器的选项。
- depends_on: 此选项确保您的容器将按照依赖顺序启动,wordpress容器将在db容器之后启动。您的WordPress应用程序依赖于应用程序数据库和用户的存在,因此表达这种依赖顺序将使您的应用程序能够正常启动。
- image: 在此设置中,您使用的是5.1.1-fpm-alpine WordPress镜像。如步骤1中所述,使用此镜像可确保您的应用程序拥有Nginx处理PHP所需的php-fpm处理器。这也是一个alpine镜像,源自Alpine Linux项目,这将有助于保持您的整体镜像大小较小。有关使用alpine镜像的优缺点以及这对您的应用程序是否有意义的更多信息,请查看Docker Hub WordPress镜像页面的镜像变种部分下的完整讨论。
- env_file: 同样,您指定要从.env文件中提取值,因为这是您定义应用程序数据库用户和密码的地方。
- environment: 在这里,您使用在.env文件中定义的值,但将它们分配给WordPress镜像期望的变量名:WORDPRESS_DB_USER和WORDPRESS_DB_PASSWORD。您还定义了一个WORDPRESS_DB_HOST,它将是运行在db容器上的MySQL服务器,可通过MySQL的默认端口3306访问。您的WORDPRESS_DB_NAME将是您在MySQL服务定义中为MYSQL_DATABASE指定的相同值:wordpress。
- volumes: 您正在将一个名为wordpress的命名卷挂载到WordPress镜像创建的/var/www/html挂载点。以这种方式使用命名卷将允许您与其他容器共享您的应用程序代码。
- networks: 您还将wordpress容器添加到app-network网络。
接下来,在WordPress应用程序服务定义之下,添加以下定义以配置您的Web服务器Nginx服务。
...
webserver:
depends_on:
- wordpress
image: nginx:1.15.12-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
volumes:
- wordpress:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- app-network
在这里,您为容器命名,并设置其依赖于wordpress容器以控制启动顺序。您还使用了alpine版本的Nginx映像——nginx:1.15.12-alpine。
此服务定义还包括以下选项:
- ports: 此配置将容器的80端口暴露出来,以启用您在第一步中定义的nginx.conf文件中的配置选项。
- volumes: 在这里,您定义了命名卷和绑定挂载的组合:
- wordpress:/var/www/html: 这会将您的WordPress应用程序代码挂载到/var/www/html目录,该目录是您在Nginx服务器块中设置为根目录的位置。
- ./nginx-conf:/etc/nginx/conf.d: 这会将主机上的Nginx配置目录绑定挂载到容器中的相应目录,确保您在主机上对文件所做的任何更改都会反映在容器中。
- certbot-etc:/etc/letsencrypt: 这会将您域名的相关Let’s Encrypt证书和密钥挂载到容器中的适当目录。
您还将此容器添加到了app-network网络中。
最后,在Web服务器定义的下方,添加certbot服务的最后一个服务定义。请确保将此处列出的电子邮件地址和域名替换为您自己的信息。
建议的文件路径为:~/wordpress/docker-compose.yml
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- wordpress:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
这个定义告诉Compose从Docker Hub拉取certbot/certbot镜像。它还使用了命名卷来与Nginx容器共享资源,包括certbot-etc中的域名证书和密钥,以及wordpress中的应用程序代码。
再说一遍,你使用了depends_on来指定在webserver服务运行时应启动certbot容器。
你还包含了一个命令选项,用于指定要与容器的默认certbot命令一起运行的子命令。certonly子命令将使用以下选项获取证书。
- –webroot: 这告诉Certbot使用webroot插件将文件放置在webroot文件夹中进行身份验证。此插件依赖于HTTP-01验证方法,该方法使用HTTP请求来证明Certbot可以从响应给定域名的服务器访问资源。
- –webroot-path: 这指定了webroot目录的路径。
- –email: 你用于注册和恢复的首选电子邮件。
- –agree-tos: 这表示你同意ACME的订阅者协议。
- –no-eff-email: 这告诉Certbot你不希望与电子前沿基金会(EFF)共享你的电子邮件。如果你愿意,可以省略此选项。
- –staging: 这告诉Certbot你想要使用Let’s Encrypt的测试环境来获取测试证书。使用此选项允许你测试配置选项并避免可能的域名请求限制。有关这些限制的更多信息,请阅读Let’s Encrypt的速率限制文档。
- -d: 这允许你指定要应用于请求的域名。在这种情况下,你包含了your_domain和www.your_domain。请确保用你自己的域名替换这些。
在certbot服务定义的下方添加你的网络和卷定义:
...
volumes:
certbot-etc:
wordpress:
dbdata:
networks:
app-network:
driver: bridge
您的顶级卷键定义了卷certbot-etc、wordpress和dbdata。当Docker创建卷时,卷的内容存储在由Docker管理的主机文件系统的/var/lib/docker/volumes/目录中。然后,每个卷的内容都会从该目录挂载到使用该卷的任何容器中。通过这种方式,可以在容器之间共享代码和数据。
用户定义的桥接网络应用网络允许容器间的通信,因为它们位于同一台Docker守护进程主机上。这样可以简化应用程序内部的流量和通信,因为它在同一桥接网络上打开了所有容器之间的端口,同时不向外界公开任何端口。因此,您的数据库、WordPress和Web服务器容器可以彼此通信,您只需要暴露80端口以供应用程序的前端访问。
以下是完整的docker-compose.yml文件:
以下是docker-compose.yml文件的整个内容:
~/wordpress/docker-compose.yml可以改写为:~/wordpress/docker-compose文件。
version: '3'
services:
db:
image: mysql:8.0
container_name: db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_DATABASE=wordpress
volumes:
- dbdata:/var/lib/mysql
command: '--default-authentication-plugin=mysql_native_password'
networks:
- app-network
wordpress:
depends_on:
- db
image: wordpress:5.1.1-fpm-alpine
container_name: wordpress
restart: unless-stopped
env_file: .env
environment:
- WORDPRESS_DB_HOST=db:3306
- WORDPRESS_DB_USER=$MYSQL_USER
- WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
- WORDPRESS_DB_NAME=wordpress
volumes:
- wordpress:/var/www/html
networks:
- app-network
webserver:
depends_on:
- wordpress
image: nginx:1.15.12-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
volumes:
- wordpress:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- app-network
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- wordpress:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
volumes:
certbot-etc:
wordpress:
dbdata:
networks:
app-network:
driver: bridge
当您编辑完毕,请保存并关闭文件。
现在,您已经有了服务定义,可以启动容器并测试证书请求了。
第四步:获取SSL证书和凭证
使用docker-compose up
命令启动容器,按照您指定的顺序创建并运行容器。通过添加-d
参数,该命令会在后台运行数据库、WordPress和Web服务器容器。
$ docker-compose up -d
以下输出确认您的服务已经创建成功:
Creating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot ... done
使用docker-compose ps
命令,查看您的服务的状态。
$ docker-compose ps
完成后,您的数据库、WordPress和Web服务器服务将处于运行状态,并且certbot容器将以退出状态0退出。
Name Command State Ports
---------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
db docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp
webserver nginx -g daemon off; Up 0.0.0.0:80->80/tcp
wordpress docker-entrypoint.sh php-fpm Up 9000/tcp
如果数据库、WordPress或Web服务器服务的”State”列中显示除”运行中”以外的任何状态,或者certbot容器的退出状态不是0,这意味着您可能需要使用docker-compose logs
命令检查服务日志。
$ docker-compose logs service_name
现在您可以使用docker-compose exec
命令检查您的证书是否已经挂载到Web服务器容器上。
$ docker-compose exec webserver ls -la /etc/letsencrypt/live
一旦您的证书请求成功,下面是输出内容:
total 16
drwx------ 3 root root 4096 May 10 15:45 .
drwxr-xr-x 9 root root 4096 May 10 15:45 ..
-rw-r--r-- 1 root root 740 May 10 15:45 README
drwxr-xr-x 2 root root 4096 May 10 15:45 your_domain
既然您知道您的请求会成功,您可以编辑certbot服务定义,移除--staging
标志。
打开 docker-compose.yml 文件。
$ nano docker-compose.yml
在文件中找到certbot服务定义的部分,并用命令选项中的--force-renewal
标志替换--staging
标志,这将告诉Certbot您希望使用与现有证书相同的域名请求新证书。以下是更新标志的certbot服务定义:
~/wordpress/docker-compose.yml
...
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- wordpress:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...
您现在可以运行docker-compose up来重新创建certbot容器。您还需在命令中加上–no-deps选项,告诉Compose可以跳过启动webserver服务的步骤,因为它已经在运行中。
- docker-compose up –force-recreate –no-deps certbot
以下输出表明您的证书请求成功:
重新创建certbot ... 完成
连接到certbot
certbot | 将调试日志保存到 /var/log/letsencrypt/letsencrypt.log
certbot | 选择的插件:验证器 webroot,安装程序 无
certbot | 续订现有证书
certbot | 执行以下挑战:
certbot | 对 your_domain 的 http-01 挑战
certbot | 对 www.your_domain 的 http-01 挑战
certbot | 对所有未匹配的域名使用 webroot 路径 /var/www/html
certbot | 等待验证...
certbot | 清理挑战
certbot | 重要说明:
certbot | - 恭喜!您的证书和链已保存在:
certbot | /etc/letsencrypt/live/your_domain/fullchain.pem
certbot | 您的密钥文件已保存在:
certbot | /etc/letsencrypt/live/your_domain/privkey.pem
certbot | 您的证书将于 2019-08-08 过期。要在将来获取新的或调整的
certbot | 证书版本,只需再次运行 certbot
certbot | 要非交互式续订所有证书,请运行
certbot | "certbot renew"
certbot | - 您的帐户凭据已保存在 Certbot
certbot | 配置目录 /etc/letsencrypt 中。您现在应该制作一个
certbot | 此文件夹的安全备份。此配置目录将
certbot | 还包含由 Certbot 获取的证书和私钥,因此
certbot | 定期备份此文件夹是理想的。
certbot | - 如果您喜欢 Certbot,请考虑通过以下方式支持我们的工作:
certbot |
certbot | 向 ISRG / Let's Encrypt 捐款:https://letsencrypt.org/donate
certbot | 向 EFF 捐款:https://eff.org/donate-le
certbot |
certbot 以代码 0 退出
有了您的证书,您可以继续修改您的Nginx配置以包含SSL。
步骤五 – 修改网络服务器配置和服务定义
在您的Nginx配置中启用SSL将涉及到添加一个HTTP重定向到HTTPS,指定SSL证书和密钥的位置,以及添加安全参数和头部。
由于您将重新创建Web服务器服务以包含这些附加功能,您现在可以停止它。
- docker-compose stop webserver
在修改配置文件之前,使用curl从Certbot获取推荐的Nginx安全参数。
- curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf
这个命令将把这些参数保存在一个名为 options-ssl-nginx.conf 的文件中,该文件位于 nginx-conf 目录中。
接下来,删除你之前创建的Nginx配置文件。
- rm nginx-conf/nginx.conf
创建并打开文件的另一个版本。
- nano nginx-conf/nginx.conf
请将以下代码添加到文件中,以将HTTP重定向到HTTPS,并添加SSL凭据、协议和安全标头。请记得将your_domain替换为您自己的域名。
~/wordpress/nginx-conf/nginx.conf~/wordpress/nginx-conf/nginx.conf
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your_domain www.your_domain;
index index.php index.html index.htm;
root /var/www/html;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
include /etc/nginx/conf.d/options-ssl-nginx.conf;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}
HTTP 服务器块指定 Certbot 更新请求的网站根目录为 `.well-known/acme-challenge` 目录。它还包括一个重写指令,将 HTTP 请求指向根目录并转换为 HTTPS。
HTTPS服务器块启用了SSL和HTTP2。要了解有关HTTP/2对HTTP协议的迭代以及其对网站性能的好处的更多信息,请阅读《如何在Ubuntu 18.04上设置支持HTTP/2的Nginx》的介绍部分。
该块还包括您SSL证书和密钥的位置,以及您保存在nginx-conf/options-ssl-nginx.conf中的已建议的Certbot安全参数。
此外,还包括一些安全头部,能够使您在SSL Labs和Security Headers服务器测试网站上获得A级评价。这些头部包括X-Frame-Options、X-Content-Type-Options、引荐政策、内容安全策略以及X-XSS-Protection。HTTP严格传输安全(HSTS)头部被注释掉了 —— 只有在您理解相关影响并评估其”preload”功能后才能启用。
您的根目录和索引指令也位于此块中,与第一步中讨论的其余WordPress特定的位置块一样。
编辑完成后,保存并关闭文件。
在重新创建网络服务器服务之前,您需要向网络服务器服务定义中添加一个443端口映射。
打开你的 docker-compose.yml 文件。
- nano docker-compose.yml
在Web服务器服务定义中,添加以下端口映射:
~/wordpress/docker-compose.yml
...
webserver:
depends_on:
- wordpress
image: nginx:1.15.12-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- wordpress:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- app-network
编辑后的内容如下,这是完整的docker-compose.yml文件。
version: '3'
services:
db:
image: mysql:8.0
container_name: db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_DATABASE=wordpress
volumes:
- dbdata:/var/lib/mysql
command: '--default-authentication-plugin=mysql_native_password'
networks:
- app-network
wordpress:
depends_on:
- db
image: wordpress:5.1.1-fpm-alpine
container_name: wordpress
restart: unless-stopped
env_file: .env
environment:
- WORDPRESS_DB_HOST=db:3306
- WORDPRESS_DB_USER=$MYSQL_USER
- WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
- WORDPRESS_DB_NAME=wordpress
volumes:
- wordpress:/var/www/html
networks:
- app-network
webserver:
depends_on:
- wordpress
image: nginx:1.15.12-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- wordpress:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- app-network
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- wordpress:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email 你的邮箱@你的域名 --agree-tos --no-eff-email --force-renewal -d 你的域名 -d www.你的域名
volumes:
certbot-etc:
wordpress:
dbdata:
networks:
app-network:
driver: bridge
编辑完成后保存并关闭文件。
重建Web服务器服务。
- docker-compose up -d –force-recreate –no-deps webserver
请使用docker-compose ps命令检查您的服务。
- docker-compose ps
输出应指示您的数据库、WordPress和Web服务器服务正在运行。
名称 命令 状态 端口
--------------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
db docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp
webserver nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress docker-entrypoint.sh php-fpm Up 9000/tcp
第六步:通过网络界面完成WordPress安装
在您的容器运行时,您可以通过Web界面完成WordPress安装。在容器运行的情况下,通过WordPress的网页界面完成安装。
在您的浏览器中,导航到您服务器的域名。请记得将your_domain
替换为您自己的域名:
https://your_domain
请选择您希望使用的语言:

点击”继续”后,您将会进入主设置页面,您需要为您的网站选择一个名称和一个用户名。在这里选择一个容易记住的用户名(而不是”admin”)和一个强密码是一个好主意。您可以使用WordPress自动生成的密码,也可以自己创建密码。
最后,您需要输入您的电子邮件地址,并决定是否要阻止搜索引擎对您的网站进行索引。

点击页面底部的”安装WordPress”按钮会带您到登录界面。

一旦登录,您将可以访问WordPress管理仪表板。

完成WordPress安装后,您可以采取措施确保您的SSL证书能够自动更新。
步骤 7 — 更新Let’s Encrypt证书
Let’s Encrypt证书有效期为90天。您可以设置自动更新流程以确保其不过期。其中一种方法是使用cron定时工具创建一个任务。在下面的示例中,您将创建一个cron任务,定期运行一个脚本来更新您的证书并重新加载您的Nginx配置。
首先,创建一个名为 ssl_renew.sh 的脚本:
nano ssl_renew.sh
将以下代码添加到脚本中,以更新您的证书并重新加载您的Web服务器配置。请记住将示例用户名sammy
替换为您自己的非根用户名:
#!/bin/bash
COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"
cd /home/sammy/wordpress/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af
这个脚本的工作原理如下:
- 首先,将docker-compose二进制文件路径指定给COMPOSE变量,并添加–no-ansi选项以禁用ANSI控制字符。
- 然后,将docker二进制文件路径指定给DOCKER变量。
- 接着,切换到~/wordpress项目目录,并执行以下操作:
- 使用
docker-compose run
命令启动certbot容器并运行renew子命令,该命令会更新即将到期的证书。–dry-run选项用于测试脚本。 - 使用
docker-compose kill
命令向webserver容器发送SIGHUP信号,以重新加载Nginx配置。 - 最后,运行
docker system prune
命令来移除所有未使用的容器和镜像。
编辑完成后保存并关闭文件。使用以下命令使其可执行:
chmod +x ssl_renew.sh
接下来,打开您的根crontab文件,以在指定的时间间隔运行续订脚本:
sudo crontab -e
如果这是您第一次编辑此文件,您将被要求选择一个编辑器:
no crontab for root - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed
Choose 1-4 [1]:
在这个文件的最底部,添加如下一行,以设置定时任务:
...\n*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1\n
\n这将把任务间隔设置为每五分钟一次,这样你就可以测试你的续订请求是否按预期工作。一个名为cron.log的日志文件将被创建来记录任务的相关输出。\n\n五分钟后,检查cron.log文件以确认续约请求是否成功。\n
\n
- \n
- tail -f /var/log/cron.log
\n
\n
\n \n
\n下面的输出证实了成功续订。\n
\n
\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** 试运行:模拟证书到期时的'certbot renew'操作 **(下面的测试证书尚未保存。)恭喜,所有续订均已成功。以下证书已续订:/etc/letsencrypt/live/your_domain/fullchain.pem(成功)** 试运行:模拟证书到期时的'certbot renew'操作 **(上面的测试证书尚未保存。)- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n
\n在命令行中输入CTRL+C,以退出。\n\n你可以修改定时任务表文件来设置每日的间隔。例如,要在每天中午运行脚本,你可以修改文件的最后一行为以下内容。\n
...\n0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1\n
\n您还需要从您的ssl_renew.sh脚本中移除--dry-run选项。\n
#!/bin/bash\n\nCOMPOSE="/usr/local/bin/docker-compose --no-ansi"\nDOCKER="/usr/bin/docker"\n\ncd /home/sammy/wordpress/\n$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver\n$DOCKER system prune -af\n
\n你的定时任务将确保你的Let's Encrypt证书在符合条件时进行续订,以防止过期。你还可以使用日志轮转工具设置日志轮转并压缩日志文件。\n
结论
在这个教程中,你使用Docker Compose来创建一个带有Nginx web服务器的WordPress安装。作为工作流的一部分,你获取了与你的WordPress网站关联的域名的TLS/SSL证书。此外,你创建了一个定时任务,在需要时更新这些证书。\n\n为进一步提高网站性能和冗余度,您可以参考以下有关WordPress资源传递和备份的文章。\n
- \n
- 如何使用Silicon Cloud Spaces CDN加速WordPress资源传递。
- 如何将WordPress网站备份到Spaces。
- 如何在Silicon Cloud Spaces上存储WordPress资源。
\n
\n
\n
\n如果你对使用Kubernetes进行容器化工作流感兴趣,你还可以查看:\n
- \n
- 如何使用Helm在Kubernetes上设置WordPress与MySQL。
\n