第 4 章
一台服务器上跑了些什么
博客跑在一台阿里云 ECS 上。不是很贵的配置,但一个人的博客够用了。
域名和备案
yustia.com 这个域名是在阿里云买的。国内服务器要备案,ICP 备案和公安备案都走了一遍。
ICP 备案是工信部要求的,没有备案的域名不能解析到国内服务器。流程是在阿里云提交资料,等审核,前后大概一两周。公安备案是公安部要求的,ICP 备案通过之后还要去全国互联网安全管理服务平台再报一次。
不复杂,但琐碎,需要耐心等。原以为备好之后就不用再管了,后来才发现备案时填的内容会一直跟着网站。公安备案里有一项"是否提供互联网交互服务",我填的是"否",这就决定了网站上不能开放评论——第一章最后一节讲了这件事。
服务器上有什么
astra 上现在跑着两个 Docker 容器:
博客容器(yustia-blog)——就是上一章构建出来的那个 Nginx 镜像,端口 3000:80。里面只有静态 HTML 文件,没有运行时逻辑,随时可以销毁重建。
信箱转发服务(letter-relay)——读者在信箱页写的信,由它通过 QQ 邮箱转给我。用 Python 标准库写的,只监听本机端口,信不落盘,转完就忘。
之前还有一个 Twikoo 评论容器,关掉评论以后就删掉了。
除了容器,还有一个磁盘目录存着不进 git 的大文件:/data/blog-downloads/,放下载资源——PPT 模板之类的文件,手动 SCP 传上去。图片原本也打算放在服务器上,后来改成跟文章一起进仓库,随网站一起部署,第五章会讲。
这些数据都在容器外面。博客容器不知道它们的存在,也不需要知道。
一个 Nginx 拼起来
服务器上有一个宿主机 Nginx(跑在容器外面),负责把不同路径的请求分发到不同的地方:
访问 yustia.com 的根路径,Nginx 转发给博客容器的 80 端口,拿到静态 HTML 返回给浏览器。
访问 /downloads/ 路径,Nginx 直接从 /data/blog-downloads/ 目录读文件,不经过任何容器,还加了一个 Content-Disposition: attachment 让浏览器下载而不是打开。
访问 /api/letter,也就是信箱页提交表单的地址,Nginx 反向代理到信箱转发服务。这一层还加了限流,同一个 IP 短时间内寄太多封会被挡回去。
HTTPS 也是这个 Nginx 管的——域名证书配在这一层,所有容器内部都走 HTTP,不用各自处理证书。
这样做的好处是:对外只暴露 443 端口,所有服务藏在后面。博客容器只管托管静态文件,不知道下载和信箱的存在。各管各的,互不影响。
这份 Nginx 配置一开始是我 SSH 上去手改的,后来改成了用 Ansible 模板管理:改配置就是改模板,再跑一遍 playbook。正式执行前可以先预演一遍,看清楚会改哪几行再动手;换一台机器,也能照着模板原样装上。
容器里不放数据
架构上有一个刻意的设计:容器里不放任何持久数据。
博客容器是纯静态文件,构建时就定型了,运行时不写任何东西。信箱转发服务也一样,信只是经过它,不留在服务器上。下载资源本来就在磁盘上,跟容器无关。
这意味着容器可以随时销毁重建,不会丢任何东西。部署新版本的时候 docker-compose down 再 up,干干净净。迁移的时候只需要关心磁盘上的下载目录,不用导出容器内部的状态。
一路减下来,服务器上需要我照看的数据越来越少:评论停了,图片进了仓库,现在只剩那个下载目录。
从旧架构迁移过来的时候,清理了 MySQL 的数据卷、旧镜像、旧的 uploads 挂载和 .env 文件,回收了大概 5.5GB 空间。