介绍
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 证书来保护您的安装。最后,您将设置一个 cron 任务来续订证书,以确保您的域名安全。.
先决条件
- 一台运行Ubuntu系统的服务器,使用具有权限的非root用户。
sudo并启用防火墙。. - 您的服务器上已安装 Docker。.
- 您的服务器上必须安装 Docker Compose。.
- 已注册的域名。本教程将完整使用您的域名。.
- 以下两条 DNS 记录已为您的服务器设置。.
一条记录,其 your_domain 指向您服务器的公共 IP 地址。.
指向您服务器公共 IP 地址的 www.your_domain 记录。.
步骤 1 – 定义 Web 服务器配置
在运行任何容器之前,第一步是配置 Nginx Web 服务器。您的配置文件包含一些 WordPress 特有的 location 块,以及一个用于将 Let's Encrypt 验证请求路由到 Certbot 客户端以实现证书自动续期的 location 块。.
首先,创建一个用于存放 WordPress 项目目录。在本例中,我们将目录命名为 WordPress。您可以根据需要将此目录命名为其他名称:
mkdir wordpress然后进入该目录:
cd wordpress接下来,创建一个目录来存放配置文件:
mkdir nginx-conf文件 纳米 或者打开你最喜欢的编辑器:
nano nginx-conf/nginx.conf在此文件中,添加一个服务器块,其中包含服务器名称和文档根目录的说明,以及用于指导 Certbot 客户端对证书、PHP 处理和固定资产请求的位置块。.
将以下代码添加到文件中。请务必将 your_domain 替换为您的域名:
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;
}
} 我们的服务器块包含以下信息:
指示:
听这会指示 Nginx 监听 80 端口,以便您可以使用 Webroot Certbot 插件来请求证书。请注意,您尚未设置 443 端口——您需要在成功收到证书后更新配置以启用 SSL。.服务器名称:指定您的服务器名称以及用于向服务器发送请求的服务器块。请务必将此行中的 your_domain 替换为您的域名。.指数此指令定义了在处理服务器请求时用作索引的文件。您在此处更改了默认优先级顺序,并将 index.php 移到了 index.html 之前,以便 Nginx 尽可能优先处理名为 index.php 的文件。.根此指令指定服务器请求的根目录。该目录 /var/www/html 由 WordPress Dockerfile 中的指令在构建时创建为挂载点。这些 Dockerfile 指令还确保 WordPress 版本文件安装在此卷上。.
位置块:
位置 ~ /.well-known/acme-challenge此模块处理对 .well-known 目录的请求,Certbot 会在该目录下放置一个临时文件,以验证您的域名 DNS 是否解析到您的服务器。通过此配置,您可以使用 Webroot Certbot 插件为您的域名获取证书。.地点/:在此位置代码块中,使用 try_files 指令来检查是否存在与请求的 URI 匹配的文件。但是,与默认返回 404 Not Found 状态不同,您将控制权交给 WordPress 的 index.php 文件,并传递请求参数。.location ~ \.php$:此位置块处理 PHP 请求,并将这些请求代理到您的 WordPress 容器。由于您的 WordPress Docker 镜像基于 php:fpm 镜像,因此您还需要在此块中包含 FastCGI 协议特有的配置选项。Nginx 需要一个单独的 PHP 处理器来处理 PHP 请求。在这种情况下,这些请求将由 php:fpm 镜像自带的 php-fpm 处理器处理。此外,此位置块还包含 FastCGI 特有的指令、变量和选项,用于配置代理请求到运行在 WordPress 容器中的 WordPress 应用程序、设置已解析请求 URI 的优先级列表以及解析请求 URI。.位置 ~ /\.ht此代码块处理 .htaccess 文件,因为 Nginx 不提供这些文件。deny_all 指令确保 .htaccess 文件永远不会提供给用户。.location = /favicon.ico, location = /robots.txt这些代码块确保不会记录对 /favicon.ico 和 /robots.txt 的请求。.location ~* \.(css|gif|ico|jpeg|jpg|js|png)$:此模块禁用固定资产请求的日志记录,并确保这些资产具有很高的可缓存性,因为它们的维护成本通常很高。.
编辑完成后,请保存并关闭文件。如果您使用的是 nano 编辑器,请按 CTRL+X,Y,然后回车。配置好 Nginx 后,您可以继续创建环境变量,以便在运行时传递给应用程序和数据库容器。.
步骤 2 – 定义环境变量
为了确保应用程序数据可用且可供应用程序访问,您的 WordPress 应用程序数据库和容器需要在运行时访问某些环境变量。这些变量包含敏感信息和非敏感信息:敏感值包括 MySQL root 密码和应用程序数据库的用户名和密码,非敏感值包括应用程序数据库的名称和主机。与其在 Docker Compose 文件(包含容器运行信息的主要文件)中设置所有这些值,不如将敏感值设置在单独的环境变量文件中,并限制其传播范围。这样可以防止这些值被复制到项目仓库中并公开可见。.
在项目根目录 ~/wordpress 中,打开一个名为 .env 的文件:
nano .env此文件中设置的密钥值包括 MySQL root 用户的密码,以及 WordPress 用于访问数据库的用户名和密码。请将以下变量名和值添加到文件中。请记住,您需要为每个变量提供您自己的值:
MYSQL_ROOT_PASSWORD=your_root_password MYSQL_USER=your_wordpress_database_user MYSQL_PASSWORD=your_wordpress_database_password
请为根管理员账户设置密码,并填写您希望用于应用程序数据库的用户名和密码。编辑完成后,保存并关闭文件。.
由于您的 env 文件包含敏感信息,因此您需要确保将其添加到项目的 .gitignore 和 .dockerignore 文件中。这样可以分别告诉 Git 和 Docker 哪些文件不要复制到您的 Git 仓库和 Docker 镜像中。.
使用 git init:
git init然后创建并打开一个 .gitignore 文件:
nano .gitignore将环境变量添加到文件中:
.env编辑完成后,请保存并关闭文件。.
同样,将 .env 添加到 .dockerignore 文件中是一个很好的预防措施,这样当您使用此目录作为构建上下文时,它就不会被包含在您的容器中。.
打开文件:
nano .dockerignore将环境变量添加到文件中:
.env
在此下方,您可以选择添加与应用程序开发相关的文件和目录:
.env
.git
docker-compose.yml
.dockerignore完成后保存并关闭文件。.
敏感信息准备就绪后,您现在可以继续在 docker-compose.yml 文件中定义您的服务。.
步骤 3 – 使用 Docker Compose 定义服务
您的 docker-compose.yml 文件将包含您配置的服务定义。在 Compose 中,服务指的是正在运行的容器,服务定义则指定了每个容器的运行方式。.
使用 Compose,您可以定义不同的服务来运行多容器应用程序,因为 Compose 允许您将这些服务通过共享网络和卷连接起来。这对于您当前的设置非常有用,因为您需要为数据库、WordPress 应用程序和 Web 服务器创建不同的容器。您还需要创建一个容器来运行 Certbot 客户端,以便为您的 Web 服务器获取证书。.
首先,创建并打开 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
数据库服务定义包含以下选项:
图像这告诉 Compose 要拉取哪个镜像来创建容器。这里指定使用 mysql:8.0 镜像是为了避免 mysql:latest 镜像持续更新时出现冲突。有关版本锁定和避免依赖冲突的更多信息,请阅读 Docker 文档中关于 Dockerfile 最佳实践的部分。.容器名称:指定容器的名称。.重启此策略指定容器是否重启。默认值为否,但您已将容器配置为除非手动停止,否则会自动重启。.环境文件此选项告诉 Compose,您希望从位于构建上下文中的名为 .env 的文件中添加环境变量。在本例中,构建上下文是您的当前目录。.环境此选项允许您添加除 .env 文件中定义的环境变量之外的其他环境变量。您可以将 MYSQL_DATABASE 变量设置为 wordpress,为您的应用程序数据库指定一个名称。由于此信息不涉及敏感信息,您可以将其直接添加到 docker-compose.yml 文件中。.卷这里,您正在容器的 /var/lib/mysql 文件夹中挂载一个名为 dbdata 的卷。这是大多数发行版中 MySQL 的标准数据目录。.命令此选项指定一个命令来覆盖镜像的默认 CMD 命令。在本例中,您将向启动容器上 MySQL 服务器的标准 mysqld Docker 镜像命令添加一个选项。此选项 `--default-authentication-plugin=mysql_native_password` 将系统变量 `--default-authentication-plugin` 设置为 `mysql_native_password`,并指定应使用哪种身份验证机制来处理发送到服务器的新身份验证请求。由于 PHP(以及您的 WordPress 镜像)不支持新的 MySQL 身份验证默认机制,因此您需要配置此选项来验证您的应用程序数据库用户。.- networks: 这指定您的应用程序服务将加入您在文件底部定义的 application-network 网络。.
然后,在数据库服务定义下方,添加 WordPress 应用程序服务定义:
... 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
在此服务定义中,您需要为容器命名并定义重启策略,就像您为数据库服务所做的那样。您还需要向此容器添加一些特定选项:
依赖于此选项可确保容器按依赖顺序启动,WordPress 容器在数据库容器之后启动。WordPress 应用程序依赖于数据库和应用程序用户的存在,因此指定此依赖顺序可确保应用程序正常启动。.图像在此配置中,您将使用 WordPress 5.1.1-fpm-alpine 镜像。如步骤 1 所述,使用此镜像可确保您的应用程序拥有 Nginx 处理 PHP 所需的 php-fpm 处理器。此外,此镜像源自 Alpine Linux 项目,因此有助于减小镜像的整体大小。有关使用 Alpine 镜像的优缺点以及它是否适合您的应用程序的更多信息,请参阅 WordPress Docker Hub 镜像页面上的“镜像变体”部分的完整讨论。.环境文件您再次指定要从 .env 文件中提取值,因为您在此处定义了应用程序数据库的用户和密码。.环境这里,您使用的是在 .env 文件中定义的值,但将它们分配给 WordPress 镜像所期望的变量名:WORDPRESS_DB_USER 和 WORDPRESS_DB_PASSWORD。您还定义了 WORDPRESS_DB_HOST,它将指向运行在数据库容器上、可通过默认 MySQL 端口 3306 访问的 MySQL 服务器。您的 WORDPRESS_DB_NAME 将与您在 MySQL 服务定义中为 MYSQL_DATABASE 指定的值相同:wordpress。.卷您正在将名为 wordpress 的卷挂载到 WordPress 镜像创建的 /var/www/html 挂载点。通过这种方式使用命名卷,您可以将应用程序代码与其他容器共享。.网络您还将 WordPress 容器添加到应用程序网络。.
然后,在 WordPress 应用程序服务定义下,为您的 Nginx Web 服务器服务添加以下定义:
... 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 镜像——即 1.15.12-alpine 版本的 Nginx 镜像。.
此服务定义还包括以下选项:
端口:这将开放端口 80,以启用您在步骤 1 中在 nginx.conf 文件中定义的配置选项。.卷在这里,您可以定义命名卷和挂载点的组合:- wordpress:/var/www/html: 此代码会将您的 WordPress 应用程序放置在 /var/www/html 文件夹中,该目录是您在 Nginx 服务器块中设置为根目录的目录。.
./nginx-conf:/etc/nginx/conf.d这将把主机上的 Nginx 配置文件夹连接到容器中的相应目录,确保对主机上的文件所做的任何更改都会反映在主机上。.certbot-etc:/etc/letsencrypt这会将您域名的 Let's Encrypt 证书和密钥安装到容器上的相应目录中。.
您已将此容器添加到应用程序网络。.
最后,在您的 Web 服务器定义下,添加 certbot 服务的最终服务定义。请务必将此处列出的电子邮件地址和域名替换为您自己的信息:
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 中的应用程序代码。此外,您使用了 dependent_on 来指定 certbot 容器应在 Web 服务器服务启动后启动。您还添加了一个命令选项,用于指定要与容器默认 certbot 命令一起运行的子命令。certonly 子命令使用以下选项获取证书:
--webroot这指示 Certbot 使用 webroot 插件将文件放置在 webroot 文件夹中以进行身份验证。该插件依赖于 HTTP-01 身份验证方法,该方法使用 HTTP 请求来证明 Certbot 可以访问响应给定域名的服务器的资源。.--webroot-path:这指定了网站根目录的路径。.- 电子邮件:您用于注册和恢复的电子邮件地址。.--同意这表明您同意 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 创建卷时,卷的内容存储在主机文件系统上的一个目录 /var/lib/docker/volumes/ 中,该目录由 Docker 管理。然后,每个卷的内容都会从此目录挂载到使用该卷的任何容器。这样就允许在容器之间共享代码和数据。.
用户自定义桥接网络应用网络允许容器之间进行通信,因为它们与 Docker 守护进程位于同一主机上。这简化了应用内部的流量和通信,因为它会打开同一桥接网络上所有容器之间的端口,而无需将任何端口暴露给外部。因此,您的数据库、WordPress 和 Web 服务器容器可以相互通信,而您只需暴露 80 端口以供前端访问应用即可。.
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" 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以下输出确认您的服务已创建:
Output
Creating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot ... done使用 docker-compose ps 命令检查服务状态:
docker-compose ps完成后,您的数据库、WordPress 和 Web 服务器服务将启动,certbot 容器将以状态 0 消息退出:
Output
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 服务器服务的“状态”列中显示的内容不是上述内容,或者 certbot 容器的退出状态不是 0,则表示您可能需要使用 docker-compose logs 命令检查服务日志:
docker-compose logs service_name现在您可以使用 docker-compose exec 命令验证您的证书是否已安装到 Web 服务器容器中:
docker-compose exec webserver ls -la /etc/letsencrypt/live当您的证书请求成功时,代码输出如下:
Output
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 服务定义的部分,并将命令选项中的 `--staging` 替换为 `--force-renewal`,这会告诉 Certbot 您要申请一个具有相同域名的新证书。证书信息会在 certbot 服务定义下方更新,更新后的变量如下:
...
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 来重新创建 certbot 容器。你还需要添加 --no-deps 选项,告诉 Compose 可以跳过启动 Web 服务器服务,因为它已经在运行了:
docker-compose up --force-recreate --no-deps certbot以下输出表明您的证书请求已成功:
Output Recreating certbot ... done Attaching to certbot certbot | Saving debug log to /var/log/letsencrypt/letsencrypt.log certbot | Plugins selected: Authenticator webroot, Installer None certbot | Renewing an existing certificate certbot | Performing the following challenges: certbot | http-01 challenge for your_domain certbot | http-01 challenge for www.your_domain certbot | Using the webroot path /var/www/html for all unmatched domains. certbot | Waiting for verification... certbot | Cleaning up challenges certbot | IMPORTANT NOTES: certbot | - Congratulations! Your certificate and chain have been saved at: certbot | /etc/letsencrypt/live/your_domain/fullchain.pem certbot | Your key file has been saved at: certbot | /etc/letsencrypt/live/your_domain/privkey.pem certbot | Your cert will expire on 2019-08-08. To obtain a new or tweaked certbot | version of this certificate in the future, simply run certbot certbot | again. To non-interactively renew *all* of your certificates, run certbot | "certbot renew" certbot | - Your account credentials have been saved in your Certbot certbot | configuration directory at /etc/letsencrypt. You should make a certbot | secure backup of this folder now. This configuration directory will certbot | also contain certificates and private keys obtained by Certbot so certbot | making regular backups of this folder is ideal. certbot | - If you like Certbot, please consider supporting our work by: certbot | certbot | Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate certbot | Donating to EFF: https://eff.org/donate-le certbot | certbot exited with code 0
有了证书之后,你就可以修改 Nginx 配置以启用 SSL 了。.
步骤 5 – 更改 Web 服务器配置和服务定义
在 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该命令会将这些参数保存到位于 nginx-conf 目录中的名为 options-ssl-nginx.conf 的文件中。.
接下来,删除之前创建的 Nginx 配置文件:
rm nginx-conf/nginx.conf创建并打开该文件的另一个版本:
nano nginx-conf/nginx.conf将以下代码添加到文件中,以将 HTTP 重定向到 HTTPS,并添加凭据、协议和 SSL 安全标头。请务必将 your_domain 替换为您的域名:
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 和 HTTP/2。要了解有关 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、Referrer Policy、Content-Security-Policy 和 X-XSS-Protection。HTTP 严格传输安全 (HSTS) 标头也已在文档中解释——仅当您理解其概念并评估过其“预加载”功能后才启用它。.
您的根目录和目录指令也位于此代码块中,就像步骤 1 中讨论的其他 WordPress 特定位置代码块一样。编辑完成后,保存并关闭文件。.
在重新创建 Web 服务器服务之前,需要将 443 端口映射添加到 Web 服务器服务定义中。.
打开你的 docker-compose.yml 文件:
nano docker-compose.yml在 Web 服务器服务定义中,添加以下端口映射:
...
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 sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain 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 服务器服务正在运行:
Output
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:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress docker-entrypoint.sh php-fpm Up 9000/tcp容器运行后,您可以通过网页界面完成 WordPress 安装。.
步骤 6 – 通过网页界面完成安装
在容器运行期间,通过 WordPress 网页界面完成安装。.
在您的网络浏览器中,访问您的服务器域名。请务必将 your_domain 替换为您的域名:
https://your_domain请选择您想使用的语言:
点击“继续”后,您将进入主设置页面,您需要在此选择网站名称和用户名。建议您选择一个容易记住的用户名(而不是“admin”),并设置一个强密码。您可以使用 WordPress 自动生成的密码,也可以创建自己的密码。最后,您需要输入您的电子邮件地址,并决定是否阻止搜索引擎索引您的网站:
点击页面底部的“安装 WordPress”按钮,您将被引导至登录提示页面:
登录后,您即可访问 WordPress 管理后台:
WordPress 安装完成后,您可以采取措施确保 SSL 证书自动续期。.
第七步——证书续期
Let's Encrypt 证书有效期为 90 天。您可以设置自动续订流程,以确保证书不会过期。一种方法是创建 cron 任务。在下面的示例中,您创建了一个 cron 任务,定期运行一个脚本来续订证书并重新加载 Nginx 配置。.
首先,打开名为 ssl_renew.sh 的脚本:
nano ssl_renew.sh将以下代码添加到脚本中,以续订证书并重新加载 Web 服务器配置。请记住将此处的示例用户名替换为您的非 root 用户用户名:
#!/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 选项,该选项会在运行 docker-compose 命令时禁用 ANSI 控制字符。然后,它对 docker 二进制文件执行相同的操作。最后,它切换到 ~/wordpress 项目目录并运行以下 docker-compose 命令:
-
docker-compose此命令会启动一个 certbot 容器,并覆盖您在 certbot 服务定义中提供的命令。它会使用 renew 子命令而不是 certonly 子命令来续订即将过期的证书。此外,它还包含 --dry-run 选项,用于测试您的脚本。. docker-compose kill:这将向 Web 服务器容器发送 SIGHUP 信号以重新加载 Nginx 配置。.
然后系统运行 docker prune 来删除所有未使用的容器和镜像。.
文件编辑完成后,请将其关闭。使用以下命令使其可执行:
chmod +x ssl_renew.sh接下来,打开 root 用户的 crontab 文件,以按指定的时间间隔运行续订脚本:
sudo crontab -e如果您是第一次编辑此文件,系统会提示您选择编辑器:
Outputno 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]: ...
在此文件的末尾添加以下行:
...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1这会将作业间隔设置为每五分钟一次,以便您可以检查扩展请求是否按预期工作。系统会创建一个名为 cron.log 的日志文件,用于记录作业的相关输出。.
五分钟后,检查 cron.log 文件以确认扩展请求是否成功:
tail -f /var/log/cron.log以下输出确认扩展成功:
Output- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/your_domain/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
在终端中输入 CTRL+C 退出。.
您可以修改 crontab 文件来设置每日运行间隔。例如,要让脚本每天中午运行,请将文件的最后一行更改为如下所示:
...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1您还需要从 ssl_renew.sh 脚本中移除 --dry-run 选项:
#!/bin/bash COMPOSE="/usr/local/bin/docker-compose --no-ansi" DOCKER="/usr/bin/docker" cd /home/sammy/wordpress/ $COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver $DOCKER system prune -af
您的 cron 任务会定期续订 Let's Encrypt 证书,确保它们不会过期。您还可以使用 Ubuntu 22.04 / 20.04 中的 Logrotate 工具设置日志轮换,以轮换和压缩日志文件。.
结果
在本教程中,您使用 Docker Compose 创建了一个基于 Nginx Web 服务器的 WordPress 安装。在此过程中,您为要与 WordPress 站点关联的域名获取了 TLS/SSL 证书。此外,您还创建了一个 cron 任务,以便在需要时续订这些证书。.













