cloudcone云服务器部署wp

1. 前言
之前我使用过阿里云服务器,也是我购买的第一个服务器,在使用它部署wp的过程中发现不是很好用,想着买一个境外的,我想着就买个稳定一点香港或者美国的大牌,本来想入手香港“莱某云”的,但是想想还是入手cloudcone算了。我要的就是完全无政策限制的网络环境,美国的VPS显得可靠一点,因为很多香港VPS是国内公司的,还有一个原因我喜欢cloudcone这个厂家名称,听着就很喜欢。我想日后有空搭建VPN的时候,选择美国的服务器就显得尤为重要,被限制IP的可能性小一点,况且cloudcone支持更换IP且价格也是很便宜的。
现在我还是以部署wp博客服务为主题,但是因为网络环境友好没有墙的阻碍,部署过程就显得简单很多了。这一篇中,我着重对部署过程一些网络概念进行详细说明,以增加对整个部署搭建过程的掌握以及排查错误。开启SSL的部分不再赘述,请参考之前的文章。
2. 系统环境与容器安装
我们还是以Ubuntu22.04为系统,安装容器环境与运维面板。

部署wordpress容器:

PS:这是官方docker镜像的部署指导,我们一般不使用创建卷volume来做数据的持久化,我们更多使用目录的映射。使用数据卷是一种更高级的数据管理方法,更好得做备份迁移,可使用portainer面板可以统一管理数据卷。
wordpress编排:
version: '3.8'
services:
mysql:
# 固定位8.0版本
image: mysql:8.0
restart: always
#command 防止日志爆满,通过环境变量方式
environment:
MYSQL_ROOT_PASSWORD: mysql_root_pass
MYSQL_DATABASE: wordpress_db
MYSQL_USER: wordpress_user
MYSQL_PASSWORD: wordpress_password
# 兼容性,旧版PHP(<7.4)需要旧的认证插件,兼容 WordPress 的 PHP 环境
MYSQL_DEFAULT_AUTH: mysql_native_password
# 字符集,新版本没有这个环境变量
#MYSQL_CHARSET: utf8mb4
#MYSQL_COLLATION: utf8mb4_unicode_ci
volumes:
- /root/data/docker_data/wordpress/mysql_data:/var/lib/mysql
- /root/data/docker_data/wordpress/mysql_config/mysql.cnf:/etc/mysql/conf.d/custom.cnf:ro # 关键挂载
mem_limit: 512m # 限制最大内存512M(关键)
networks:
- default_network # 数据库和WP用默认网络通信
# 解决 MySQL 容器权限问题(可选,避免宿主机目录权限不足导致启动失败)
user: root
wordpress:
image: wordpress:latest
restart: always
environment:
# 数据库主机名:直接填写 MySQL 服务名(docker 内部网络会自动解析)
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_NAME: wordpress_db
WORDPRESS_DB_USER: wordpress_user
WORDPRESS_DB_PASSWORD: wordpress_password
ports:
- "8089:80"
volumes:
- /root/data/docker_data/wordpress/wp_data:/var/www/html
# 新增:挂载自定义 PHP 配置文件(控制上传大小)
- /root/data/docker_data/wordpress/php_config/wordpress-upload-limit.ini:/usr/local/etc/php/conf.d/wordpress-upload-limit.ini
mem_limit: 256m # 可选:限制wordpress容器内存,减轻服务器压力
depends_on:
- mysql
networks:
- default_network
- my_npm_prj_npm_network #加入npm网络,反代理
user: root
phpmyadmin:
image: phpmyadmin:latest
restart: always
environment:
# 数据库主机名:填写 MySQL 服务名(同一网络内可解析)
PMA_HOST: mysql
MYSQL_ROOT_PASSWORD: mysql_root_pass
ports:
- "8088:80"
depends_on:
- mysql
networks:
- default_network
- my_npm_prj_npm_network #加入npm网络,反代理
# 网络段(桥接模式)
networks:
my_npm_prj_npm_network:
external: true # 声明为外部网络,external: true不自动加前缀创建
default_network:
# 网络驱动:bridge(桥接模式,docker 默认网络模式,支持宿主机端口映射访问)
driver: bridge
wordpress php环境变量配置:
# 核心:设置上传文件最大大小为 1024M
upload_max_filesize = 1024M
# 核心:设置 POST 请求最大大小(必须 ≥ upload_max_filesize,避免表单提交超限)
post_max_size = 1024M
# 可选:设置 PHP 内存限制(大文件上传需要足够内存,避免超时)
memory_limit = 1024M
# 可选:设置脚本执行超时时间(大文件上传耗时久,延长超时到 300 秒)
max_execution_time = 300
# 可选:设置脚本输入输出超时时间
max_input_time = 300
mysql环境变量配置:
# my.cnf - mysql:8.0 小内存优化配置(适配512M容器内存)
[mysqld]
# 核心缓存:设为容器内存的50%(512M容器对应256M),兼顾效率和内存
innodb_buffer_pool_size = 256M
# 最大连接数:WordPress使用场景下50足够,避免连接过多占用内存
max_connections = 50
# 临时表大小限制:32M,避免过大占用内存
tmp_table_size = 32M
max_heap_table_size = 32M
# 关闭不必要的日志,节省资源
slow_query_log = 0
general_log = 0
# 字符集配置(与WordPress保持一致,避免乱码)
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 兼容WordPress的sql_mode,避免查询报错
sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
# 关闭MySQL 8.0 特有功能,减少内存消耗
disabled_storage_engines = MyISAM
innodb_flush_log_at_trx_commit = 2
# 日志大小
max-binlog-size = 200M
expire-logs-days = 2
[mysql]
default-character-set = utf8mb4
bash命令:
rm -rf /root/data/docker_data/wordpress #r,recursive是递归,f,force是强制
docker-compose down #卸载编排
docker-compose up -d #部署编排
chmod -R 777 wp-content #修改权限,R是递归,三个组的rwx权限全开。chown是更改所有者与组
phpmyadmin的检查:
mysql8.0默认排序规则是 utf8mb4_0900_ai_ci,取消了compose中的环境变量,使用cfg文件配置。我们需要使用读取配置文件的方式去配置,环境变量导入后,就正常了。

3. NPM部署
3.1 可选部署portainer
Portainer的安装,首先确保系统已经安装了docker,没有安装的话可以安装apt install docker.io Ubuntu官方版本。参看docs.portainer.io官方安装指导,新建 /root/data/docker_data 统一管理容器数据,最后映射登录81端口,Portainer的管理页面登录端口。
mkdir -p /root/data/docker_data #p,parent自动创建父目录。

3.2 部署NPM,部署运维面板
关于宝塔或者1panel的安装,其实官方已经有脚本了,很简单不赘述了。
关于宝塔Nginx与NginxProxyManager容器的代理问题:
宝塔自带Nginx,是系统层的服务,会抢占80/443 web服务端口,如果你想使用 NginxProxyManager容器来管理你的反代理,先把宝塔的系统层Nginx禁用,让NginxProxyManager容器接管并占用80/443 web服务端口的监听;
补充:如果你没有反代理,所有的服务访问都需要 IP+Port 才行,当然宝塔的网站模块里面是可以设置反代理静态网站或者动态网站的(其本质是修改系统层的Nginx配置文件),但是我不喜欢用宝塔进行反代,还是使用NPM方便好用一点。
npm部署:
我们先把ufw防火墙关闭(后续针对性放行端口):
ufw disable
ufw status
ufw reload

容器编排:

我们登录自己的域名aahaiou.com,发现重定向到npm的默认网页上,说明部署成功了:

PS:我们域名解析aahaiou.com根域名到宿主ip,访问根域名时候,如果npm部署成功并接管80/443的流量的时候,就会显示上图“congratulations!”恭喜成功字样。
3.3 设置NPM反代
接下来我们登录使用IP+端口,登录npm后台进行配置,使用二级域名为nginx与portainer,给一个好用的访问地址nginx.aahaiou.com/portainer.aahaiou.com,
使用npm反代理npm与portainer:

4.4 设置NPM反代的隐蔽端口与地址
云服务器侧的防火墙,我们仅仅允许80/443/22的流量放行,所有流量只能通过Nginx的80/443端口转发,只在测试时候才放行需要的端口(之后保持这样的设置才是规范的):


反代设置目的地的填写,两者方法都可以(docker ps 命令(process status)查看容器名称):

我们在编写编排的时候,最好使用container_name字段,明确容器的名称,在反代理时候填写名称就可以,不需要填写IP(如果省略该字段,会自动添加前缀为文件夹名称,后缀为数值)。

使用容器名称或者容器地址访问:当使用npm代理作为所有容器服务访问的中介的时候,我们可以把所有的云服务侧的端口给屏蔽掉,即使容器做了端口映射,但是服务器防火墙我们不放行容器的映射端口。外部再也不能通过 【宿主机IP+容器映射端口】的形式访问宿主机的容器服务了,因为此时能通过防火墙的只有npm的80/443端口的流量了。这样就很大程度保证了安全性。我们让npm的网络与要访问的容器的网络在同一网络内就可以互相访问。
sudo ufw allow 80/tcp #允许使用网络访问80/443
sudo ufw allow 443/tcp
使用宿主机地址+映射端口访问:如果我们还是把把云服务器侧的端口给关闭,我们代理的目的地为【宿主机+映射端口】,npm会将访问流量转发到宿主机,宿主机通过映射端口访问到目的容器的服务(若流量是指向宿主IP的,流量包会在栈中循环)。这个前提是允许npm访问映射端口号。假设wordpress容器的映射端口号是8089,执行以下命令放行某网段访问8089端口。
ufw allow from 172.20.0.0/10 to any port 8089 #允许172.20.0.0所有容器网络访问8089端口,如果看不懂需要补充一下网段的知识了
#ufw delete allow 172.20.0.0/10 to any port 8089 #禁用
ufw reload
ufw status numbered #查看列表
#ufw delete 10 #删除第10个列表

PS: 显示我们已经放行了网段172.16.0.0/12的8089端口
4.4.1 测试网络连通性
我们进入NPM容器,测试反代是否正常通信;使用docker exec -it nginx-proxy-manager bash 进入,退出执行exit
docker exec -it nginx-proxy-manager bash #进入容器内shell
curl -I http://142.171.xxx.xxx:8089 #宿主IP+端口的外部测试
curl -I http://172.20.x.x:80 #容器IP+80端口的内部测试
exit #退出
如果没有放行8089端口,显示以下错误:

如果放行8089端口,显示以下成功信息:

如果是在npm容器内,测试容器wordpress的内网地址172.20.0.4通讯,显示失败,是因为没有在编排时候接入同一网络:

如果是在npm容器内,测试容器wordpress的内网地址172.19.0.4通讯,显示成功(npm容器与wordpress容器网络互通):


PS:npm容器与wordpress容器内部网络互通,反代的时候,可以直接填写容器名称: http://wordpress_wordpress_1:80就可以了。

如果反代跳转报错502,那么百分之90就是反代的问题:

4.4.2 查看docker网络:
- ip addr 命令
- docker面板
我们使用ip addr 命令查看当前所有网络,找出docker服务的内网网段即可,以下为找到内网地址为172.17.0.1:

docker面板,查看网络ip:

4.4.3 加入同一个docker网络
让容器加入npm_network,之后需要代理的容器全部都加入该网络,docker-compose如下:

PS:显示指定网络的名称的定义,使用name字段(不加的话前缀为文件夹名称):

4.4.4 两个不同流量路径
方法一流量路径:NPM 容器 → Docker 内网交换机 → WordPress 容器(全程在 Docker 内部);
方法二流量路径:NPM 容器 → 宿主机网卡(8089 端口) → WordPress 容器;

当我们使用端口映射的时候,更多是希望通过【宿主机的IP+容器暴露端口】进行访问的,这会非常方便测试,特别是反代没有搭建好的时候,我们禁用ufw,任何容器端口都有访问权限,就能通过【宿主机的IP+容器暴露端口】访问,当然在完成测试之后,我们把云服务器侧防火墙启用后,外部的访问流量到宿主机就只能是80/443/22端口了。我们启用ufw并设置放行的端口规则,是指宿主机内进程的访问规则,如果一个云服务器侧放行所有端口,宿主机就能接收所有端口的流量并转发到有被容器服务绑定的端口号上,容器也就能收到外部的流量了。
在不熟悉的情况下,配置反代理,最简单的方法就是设置反代目标为http: //142.171.x.x:8088;8088是容器暴露端口号,那么我们在ufw增加放行npm容器访问8088权限就可以完成反代了,因为反代容器必须有80/443端口的权限,另外增加8088权限就行了。这一种方法不是最好的,通过npm后台会暴露宿主IP。建议使用容器名称访问。
4.5 wordpress后台的主页地址设置
注意:设置wordpress的地址,是确保在完成反代设置之后,不然改为域名后,以IP形式的访问是进不去的。
如果第一次安装配置wordpress的时候是通过IP+PORT进入的,那么wordpress就自动设置站点地址设置为IP+PORT,到时做域名反代理访问的时候就会出现地址栏的域名自动追加端口的问题。
进入wordpress设置站点地址把原来IP+PORT改为域名,以防wordpress重定向到IP+PORT上,反代理就会把IP改为域名,最后变为域名加端口号这一种奇怪的地址形式。

4. 后记
对于部署wordpress,其实宝塔面板与docker(docker面板)都可以完成。宝塔面板简直是小白的福音,宝塔面板我们使用起来很方便,一键部署LNMP web服务环境,特别是使用FinalShell终端时候,可以输入bt命令来获取面板登录信息,登录面板后做服务器的管理,比如文件管理/计划任务(备份网站/数据库),网站与数据库等(我更加倾向使用docker打包WordPress与mysql进行部署(docker-compose up -d 后台运行),宝塔的网站与数据库模块基本不使用)
宝塔的缺点是有的,比如宝塔非容器部署WordPress/MySQL/phpMyAdmin建站三件套后,迁移备份是很麻烦的;但是使用docker就不一样了,使用一个docker-compose文件就可以把WordPress/MySQL/phpMyAdmin建站三件套的环境打包好,迁移备份的时候把数据目录压缩打包带走到新的服务器,再docker-compose命令部署就行,简直不要太方便了,日后可以把压缩包做FTP/SFTP/WEBDAV远程文件传输的脚本运行定时计划或者备份版本控制,这个我还没有做过,日后尝试(sync/Duplicate/Syncthing)。
最后一点,其实两者可以同时安装,一起食用更好。宝塔就专业做服务器的运维管理,Portainer就专业做容器的部署管理。因为docker是日后经常使用的,很多服务都是使用docker部署的。