前言
经过上次对1037U小主机的OpenWrt固件编译,我也成功获得了一个可以运行docker容器的环境,我就想着要不整个网站把我相关的折腾经历给记录下来,也方便我后期查找以及整其他的方面的东西。所以就有了搭建博客的想法,那么这篇文章也就应运而生。
市面上大多数搭建WordPress博客的架构是LAMP(Linux+Apache+Mysql+PHP),由于我个人觉得Apache的配置文件不太美观以及性能可能没有Nginx好,也没有Nginx方便部署,所以采用了Nginx作为后端静态资源的web服务。同时由于1037U整体性能较差,所以我才用MariaDB来作为web服务的数据库,MariaDB对老的连接池有着更好的兼容性,也方便我后期挂载更多的服务。同时,我们还需要使用acme脚本来自动帮我们更新SSL证书,以保证服务的持续可用,也解放了我们的双手,也节省了钱包。
经过以上的需求分析,那么我们本次的架构也就敲定下来了,也就是LDNMP(Linux+Docker+Nginx+MariaDB+PHP),这里值得注意的是,PHP服务在这里不是完整的PHP后端,而是PHP-fpm,是作为处理CGI脚本的后端服务,和nginx共享web静态页面的存储目录。
话不多说,我们来看一下如何来搭建这样一个架构的WordPress服务吧。
环境部署
首先,我们本次的部署环境是OpenWrt 24.10-SNAPSHOT r28458-cc5bc05a0e / LuCI openwrt-24.10 branch 25.044.01357~67d27ad
采用docker-compose
方式来进行部署。
由于我编译系统时以及选择了docker
containerd
docker-compose
等一系列docker组件,我这里就不需要再进行安装了。
那么OpenWrt下的docker环境可能会存在无法联网的情况,我们需要通过以下的操作来为容器的网络接口请求创建NAT。
[来源于知乎] https://zhuanlan.zhihu.com/p/446948929
1、Luci>网络>防火墙>转发:接受
2、添加如下防火墙规则
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE (172.17.0.0改成自己docker0的网段)
3、删除 docker0 并重启
ip link del docker0
reboot
那么接下来我们就可以开始部署服务了。
目录环境
我们首先使用以下命令来选择一个合适的目录来对docker数据进行持久化存储。(站长这里直接选择的/root
目录)
/root
├── docker
│ ├── html
│ │ └── wordpress
│ │ └── ···
│ ├── mysql
│ │ ├── conf
│ │ └── data
│ │ └── ···
│ └── nginx
│ ├── certs
│ │ └── ···
│ └── conf
│ ├── blog.conf
│ └── default_80.conf
└── service
└── docker-compose.yml
那么我设想的root文件夹下的整体目录树就是这样了,那么接下来我们就可以来编辑docker-compose
文件。
Docker-Compose文件编辑
如果你想采用别的域名解析服务提供商,请自行到Wiki查询自己域名提供商所需的相关Token
。
services:
proxy:
image: 'nginx:latest' #拉取最新的nginx镜像
container_name: proxy
restart: always
volumes:
- '/root/docker/html:/var/www/html' #静态网站文件的挂载点
- '/root/docker/nginx/conf:/etc/nginx/conf.d' #nginx配置文件的存放位置
- '/root/docker/nginx/certs:/etc/nginx/certs' #ssl证书的存放位置
ports: #将容器的80和443端口映射到宿主机的8080和4430端口
- '8080:80'
- '4430:443'
logging: #日志记录的设定,超过1M自动废弃
driver: json-file
options:
max-size: 1m
depends_on: #依赖运行的容器列表
- php-fpm
- mariadb
- acme
php-fpm:
image: 'php:fpm' #拉取php-fpm分支
container_name: php-fpm
restart: always
volumes:
- '/root/docker/html:/var/www/html' #需要挂载到和nginx相同的页面目录,以处理nginx的页面请求
logging:
driver: json-file
options:
max-size: 1m
mariadb:
image: 'mariadb:latest'
container_name: mariadb
restart: always
volumes:
- '/root/docker/mysql/conf:/etc/mysql/conf.d' #mariadb的配置目录
- '/root/docker/mysql/data:/var/lib/mysql' #持久化存储mariadb的数据
environment: #配置环境变量
- MYSQL_DATABASE=blog #创建blog数据库
- MYSQL_USER=wordpress #创建wordpress用户
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PWD} #为root用户设置密码
- MYSQL_PASSWORD=${MYSQL_PWD} #为wordpress用户设置密码
env_file: #外部环境变量文件,保证密码文件的安全,防止明文出现在命令中
- .env
logging:
driver: json-file
options:
max-size: 1m
acme:
image: 'neilpang/acme.sh:latest'
container_name: acme
restart: always
volumes:
- '/root/docker/nginx/certs:/acme.sh' #将acme.sh文件夹的证书文件挂载到留存的ssl证书文件夹
environment:
- CF_Zone_ID=xxxxxxx #这里选择的cloudflare的申请方式,填写cf相关的鉴权密钥
- CF_Token=xxxxxxx
command: 'daemon'
logging:
driver: json-file
options:
max-size: 1m
这样我们就完成了对docker-compose.yml
的填写,接下来将其丢进/root/service
目录下,并在其中创建.env
文件来存放我们的MariaDB服务的相关密码。
vim /root/service/.env
MYSQL_ROOT_PWD=xxxxxxx #root的密码
MYSQL_PWD=xxxxxxxx #wordpress用户的密码
这里我们就可以启用容器集群试一下效果了。(如果没有办法直接拉取docker镜像,请自行配置docker镜像源)
cd /root/service
docker-compose up -d
容器创建好应该类似这样的提示
Acme服务搭建
接下来使用命令来生成证书,这里以Cloudflare作为解析商为例:
#利用你的邮箱来申请证书
docker exec acme --register-account -m xxxxx@xx.xxx
#开始签名证书,支持多个域名
docker exec acme --issue --dns dns_cf -d xxx.com -d *.xxx.com
不出意外,网络状态正常,那么就会出现以上类似的提示,同时会显示一个密钥。随后我们运行以下命令来启用自动更新acme.sh的脚本。
自动更新 acme.sh 脚本
docker exec acme --upgrade --auto-upgrade
以及添加自动更新的定时任务。
添加自动更新任务
10 0 * * * docker exec acme --cron > /dev/null
10 1 * * * docker restart nginx # 重新加载nginx配置
Nginx配置
接下来我们在/root/docker/nginx/conf
目录下创建一个名为default_80.conf
的文件,我这里因为有多个服务,所以就这样命名了,你们在自行部署的时候完全可以将重定向的配置文件和https的配置文件放在同一个文件里面。
server {
listen 80 default_server;
#永久重定向http请求到https
return 301 https://$http_host$request_uri; #这里因为服务不是默认的80端口,在内网直接访问需要使用带端口号的链接重定向
}
以及创建blog.conf
来为wordpress服务选择一个合适的配置文件。
server {
listen 443 ssl;
server_name www.jiale233.top jiale233.top;
#配置证书密钥的存放位置,这里使用docker的挂载可以方便的取用
ssl_certificate /etc/nginx/certs/jiale233.top_ecc/fullchain.cer;
ssl_certificate_key /etc/nginx/certs/jiale233.top_ecc/jiale233.top.key;
root /var/www/html/wordpress; #配置博客的根目录
index index.php;
location / { #适配wordpress的自定义链接,以及其resetapi
try_files $uri $uri/ /index.php?$args;
}
try_files $uri $uri/ =404;
#限制文件的最大大小
client_max_body_size 500m;
#cgi的配置,用以调用php-fpm来加载页面的php脚本
location ~ \.php$ {
fastcgi_pass php-fpm:9000; #处于同一compose环境下的容器可以通过容器名+端口号互访
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
WordPress源文件拉取
这样配置好了之后我们先不急着进行重启,我们先来拉取一下wordpress的源文件。
cd /root/docker/html
wget https://cn.wordpress.org/latest-zh_CN.zip
unzip latest-zh_CN.zip
rm latest-zh_CN.zip
目录权限设置
接下来我们为目录配置以下权限,以保证wordpress相关服务能正常运行。
docker exec -it proxy chmod -R 777 /var/www/html #改变目录的写入权限
docker exec -it php chmod -R 777 /var/www/html
docker exec -it proxy chown -R www:www /var/www/html #改变文件目录的拥有者
docker exec -it php chown -R www:www /var/www/html
PHP拓展安装
接下来就是安装相关的php扩展,使得wordpress服务能正常运行,这里有条件可以为容器配置代理或者进行科学上网。
docker exec php-fpm apt update
docker exec php-fpm apt install -y libmariadb-dev-compat libmariadb-dev libzip-dev libmagickwand-dev imagemagick
docker exec php-fpm docker-php-ext-install mysqli pdo_mysql zip exif gd intl bcmath opcache
docker exec php-fpm pecl install imagick
docker exec php-fpm sh -c 'echo "extension=imagick.so" > /usr/local/etc/php/conf.d/imagick.ini'
docker exec -it php-fpm sh -c 'echo "upload_max_filesize=500M \n post_max_size=500M" > /usr/local/etc/php/conf.d/uploads.ini'
配置代理可用环境变量亦可使用全局代理。
export http_proxy='127.0.0.1:7890'
export https_proxy='127.0.0.1:7890'
接下来我们重启nginx和php-fpm服务即可,别忘了在防火墙或者openwrt对端口进行转发。
docker-compose restart proxy
docker-compose restart php-fpm