CChunHo教程
本站同款 · Docker + Caddy

Docker + Caddy 建站

一个 compose 跑全站:Caddy 自动 HTTPS + 反代 + 静态站。本站 chunho.im 就是这套。

1. 架构:一句话

公网 80/443 只给 Caddy,业务全放容器内网,Caddy 按域名分发。证书自动申请续期,不用管 certbot。

Internet ──80/443──▶ Caddy ──▶ static /srv/homepage (本站)
                          ├──▶ komari:25774 (monitor.chunho.im)
                          └──▶ any:8080 (你的下一个服务)
DNS 先 A 到公网 IP,80/443 放行,Caddy 才能签出证书。

2. docker-compose.yml

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./homepage:/srv/homepage:ro
      - caddy_data:/data
      - caddy_config:/config
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  whoami: # 占位业务,验证反代用
    image: traefik/whoami
    restart: unless-stopped

volumes:
  caddy_data:
  caddy_config:

3. Caddyfile:本站精简版

example.com, www.example.com {
  root * /srv/homepage
  encode gzip
  try_files {path} {path}/ /index.html
  file_server
}

monitor.example.com {
  reverse_proxy komari:25774 {
    header_up Host {host}
    header_up X-Real-IP {remote_host}
    header_up Connection {http.request.header.Connection}
    header_up Upgrade {http.request.header.Upgrade}
    flush_interval -1
  }
}

app.example.com {
  reverse_proxy whoami:80
}

反代 WebSocket(Komari 这类)必须透传 Connection/Upgrade + flush_interval -1,否则探针掉线。

4. 静态站:丢文件夹就行

每个子目录一个 index.html 就是一个页面:/love、/vps-init、/komari 都是这么来的。

homepage/
  index.html        # example.com/
  love/index.html   # example.com/love
  vps-init/index.html   # example.com/vps-init
  caddy/index.html  # example.com/caddy (本页)

# 改完直接刷新看效果,无需 reload(Caddyfile 没变)
ls homepage/

5. 重载与排错

# 改了 Caddyfile 才需 reload
docker compose exec -T caddy caddy reload --config /etc/caddy/Caddyfile
# 或宿主机版
# caddy reload --config /etc/caddy/Caddyfile

# 看日志 / 验证
docker compose logs caddy --tail=50
curl -I https://example.com
curl -I http://127.0.0.1:25774  # 面板本机端口通不通
443 不通先查三件:DNS A 记录、云安全组、ufw。证书没下来前 https 必失败是正常的。

6. 常见问题