使用容器搭建 WordPress

1. 前言

作为一个程序员,大家都有一个使用自己域名搭建一个网站的心愿,哪怕这个网站是一个 WordPress。

从 2015 年第一篇博客算起,写了五年了。当初搭建的时候为了图便宜(每年 60 人民币)使用了万网的云虚拟主机,彼时万网还没有被阿里收购。

现在,万网的云虚拟主机虽然还能接着续,但是时不时就因为资源消耗超标被关闭。恰好,为了一些不知名的原因,我在 Vultr 购买了 VPS。我决定充分利用这个 VPS,把我的 WordPress 迁移到这个 VPS 上。

2. 迁移过程

五年前我安装 WordPress 的时候容器技术还没有成熟,我还特意写了一个脚本进行安装。

今天,我决定使用 WordPress 官方镜像来快速搭建,然后迁移数据。

2.1 安装 Docker

有意思的是按照我的理解 Vultr 的 VPS 就是一个单独的容器。也就是说,接下来我们要在容器里面跑容器,就是容器的套娃。

首先我们按照官方文档安装 Docker:

apt-get update
apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
apt-key fingerprint 0EBFCD88
add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io

2.2 安装数据库

# 安装数据库
apt-get install mariadb-server

# 启动数据库
systemctl start mariadb

2.3 创建用户和授权

接下来我们要为 WordPress 创建数据库以及专属的用户并分配权限。

create database wordpress;
grant all privileges on wordpress.* to '<user>'@'172.17.0.2'  identified by '<password>';
flush privileges;

这里要注意的是 IP 部分写死了 172.17.0.2,这是 WordPress 容器访问所用的地址。

2.4 启动服务

docker run --name wordpress -e WORDPRESS_DB_HOST=172.17.0.1 -e WORDPRESS_DB_USER=wordpress -e WORDPRESS_DB_PASSWORD=wordpress -p 8000:80 -d wordpress

注意,我们把 WordPress 暴露的 80 端口映射到了宿主机(容器)的 8000 端口。

然后我们访问 VPS 的 8000 端口初始化 WordPress。

选择语言:

image-20200306004951786

基本设置:

image-20200306005123378

然后就结束了:

image-20200306005150137

2.5 数据迁移

2.5.1 安装插件

这里我们要介绍一个 WordPress 的插件来做迁移,名字叫做:All-in-One WP Migration

image-20200306005323777

这个插件的新版本在导入备份的时候会卡在 100% 的进度,大家可以先先下载,然后上传压缩包进行安装,下载地址可以点这里

2.5.2 备份和下载

然后使用导出功能:

image-20200306005445188

导出完成后下载到本地:

image-20200306005518211

2.5.3 修改上传文件的大小限制

在向新站点恢复数据之前,我们要修改 WordPress 上传文件的大小上限。参考这篇文章:How to Increase Maximum Upload File Size in WordPress

具体的执行方法:

root@MyHost:~# docker exec -it wordpress /bin/bash
root@ded70a3e6cab:/var/www/html# echo 'php_value upload_max_filesize 128M
php_value post_max_size 128M
php_value memory_limit 256M
php_value max_execution_time 300
php_value max_input_time 300' >> /var/www/html/.htaccess

2.5.4 恢复数据

下面在新站点导入备份数据,注意这里上传文件的大小,上面的修改生效了。

image-20200306154815174

中间会有提示,继续就好:

image-20200306154958077

显示完成:

image-20200306155034388

用原来的账号重新登录,提示要升级数据库:

image-20200306155154449

反正选择升级就好了。

至此,迁移完毕。

3. 后记

建议大家在初始化新站点之前先配置好域名,否则初始化会把当时的访问地址记下来,这个就容易悲剧了!

告别万网的云虚拟主机,可以起飞了!

使用 Docker 构建工作环境

1. 前言

作为一个程序员,在家加班或者处理紧急需求是一种常态。为了应对这种情况(也为了更好地压榨程序员的剩余时间)大部分公司都会给员工配发笔记本电脑。

新员工入职第一件事情就是配置工作环境,这个工作至少耗费一天的时间。有经验的程序员一般会用一个 dotfile 项目来保存常用的配置文件,比如 .zshrc.vimrc.ssh/config 等。

本文更进一步,使用 Docker 来构建工作环境。

原因在于以下几个方面:

  • 任意电脑都可以快速初始化工作环境。本人不喜欢把公司电脑背回家,一来太重太麻烦,而来丢了坏了还要找你赔。

  • 隔离工作环境。把工作环境当做不同的 profile,以插件的形式加载到环境中,灵活而且干净。

2. 实施方案

为了更好地保障安全性,本人把工作环境的 Docker 分为两个部分:

  • Docker 镜像

  • dotfile (Git 仓库)

本质上是代码和配置分离的策略,镜像可以使用阿里云提供的服务来存储,而 Dockerfile 和 dotfile 则利用 Git 的私有库做版本控制和多机器同步。

2.1 Docker 镜像

以下是本人人生中第一个 Dockerfile:

 ARG UBUNTU_VERSION=18.04
 FROM ubuntu:${UBUNTU_VERSION}
 MAINTAINER wuzhiyu "wuzhiyu@avalon-inc.com"
 
 ###################### SYSTEM SETTINGS ######################
 
 ARG USER_NAME=<account name>
 ARG GROUP_NAME=sudo
 ARG PASSWORD=<password>
 ARG HOME=/home/${USER_NAME}
 ARG HOST_NAME=ubuntu-docker
 
 # 1. update chinese software repository
 RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak
 COPY 18.04.aliyun.sources.list /etc/apt/sources.list
 
 # 2. install necessary software
 ENV DEBIAN_FRONTEND=noninteractive
 RUN apt-get update && apt-get install -y sudo man curl inetutils-ping git tmux vim autojump python-pip zsh oathtool expect && apt-get clean && pip install mycli virtualenv virtualenvwrapper
 RUN apt-get update && apt-get install -y locales && apt-get clean && locale-gen en_US.UTF-8
 
 # 3. (1)create a user account without password (2) grant sudo permission by adding account to sudo group (3) set password for the account
 
 RUN adduser --home ${HOME} --ingroup ${GROUP_NAME} --shell /bin/bash --disabled-password --gecos "" ${USER_NAME} && echo "${USER_NAME}:${PASSWORD}" | chpasswd
 RUN chown -R ${USER_NAME}:${GROUP_NAME} ${HOME}
 
 ###################### USER SETTINGS ######################
 
 # set default user and work dir
 USER ${USER_NAME}
 WORKDIR ${HOME}
 ENV USER ${USER_NAME}
 
 # install oh-my-zsh
 RUN export RUNZSH=yes && sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
 
 # config-files -v when docker run
 
 # CMD
 CMD /usr/bin/zsh

这个 Dockerfile 干的事情非常简单,简单来说就是:

  1. 指定基础镜像。

  2. 更新 Ubuntu 的软件源。国情在此,用阿里云的替换。

  3. 使用非交互模式安装必要的软件。

  4. 创建用户账户并授予 sudo 的权限。

  5. 切换到用户账户和家目录。

  6. 安装 oh-my-zsh

  7. 指定默认进入 zsh

构建命令为:

 docker build -t workspace:latest ubuntu

其中 ubuntu 是保存 Dockerfile 和其他文件的上下文目录。

看的出来镜像本身是比较简单的,主要是准备必要的软件和运行账户,下面来介绍一下 dotfile。

2.2 dotfile

dotfile 项目包括不限于以下内容:

  • .zshrc

  • .vimrc

  • .ssh/config

  • 公钥私钥

  • 业务脚本

2.2.1 .zshrc

这个文件是 zshell 启动时默认加载的文件,一般也是我们所有环境配置的公共部分。我们可以通过一些命令来判断加载特定的 profile。

比如:

 # 为 true 表示为 Mac 环境
 [[ $(uname) = "Darwin" ]]
 
 # 为 true 表示为 Docker 环境
 [[ -f /.dockerenv ]]

如果为 docker 环境,我们可以 source 包含业务信息的脚本(比如自动进行两步校验的登录脚本、包含数据库连接串信息的脚本等等),也可以进行环境配置文件的自动更新。

2.2.2 .vimrc

Vim 的配置文件,此处不表。

2.2.3 .ssh/config

常见来说两种使用功能:

  • 自动指定跳板机或端口信息

  • 对应特定应用使用特定私钥

首先一般公司内部连接线上服务器都要求通过指定的跳板机和特定端口(非默认 22)来连接,每次指定自然非常繁琐,通过 .ssh/config 文件则可以大大减轻负担。

 Host *.dev
     HostName %h.xxx.com
     User wuzhiyu
     Port 10086
     ProxyJump <gateway>
     IdentityFile <path_to_private_key>

一般来说,如果我们要连接 master01.dev.xxx.com 这台机器一般要先跳到跳板机,然后使用如下命令:

 ssh -i <path_to_private_key> wuzhiyu@master01.dev.xxx.com -p 10086

但是有了上述配置,我们可以写作:

 ssh master01.dev

跳板机、端口、机器后缀、私钥位置自动带上了。

2.2.4 公钥私钥

接上文,对于不同的版本控制系统使用不同的密钥是很常见的一种场景。比如公司内部用一套密钥,个人 GitHub 账户使用另外一套,把公司的密钥放在 dotfile 私有库进行同步便于配置的保存与迁移。

2.2.5 业务脚本

比如数据库连接串的别称、自动登录脚本等,不再赘述。

3. 实践使用

Docker 运行的时候可以使用如下命令进行启动:

 docker run -it --rm -h docker --network host -v <path_to_dotfile_dir>:/home/wuzhiyu/.config-files:ro -v <path_to_zshrc_file>:/home/wuzhiyu/.zshrc:ro --name workspace workspace:latest /usr/bin/zsh

这里有几点要注意:

  1. 网络模式使用了 -—network host 模式是为了使用宿主机的 VPN 网络。

  2. 加载的时候直接挂在了 .zshrc 文件,这样容器运行 zshell 的时候就可以直接加载初始化的脚本。

  3. 默认指定一下 HOST 名称否则部分软件运行会报错。