使用Docker Caddy Nginx部署WordPress博客

736次阅读
一条评论

共计 6706 个字符,预计需要花费 17 分钟才能阅读完成。

前言

最近想着写写博客, 之前使用了Hexo搭建了一个静态博客, 使用下来存在着无法管理评论, 生成发布过程繁琐, 在注重随时想起来就写点什么的场景下有些麻烦, 还有媒体资源管理也存在着许多问题. 权衡下我选择了Wordpress,这两天使用下来感觉, WordPress更加的功能全面, 也确实存在着一些麻烦的让人疑惑的地方, 相对Hexo等以前也用过各种静态博客, 在搭建完成后, 用来做博客感觉更加省心, 在搭建完成后只需要专注于写博客就行了.有一种折腾了半天最后还是Wordpress好的惭愧感.

部署技术选择

个人经验来说docker部署应用应该是现在最为简单高效方式了,它有着可随时重启,与主机隔离的运行环境,在部署测试完成后只需要保存数据卷或者目录, 在任意节点快速恢复的特性都相当的有优势, 下面的部署中mysql数据我也使用了docker进行部署, 但这从数据库的角度包括磁盘读取性能, 数据管理的角度来说往往是不推荐的.只是个人博客数据管理相对方便负载量不大的时候这样使用, 当网站访问量上升后数据库肯定是首先迁移到单独的主机独立运行.

docker环境安装

docker的安装过程可以查看官方文档 下面是ubuntu安装docker的一个参考

# Ubuntu Jammy 22.04 (LTS)
# 更新包并注册docker包源的GPG密钥
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# 将存储库添加到apt源 [/etc/apt/sources.list.d/docker.list]
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

# 安装 docker
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

注意: 我是最近才发现 docker 好像不用安装 docker-compose 那个包了 替代的 docker-compose-plugin 这个包docker-compose python的实现已经很久没有更新了, docker-compose 命令最新的写法为 docker compose 先前一直使用着 archlinux 在 archlinux 中 docker-compose好像做了一个别名 调用的 实际是 docker compose 命令.

在不是root用户登录的情况下 docker info 会提示没有权限 使用以下代码将你自己的用户添加到docker组

# 添加 docker 组
sudo groupadd docker
# 将当前用户添加到 docker 组
sudo usermod -aG docker $USER
# 重启 docker 实例
sudo systemctl restart docker

注意: 这里往往又会碰到另外一个问题 当添加了用户组之后 当前登录的用户还没有重新登录依旧显示没有权限… 从新登录当前用户就好了. 在时候我们都是远程ssh登录的服务器, 断开连接重新登录后, 有时… 会话会保持… 暂时我没找到什么好的解决办法. 重启大法解决.

选择镜像

链接: wordpress caddy nginx

其中caddy是http服务器 它的最大优势是可以全自动签发管理域名免费的https证书, 这对于小型博客站点而言相当有用. caddy在大流量场景下的性能表现这里不做讨论. 如果你的站点需要配置https的话caddy会是一个很好的选择, 但… 它确实也有很多坑. > 因为 caddy 本身是支持 php_fastcgi 的配置方式 在最开始的配置中我使用了 caddy + wordpress-fpm 的方式配置, 在实际使用中却出现了很多意想不到的错误我会在下面的文中说明 以至于最后 我最后采用了 caddy > nginx > wordpress-fpm 组合.

wordpress 镜像我选择了 wordpress:fpm-alpine , wordpress docker 提供了两种部署方式 apache or fpm 或许 apache 更加适合但… 我不太了解 apache 的配置…

caddy + wordpress-fpm 配置 (存在一定问题)

以下配置设在一个空的文件夹中 相关配置根据相对路径创建相应文件

  • php ./etc/wordpress/my.ini
# post 最大大小
post_max_size = 48M
# 最大上传文件大小
upload_max_filesize = 48M
  • Caddy ./etc/caddy/Caddyfile
{
    log {
        format console
    }
}
# 下方对应自己的域名
nenufm.com, www.nenufm.com {
    encode zstd gzip
    root * /var/www/html
    file_server
    php_fastcgi wordpress:9000
}
  • docker compose ./docker-compose.yml
version: '2.4'
services:
  # 这种配置方式数据库并不稳定且性能不高
  mysql:
    image: mysql:latest
    container_name: server_mysql
    command:
      - --default-authentication-plugin=mysql_native_password
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --lower_case_table_names=1
      - --performance_schema=off
    restart: always
    ports:
      - '3306:3306'
    environment:
      TZ: 'Asia/Shanghai'
      MYSQL_ROOT_PASSWORD: {MysqlPassword}
    volumes:
      - ./data/mysql/data:/var/lib/mysql

  caddy:
    container_name: server_caddy
    image: caddy:alpine
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./etc/caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./data/caddy/run/data:/data
      - ./data/caddy/run/config:/config
      # 挂载wordpress的静态资源
      - ./data/wordpress/html:/var/www/html

  wordpress:
    image: wordpress:fpm-alpine
    container_name: server_wordpress
    restart: always
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: {MysqlPassword}
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./etc/wordpress/my.ini:/usr/local/etc/php/conf.d//my.ini
      - ./data/wordpress/html:/var/www/html

这里需要注意由于caddy会自动申请ssl证书并且强制使用https, 请在运行命令之前将你自己的域名解析到你的主机, 例如本站域名 nenufm.com, www.nenufm.com 都要解析到执行这个命令的主机上. 才能进行证书的验证与签发. 通常www与@记录都是同时解析一个服务.

创建好以上文件 即可在 docker-compose.yml 所在目录执行 docker compose up -d 命令执行完成后退出.等待一会儿 即可在浏览器打开 nenufm.com 域名 进入 wordpress 的初始化配置页面. wordpress 内部配置不再赘述, 本文只讨论如何部署.

存在的问题

在 wordpress 使用中 由于caddy并未大量使用并缺乏配置资料, 查询了大量的文档, 网上资料都是配置nginx转发到fpm的资料. 如伪静态, 一些主题中要求配置特殊参数等, 能够找到的资料都是关于nginx的. 多次尝试后发现往往是 caddy php_fastcgi 配置默认了许多参数, 并且并没有配置的地方导致. 以下是已知的一个比较严重的问题.

  • wordpress主题中常用的 wp_redirect 函数在跳转外部链接的时候 /var/www/html/wp-includes/pluggable.php 1408行 中如下代码
if ( ! $is_IIS && 'cgi-fcgi' !== PHP_SAPI ) {
    status_header( $status ); // This causes problems on IIS and some FastCGI setups.
}

cgi-fcgi 协议可能无法发出302状态码或者存在其他问题, 在nginx fastcgi 实现中会有在返回头中带有location参数即设置302状态码. caddy 并未做相关处理, 会出现返回头中有location参数, 但返回的http状态码是200, 这在最新版本的chrome浏览器中将不会发生跳转.查询了相关资料这好像是php中一直存在的问题. 可通过修改代码解决. 例如在使用 wp_redirect 的后面加入 exit; 指令解决. 可大量的主题插件, 并不存在这种适配.

思考

caddy在https普及的现在,在单机部署测试,小流量网站中自动申请免费的证书的优势是非常明显的.在明显感觉到可能存在兼容问题后, 我曾考虑过使用certbot + nginx 利用自动签发证书的方式进行. 这并不太适合小型建站. 往往又是一大堆各种问题.

最终配置

  • php ./etc/wordpress/my.ini
# post 最大大小
post_max_size = 48M
# 最大上传文件大小
upload_max_filesize = 48M
  • nginx ./etc/nginx/nginx.conf
worker_processes  auto;
events {
   worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    server_tokens off;
    access_log  off;
    sendfile        on;
    keepalive_timeout  65;
    gzip on;
    server {
        listen     9000;
        root /var/www/html;
        index index.php;
        ## 配置内容体最大大小
        client_max_body_size 48M;

         # 下面三行为重点,添加后就可以获取到客户端真实IP
        set_real_ip_from 0.0.0.0/0;
        real_ip_header  X-Forwarded-For;
        real_ip_recursive on;
        # 下面三行为常见反向代理传递真实客户端IP的配置
        proxy_set_header Host      $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        location = /favicon.ico {
            log_not_found off;
            access_log off;
        }

        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }

        location / {
            try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
            include fastcgi_params;
            fastcgi_intercept_errors on;
            fastcgi_pass wordpress:9000;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            expires max;
            log_not_found off;
        }
    }
}
  • Caddy ./etc/caddy/Caddyfile
{
    log {
        format console
    }
}
# 下方对应自己的域名
nenufm.com, www.nenufm.com {
    encode zstd gzip
    reverse_proxy http://nginx:9000
}
  • docker compose ./docker-compose.yml
version: '2.4'
services:
  # 这种配置方式数据库并不稳定且性能不高
  mysql:
    image: mysql:latest
    container_name: server_mysql
    command:
      - --default-authentication-plugin=mysql_native_password
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --lower_case_table_names=1
      - --performance_schema=off
    restart: always
    ports:
      - '3306:3306'
    environment:
      TZ: 'Asia/Shanghai'
      MYSQL_ROOT_PASSWORD: {MysqlPassword}
    volumes:
      - ./data/mysql/data:/var/lib/mysql

  wordpress:
    image: wordpress:fpm-alpine
    container_name: server_wordpress
    restart: always
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: {MysqlPassword}
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./etc/wordpress/my.ini:/usr/local/etc/php/conf.d//my.ini
      - ./data/wordpress/html:/var/www/html

  nginx:
    image: nginx:alpine
    volumes:
      - ./etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
     # 挂载wordpress的静态资源
      - ./data/wordpress/html:/var/www/html

  caddy:
    container_name: server_caddy
    image: caddy:alpine
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./etc/caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./data/caddy/run/data:/data
      - ./data/caddy/run/config:/config

总结

像是一个临时的解决方案, 在使用中, 经过了两次反向代理后 x- 等参数好像有存在异常的情况. 这也是目前本站的配置. 目前未发现较大的兼容性问题. 再继续探索吧.

正文完
 1
太阳
版权声明:本站原创文章,由 太阳 2023-10-11发表,共计6706字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(一条评论)
闪闪发光的太阳 评论达人 LV.1
2023-10-12 17:18:35 回复

嘻嘻

 Windows  Edge  内网IP