使用Docker-Compose搭建WordPress并启用HTTPS访问:结合Nginx与Let’s Encrypt实现安全访问

在数字时代,网站的安全性和性能对于用户体验和搜索引擎排名至关重要。WordPress,作为一款流行的开源内容管理系统,为众多网站提供了强大的内容创作和发布平台。而Docker-Compose,作为Docker的编排工具,能够简化多容器应用的部署和管理。通过结合Nginx和Let's Encrypt,我们可以轻松地搭建一个安全、高效的WordPress网站,实现HTTPS访问。
接下来,我将为您介绍如何使用Docker-Compose搭建WordPress,通过Nginx实现Let's Encrypt启用HTTPS访问,并通过定时任务实现证书的自动续签。
安装前环境介绍:
1、服务器为阿里云;
2、操作系统 Ubuntu 22.04.3;
3、防火墙已开通80及443访问端口;
4、安全组已放行80及443端口;
5、域名已指向服务;
6、本文使的是非root用户进行操作;

一、搭建WordPress

1、安装Docker和Docker-Compose
首先,确保您的服务器上已经安装了Docker和Docker-Compose。您可以通过官方文档或相关教程进行安装(Docker与Docker-Compose安装指南:Ubuntu 22.04)。
2、创建Docker-Compose文件
在您的服务器上创建“docker-compose”文件夹。在该目录下创建一个名为docker-compose.yml的文件,并添加以下内容:
version: '3.1'

services:
  nginx:
    image: nginx:1.22.1
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ~/nginx/conf.d:/etc/nginx/conf.d:ro
      - ~/nginx/html:/usr/share/nginx/html:ro
      - ~/nginx/logs:/var/log/nginx:rw
    depends_on:
      - blog_wordpress
    networks:
      - mynet   
        
  blog_wordpress:
    image: wordpress:6.4.3
    restart: always
    environment:
      WORDPRESS_DB_HOST: db_mysql:3306
      WORDPRESS_DB_USER: your_wordpress_user
      WORDPRESS_DB_PASSWORD: your_wordpress_password
      WORDPRESS_DB_NAME: your_wordpress_db
    volumes:
      - ~/wordpress/html:/var/www/html
    depends_on:
      - db_mysql
    networks:
      - mynet

  db_mysql:
    image: mysql:8.3.0
    restart: always
    environment:
      MYSQL_DATABASE: your_wordpress_db
      MYSQL_USER: your_wordpress_user
      MYSQL_PASSWORD: your_wordpress_password
      MYSQL_ROOT_PASSWORD: your_root_password
    volumes:
      - ~/mysql/data:/var/lib/mysql
      - ~/mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf
    networks:
      - mynet

networks:
  mynet:

注意事项:
  • 请确保将配置中的 your_wordpress_dbyour_wordpress_useryour_wordpress_passwordyour_root_password换为您自己的配置。
  • 注意服务的命名及引用,尤其是:blog_wordpress 、db_mysql 后面会用到;
  • 这里配置了自定义网络mynet(桥接的方式),便于后续容器间的互相访问;
  • WordPress (80)和 MySql(3306) 服务均为开放端口映射,后续通过服务名加默认端口访问;(如有需要可通过添加ports自行开启);
  • 注意上面各个服务的文件挂载路径,用于存放不同的nginx配置、日志及mysql配置及存储数据等;
3、nginx配置
放到宿主机的~/nginx/conf.d 目录下, 名称可以为blog.conf,内容如下:
server {
    listen 80;
    listen [::]:80;

    server_name example.xyz www.example.xyz;
    server_tokens off;

    location / {
        proxy_set_header Host $host;
    	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://blog_wordpress:80;
    }
}

4、mysql 配置

放到宿主机的~/mysql/conf目录下, 名称可以为my.cnf,内容如下:
[mysql]
#设置mysql客户端默认字符集
default-character-set=UTF8MB4
[mysqld]
#设置3306端口
port=3306
#允许最大连接数
max_connections=200
#允许连接失败的次数
max_connect_errors=10
#默认使用“mysql_native_password”插件认证
default_authentication_plugin=mysql_native_password
#服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=UTF8MB4
#开启查询缓存
explicit_defaults_for_timestamp=true
#创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
#等待超时时间秒
wait_timeout=60
#交互式连接超时时间秒
interactive-timeout=600
5、启动容器及服务
在终端中进入存放docker-compose.yml文件的目录,并执行以下命令启动WordPress容器:
docker-compose up -d

此时如无问题,应该可以通过http://example.xyz访问到wordpress界面了。

二、启用HTTPS访问

接下来,我们将使用Let's Encrypt来启用WordPress的HTTPS访问。这里我们将使用Certbot工具来自动获取和更新SSL证书。在docker-compose.yml 中增加certbot服务,完整docker-compose.yml内容如下:
version: '3.1'

services:
  nginx:
    image: nginx:1.22.1
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ~/nginx/conf.d:/etc/nginx/conf.d:ro
      - ~/nginx/html:/usr/share/nginx/html:ro
      - ~/certbot/www:/var/www/certbot/:ro
      - ~/nginx/logs:/var/log/nginx:rw
      - ~/nginx/ssl:/etc/ssl:ro
    depends_on:
      - blog_wordpress
    networks:
      - mynet
        
  certbot:
    image: certbot/certbot:latest
    volumes:
      - ~/certbot/www:/var/www/certbot:rw
      - ~/nginx/ssl:/etc/letsencrypt:rw
      - ~/certbot/logs:/var/log/letsencrypt:rw
    networks:
      - mynet
        
  blog_wordpress:
    image: wordpress:6.4.3
    restart: always
    environment:
      WORDPRESS_DB_HOST: db_mysql:3306
      WORDPRESS_DB_USER: your_wordpress_user
      WORDPRESS_DB_PASSWORD: your_wordpress_password
      WORDPRESS_DB_NAME: your_wordpress_db
    volumes:
      - ~/wordpress/html:/var/www/html
    depends_on:
      - mysql
    networks:
      - mynet

  db_mysql:
    image: mysql:8.3.0
    restart: always
    environment:
      MYSQL_DATABASE: your_wordpress_db
      MYSQL_USER: your_wordpress_user
      MYSQL_PASSWORD: your_wordpress_password
      MYSQL_ROOT_PASSWORD: your_root_password
    volumes:
      - ~/mysql/data:/var/lib/mysql
      - ~/mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf
    networks:
      - mynet

networks:
  mynet:

nginx配置修改:

server {
    listen 80;
    listen [::]:80;

    server_name example.xyz www.example.xyz;
    server_tokens off;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        proxy_set_header Host $host;
    	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://blog_wordpress:80;
    }
}

先执行 docker-compose up -d certbot 启动certbot 服务,然后执行如下命令生成证书,并完成认证:

docker-compose run --rm  certbot certonly --webroot --webroot-path /var/www/certbot/  -d example.xyz -d www.example.xyz

修改nginx配置文件,并重新加载nginx服务,完整nginx配置如下:

server {
    listen 80;
    listen [::]:80;

    server_name example.xyz www.example.xyz;
    server_tokens off;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://example.xyz$request_uri;
    }
}

server {
    listen 443 default_server ssl http2;
    listen [::]:443 ssl http2;

    server_name example.xyz;

    ssl_certificate /etc/ssl/live/example.xyz/fullchain.pem;
    ssl_certificate_key /etc/ssl/live/example.xyz/privkey.pem;
    
    location / {
        proxy_set_header Host $host;
    	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://wordpress:80;
    }
}
执行以下语句,重新加载配置文件:
docker-compose exec nginx nginx -s reload
完成以上步骤后,您的WordPress站点就已经启用了HTTPS访问,并通过Let's Encrypt获得了有效的SSL证书。

三、证书续订

通过定时任务的方式完成证书的续签。
1、 在docker-compose 下增加renew_certificates.sh文件,内容如下:
#!/bin/bash

# 对应的docker-compose 目录
cd /path/to/docker-compose

# 执行 certbot renew
docker-compose run --rm certbot renew

# 检查 certbot 是否成功生成了新的证书
if [[ $? -eq 0 ]]; then
    echo "Certbot renewed certificates successfully."
    
    # 重新加载 Nginx 以应用新的 SSL 证书
    docker-compose exec nginx nginx -s reload
else
    echo "Certbot did not renew any certificates."
fi

2、进行文件授权,防止无法执行:

chmod +x renew_certificates.sh

3、设定cron定时任务:

例如每月的第一天凌晨执行此脚本,执行以下命令并创建定时任务:
crontab -e

输入 对应的数字 ,选择 /usr/bin/vim.basic  模式,进入vim。如果选择错误,可以按照说明退出后,执行select-editor 进行重新选择。

然后在打开的编辑器中添加一行:
0 0 1 * * /path/to/docker-compose/renew_certificates.sh >/dev/null 2>&1

这行的意思是在每个月的第一天凌晨0点0分执行 /path/to/renew_certificates.sh 脚本,并将输出重定向到/dev/null以避免邮件通知。

这样就可以完成证书的续签了。