背景:
以前为了方便部署以及便于迁移,用docker部署wordpress。而且不是用单一的wordpress镜像。
一个wordpress站点就用一个mysql容器,多一个站点,就得又开一个mysql容器;
nginx在同一台服务器上,需要反代好几个网站。 同理把nginx部署到wordpress里面,那么就意味着每个网站都是一个docker,有多个nginx并存,造成的资源浪费。
所以当时的做法是把每个功能单独用一个容器部署,mysql一个容器,php一个容器,nginx一个容器。
当时的部署命令:
MYSQL
bash
docker run -p 3306:3306 --name mysql57 --restart=always -v /root/database/mysql57/conf.d:/etc/mysql/conf.d -v /root/database/mysql57/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=xxxxx -d mysql57
PHP
bash
docker run -d -p 9000:9000 -v /root/database/php74fpm/conf/php:/usr/local/etc/php -v /root/database/wordpress:/var/www/html --link mysql57 --privileged=true --name php-mysql
php里面安装了一些第三方的插件,比如memcach,用于满足wordpress的缓存控制。
NGINX. 同时挂载了几个站点,同时解析不同的域名
bash
docker run -d -p 80:80 -p 443:443 --name nginx-php-mysql -v /root/database/wordpress:/var/www/html -v /root/database/nginx/conf.d/:/etc/nginx/conf.d/ -v /root/database/nginx/nginx.conf:/etc/nginx/nginx.conf -v /root/database/static_web:/var/www/static_web -v /root/database/demo_website:/var/www/demo_website --link php-mysql --privileged=true ngnix:v1.3
服务器到期,续费价格翻了几倍,所以要对wordpress和其他的网站服务进行迁移。
迁移后保持MYSQL和PHP的容器,nginx用centos宿主机的。
首先停止几个容器的运行。
bash
docker stop wp-nginx
docker stop wp-php
docker stop wp-mysql
把 3 个容器分别 commit 成镜像
bash
# mysql容器打包
docker commit wp-mysql wp-mysql-backup:v1
# php‑fpm容器打包
docker commit wp-php wp-php-backup:v1
# nginx容器打包
docker commit wp-nginx wp-nginx-backup:v1
记下你的宿主机路径(示例,换成你自己真实路径)
- mysql 宿主机目录:
/opt/wp/mysql - wordpress 网站目录:
/opt/wp/www - nginx 配置目录:
/opt/wp/nginx/conf.d
将镜像导出成 tar 文件(可以拷贝走)
bash
docker save -o wp-mysql-backup.tar wp-mysql-backup:v1
docker save -o wp-php-backup.tar wp-php-backup:v1
现在得到 3 个镜像文件:
bash
- wp‑mysql‑backup.tar
- wp‑php‑backup.tar
因为我们新服务器的nginx用宿主机的,所以就不需要备份它了。
但是!!mysql 数据库、wordpress 网站文件依然不在这 3 个镜像里面 ,因为你 -v 挂载到宿主机了。 所以必须额外打包宿主机目录:
bash
tar -zcvf wp-volume-data.tar.gz /opt/wp/mysql /opt/wp/www /opt/wp/nginx
全部传到新服务器
bash
scp wp-mysql-backup.tar wp-php-backup.tar wp-nginx-backup.tar wp-volume-data.tar.gz root@新IP:/opt
新服务器操作
首先是把导出的镜像载入到新服务器。
bash
docker load -i wp-mysql-backup.tar
docker load -i wp-php-backup.tar
然后使用
docker
docker images
可以看到2个导入的镜像
bash
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
mysql57-backup:v1 a85d55dcbe90 1.23GB 601MB U
php-mysql-backup:v1 8f81b6850808 1.89GB 913MB U
然后把数据解压出来
bash
cd /opt
tar -zxvf wp-volume-data.tar.gz
用打包好的镜像启动容器,挂载依然要加上!!
镜像里面是空的数据库,数据还是靠宿主机挂载目录提供
bash
# mysql
docker run -d \
--name wp-mysql \
-v /opt/wp/mysql:/var/lib/mysql \
wp-mysql-backup:v1
# php
docker run -d \
--name wp-php \
-v /opt/wp/www:/var/www/html \
wp-php-backup:v1
然后大功告成,
最后来配置nginx
把旧主机的nginx conf文件复制到新服务器。
对于
bash
server {
listen 80;
server_name 你的域名或者服务器IP;
root /opt/wp/www;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
这里有几个坑点。
- nginx的配置文件
fastcgi_param SCRIPT_FILENAME documentrootdocument_rootdocumentrootfastcgi_script_name;
报错:
Primary script unknown Nginx 找到了网站目录文件,但是传给 PHP‑FPM 之后,PHP‑FPM 在自己容器内部找不到这个 php 文件。
本质:Nginx 的物理路径 ≠ PHP 容器内的挂载路径
原理拆解
- Nginx(宿主机):
root /opt/wp/wordpress; - Nginx 传给 FastCGI 的脚本路径:
/opt/wp/wordpress/index.php - 但是你的 php‑fpm 容器里面,网站目录挂载到了
/var/www/html在容器里面根本不存在/opt/wp/wordpress/index.php,PHP 找不到文件,抛出Primary script unknown
根源:fastcgi_param SCRIPT_FILENAME 的坑
你现在 nginx 配置里面大概率写了:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
$document_root 是宿主机路径 /opt/wp/wordpress,php 容器不认这个宿主机路径。
修复方案
方案 1【标准 docker‑php‑fpm 修复】修改 nginx php 块
打开你的站点配置文件 qmtptrade.conf 找到 location ~ .php$ 区块,改成下面完整代码:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# 不要使用 $document_root,改用容器内路径
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
}
/var/www/html 就是你 docker -v 挂载到容器内部的目录。