Caddy VS Nginx:code-server 部署实践中的一次小跃迁 – esap~!
esap~!
esap~!

Caddy VS Nginx:code-server 部署实践中的一次小跃迁

Caddy VS Nginx:code-server 部署实践中的一次小跃迁

本文以部署 code-server 为例,带你体验一下 Caddy 这位自动签 HTTPS 的“懒人福音”,同时对比我之前用 Nginx + acme.sh 的传统组合。全程使用 Docker,仅为复刻部署痛点与爽点。


一、背景交代:曾经的我也写 Nginx 配置写到想跑路

曾经是一个靠 Google + StackOverflow 生存的普通部署民工,我给我的网站使用的是 Nginx + acme.sh:

server {
    listen 443 ssl;
    server_name code.example.com;

    ssl_certificate /etc/ssl/code.crt;
    ssl_certificate_key /etc/ssl/code.key;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

然后每次证书更新、服务重启、莫名其妙 403,我都要怀疑人生一遍。

别误会,我并不讨厌 Nginx,它是个强大又稳定的工具。我甚至还用它配过 ModSecurity 做 WAF,用起来稳如老狗。但对于一些轻量级服务,比如 code-server、某些只需要转发 + HTTPS 的容器服务——就显得有些杀鸡用牛刀了。

于是,我试了试 Caddy,然后我就没回去过。


二、用 Docker 跑个 code-server(不装插件,先跑起来)

我们先用 Docker Compose 跑一个 code-server,先不考虑 HTTPS,加密之事交给后面。

services:
  code-server:
    image: codercom/code-server:latest
    container_name: code-server
    networks:
      - caddy-network
    volumes:
      - ./local:/home/coder/.local:Z
      - ./config:/home/coder/.config:Z
      - ./project:/home/coder/project:Z
    environment:
      - PUID=1000
      - PGID=1000
      - DOCKER_USER=1000
    user: "1000:1000"
    restart: unless-stopped
    # 注意:不暴露端口到主机,只在容器网络内通信

  caddy:
    image: caddy:latest
    container_name: caddy
    networks:
      - caddy-network
    ports:
      - "80:80/tcp"
      - "443:443/tcp"
      - "443:443/udp"     # HTTP/3 协议支持
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    restart: unless-stopped

networks:
  caddy-network:
    driver: bridge

volumes:
  caddy_data:
  caddy_config:

现在 code-server 完全不暴露端口了,只有 Caddy 能访问它。虽然安全了一点点,但是,我们怎么能够让 Caddy 转发流量出来呢?


三、Caddy 上场:自动 HTTPS?真的只要一行!

Caddy 的配置文件叫 Caddyfile,长这样:

code.example.com {
    reverse_proxy code-server:8080
}

你没看错,就这样。

关键点:code-server:8080 而不是 localhost:8080,因为在 Docker 网络里,服务名就是主机名。这比在宿主机上配置还要干净——不用担心端口冲突,不用记住谁占了哪个端口。

四、一键启动:Docker Compose 的快感

docker compose up -d

就这样,一条命令搞定:

  • code-server 容器启动,开始监听内部 8080 端口
  • Caddy 容器启动,自动申请 code.example.com 的 HTTPS 证书
  • 证书存储在 Docker volume 里,重启不丢失
  • 80 端口自动重定向到 443,HTTPS 强制生效

第一次启动会看到 Caddy 疯狂输出日志,那是它在跟 Let’s Encrypt 握手申请证书。稍等片刻,就能愉快地通过 https://code.example.com 访问你的远程 VSCode 了。

部署门槛之低,适合手还没从 Nginx 伤痛中恢复过来的开发者。(bushi)


五、HTTPS 验证方式:Caddy 默认 http-01,有坑提前避

虽然 Caddy 看起来像个“HTTPS 魔法棒”,但其实背后干的还是老三样,只不过它帮你封装得很好。

重点是:Caddy 默认使用的是 HTTP-01 验证方式。这意味着:

  • 你必须已经将 code.example.com 正确解析到服务器公网 IP
  • 并且服务器的 80 端口必须畅通(Caddy 会自动监听)
  • 确保防火墙、云服务商安全组都放行了 80/443

否则 Caddy 就会哭着跟你说:

[ERROR] obtaining certificate: failed to get certificate: ...

相比之下,我之前用的 acme.sh 更像一个命令行工具箱:支持 DNS-01 / HTTP-01 / ALPN-01,各种奇技淫巧随你挑,尤其适合那种不方便开放 80/443 的“地下服务”。

如果你的服务器在某些特殊网络环境(比如内网、NAT 后面),可以考虑 DNS-01 验证。虽然 Caddy 也支持,但配置会复杂一些,需要提供 DNS API 凭据:

code.example.com {
    tls {
        dns cloudflare {env.CLOUDFLARE_API_TOKEN}
    }
    reverse_proxy code-server:8080
}

不过,这也是选择 Caddy 的 trade-off:易用 vs 灵活。适合场景不同罢了。


六、Nginx VS Caddy:容器化时代的对比

维度 Nginx + acme.sh Caddy + Docker
HTTPS 管理 手动配置 + cron 更新 + 容器挂载卷 自动申请 + 自动续期 + Volume 持久化
配置复杂度 proxy + SSL + 容器网络配置 几乎傻瓜式,容器服务名即可
容器编排友好度 需要额外处理证书卷、网络配置 天生为容器时代而生
多服务代理 upstream 配置相对复杂 一个域名一个代码块,清晰明了
重启后证书丢失风险 需要正确挂载 acme.sh 生成的证书 Docker Volume 自动持久化

一句话总结:Caddy 是你懒得手写配置时的部署队友,Nginx 则是在你需要最大控制权时的可靠选手。


七、最终成品结构参考

.
├── docker-compose.yml  # 容器编排配置
├── Caddyfile          # Caddy 配置文件
├── local/             # code-server 用户配置
├── config/            # code-server 全局配置
└── project/           # 你的代码项目目录

启动命令:

# 启动所有服务
docker compose up -d

# 查看日志(观察证书申请过程)
docker compose logs -f caddy

# 停止服务
docker compose down

证书和配置数据会自动存储在 Docker volumes 里,即使 docker compose down 也不会丢失。

搞定,访问 https://code.example.com,你的远程开发环境已经热乎上桌了。


尾声:用什么工具,从来都不是非黑即白

我喜欢 Caddy,但我依然保留着 Nginx 配置仓库;我用 acme.sh 自动签某些非标准服务的证书,也用 Caddy 快速暴露临时 Web 服务。

没有最好的工具,只有最适合的场景。Caddy 的存在,并不是为了替代 Nginx,而是给我们提供一个新的选择:
当你只想把服务跑起来,不想再为了 HTTPS 而熬夜对着 nginx.conf 发呆时,它就很香。

赞赏

AptS:1547

文章作者

这里是AptS:1547!希望能给你带来快乐!

发表回复

textsms
account_circle
email

esap~!

Caddy VS Nginx:code-server 部署实践中的一次小跃迁
本文以部署 code-server 为例,带你体验一下 Caddy 这位自动签 HTTPS 的“懒人福音”,同时对比我之前用 Nginx + acme.sh 的传统组合。全程使用 Docker,仅为复刻部署痛点与爽点。 一、背…
扫描二维码继续阅读
2025-05-25