单服务器也需要架构,不等于所有东西混在一起
小网站用一台服务器很正常。问题不在机器数量,而在反向代理、应用、数据库和备份是否各自有清楚边界。若所有进程都用 root、数据库直接暴露公网、代码和用户上传混在同一目录,第一次故障就会变成全盘搜索。 架构图不用画云厂商图标。只要能回答请求从哪里进、每个进程以谁运行、数据落在哪里、备份到哪里、哪一层失败会看到什么现象,就已经足够指导部署。
从公网入口向内画一条请求链
典型路径是:DNS 把域名指向服务器公网 IP,防火墙只开放 80/443 和受控 SSH,Caddy 接收 HTTP/HTTPS,请求再转发到监听回环地址的应用,例如 127.0.0.1:3000。数据库只接受本机或容器内部网络连接,不需要暴露 5432、3306 等端口。
Internet -> 80/443 -> Caddy -> 127.0.0.1:3000 -> Application
|-> Database
|-> Uploaded files这条链能直接帮助排错:域名不对先看 DNS,证书和 4xx 先看 Caddy,502 再看上游端口与应用状态,数据错误最后进入数据库与业务日志。
每个组件只拥有必要权限
Caddy、应用和数据库分别使用专用系统用户。应用代码目录可以只读,运行时只对日志、上传和临时目录有写权限。部署账号通过 sudo 管理服务,但日常进程不以部署账号或 root 长期运行。 环境文件由 root 或专用用户读取,权限限制到最小。不要把 .env 放进公开静态目录,也不要把完整环境变量打印到启动日志。目录名也要表达用途,例如 /opt/myapp/releases、/var/lib/myapp/uploads、/var/backups/myapp,而不是所有文件都放在 /root/app。
把持久数据与可重建文件分开
代码、依赖和构建产物应该可以从仓库或镜像重新生成;数据库、用户上传和密钥不可以。画图时用不同颜色标出持久数据,并给每一项写备份与恢复方法。容器卷不是备份,云盘快照也不能替代应用一致性备份。 日志可以重新产生,但故障调查需要保留周期。设置轮转和磁盘上限,避免一个异常请求把根分区写满。临时文件应放在明确目录,并能安全清理。
端口表比‘已开防火墙’更有用
| 端口/地址 | 使用者 | 公网可见 | 说明 |
|---|---|---|---|
| 22/tcp | 管理员 | 受控 | SSH,可结合安全组限制来源 |
| 80/443 | Caddy | 是 | 网站唯一公开入口 |
| 127.0.0.1:3000 | 应用 | 否 | 仅反向代理访问 |
| 127.0.0.1:5432 | 数据库 | 否 | 仅本机应用访问 |
实际端口可以不同,但原则是公开入口少、内部地址明确。执行 ss -lntp 核对监听结果,不能只看配置文件。
单机的主要风险要提前接受
一台机器宕机,代理、应用和数据库都会停止;磁盘损坏可能影响所有本地副本。对低流量内容站,这个风险可以通过异地备份、自动启动、监控和清楚恢复手册控制。若业务已经要求跨机房高可用,单服务器不该被包装成无故障方案。 上线前写恢复目标:最多能丢多久数据、最多能停多久、谁执行恢复。答案决定备份频率和是否需要第二台机器,而不是反过来先买复杂集群。
这一篇的完成标准
你应当得到四份简单记录:请求链、进程与用户表、端口表、持久数据与备份表。下一篇开始把应用从临时终端搬进 systemd 服务,让它能自动启动、限制权限并留下可查日志。
参考来源
- Caddy reverse_proxy directiveCaddy Documentation