终于建站了!

几年前就跟老朋友扯淡要开自己的博客,今天终于把这个任务完成了,作为第一篇博客,先来记录一下这个不甚顺利的建站过程吧。

为什么选择 WordPress

随手 Google 一下就可以找到诸多博客框架,如 WordPressHexoJekyllHugo 等,促使我选择 WordPress 的理由主要有:

  • 企业更多会选择 WordPress 来构建主页,作为一个要成为 CTO 的男人,我的技术栈都是面向企业而非独立开发者,选择 WordPress (以及后面会提到的 NGINX, Docker 等) 是自然而然的事。
  • WordPress 生态最大,未来即使迁移到其他博客框架上也有很多轮子可以用,上面提到的博客框架都有官方提供的迁移工具:HexoJekyllHugo

建站过程

购买云服务

促使我选择 Azure 云服务的理由只有一个:!毕竟公司每个月 150 USD 的羊毛不用白不用。个人认为 Azure Portal 还算好用,比 AWS 的 UX 顺滑那么一些…

在 Azure Portal 注册以及绑定 billing 信息后,搜索如下资源进行购买

资源名称价格购买流程文档
域名 (frankzhang.net)每年 11.99 USD 起搜索 “App Service Domains” 进行购买Buy a custom domain name – Azure App Service | Microsoft Docs
虚拟机
(Azure Ubuntu VM)
B2S (双核 4 GB) 每月 38.544 USD搜索 “Virtual Machines” 进行购买Quickstart – Create a Linux VM in the Azure portal – Azure Virtual Machines | Microsoft Docs
数据库
(Azure Database for MySQL servers)
0想什么呢,云数据库你用得起么?🤣MySQL :: A Quick Guide to Using the MySQL APT Repository

购买好上述服务后,需要将域名绑定到对应虚拟机的 IP 上,在 Azure Portal 上只需打开 VM 对应的 public IP 资源,在其配置中增加一条 alias record (A 记录),如下我添加了 blog.frankzhang.net 指向此 IP

安装 MySQL

如上面表格罗列的,由于我买不起云数据库,只好自行在 Azure VM 中安装 MySQL,参照官方文档,但 Azure Ubuntu VM 似乎已经包含了 MySQL 的 apt repository,所以只需下面两行命令搞定

sudo apt update
sudo apt install mysql-server

由于 MySQL 默认只监听 localhost 的 3306 端口,下面的命令修改其监听任意来源而不仅仅是 localhost。不用担心,云服务的网络设置默认只开放 22 端口,未来我们还会放开 80 和 443 端口,但无论如何 3306 端口是不会被外网所访问到的。这步卡了我很久,由于我的 WordPress 是安装在 Docker 容器内,在后续的安装中显示 “Error establishing a database connection”,从怀疑 MySQL 用户密码错误到怀疑 Azure 内网设置不正确,最后才发现是由于 MySQL “bind_address” 这个默认配置。

echo 'bind-address = 0.0.0.0' | sudo tee -a /etc/mysql/mysql.conf.d/mysqld.cnf
sudo systemctl restart mysql

这里我选择在宿主机上直接安装 MySQL 而非在 Docker 中,是因为在企业中我们都会购买云数据库 (RDS),其架构是远程/内网有一或多台数据库服务器,在宿主机上直接安装 MySQL 模拟了这样的网络架构。(哈哈不吹了,其实是因为这样最简单也更偏向于企业内的用法,没听说过哪家线上 MySQL 是用 Docker image 来启动的。另外最近听朋友说到一个惨案,他习惯使用 docker 删除操作,一不小心把数据 volume 也删了…)

此处省略了创建数据库和用户(给 WordPress 专用)的步骤,请自行脑补。

安装 Docker

都 2021 年了,哪个公司的服务器上还能不安装 Docker 呢?(好吧微软的 Windows 服务器的确不用 Docker…)

继续根据官方文档,一顿操作即可

# Set up repository, can be ignored in cloud ubuntu vm.
sudo apt update
sudo apt install apt-transport-https ca-certificates gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Install Docker Engine
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

安装 WordPress

官方文档的安装方式需要提前在服务器上安装好 PHP,由于我不清楚 PHP 为什么是世界上最好的语言,抱着敬而远之的态度,我选择使用 Docker 来帮我隔离掉这项我不甚了解的技术,所幸 WordPress Community 维护WordPress Docker Images(这就是选择大生态工具的好处),于是事情变得十分简单。

cd /var/www/blog.frankzhang.net
docker pull wordpress
docker run -e WORDPRESS_DB_HOST=<host_ip>:3306 -e WORDPRESS_DB_USER=<username> -e WORDPRESS_DB_PASSWORD=<password> --name wordpress -p 8181:80 -v "$PWD/html":/var/www/html -d wordpress

上述参数的简单解释

  • –name,给容器起个名字
  • -p,指定端口映射,格式为:宿主机端口:容器端口,后续我会使用 NGINX 来反向代理此宿主机端口。
  • -v,映射宿主机一个 volume 到容器内,用这种方式即使 WordPress Docker 容器 / image 被删除,宿主机上的文件仍然存在,Wordpress Docker 容器 /var/www/html 目录内存放 WordPress 的 PHP 代码,主题及配置,图片和视频等多媒体文件等。
  • -d,在后台运行容器。
  • -e 环境参数皆在 Docker Hub WordPress Image 主页里有详细介绍,这里不再赘述。

至此,咱们的 WordPress 已经可以在内网访问了,通过 curl localhost:8181 应该可以看到返回的 WordPress html 网页了。

安装 NGINX

关于 NGINX 是否应该通过 Docker 容器来运行,暂时我认为是否定的,有以下几个原因

  1. NGINX 不像应用那样改动 / 升级频繁
  2. NGINX 本身的安装十分简便 (apt install nginx)
  3. 我想要使用 Certbot 自动更新 SSL 证书,使用容器不方便做到。

惯例:官方文档,不过这次我是按照这篇教程来的,安装 NGINX 后要记得去 Azure Portal 将网络设置修改一下,允许外网访问 80 和 443 端口,如下

然后可以去写入 NGINX 配置文件了,sudo vi /etc/nginx/sites-available/blog.frankzhang.net 填入如下配置,之后记得在 /etc/nginx/sites-enabled 目录下创建一个到此配置的软链接。

server {
    listen 80;
    server_name blog.frankzhang.net;
    return 301 https://blog.frankzhang.net$request_uri; # 将 HTTP 请求都转至 HTTPS
}
server {
    listen 443 ssl http2;
    server_name blog.frankzhang.net;

    ssl_session_timeout 5m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;

    location / {
        proxy_pass http://localhost:8181;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

其实上述配置的核心就一句话,将 443 端口的请求转发至 localhost:8181,Docker 来运行 WordPress 真香,否则还要去配置什么我并不大懂的 PHP FastCGI。

最后一步便是安装 SSL 证书了,作为个人用户咱们就省点钱用用免费的 Certbot (Let’s Encrypt) 好了,命令也十分简单,如下

sudo apt install certbot
sudo certbot --nginx

然后按照其指示安装即可,安装成功后如果设置了自动 renew,Certbot 会在 /etc/cron.d 目录下放置一个脚本,每 12 小时尝试更新一次。

初始化 WordPress

第一次访问 https://blog.frankzhang.net,Wordpress 会出现配置页面,根据指示不断的下一步,大功告成!

结语

在整个过程中遇到的几个坑

  1. MySQL 默认只监听 localhost 3306 端口,通过内网 IP 不可访问。
  2. 网上很多 WordPress 和 NGINX 的教程,基本都会跟你讲 FastCGI 在 NGINX 内的相关配置,把我搞得晕头转向。其实由于咱们使用了 WordPress 默认的 Docker image,内部已经用 Apache server 来 host PHP 提供 HTTP 服务了,所以只需要无脑转发 HTTP 请求即可。

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注