← 返回文章归档

VPS / DEPLOY / INFRASTRUCTURE

把个人博客部署到 VPS 后,我补齐了哪些基础设施

真正需要维护的,从来不只是一个 index.html。把博客放到 VPS 后,我才发现域名、HTTPS、反向代理、权限、缓存、监控和备份都会成为长期写作体验的一部分。这篇文章记录我怎样把一个能打开的静态站点,整理成更稳定、可排查、可回滚的个人基础设施。

目标不是“上线一次”,而是“以后还能轻松维护”

刚开始做个人博客时,最容易兴奋的是页面终于能打开:域名解析好了,浏览器里出现了自己的首页,似乎就算完成。 但真正把它放到 VPS 上长期使用以后,问题会变得具体很多:证书什么时候续期,Nginx 配置改错了怎么回滚,文章页面为什么 404,Edge 和 Chrome 为什么表现不一样,更新 CSS 后用户为什么还看到旧样式。

所以我后来给这个博客定下的目标不是“今天能访问”,而是“以后每次改动都能放心”。这意味着我需要知道请求经过了哪几层,文件放在哪里,日志怎么看,哪些端口暴露在公网,出现问题时先查哪一条线索。

我现在判断一个个人站点是否健康,会看四件事: 访问链路能说清楚,配置变更有备份,页面错误能从日志定位,发布以后可以快速验证和回滚。

先把访问链路画清楚,再决定配置怎么写

我的博客不是直接把文件裸露给公网,而是经过域名、HTTPS、反向代理和静态文件服务这几层。链路越清晰,排查时越不容易乱。 现在我会先把请求路径写出来,再回头检查每一层应该负责什么。

浏览器
   |
blog.020814.xyz
   |
HTTPS 443 / HTTP 80
   |
Nginx Proxy Manager
   |
Host Nginx :8080
   |
/var/www/junhao-blog
   |
index.html + posts/ + styles.css + script.js

这样拆开以后,80 和 443 主要负责外部访问入口,反向代理负责证书和域名转发,宿主机 Nginx 负责静态文件读取。 如果首页正常但文章页打不开,我就不会一上来怀疑域名,而是会继续检查静态目录、文件权限和 Nginx error log。

  • 域名解析只负责把域名指到服务器公网 IP。
  • HTTPS 证书和反向代理负责让浏览器安全访问。
  • 静态文件目录负责真正提供 HTML、CSS、JS 和文章页。
  • 日志负责在出问题时告诉我是哪一层拒绝了请求。

目录结构先定好,后面的部署动作就会很稳定

个人服务器最怕“临时能用”:今天在一个目录手改文件,明天在另一个目录补配置,过一周自己也忘了真实入口在哪里。 我把博客的文件集中放在一个固定目录,并把页面、文章、样式和脚本分开管理。

/var/www/junhao-blog
├── index.html
├── styles.css
├── script.js
├── favicon.svg
├── 404.html
└── posts
    ├── index.html
    ├── vps-infra.html
    ├── playwright-stability.html
    ├── ai-workflow.html
    └── cache-debugging.html

这个结构的好处是发布动作可以很简单:先在本地改文章,检查链接,再同步到站点目录。每次上传前做一份压缩备份, 如果新页面出现问题,可以直接恢复上一版,而不是在服务器上凭记忆一点点改回去。

这次博客文章页打不开时,真正的问题就藏在目录权限里。 首页文件能读,posts 目录却没有给 Nginx 读取权限,所以点击文章会失败。最后把目录设为 755、文件设为 644 后,访问才恢复稳定。

Nginx 配置里,我优先保证的是清晰和可预测

对静态博客来说,Nginx 配置不需要复杂,但必须可读。我的习惯是先把站点根目录、默认首页、404 策略、静态资源缓存和访问日志写清楚。 配置越朴素,出问题时越容易确认“它应该怎样工作”。

server {
    listen 8080;
    server_name _;

    root /var/www/junhao-blog;
    index index.html;

    access_log /var/log/nginx/junhao-blog.access.log;
    error_log  /var/log/nginx/junhao-blog.error.log;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~* \.(css|js|svg|png|jpg|jpeg|webp|ico)$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000, immutable";
    }
}

如果前面还有 Nginx Proxy Manager,宿主机 Nginx 就可以只监听内部转发端口,让职责更单一。 配置改完以后,我会先跑 nginx -t,确认语法没问题再 reload。这个动作很小,但能避免很多低级事故。

日志、缓存和备份,决定了你能不能安心长期写下去

个人博客不是大系统,但它承载的是长期积累。只要你希望它稳定存在,日志、缓存和备份就不是“以后再说”的边角料。 它们决定了你遇到问题时是靠猜,还是靠证据。

  • 访问异常时先看 HTTP 状态码,再看 Nginx error log。
  • HTML 不要缓存太重,CSS 和 JS 可以长缓存,但最好配合版本策略。
  • 每次改页面前先备份站点目录,至少保留最近几次可用版本。
  • 用 Uptime Kuma 盯外部访问,用 Beszel 看服务器资源,用 Docker 管理其他服务。
# 备份站点目录
tar -czf /var/backups/junhao-blog-$(date +%F-%H%M%S).tar.gz /var/www/junhao-blog

# 检查页面是否可访问
curl -I https://blog.020814.xyz/
curl -I https://blog.020814.xyz/posts/index.html

这套动作并不复杂,但它会把很多“玄学问题”变成可以定位的问题。比如用户说“有时候能打开有时候不行”,我会先连续请求几次, 看是 DNS 解析、TLS、代理、状态码,还是某个具体页面路径出现异常。

我现在每次上线前都会过一遍这份检查清单

  • 域名解析是否指向正确公网 IP,公网 DNS 是否已经生效。
  • Nginx Proxy Manager 的域名、证书、转发目标是否一致。
  • 宿主机 Nginx 配置是否通过 nginx -t
  • 目录权限是否允许 Nginx 读取:目录 755,文件 644。
  • 首页、归档页、文章页、CSS、JS、favicon 是否全部返回 200。
  • 浏览器强制刷新后,最新 HTML 和样式是否已经生效。
  • 更新前是否有备份,出错时是否能在几分钟内回滚。

对我来说,博客不只是展示页,而是一个持续整理技术经验的入口。基础设施越稳,写文章时就越不用担心“站点会不会又出问题”, 注意力也能真正回到内容本身。

NEXT STEP

这篇文章记录的是站点基础设施。接下来我会继续把排障、自动化测试和 AI 工作流这些经验整理成可复用的笔记。

回到首页继续看