共计 6650 个字符,预计需要花费 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登录的服务器, 断开连接重新登录后, 有时… 会话会保持… 暂时我没找到什么好的解决办法. 重启大法解决.
选择镜像
其中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- 等参数好像有存在异常的情况. 这也是目前本站的配置. 目前未发现较大的兼容性问题. 再继续探索吧.