将博客迁移到Docker上

之前的博客是搭建在linode上面的,选择的是日本节点,一个月5美元,一直用的挺好的,但是前几天收到一封来自阿里云的邮件:
经检查您的网站域名wenchao.ren未指向阿里云服务器且无访问记录 ,依据工信部相关法规规定属于空壳网站,请您尽快将域名解析IP地址指向阿里云的网站空间。 如果3个工作日后检查不合格,我们将删除网站备案接入信息,备案号可能被注销,影响网站访问。
没办法,我这等良民虽然很瞧不起阿里这种无节操的行为,但是还是乖乖的把博客迁移到了阿里云的香港主机上面,第一年有很大的优惠,只需要三百多块钱。价钱还算合理,所以也就只能忍气吞声的迁移了,我想这可能不会是最后一次迁移,所以就萌生了将博客迁移到docker上,方便后续迁移。
我使用的是系统为:Ubuntu 16.04, 下面的内容就会一步一步的介绍如何在docker环境下搭建WordPress,本文章使用假设使用的域名为:wenchao.ren,在文章的后面我们也会为博客使用Let’s Encrypt配置HTTPS。

安装docker

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y docker.io

安装完docker以后,我们需要启动它,并且希望在系统重启的时候自动启动docker:

systemctl start docker
systemctl enable docker

在这几步骤弄完以后,我们就可以验证我们的docker是否安装成功:

docker run hello-world

安装Docker-Compose

sudo apt-get install -y python python-pip
pip install docker-compose
docker-compose -v

搭建WordPress

安装完docker以及docker-compose以后,我们就可以开始搭建我们的WordPress环境了。先说一下我计划的目录组织结构:

root@iZj6cb2z32hinqm7d4sc99Z:~# tree -L 3 wordpress-compose
wordpress-compose
├── db-data (mysql数据目录)
├── docker-compose.yml
├── letsencrypt (letsencrypt密匙目录)
│   ├── cert1.pem
│   ├── chain1.pem
│   ├── fullchain1.pem
│   └── privkey1.pem
├── logs (日志目录)
│   └── nginx (nginx日志目录)
│       ├── access.log
│       ├── error.log
│       ├── wenchao.ren-access.log
│       └── wenchao.ren-error.log
├── nginx (nginx配置文件目录)
│   └── wordpress.conf
└── wordpress (WordPress文件目录)
    ├── index.php
    ├── license.txt
    ├── readme.html
    ├── wp-activate.php
    ├── wp-admin
    ├── ....

在本文章中,我们会启动3个docker容器:Nginx,MySQL,WordPress。
如果你不想使用root用户进行后续的操作的话,可以新增加一个用户,比如:testuser

useradd -m -s /bin/bash testuser
passwd testuser

然后我们需要把testuser用户加入到docker的用户组内,这样这个用户才可以使用docker相关的命令:

usermod -a -G docker testuser
systemctl restart docker

接下来我们切换到刚刚创建的用户,然后创建工程的目录:

su - testuser
mkdir -p wordpress-compose
cd wordpress-compose/

然后在wordpress-compose目录下创建docker-compose.yml文件,以及我们需要的几个目录,关于这几个目录的用户在之前我们也介绍过了:

touch docker-compose.yml
mkdir -p nginx/
mkdir -p letsencrypt/
mkdir -p db-data/
mkdir -p logs/nginx/
mkdir -p wordpress/

然后我们编辑docker-compose.yml文件并写入下面的内容:

version: '2'
services:
  nginx:
      image: nginx:latest
      ports:
          - '80:80'
          - "443:443"
      volumes:
          - ./nginx:/etc/nginx/conf.d
          - ./logs/nginx:/var/log/nginx
          - ./wordpress:/var/www/html
          - ./letsencrypt:/etc/letsencrypt/live/wenchao.ren
      links:
          - wordpress
      restart: always
  mysql:
      image: mariadb
      ports:
          - '3306:3306'
      volumes:
          - ./db-data:/var/lib/mysql
      environment:
          - MYSQL_ROOT_PASSWORD=wordpress
      restart: always
  wordpress:
      image: wordpress:4.8.0-php7.0-fpm
      ports:
          - '9000:9000'
      volumes:
          - ./wordpress:/var/www/html
      environment:
          - WORDPRESS_DB_NAME=wpdb
          - WORDPRESS_TABLE_PREFIX=wp_
          - WORDPRESS_DB_HOST=mysql
          - WORDPRESS_DB_PASSWORD=wordpress
      links:
          - mysql
      restart: always

当然,笔者在写这篇文章的时候,wordpress:4.8.0-php7.0-fpm是最新的版本,因此你可能需要使用docker search目录去查询一下最新的版本,或者去docker hub上面通过结果进行搜索。此处之所以使用wordpress:4.8.0-php7.0-fpm而不是wordpress:latest,是因为前者就不需要我们配置php环境了。
编辑完成docker-compose.yml文件以后,我们就可以编写我们的nginx配置文件了
如果你并不想为你的博客启动HTTPS,那么直接vi nginx/wordpress.conf然后写入下面的内容就可以了:

server {
    listen 80;
    server_name wenchao.ren;
    root /var/www/html;
    index index.php;
    access_log /var/log/nginx/wenchao.ren-access.log;
    error_log /var/log/nginx/wenchao.ren-error.log;
    location / {
        try_files $uri $uri/ /index.php?$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;
    }
}

截止到现在,一个并没有开始HTTPS的WordPress环境就已经完全准备ok了。我们可以先启动验证功能一切ok,然后在为博客配置HTTPS。

cd ~/wordpress-compose/
docker-compose up -d
docker-compose ps

这样就可以启动nginx,mysql,WordPress了。如果你想查看日志输出,那么可以使用下面的命令

docker-compose logs nginx
docker-compose logs mysql
docker-compose logs wordpress

当然也可以使用下面的命令:

docker ps
docker logs [containerId]

如果一切正常的话,启动成功以后,我们就可以访问:http://serverIP/页面,就可以看到WordPress的安装界面了。剩下的就是界面操作了。

访问docker容器

 访问nginx容器
docker-compose exec nginx bash
访问MySQL容器
docker-compose exec mysql bash
mysql -u 「用户名」 -p 「密码」
访问WordPress容器
docker-compose exec wordpress bash

使用Let’s Encrypt开启HTTPS

先说一下思路吧,从上面的docker-compose.yml就可以看出来,我的做法其实是在宿主机上使用Let’s Encrypt生成证书,然后在nginx容器中挂载这些证书。下面让我们开始吧。
首先安装Let’s Encrypt,然后在生成证书,然后复制证书到指定目录

cd ~/wordpress-compose/
sudo apt-get install letsencrypt
letsencrypt certonly  --standalone --email me@wenchao.ren -d wenchao.ren -d www.wenchao.ren
sudo cp /etc/letsencrypt/archive/wenchao.ren/* ./letsencrypt/

上面的email中的me@wenchao.ren你需要替换为你自己的邮箱,-d选项后面的跟着的是自己的域名。Let’s Encrypt 最多支持添加100个域名,但不支持通配符。 这里要注意提前将本机的80端口和443端口空出来。当看到返回 Congratulations 的字样则表示证书生成成功了。
生成的证书存地址会在返回的文本中显,一般会存放在/etc/letsencrypt/live/$domain 目录下,注意该目录下的文件其实是链接,文件的真实的地址在/etc/letsencrypt/archive/$domain(由于 Let’s Encrypt 每三个月要续约一次,续约后会生成新的证书,存放在 archive 文件夹下,然后自动更新 live 文件下的链接。)。因此,我们在把证书挂载到 docker 里时,应注意要挂载真实的文件,而不可挂载链接,不然会导致找不到文件。
然后修改nginx的配置:vi nginx/wordpress.conf然后加入下面的内容:

server {
    listen 80;
    server_name wenchao.ren;
    return 301 https://$host$request_uri;
}
server {
    #listen 80;
    listen 443 ssl;
    listen [::]:443 ssl;
    ssl_certificate /etc/letsencrypt/live/wenchao.ren/fullchain1.pem;
    ssl_certificate_key /etc/letsencrypt/live/wenchao.ren/privkey1.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    server_name wenchao.ren;
    client_max_body_size 50M;
    root /var/www/html;
    index index.php;
    access_log /var/log/nginx/wenchao.ren-access.log;
    error_log /var/log/nginx/wenchao.ren-error.log;
    location / {
        try_files $uri $uri/ /index.php?$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;
    }
}

需要注意的是上面中的2行:

ssl_certificate /etc/letsencrypt/live/wenchao.ren/fullchain1.pem;
ssl_certificate_key /etc/letsencrypt/live/wenchao.ren/privkey1.pem;

需要把wenchao.ren修改为你自己的域名,同时检查一下fullchain1.pem以及privkey1.pem是否和~/wordpress-compose/letsencrypt/目录下我们复制的证书的名字一致.
完成上面的操作以后,我们的https证书就配置完成了,然后我们需要重启容器:

docker stop `docker ps -a -q`
cd ~/wordpress-compose
docker-compose up -d

然后访问http://serverIP/会发现地址栏中的域名会自动跳转为https://serverIP/

Let’s Encrypt证书续期

Let’s Encrypt 每三个月要续约一次,续约后会生成新的证书,存放在 archive 文件夹下,然后自动更新 live 文件下的链接。因此我们需要重新生成证书并更新我们~/wordpress-compose/letsencrypt下面的证书文件:

cd ~/wordpress-compose
docker stop `docker ps -a -q`
sudo letsencrypt renew --dry-run --agree-tos
sudo rm ./letsencrypt/*
sudo cp /etc/letsencrypt/archive/wenchao.ren/* ./letsencrypt/
docker-compose up -d

手动更新比较麻烦,因此我们可以把上面的命令写入renew_letsencrypt.sh然后通过crontab来定时调度:

MAILTO=me@wenchao.ren
0 19 1 * * sudo sh -x ~/wordpress-compose/renew_letsencrypt.sh  1>/dev/null
本文版权归作者所有,禁止一切形式的转载,复制等操作
赞赏

微信赞赏支付宝赞赏

13 replies to 将博客迁移到Docker上

  1. 域名迁出啊……

    • 你居然使用公司邮箱在外回复。我尝试把域名迁出到godaddy, 结果对方提示【不支持优惠域名迁移】,我也不明白啥意思。我也尝试了腾讯云,发现腾讯云不支持.ren域名。所以也就放弃了。先把今年的优惠用完,明年再重新选择一个境外服务器吧。实在不行又用linode吧。

  2. linode,稳定啊。
    域名转出吧,gandi估计可以

  3. 博主你好,我也要把博客迁移到docker,请问原网站使用的数据库版本与你教程里面的MySQL 版本不一致能够迁移导入吗? 您教程中的nginx如何设置绑定多个域名?谢谢您的教程!祝好!

    • 和特定版本的MySQL关系不大, 你如果想指定mysql的版本的话, 那么修改一下依赖的mysql的image的tag.
      关于nginx如何绑定多个域名的话, 你可以百度一下[nginx设置多个域名] 有很多这样的文章教程的.

      • 谢谢回复! 博主,我是用wordpress的备份插件BackWPup 备份数据库, mysql版本比较旧, 按照您上面的教程搭建好wordpress, 这样导入您觉得有问题吗?

        • 因为我是程序员…我是使用的mysqldump导入的…, 其实workpress自带的[工具]->[导入][导出]我觉的也挺好用的

      • 博主请问您是如何导入备份的数据库到这个Docker 中?需要再部署个PHPadmin 吗? 谢谢

  4. 博主按照您的教程部署,博客图片的地址显示的是V P S的 IP地址,要如何设置让他显示域名呢?

    • 你可以考虑一下使用七牛做图床, 七牛支持自定义域名

      • 谢谢回复!请问如果不用第三方图床,有办法设置吗?

  5. Pingback:

    • 看了一下你的博客,还没有启动HTTPS,建议开启HTTPS。而且现在Let’s Encrypt 也支持通配符证书了。搞起来也不复杂,折腾折腾

发表评论

电子邮件地址不会被公开。 必填项已用*标注