一个 compose 跑全站:Caddy 自动 HTTPS + 反代 + 静态站。本站 chunho.im 就是这套。
公网 80/443 只给 Caddy,业务全放容器内网,Caddy 按域名分发。证书自动申请续期,不用管 certbot。
Internet ──80/443──▶ Caddy ──▶ static /srv/homepage (本站)
├──▶ komari:25774 (monitor.chunho.im)
└──▶ any:8080 (你的下一个服务)
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:
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,否则探针掉线。
每个子目录一个 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/
# 改了 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 # 面板本机端口通不通