通过 Docker 快速部署 WordPress

楔子

时隔多年又有意愿重新制作博客,依然选择最广泛的 WordPress。趁着刚刚部署好,将部署过程记录下来。

架构

服务器:阿里云 ECS,买了个 99 元一年的。点此购买 ECS 服务器

Docker:容器部署方案。

traefik:反向代理应用。由于服务器上同时部署了其他应用,且其中部分需要支持泛域名 HTTPS 证书,故通过 traefik 部署,因为 traefik 支持泛域名 HTTPS 证书申请。原先常用方案 nginx-proxy/acme-companion: Automated ACME SSL certificate generation for nginx-proxy (github.com) 不支持泛域名 HTTPS 证书申请。

nginx:高性能反向代理应用。

WordPress:最广泛的博客应用。WordPress 说第二,没人敢说第一。

MySQL:数据库。本例中数据库独立部署。

部署

相关配置文件

WordPress + Ngnix 的 docker-compose.yml

name: egeeke-blog
services:
  wordpress:
    image: wordpress:6.5.3-php8.3-fpm-alpine
    restart: always
    networks:
      - web
    environment:
      WORDPRESS_DB_HOST: 数据库主机
      WORDPRESS_TABLE_PREFIX: wp
      WORDPRESS_DB_NAME: 数据库名
      WORDPRESS_DB_USER: 数据库用户名
      WORDPRESS_DB_PASSWORD: 数据库密码
    volumes:
      - /mnt/nas/other/data/egeeke-blog/wordpress:/var/www/html
  nginx:
    image: nginx:1.25.5-alpine
    restart: always
    networks:
      - web
    volumes:
      - ./conf:/etc/nginx/conf.d
      - /mnt/nas/other/data/egeeke-blog/logs:/var/log/nginx
      - /mnt/nas/other/data/egeeke-blog/wordpress:/var/www/html
    depends_on:
      - wordpress
    labels:
      # The labels are usefull for Traefik only
      - "traefik.enable=true"
      - "traefik.docker.network=web"
      # Get the routes from http
      - "traefik.http.routers.egeeke-blog.rule=Host(`egeeke.com`) || Host(`www.egeeke.com`)"
      - "traefik.http.routers.egeeke-blog.entrypoints=http"

      # Redirect these routes to https
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.routers.egeeke-blog.middlewares=redirect-to-https"
      # Get the routes from https
      - "traefik.http.routers.egeeke-blog-secured.rule=Host(`egeeke.com`) || Host(`www.egeeke.com`)"
      - "traefik.http.routers.egeeke-blog-secured.entrypoints=https"
      # Apply autentificiation with http challenge
      - "traefik.http.routers.egeeke-blog-secured.tls=true"
      - "traefik.http.routers.egeeke-blog-secured.tls.certresolver=myresolver"
networks:
  web:
    external: true

nginx 配置文件

server {
    listen 80;

    root /var/www/html;
    index index.php;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php?$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;
    }
}

MySQL 的 docker-compose.yml

version: '3.1'
services:
mysql:
image: mysql:8.0
restart: always
environment:
MYSQL_RANDOM_ROOT_PASSWORD: yes
ports:
- 3306:3306
volumes:
- /mnt/nas/mysql/data:/data

traefik 的 docker-compose.yml

name: web
volumes:
  acme:
networks:
  default:
    name: web
services:
  traefik:
    image: traefik
    restart: always
    command:
      # 开启 api 功能
      - "--api=true"
      # 开启 dashboard 功能
      - "--api.dashboard=true"
      # 对外开启 8080 端口,此处注释不开启
      # - "--api.insecure=true"
      # 开启 ping 功能
      - "--ping=true"
      # 配置 http 端口
      - "--entrypoints.http.address=:80"
      # 配置 https 端口
      - "--entrypoints.https.address=:443"
      #  开启提供者 docker
      - "--providers.docker=true"
      #  配置提供者 docker 接入点
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      # HTTPS 证书处理 ACME 配置
      - "--certificatesresolvers.myresolver.acme.email=wanxger@egeeke.com"
      # 配置 ACME 证书的签发机构(CA),此处注释时不生效,使用正式 CA 服务器
      # - "--certificatesresolvers.myresolver.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory"
      # ACME 证书保存到的位置
      - "--certificatesresolvers.myresolver.acme.storage=/etc/traefik/acme/acme.json"
      # 配置 DNS 挑战相关内容
      # DNS 挑战服务商
      - "--certificatesresolvers.myresolver.acme.dnsChallenge.provider=alidns"
      # 全资格域名(FQDN)解析,用以验证挑战完成状态,此处注释不配置,使用默认
      # - "--certificatesresolvers.myresolver.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53"
      # 延迟通知 ACME 进行 DNS 验证,用来防止 ACME 方 DNS 信息不正确
      - "--certificatesresolvers.myresolver.acme.dnsChallenge.delayBeforeCheck=30"
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - acme:/etc/traefik/acme
    environment:
      # 阿里云 DNS 密钥对
      - ALICLOUD_ACCESS_KEY=xxx
      - ALICLOUD_SECRET_KEY=xxx
    labels:
      - "traefik.http.routers.traefik-dashboard.entrypoints=http"
      - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.ldsgy.com`)"
      - "traefik.http.routers.traefik-dashboard.service=dashboard@internal"
      - "traefik.http.routers.traefik-dashboard-api.entrypoints=http"
      - "traefik.http.routers.traefik-dashboard-api.rule=Host(`traefik.ldsgy.com`) && PathPrefix(`/api`)"
      - "traefik.http.routers.traefik-dashboard-api.service=api@internal"
    logging:
      driver: "json-file"
      options:
        max-size: "1m"
    # 健康检查
    healthcheck:
      # 通过轮训 ping 接口判断健康状态
      test:
        [
          "CMD-SHELL",
          "wget -q --spider --proxy off localhost:8080/ping || exit 1"
        ]
      interval: 3s
      retries: 10

TODO

  • 有空再写一篇更简单的部署方案,使用 Dokcer + Ngnix + MySQL + WordPress 单 docker-compose.yml 文件实现 HTTPS 部署。

评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注