WordPress是一种流行的开源内容管理系统(CMS),用于构建和管理网站。它提供了一个易于使用的界面,使用户可以通过简单的拖放操作来创建和编辑网站内容。
本文章内容需要对docker、ubuntu有较高的掌握程度以及有较强的动手能力,否则请勿根据文章进行实际操作。
服务器资源
负载均衡服务器:192.168.1.2 Ubuntu 22.04 1C1G 40G wordpress节点1服务器:192.168.1.3 Ubuntu 22.04 2C2G 40G wordpress节点2服务器:192.168.1.4 Ubuntu 22.04 2C2G 40G 不同VPS运营商可以通过NETBIRD组网,机房之间地理位置不要太远。 NETBIRD组网参考文章
软件清单
负载均衡:haproxy 单节点 web服务:nginx 双节点 php服务: wordpress 双节点 缓存数据库: redis 主从 对象存储:minio 双节点 关系型数据库:mysql 主从 容器引擎:docker 容器编排: docker-compose
wordpress插件
用户会话存储:Redis User Session Storage 媒体附件存储:Media Cloud
docker安装
docker-compose安装
wordpress镜像支持php redis扩展
由于官方镜像不支持redis,我们需要修改官方的Dockerfile。 官方地址 下载3个文件:Dockerfile、docker-entrypoint.sh、wp-config-docker.php php redis扩展下载地址 请下载Source code (tar.gz) 压缩包。 注:以上4个文件下载到wordpress节点服务器的同一个文件夹中,比如文件夹名称:wordpress-php8.1-fpm-alpine 将下载下来的redis压缩包重新解压压缩,得到redis.tar.gz。
tar zxvf phpredis-6.0.1.tar.gz
mv phpredis-6.0.1 redis
tar zcvf redis.tar.gz redis
修改Dockerfile
ADD redis.tar.gz /usr/src/php/ext/
在这个位置添加上面一行内容
# install the PHP extensions we need (https://make.wordpress.org/hosting/handbook/handbook/server-environment/#php-extensions)
...
docker-php-ext-install -j "$(nproc)" \
bcmath \
exif \
gd \
intl \
mysqli \
zip \
redis \
在这个位置添加redis
...
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
倒数第二行修改成这样
保存后,docker-entrypoint.sh赋予可执行权限
chmod +x docker-entrypoint.sh
编译容器镜像
docker build -t wordpress:php8.1-fpm-redis-alpine ./
负载均衡服务器 192.168.1.2
docker-compose.yml
version: '3.1'
services:
haproxy:
image: haproxy
container_name: haproxy
restart: always
environment:
- TZ=Asia/Shanghai
ports:
- "443:443"
volumes:
- /data/haproxy:/usr/local/etc/haproxy:ro
- /data/haproxy/cert:/usr/local/etc/cert
sysctls:
- net.ipv4.ip_unprivileged_port_start=0
haproxy配置文件
存放路径:/data/haproxy/haproxy.cfg
global
log 127.0.0.1 local0
maxconn 4096
daemon
pidfile /tmp/haproxy.pid
defaults
log 127.0.0.1 local3
mode http
option httplog
option dontlognull
option httpclose
retries 3
option redispatch
option abortonclose
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
stats enable
stats uri /haproxy-stats
stats auth 用户名:密码 #设置监控页面的用户和密码
stats hide-version
frontend https_frontend
bind *:443 ssl crt /usr/local/etc/cert/xxx.com.pem
mode http
acl domain_s3 hdr_beg(host) -i s3.xxx.com
acl domain_minio hdr_beg(host) -i minio.xxx.com
use_backend s3 if domain_s3
use_backend minio if domain_minio
default_backend blog
backend blog
mode http
balance roundrobin
server s1 192.168.1.3:80 check inter 2000 fall 3
server s2 192.168.1.4:80 check inter 2000 fall 3
backend s3
mode http
balance roundrobin
server s1 192.168.1.3:9000 check inter 2000 fall 3
server s2 192.168.1.4:9000 check inter 2000 fall 3
backend minio
mode http
balance roundrobin
server s1 192.168.1.3:9001 check inter 2000 fall 3
server s2 192.168.1.4:9001 check inter 2000 fall 3
将域名SSL证书文件xxx.com.pem , xxx.com.pem.key存放到/data/haproxy/cert/目录
wordpress节点1服务器 192.168.1.3
docker-compose.yml
version: '3.8'
services:
mysql:
image: mysql
container_name: mysql
volumes:
- /data/mysql/data:/var/lib/mysql
- /data/mysql/mysql.cnf:/etc/my.cnf
environment:
- MYSQL_ROOT_PASSWORD=数据库ROOT密码
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress用户密码
restart: always
ports:
- "3306:3306"
wordpress:
image: wordpress:php8.1-fpm-redis-alpine
restart: always
container_name: wordpress
environment:
- WORDPRESS_DB_HOST=mysql
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress用户密码
- WORDPRESS_DB_NAME=wordpress
volumes:
- /data/nginx/html:/var/www/html:rw
- /data/php/php.ini:/usr/local/etc/php/php.ini
- /etc/localtime:/etc/localtime
links:
- mysql
- redis
nginx:
image: nginx:1.22.0-alpine
container_name: nginx
restart: always
environment:
- TZ=Asia/Shanghai
ports:
- "80:80"
volumes:
- /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
- /data/nginx/logs:/etc/nginx/logs
- /data/nginx/html:/var/www/html:rw
- /etc/localtime:/etc/localtime
links:
- wordpress
redis:
image: redis:7.0.4
restart: always
container_name: redis
ports:
- 6379:6379
environment:
- TZ=Asia/Shanghai
volumes:
- /data/redis/data:/data/data
- /data/redis/conf:/usr/local/etc/redis
- /data/redis/logs:/data/logs
command: ["redis-server","/usr/local/etc/redis/redis.conf"]
minio:
image: minio/minio
container_name: minio
restart: always
network_mode: "host"
expose:
- '9000'
- '9001'
volumes:
- /data/minio/data:/data
- /etc/localtime:/etc/localtime
- /etc/timezone:/etc/timezone
environment:
- MINIO_ROOT_USER=用户名
- MINIO_ROOT_PASSWORD=密码
command: server --console-address ":9001" http://minio{1...2}/data
nginx配置文件
存放路径/data/nginx/conf/nginx.conf
server {
listen 80;
server_name xxx.com www.xxx.com;
access_log logs/xxx.access.log main;
error_log logs/xxx.error.log notice;
allow 192.168.1.2;
allow 192.168.1.4;
deny all;
location ~ /.+\.php.*$ {
if ($fastcgi_script_name ~ /(.+\.php.*)$) {
set $valid_fastcgi_script_name $1;
}
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html/$valid_fastcgi_script_name;
include fastcgi_params;
}
location / {
root /var/www/html/;
index index.html index.php;
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /index.php;
}
}
}
wordpress php配置文件
php.ini修改以下配置,存放路径/data/php/php.ini php.ini文件可在官方下载的压缩包里找到。
max_execution_time = 90
session.save_handler = redis
session.save_path = "tcp://redis:6379?auth=密码"
redis配置文件
redis.conf修改以下配置,存放路径/data/redis/conf/redis.conf redis.conf文件可在官方下载的压缩包里找到。
pidfile /data/redis_6379.pid
logfile "/data/logs/redis.log"
dir /data/data
requirepass 密码
wordpress节点2服务器 192.168.1.4
docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:1.23.3-alpine
container_name: nginx
#network_mode: "host"
ports:
- "80:80"
restart: always
volumes:
- /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
- /data/nginx/logs:/etc/nginx/logs/
- /data/nginx/html:/var/www/html/:rw
- /etc/localtime:/etc/localtime
links:
- wordpress
wordpress:
image: wordpress:php8.1-fpm-redis-alpine
restart: always
container_name: wordpress
environment:
- WORDPRESS_DB_HOST=192.168.1.3
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress用户密码
- WORDPRESS_DB_NAME=wordpress
volumes:
- /data/nginx/html:/var/www/html:rw
- /data/php/php.ini:/usr/local/etc/php/php.ini
- /etc/localtime:/etc/localtime
mysql:
image: mysql
container_name: mysql
volumes:
- /data/mysql/data:/var/lib/mysql
- /data/mysql/mysql.cnf:/etc/my.cnf
environment:
- MYSQL_ROOT_PASSWORD=ROOT用户密码
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress用户密码
restart: always
ports:
- "3306:3306"
redis:
image: redis:7.0.4
restart: always
container_name: redis
ports:
- 6379:6379
environment:
- TZ=Asia/Shanghai
volumes:
- /data/redis/data:/data/data
- /data/redis/conf:/usr/local/etc/redis
- /data/redis/logs:/data/logs
command: ["redis-server","/usr/local/etc/redis/redis.conf"]
minio:
image: minio/minio
container_name: minio
restart: always
network_mode: "host"
expose:
- '9000'
- '9001'
volumes:
- /data/minio/data:/data
- /etc/localtime:/etc/localtime
- /etc/timezone:/etc/timezone
environment:
- MINIO_ROOT_USER=用户名
- MINIO_ROOT_PASSWORD=密码
command: server --console-address ":9001" http://minio{1...2}/data
nginx配置文件
server {
listen 80;
server_name xxx.com www.xxx.com;
access_log logs/xxx.access.log main;
error_log logs/xxx.error.log notice;
allow 192.168.1.2;
deny all;
location /wp-content/uploads/ {
proxy_set_header Host $host;
proxy_pass http://192.168.1.3/wp-content/uploads/;
}
location ~ /.+\.php.*$ {
if ($fastcgi_script_name ~ /(.+\.php.*)$) {
set $valid_fastcgi_script_name $1;
}
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html/$valid_fastcgi_script_name;
include fastcgi_params;
}
location / {
root /var/www/html/;
index index.html index.php;
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /index.php;
}
}
}
wordpress php配置文件
max_execution_time = 90
session.save_handler = redis
session.save_path = "tcp://192.168.1.3:6379?auth=密码"
redis配置文件
pidfile /data/redis_6379.pid
logfile "/data/logs/redis.log"
dir /data/data
replicaof 192.168.1.3 6379
masterauth 密码
requirepass 密码
appendonly yes
mysql主从配置
minio配置
浏览器打开网址:https://minio.xxx.com,登录(账号密码见docker-compose.yml) 创建Buckets,桶名称为wordpress 修改Buckets的Access Policy为custom Write Policy内容为任何人只读:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"*"
]
},
"Action": [
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::wordpress"
]
},
{
"Effect": "Allow",
"Principal": {
"AWS": [
"*"
]
},
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::wordpress/*"
]
}
]
}
创建Policy,名称为wordpress,Raw Policy内容为桶wordpress读写权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1492520492000",
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket",
"s3:ListBucketMultipartUploads"
],
"Resource": [
"arn:aws:s3:::wordpress"
]
},
{
"Sid": "Stmt1492521245000",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::wordpress/*"
]
}
]
}
创建新用户wordpress,为该用户创建新的Access Keys,并记录Access Keys和Secret Key,设置Assign Policies为wordpress权限。
wordpress插件配置
用户会话存储 Redis User Session Storage配置
安装并启用。 修改文件/data/nginx/html/wp-config.php,添加以下内容
define( 'WP_REDIS_USER_SESSION_HOST' , '192.168.1.3' );
define( 'WP_REDIS_USER_SESSION_PORT' , 6379 );
define( 'WP_REDIS_USER_SESSION_SOCKET' , null );
define( 'WP_REDIS_USER_SESSION_AUTH' , '密码' );
define( 'WP_REDIS_USER_SESSION_DB' , '0' );
define( 'WP_REDIS_USER_SESSION_SERIALIZER' , Redis::SERIALIZER_PHP );
媒体附件存储 Media Cloud配置
安装并启用。 在设置界面中,点击Cloud Storage下面的Settings Enable Cloud Storage 开启 Storage Provider 选择minio Access Key 填入Access Keys Secret 填入Secret Key Bucket 填wordpress Region 选择Automatic Custom Region 填入Custom Custom Endpoint 填s3.xxx.com 其他设置根据自己情况修改
后台登录问题排查
/data/nginx/html/wp-config.php代码中以下常量两个节点必须一致,否则负载均衡轮询验证登录时会被踢出登录状态。
define( 'AUTH_KEY', getenv_docker('WORDPRESS_AUTH_KEY', 'xxx') );
define( 'SECURE_AUTH_KEY', getenv_docker('WORDPRESS_SECURE_AUTH_KEY', 'xxx') );
define( 'LOGGED_IN_KEY', getenv_docker('WORDPRESS_LOGGED_IN_KEY', 'xxx') );
define( 'NONCE_KEY', getenv_docker('WORDPRESS_NONCE_KEY', 'xxx') );
define( 'AUTH_SALT', getenv_docker('WORDPRESS_AUTH_SALT', 'xxx') );
define( 'SECURE_AUTH_SALT', getenv_docker('WORDPRESS_SECURE_AUTH_SALT', 'xxx') );
define( 'LOGGED_IN_SALT', getenv_docker('WORDPRESS_LOGGED_IN_SALT', 'xxx') );
define( 'NONCE_SALT', getenv_docker('WORDPRESS_NONCE_SALT', 'xxx') );
评论