在一台服务器上从零搭一个站:Caddy + systemd + Flask 的完整链路

建站实战 2026-09-23 19:01 · 53 次阅读 ·Flask,Caddy,systemd,部署
在一台服务器上从零搭一个站:Caddy + systemd + Flask 的完整链路

这套站的后台:文章、资源、日志、备份都在这里管

为什么不用 Docker

这台机器上已经跑了 7 个服务(监控台、刷题后台、网盘、技能后台…),全部是 systemd 直跑。再加一个 Docker,
内存直接吃掉 200MB,而这台机器总共就 2G。轻量优先。

三层结构

浏览器
  │  https://域名/xxx
  ▼
Caddy(占 443,负责 TLS + 路由)
  │  reverse_proxy localhost:5006
  ▼
Flask 应用(只监听 127.0.0.1,不对外)
  │  sqlite3
  ▼
SQLite 文件(data/site.db)

关键点:Flask 只绑 127.0.0.1,外面进不来,所有流量必须过 Caddy。省掉了自己搞证书和限流的麻烦。

静态文件和动态页面怎么共存

Caddy 里 file_server 是兜底,handle 块是精确接管。谁写在前面都不影响,Caddy 会按路径具体程度排序:

dongspace.asia {
    root * /usr/share/caddy
    file_server                      # 兜底:静态文件都在这

    handle /monitor/* {              # 接管 /monitor/
        reverse_proxy localhost:5003
    }
    handle /static/* {               # 接管 /static/
        reverse_proxy localhost:5006
    }
}

踩过的坑:Flask 的静态资源如果留在 Flask(static_folder=...),路径是 /static/...,不带应用前缀 ——
反代只转发 /某个前缀/*,于是样式表全部 404,页面裸奔。正确做法是挂在 Blueprint 上:

bp = Blueprint("site", __name__, url_prefix="/hub",
               static_folder=os.path.join(HERE, "static"), static_url_path="/static")

系统服务

[Unit]
Description=站点 (Flask :5006)
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/site
ExecStart=/usr/bin/python3.12 /home/ubuntu/site/app.py
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Restart=always 是关键 —— 进程崩了 3 秒后自己回来,不用人盯着。

改配置的安全顺序

改 Caddyfile 之前必须备份,改完必须校验:

sudo cp /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak.$(date +%s)
sudo caddy validate --config /etc/caddy/Caddyfile   # 先校验,别直接 reload
sudo systemctl reload caddy                          # 平滑生效,不掉连接

reload 而不是 restart:reload 是平滑的,正在下载文件的用户不会断。这台机器上还有别人在下载 APK,
restart 会把他们的连接掐掉。

上线自检清单

# 1) 新站点各页面
for p in / /learn /tools /ai; do
  curl -s -o /dev/null -w "%{http_code} $p\n" https://域名$p
done

# 2) 老站点没被改坏(最重要)
for p in /monitor/ /quiz/records /alist/ /stats/; do
  curl -s -o /dev/null -w "%{http_code} $p\n" https://域名$p
done

第 2 条比第 1 条重要。加一条路由把别人在用的服务搞挂,比新功能没上要严重得多。

结论

  • 机器小就别上 Docker,systemd 直跑够用
  • 应用只绑 127.0.0.1,路由和证书交给 Caddy
  • 静态资源挂 Blueprint,不然反代前缀对不上
  • 改配置先备份 + validate,用 reload 不用 restart
  • 上线后第一件事是验证老服务没被影响

继续看

全部 →