← 全部笔记

在一台 2GB 树莓派上搭建个人网站

树莓派nginx自托管

目录

很长一段时间里,我的自建服务都是"Mac 上 npm run dev,看完就关"。后来想通了:这些服务本来就该常驻。于是把它们全部搬上了一台树莓派——2GB 内存、SD 卡、被动散热,没有风扇。这篇文章记录现在的架构,以及两个踩过的坑。

架构:一个 Nginx 容器管所有站点

树莓派上只跑三个容器:nginx、certbot、以及一个业务容器。所有站点的 server block 都写在一个 nginx.conf 里,站点文件挂载进容器,改动配置后 docker compose up -d nginx 生效。对一个个人服务器来说,这比每个站点一套 compose 清爽得多。

每个站点一个目录,全部以只读方式挂载:

volumes:
  - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
  - ./momentum:/usr/share/nginx/momentum:ro
  - ./blog:/usr/share/nginx/blog:ro

证书:DNS 验证,不依赖 80 端口

家里宽带通常没有固定公网 IP,端口转发也未必开得起来。所以证书签发用的是 Let’s Encrypt 的 DNS-01 验证:certbot 通过 Cloudflare API 加一条 TXT 记录完成验证,全程不需要外部访问 80 端口。一个 certbot/dns-cloudflare 容器跑着 certbot renew 的 12 小时循环,续期全自动。

顺带一提:签发新子域证书时最好单独签一张,而不是 --expand 合并进已有证书——前者失败时不会影响其他站点的证书。

构建留在 Mac,Pi 只做静态服务

最初想过直接在树莓派上 npm ci && npm run build,很快放弃了:2GB 内存跑一个完整的 Vite 工具链随时可能 OOM,SD 卡的随机写也慢得让人失去耐心。现在的做法是 Mac 上构建、rsync 上传,树莓派只干一件事——把静态文件发出去。

代价是"发布"需要一条命令;收益是 Pi 的负载长期停在 0.05,内存只用了 540MiB。

两个必须配置的细节

  • SPA 回退:try_files $uri $uri/ /index.html;。少了这一行,刷新深链接就是 404。
  • Service Worker 的缓存策略:sw.js 必须 no-cache,哈希资源才敢长缓存。PWA 还需要 HTTPS——这恰好是上面证书部分存在的意义。

账单

上线后的状态:负载 0.05,芯片 62.3°C,连续运行 67 天,从未降频。这台 2GB 的小机器同时跑着七八个站点和一个监控容器,依然有大把余量。树莓派做个人站点服务器,绰绰有余。