运行环境选择:裸机环境 -> Docker
主要软件选择:NGINX,MariaDB,phpMyAdmin
由于 Mysql 所需内存过多,原先的服务器配置已无法支持运行。
因此在 DigitalOcean 上购买了新的配置的服务器,并决定使用Docker部署,方便管理。
就我观察而言,目前暂无完整的相关教程,在这里做一个简述。
Table of Contents
前述
关于Web服务器与数据库程序的选择:
Nginx 和 Apache 各有什么优缺点?,MariaDB和MySQL全面对比
参考资料(主要的):
How To Install WordPress With Docker Compose,Running WordPress with MariaDB
准备工作(你需要什么)
- 一台尚在正常运行 WordPress 的服务器
- 一个等待部署的环境(可以是同一台服务器,但因为可能需要短暂运行两套完整的WordPress服务,可能需要较多的内存 >= 1G)
安装 Docker
APT 安装 Docker 软件包
参考官方教程安装。
PS:请安装 docker-ce
而非 docker.io
,原因:What is docker.io in relation to docker-ce and docker-ee?
给予登录用户 Docker 操作权限
参考官方文档
sudo groupadd docker
sudo usermod -aG docker $USER
编写配置文件
创建一个存放所有配置文件的文件夹
mkdir -p $HOME/.config/wordpress
编写 Docker 配置文件(配置仅供参考,请仔细配置信息解释部分)
$HOME/.config/wordpress/docker-compose.yml
version: '3' services: db: image: mariadb container_name: mariadb restart: unless-stopped env_file: .env environment: - MYSQL_DATABASE=wordpress volumes: - dbdata:/var/lib/mysql networks: - app-network wordpress: depends_on: - db image: wordpress:fpm container_name: wordpress restart: unless-stopped env_file: .env environment: - WORDPRESS_DB_HOST=db:3306 - WORDPRESS_DB_NAME=wordpress - WORDPRESS_DB_USER=$MYSQL_USER - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD volumes: - ./php-conf/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini - wordpress:/var/www/html networks: - app-network webserver: depends_on: - wordpress image: nginx container_name: webserver restart: unless-stopped ports: - "80:80" - "443:443" volumes: - wordpress:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - wordpress:/var/www/html command: certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com volumes: certbot-etc: wordpress: dbdata: networks: app-network: driver: bridge
$HOME/.config/wordpress/.env
MYSQL_ROOT_PASSWORD=XXXXXXXX MYSQL_USER=wordpress MYSQL_PASSWORD=XXXXXXXX
$HOME/.config/wordpress/.dockerignore
.env .git docker-compose.yml .dockerignore
配置信息解释
.dockerignore
我的理解是类似于 .gitignore 用来忽略非必要的文件
.env
一个简单的文件,用来存储待会需要使用的环境变量,叫做其他名字或者不创建该文件均可
MYSQL_ROOT_PASSWORD=XXXXXXXX (填入初始 Root 密码) MYSQL_USER=wordpress (填入 wordpress 数据库操作用户名,可以自由填写) MYSQL_PASSWORD=XXXXXXXX (填入上面那个用户的初始密码) # 建议使用密码生成器生成足够安全的密码
docker-compose.yml
用来编排 Docker 镜像。用来描述 Docker 镜像之间的依赖关系及启动它们所设置参数。简言之,就是为了避免手动输入过多的命令,减少操作复杂程度。
使用 docker-compose 替代 docker run
版本信息
version: '3'
用于注明配置文件适配的版本号,当前(2019-07-25)是 3。
MariaDB 数据库配置
db: image: mariadb (启动镜像的名称) container_name: mariadb (启动容器的名称,可以叫做其他名字) restart: unless-stopped (宿主机重启则自动启动,永不停止) env_file: .env (环境变量,文件设置) environment: - MYSQL_DATABASE=wordpress (存储 WordPress 网站数据的数据库名称,可自由填写)(环境变量,手动设置) volumes: - dbdata:/var/lib/mysql (数据卷关联,存储数据库文件,也可以在这里挂载宿主机文件/夹) networks: - app-network (Docker 网络连接环境)
WordPress 配置
wordpress: depends_on: - db (提前启动数据库,依赖 db,就是上面那个数据库) image: wordpress:fpm (使用fpm版本,默认的 wordpress 容器内置 Apache2 作为 Web 服务器) container_name: wordpress restart: unless-stopped env_file: .env environment: - WORDPRESS_DB_HOST=db:3306 (数据库连接端口,为默认端口。因为在 Docker 中运行,网络隔离,无需更改) - WORDPRESS_DB_NAME=wordpress (数据库名称,可自由填写) - WORDPRESS_DB_USER=$MYSQL_USER (数据库登录用户名,绑定配置文件中的值) - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD (数据库登录密码) volumes: - wordpress:/var/www/html (数据卷关联,存储网站文件) networks: - app-network
NGINX 配置
webserver: depends_on: - wordpress image: nginx container_name: webserver restart: unless-stopped ports: (端口关联) - "80:80" - "443:443" volumes: - wordpress:/var/www/html (WordPress 网站文件) - ./nginx-conf:/etc/nginx/conf.d (NGINX 配置文件,尚未编写) - certbot-etc:/etc/letsencrypt (关联cerbot-etc数据卷,以使用HTTPS证书文件) networks: - app-network
Certbot 配置
certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt (存储获取到的HTTPS证书) - wordpress:/var/www/html (验证网站) command: certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com (这里的 example.com 需要替换为你自己的网址,[email protected] 需要替换为你自己申请证书的邮箱)
申请 HTTP 证书
Let’s Encrypt 的 HTTPS证书是只要你的Web服务器正常运行就能获得的,所以,我们接下来让 NGINX 能够正常运行。
编写 NGINX 配置(只为了获取证书用)
参考 How To Install WordPress With Docker Compose
创建文件夹
mkdir -p $HOME/.config/wordpress/nginx-conf
$HOME/.config/wordpress/nginx-conf/nginx.conf
server { listen 80; listen [::]:80; server_name example.com www.example.com; index index.php index.html index.htm; root /var/www/html; location ~ /.well-known/acme-challenge { allow all; root /var/www/html; } location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass wordpress:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$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 = /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; } }
运行容器
进入 docker-compose.yml 所在文件夹
cd ~/.config/wordpress
运行容器
docker-compose up -d
你将会看到:
Creating db ... done Creating wordpress ... done Creating webserver ... done Creating certbot ... done
检查容器状态
docker-compose ps
Name Command State Ports mariadb docker-entrypoint.sh mysqld Up 3306/tcp webserver nginx -g daemon off; Up 0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp wordpress docker-entrypoint.sh php-fpm Up 9000/tcp
请确认 数据库的3306端口、WordPress 使用的9000端口与两个 NGINX 的Web 服务端口正常开启。
你可以查看log
docker-compose logs service_name
# server_name 为你所想查看的容器名,例如wordpress
确认 测试用HTTPS证书 已获得
docker-compose exec webserver ls -la /etc/letsencrypt/live
total 16 drwx------ 3 root root 4096 Jul 24 14:58 . drwxr-xr-x 9 root root 4096 Jul 25 12:12 .. -rw-r--r-- 1 root root 740 Jul 24 14:58 README drwxr-xr-x 2 root root 4096 Jul 24 15:10 example.com (这里应该是你所申请的网站的域名)
再次运行单独 cerbot
docker-compose up --force-recreate --no-deps certbot
确认日志正确
Recreating certbot … done Attaching to certbot certbot | Saving debug log to /var/log/letsencrypt/letsencrypt.log certbot | Plugins selected: Authenticator webroot, Installer None certbot | Renewing an existing certificate certbot | Performing the following challenges: certbot | http-01 challenge for example.com certbot | http-01 challenge for www.example.com certbot | Using the webroot path /var/www/html for all unmatched domains. certbot | Waiting for verification… certbot | Cleaning up challenges certbot | IMPORTANT NOTES: certbot | - Congratulations! Your certificate and chain have been saved at: certbot | /etc/letsencrypt/live/example.com/fullchain.pem certbot | Your key file has been saved at: certbot | /etc/letsencrypt/live/example.com/privkey.pem certbot | Your cert will expire on 2019-08-08. To obtain a new or tweaked certbot | version of this certificate in the future, simply run certbot certbot | again. To non-interactively renew all of your certificates, run certbot | "certbot renew" certbot | - Your account credentials have been saved in your Certbot certbot | configuration directory at /etc/letsencrypt. You should make a certbot | secure backup of this folder now. This configuration directory will certbot | also contain certificates and private keys obtained by Certbot so certbot | making regular backups of this folder is ideal. certbot | - If you like Certbot, please consider supporting our work by: certbot | certbot | Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate certbot | Donating to EFF: https://eff.org/donate-le certbot | certbot exited with code 0
配置 NGINX
参考 How To Install WordPress With Docker Compose
停止 nginx 服务
docker-compose stop webserver
下载 CertBot 预置的 NGINX SSL 配置文件
curl -sSLo nginx-conf/options-ssl-nginx.conf
https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf
编辑 nginx.conf (务必替换掉example.com)
$HOME/.config/wordpress/nginx-conf/nginx.conf
server { listen 80; listen [::]:80; server_name example.com www.example.com; location ~ /.well-known/acme-challenge { allow all; root /var/www/html; } location / { rewrite ^ https://$host$request_uri? permanent; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com www.example.com; index index.php index.html index.htm; root /var/www/html; server_tokens off; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include /etc/nginx/conf.d/options-ssl-nginx.conf; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always; # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # enable strict transport security only if you understand the implications location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass wordpress:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$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 = /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; } }
CertBot 自动续订
参考 How To Install WordPress With Docker Compose
WordPress 安装完成
到这里,WordPress 的 Docker 环境已经安装完成了。
现在在浏览器上访问你服务器的 IP,应该可以正常看见 WordPress 欢迎界面。
之后的内容是关于网站完整的数据快速迁移部分。
WordPress 数据迁移
数据库迁移
参考官方文档
这里选用 phpMyAdmin 作为数据库操作工具
数据库备份
安装 phpMyAdmin(这部分时间过于遥远,细节已记不清了)
- APT 安装 phpmyadmin
sudo apt install phpmyadmin
- 关联 phpMyAdmin 至 Web 服务器
ln -s /uer/share/phpadmin /var/www/html/phpadmin
- 访问 phpMyAdmin
在浏览器上访问 http://<YOUR IP>/phpmyadmin
导出 WordPress 数据库
- 选中 WordPress 数据库(你所需要导出的数据库)
- 点击“导出”按钮
- 点击“执行”,下载备份文件到本地。
数据库导入
安装 Docker 版本 phpMyAdmin
- 确认 docker 内部网络连接
docker network ls
NETWORK ID NAME DRIVER SCOPE 096f53f6440c bridge bridge local 91cd580e6601 host host local fd96bc66d20c none null local 95dc00bd8b48 wordpress_app-network bridge local 790a7926eca2 wordpress_default bridge local
之前我们在 docker-compose.yml 文件中指定了 MariaDB 数据库的内部网络为:wordpress_app-network
- 运行 phpMyAdmin
docker run --name myadmin -d --link mariadb:db -p 8081:80 --net wordpress_app-network phpmyadmin/phpmyadmin
Docker 会尝试运行镜像(如果不存在会自动下载),将 phpMyAdmin 与 MariaDB 数据库相链接,并将容器绑定在 wordpress_app-network 中,同时将 Web 访问端口绑定在宿主机的公网 8081 端口。
- 访问 phpMyAdmin
在浏览器上访问 http://<YOUR IP>:8081
导入 WordPress 数据库
- 选中 WordPress 数据库(你所需要导入的数据库)
- 点击“导入”按钮
- 上传备份文件
- 点击“执行”
网站文件迁移
网站文件包括了你所安装的插件,你所上传的图片等资源文件。
WordPress 文件备份
SSH 登录老的服务器
ssh -p <你的ssh端口> <你的ssh登录用户名>@<你的旧服务器IP>
- 确认网站文件位置
ls -la /var/www/html/wordpress
我把文件存放在了wordpress目录下。如果你像我一样,把数据存在了子目录,请在WordPress 控制台修改站点地址(URL)为站点根目录。
total 212 drwxr-xr-x 5 www-data nogroup 4096 Jul 23 20:41 . drwxr-xr-x 3 root root 4096 Mar 19 08:16 .. -rw-r--r-- 1 www-data nogroup 420 Feb 27 03:22 index.php -rw-r--r-- 1 www-data nogroup 19935 May 8 07:09 license.txt -rw-r--r-- 1 www-data nogroup 7447 Jun 18 17:55 readme.html -rw-r--r-- 1 www-data nogroup 6919 Feb 27 03:22 wp-activate.php drwxr-xr-x 9 www-data nogroup 4096 May 8 07:09 wp-admin -rw-r--r-- 1 www-data nogroup 369 Feb 27 03:22 wp-blog-header.php -rw-r--r-- 1 wwexitw-data nogroup 2283 Feb 27 03:22 wp-comments-post.php -rw-rw-rw- 1 www-data www-data 3219 May 19 2018 wp-config.php -rw-r--r-- 1 www-data nogroup 2898 Feb 27 03:22 wp-config-sample.php drwxr-xr-x 8 www-data nogroup 4096 Jul 24 22:45 wp-content -rw-r--r-- 1 www-data nogroup 3847 Feb 27 03:22 wp-cron.php drwxr-xr-x 20 www-data nogroup 12288 May 8 07:09 wp-includes -rw-r--r-- 1 www-data nogroup 2502 Feb 27 03:22 wp-links-opml.php -rw-r--r-- 1 www-data nogroup 3306 Feb 27 03:22 wp-load.php -rw-r--r-- 1 www-data nogroup 39551 Jun 18 17:55 wp-login.php -rw-r--r-- 1 www-data nogroup 8403 Feb 27 03:22 wp-mail.php -rw-r--r-- 1 www-data nogroup 18962 May 8 07:09 wp-settings.php -rw-r--r-- 1 www-data nogroup 31085 Feb 27 03:22 wp-signup.php -rw-r--r-- 1 www-data nogroup 4764 Feb 27 03:22 wp-trackback.php -rw-r--r-- 1 www-data nogroup 3068 Feb 27 03:22 xmlrpc.php
- 打包网站文件
sudo tar -czvf ~/html.tar.gz /var/www/html/
- 修改备份压缩包权限(便于下载)
sudo chown $USER:$USER html.tar.gz
- 退出SSH登录
exit
下载备份压缩包
scp -r -P <你的ssh端口> <你的ssh登录用户名>@<你的旧服务器IP>:~/html.tar.gz ./
WordPress 文件恢复上传备份压缩包
上传备份压缩包
scp -r -P <你的ssh端口>./html.tar.gz <你的ssh登录用户名>@<你的新服务器IP>:
SSH 登录新的服务器
- 解压备份压缩包
tar -xzvf ~/html.tar.gz
- 传入备份文件到 Docker 数据卷
docker cp ~/var/www/html wordpress:/var/www
- 进入 docker-compose.yml 所在文件夹
cd $HOME/.config/.wordpress
- 检查传入文件
docker-compose exec webserver ls -la /var/www/html/
你会发现新传入的文件用户都会改为 1000,这样网站可以运行,但是为只读状态(忘记截图了)
- 修复网站文件权限
docker-compose exec wordpress chown -R www-data:www-data /var/www/html
- 覆盖 WordPress 文件(如果你把站点放在根目录下)
- 进入 WordPress 容器
docker-compose exec wordpress sh
- 覆盖 WordPress 网站文件
rm /var/www/html/wp-* && mv /var/www/html/wordpress/* /var/www/html/.
理由:WordPress 容器在启动前会检查 /var/www/html
下有无 WordPress 站点文件,所以我建议在容器内使用根目录。如果你需要在服务器上部署多个网站,可以考虑反向代理等。
修复 WordPress 数据库读取
编辑 wp-config.php 文件
cd $/HOME/var/www/html/wordpress
vim wp-config.php
# 我之前用得是子目录,请检查你自己具体的文件位置
修改以下部分 与你之前在 .env 文件中设置一致
- 修改帐号、密码与数据库名称
// ** MySQL 设置 - 具体信息来自您正在使用的主机 ** // /** WordPress数据库的名称 */ define('DB_NAME', 'wordpress'); /** MySQL数据库用户名 */ define('DB_USER', 'wordpress'); /** MySQL数据库密码 */ define('DB_PASSWORD', '123456');
- 修改数据库主机端口
/** MySQL主机 */ define('DB_HOST', 'db:3306');
- 保存
覆盖 WordPress 数据卷 wp-config.php 文件
docker cp wp-config.php wordpress:/var/www/html/wp-config.php
WordPress 数据恢复完成
- 关闭 phpMyAdmin
docker stop myadmin
为保证数据库安全,请务必停止,只在需要调试时开启。
后记
此次数据迁移主要把握两个方向:环境架设(测试可用)、数据备份(确定相关文件)。
可能会出现的错误及解决方案
- 新网站运行正常,但访问不显示信息(空白)。
原因:数据库已导入,且正常运行,网站数据未导入成功。
- 其他问题,请注意以下事项
- 请在未导入配置的情况下检查网站是否正常运行。
- WordPress 的问题主要是文件与数据库的匹配。
排查方法:
- 查看Docker日志
docker-compose logs service_name
- 使用 phpMyAdmin 检查数据库与用户是否正常
Pingback: WordPress安装教程 – Hire Camp
作者,你好!我是腾讯云+社区的小编,关注了您分享的技术文章,觉得很棒,我们诚挚邀请您加入云+社区,与我们众多的社区作者一起为开发者分享技术干货。这个是我们云+社区【腾讯云自媒体分享计划】入驻流程和权益介绍的地址:https://cloud.tencent.com/developer/support-plan。如果您愿意加入或者想了解更多的信息请联系我~微信:techou002,我们对您的加入充满期待。
老哥,加个友情,我已经把您到链接加上了:
网址:https://blog.xbss.net/
标题:小白博客
好的,谢谢支持
您好,我来自V2ex,希望能跟您交换友情链接。
我的博客也基本上是技术类文章,全部都是原创内容。
希望得到回复,我的博客地址是:https://www.fi-ads.com/
非常感谢!
谢谢, 老白终于搞定.两个半天,学vim, 学docker, 回忆linux.
自行变更了一些流程, 把certbot部分全部放弃了. http80状态下建站和数据转移全部ok, 继续用mysql, 再参考DO的那篇,我也成了不白拉.谢谢.
可以的