前言
大概是一年前我写了一篇搭建WordPress的教程。然而配置过程实属折磨,文章里说的东西有些也不太准确,现在回想起似乎有点小尬😅。所以这次我选择将一切全部打包至Docker容器,使用Docker Compose部署一个带nginx
、mariadb
、wordpress
的容器环境。
本文内容
一键搭建WordPress站点,可用于快速部署,节省时间成本,适用于小型生产环境。
特点
- 没有折磨,无痛配置
- 无需提前安装数据库
- 无需提前安装PHP
- 部署脚本简洁到极致
- 能够支持文件上传
- 能够安装插件、主题
- 没有权限问题
- 没有奇奇怪怪的“我为什么换不了站点语言”这种问题
- nginx反代
- 支持https
- 支持http重定向
一条命令部署到本地
这只是最基本演示,具体配置见下节
虽然搭建过程是很简单,但是还是要做一些准备工作😏
准备工作
- 安装Docker
- 克隆这个仓库 KarsonJo/Wordpress.DockerCompose
- 如果你没有
git
,也可以直接下载zip压缩包
- 如果你没有
- 在仓库根目录位置打开控制台
起飞
执行命令
docker compose up
泡杯咖啡
访问:wp.lndo.site或者localhost
提示不安全,正常现象,点击继续前往。
*.lndo.site是一个解析到127.0.0.1的特殊域名。如果你无法使用该域名打开,请检查:
- 你的互联网连接
- 你的浏览器代理设置
认真部署到服务器
首先还是需要完成准备工作👆
配置必要的环境变量
复制.env.template
为.env
文件,按照你的实际填写环境变量:
# Databse name for wordpress
DB_NAME=wordpress
# Database user name
DB_USER=wordpress
# Database user password
DB_PASSWORD=wordpress
# Your domain name
NGINX_HOST=wp.lndo.site
提供ssl证书
用你站点的ssl证书替换以下文件内容:
./ssl/wp.key
是站点的私钥(PRIVATE KEY)./ssl/wp.pem
是站点的公钥(CERTIFICATE)
修改文件上传限制(可选)
默认允许上传128M文件。如果你需要修改这个值,打开./php/php.ini
file_uploads = On
memory_limit = 512M
upload_max_filesize = 128M
post_max_size = 128M
max_execution_time = 600
client_max_body_size = 128M
将128M修改成更大的值,并适当提高内存限制和传输时间。
如果你需要支持上传超过1G的文件,再打开./nginx/wp.conf.template
将以下配置项修改为更高:
client_max_body_size 1G;
搭建站点
执行命令:
docker compose up
完事,到浏览器访问你的站点。
脚本解释
如果对脚本实现没有兴趣可以跳过本节
docker-compose.yaml
使用文本编辑器打开docker-compose.yaml
,你会看到类似下面的内容:
name: wp
services:
mariadb:
image: mariadb:11.3
volumes:
- mariadb_data:/var/lib/mysql
restart: always
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=1
- MYSQL_DATABASE=${DB_NAME:-wordpress}
- MYSQL_USER=${DB_USER:-wordpress} # DB user
- MYSQL_PASSWORD=${DB_PASSWORD:-wordpress} # DB password
wordpress:
image: wordpress:fpm
restart: always
environment:
- WORDPRESS_DB_HOST=mariadb
- WORDPRESS_DB_USER=${DB_USER:-wordpress} # DB user
- WORDPRESS_DB_PASSWORD=${DB_PASSWORD:-wordpress} # DB password
- WORDPRESS_DB_NAME=${DB_NAME:-wordpress}
volumes:
- wordpress_data:/var/www/html
- ./php/php.ini:/usr/local/etc/php/conf.d/php.ini
nginx:
image: nginx:latest
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- wordpress_data:/var/www/wp:ro
- ./nginx/:/etc/nginx/templates:ro
- ./ssl:/etc/ssl:ro
- nginx_log:/var/log/nginx
environment:
- NGINX_HOST=${NGINX_HOST:-wp.lndo.site} # Your domain here.
volumes:
mariadb_data:
wordpress_data:
nginx_log:
卷
命名卷
有3个命名卷,命名卷会持久存储在宿主机,不会因容器摧毁而丢失数据:
mariadb_data
: 数据库的数据位置。wordpress_data
: WordPress站点文件位置;被wordpress
容器与nginx
容器所共同使用。wordpress
容器挂载于:/var/www/html
,这是wordpress
容器决定的。nginx
容器挂载于:/var/www/wp
,这是我决定的。
nginx_log
: nginx日志的位置。
挂载卷
有若干挂载卷,挂载卷用于将宿主机的文件共享至容器内:
./php/php.ini
: php配置,处理后被容器复制到php配置目录下。./nginx/
: nginx配置模板,处理后被容器复制到nginx配置目录下。./ssl
: ssl证书,挂载到容器/etc/ssl
下。
nginx/wp.conf.template
nginx配置文件模板,占位符${xx}
会被替换成对应环境变量值,然后复制到nginx容器内的配置文件位置。
# Upstream to abstract backend connection(s) for php
upstream php {
server unix:/tmp/php-cgi.socket;
server wordpress:9000;
}
server {
listen 80;
listen [::]:80;
server_name ${NGINX_HOST};
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name ${NGINX_HOST};
http2 on;
# max payload
client_max_body_size 1G;
# ssl
ssl_certificate /etc/ssl/wp.pem;
ssl_certificate_key /etc/ssl/wp.key;
# logging
access_log /var/log/nginx/wp.access.log;
error_log /var/log/nginx/wp.error.log;
add_header Strict-Transport-Security "max-age=31536000" always;
root /var/www/wp;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri = 404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /favicon.svg {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}
文件位置
以下语句定义了WordPress站点的位置,该位置是挂在卷容器内所在位置:
root /var/www/wp;
以下语句定义了php fpm服务器中站点的位置,也就是请求upstream到wordpress
容器后的位置:
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
注意这里填写的是wordpress
容器的挂载位置,而不是当前容器的文件位置。
php/php.ini
php配置文件,主要解决文件上传问题,内容大致如下:
file_uploads = On
memory_limit = 512M
upload_max_filesize = 128M
post_max_size = 128M
max_execution_time = 600
client_max_body_size = 128M
没了,文件就这几个,想水长文都水不了一点
缺点
容器化数据库
数据库位于容器内,数据库获取的内存资源有限,而且受到虚拟化的影响运行效率相对较低,这对高负载场景并不友好。
如果数据库负载较高,建议将数据库安装到宿主机上。
docker compose作为容器编排工具
docker compose的容器编排功能比较简单,不适合高并发弹性横向扩展的情景。
如果系统规模很大,建议上Kubernetes。
小结
话虽如此,一键部署它不香吗?小型情景这套组合足够了。性能瓶颈再说吧。
常见问题
适合什么情景
小型应用的生产环境部署。
不适合大型应用部署,也不适用于开发。
在容器环境中开发WordPress建议使用Lando
如何更新WordPress版本
WordPress
与其它容器的隔离理念不同,它支持在第一次部署时将站点文件拷贝到持久存储卷中,后续的部署不会再次影响该卷。
本做法按照官方推荐,将所有站点文件托管至持久存储卷。
因此你可以在WordPress控制台进行站点更新,无需重新部署新版本的wordpress
容器。
如何安装WordPress主题或插件
到控制台装。
如何安装PHP插件
PHP由wordpress
镜像自动安装,它配备了常见的PHP插件。但如果你需要其它没配备的插件,需要以wordpress
镜像为基础构建自己的镜像,具体请参考官方镜像说明。
如何更新PHP版本
官方wordpress
镜像提供有不同PHP版本的镜像,如果你需要其它版本的PHP,可以选择特定tag的镜像版本重新部署。
我需要访问站点文件
站点文件位于wordpress_data
命名卷内。该卷映射至nginx
与wordpress
容器中,你可以在这两个容器中操作文件;也可以在docker volume中操作文件。
但这都不太方便。如果你需要经常手动操作站点文件,建议将其挂载到宿主机上。
如何备份站点
备份wordpress_data
与mariadb_data
两个命名卷。
新手~ 感觉这个和装一个宝塔面板,然后装依赖,解压wordpress到根目录在安装,好像没有什么太大区别啊, 不过是真的实打实省了很多步骤