3 步给本地 AI 服务加 HTTPS 反向代理:Docker Compose + Caddy 自动签发证书,10 分钟搞定

· 科技资讯

本地跑 AI 助手(Ollama、Open WebUI、Continue 扩展)有个常见痛点:浏览器访问 `http://localhost:11434` 没问题,但想从手机、平板、另一台电脑访问,就得上 HTTPS;不上 HTTPS 的话,浏览器会报”不安全”,某些 Web API(摄像头、麦克风、Service Worker)直接不能用。这篇教程用 Docker Compose + Caddy 3 步搞定,自动申请 Let’s Encrypt 证书、自动续期,10 分钟出活

3 步给本地 AI 服务加 HTTPS 反向代理:Docker Compose + Caddy 自动封面

适用场景

– 你在树莓派/NAS/家庭服务器上跑了 Ollama 或 Open WebUI

– 想用手机/平板在外网访问(4G/5G 下 HTTPS 必需)

– 想给本地 LLM 套个正经域名(虽然是非标准后缀)

– 想在团队内网(VPN/ZeroTier)里安全分享

不适合:纯单机本地使用(直接 `http://localhost` 就够),以及需要大规模并发的生产服务(Caddy 单机瓶颈在 ~10K 并发)。

前置条件

– Linux 服务器(Ubuntu 22.04+、Debian 12+ 验证过)

– 一个域名,DNS 已经 A 记录指向服务器公网 IP

– 服务器 80/443 端口没被占用

– Docker + Docker Compose 已装

# 检查环境
docker --version  # >= 20.10
docker compose version  # >= 2.0

步骤 1:建项目目录

mkdir -p ~/ai-gateway/{caddy_data,caddy_config,ollama_data}
cd ~/ai-gateway

步骤 2:写 docker-compose.yml

version: "3.8"

services:
  caddy:
    image: caddy:2.8-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy_data:/data
      - ./caddy_config:/config
    networks:
      - ai-net

  ollama:
    image: ollama/ollama:latest
    restart: unless-stopped
    # 不暴露公网端口,只走 Caddy 反代
    expose:
      - "11434"
    volumes:
      - ./ollama_data:/root/.ollama
    networks:
      - ai-net
    # GPU 支持(如果服务器有 NVIDIA 卡)
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    restart: unless-stopped
    expose:
      - "8080"
    volumes:
      - ./open_webui_data:/app/backend/data
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
    depends_on:
      - ollama
    networks:
      - ai-net

networks:
  ai-net:
    driver: bridge

步骤 3:写 Caddyfile(自动 HTTPS 核心)

# Ollama API 反代
ollama.你的域名.com {
    reverse_proxy ollama:11434
    
    # CORS(如果前端是另一个域名)
    header Access-Control-Allow-Origin "*"
}

# Open WebUI 反代
chat.你的域名.com {
    reverse_proxy open-webui:8080
    
    # 改写 WebSocket 路径(Open WebUI 实时对话用)
    @websockets {
        path /ws/*
    }
    reverse_proxy @websockets open-webui:8080
}

关键点

– Caddy 看到域名配置自动申请 Let’s Encrypt 证书——零配置

– 证书存 `./caddy_data/caddy/certificates/`,30 天前自动续期

– WebSocket 反代必须用 `@websockets` 命名 matcher,否则实时对话会断

启动

cd ~/ai-gateway
docker compose up -d

# 拉一个模型
docker compose exec ollama ollama pull qwen3:8b

# 等 2 分钟让 Let's Encrypt 证书签发完成
docker compose logs -f caddy
# 看到 "certificate obtained successfully" 就 OK 了

验证

# 检查 HTTPS 证书
curl -I https://ollama.你的域名.com
# 应该有 HTTP/2 200,证书 issuer = Let's Encrypt

# 检查 Ollama API
curl https://ollama.你的域名.com/api/tags
# 返回 {"models":[...]}

# 浏览器访问
# https://chat.你的域名.com  →  Open WebUI 登录页

常见失败处理

| 症状 | 原因 | 解决 |

|——|——|——|

| 证书签发失败 | 80 端口被占用或防火墙挡 | `sudo ufw allow 80/tcp && sudo ufw allow 443/tcp` |

| 502 Bad Gateway | 上游服务没起来 | `docker compose ps`,等 ollama/open-webui healthy |

| WebSocket 断连 | Caddyfile 漏了 `@websockets` matcher | 加 `reverse_proxy @websockets` 段 |

| Open WebUI 登录失败 | 时区不对,cookie 失效 | 在 `open-webui` 容器加 `TZ=Asia/Shanghai` 环境变量 |

| DNS 不生效 | A 记录没传播 | `dig ollama.你的域名.com` 确认解析到服务器 IP |

进阶玩法

加 Basic Auth:在 Caddyfile 里加 `basicauth { user $2a$14$… }`,保护敏感 API

加 Cloudflare CDN:把 NS 切到 Cloudflare,自动 DDoS 防护 + 隐藏服务器 IP

加 Fail2ban:装 fail2ban 监控 Caddy 日志,自动封禁暴力破解 IP

加 Cloudflare Tunnel:服务器不开 80/443 端口也能用,适合 NAT 网络

跟 Nginx 比,Caddy 的优势

| 特性 | Caddy | Nginx |

|——|——-|——-|

| HTTPS 自动证书 | ✅ 零配置 | ❌ 需 certbot + cron |

| 配置文件大小 | 5 行搞定 | 30+ 行 |

| 配置热重载 | ✅ `docker compose kill -s HUP caddy` | 需 reload 或重读 |

| 内存占用 | ~30MB | ~10MB |

| 中文文档 | 较少 | 极多 |

结论:本地 AI 服务要暴露公网,Caddy 是 2026 年最省心的选择。10 分钟搭完,证书 90 天自动续,基本不用再管。

安全加固清单

基础跑通后,建议立刻补这几条:

1. 改 Open WebUI 默认账号:默认 admin/admin 必须改,密码 16 位以上

2. 限制 Caddy 监听 IP:如果只给内网用,ports 改成 `127.0.0.1:443:443` 防止公网扫描

3. 加 fail2ban:装 fail2ban 监控 Caddy 日志,5 分钟内 5 次 401 自动封 IP

4. 定期备份 ollama_data:模型文件 + 对话历史都要备份

5. 监控磁盘空间:模型文件会持续增长,加个 cron 每天 `df -h` 告警

性能参考

实测在 4 核 8GB 的云服务器上:

| 指标 | 数值 |

|——|——|

| Caddy 内存占用 | ~30MB |

| 静态文件吞吐 | ~5000 req/s |

| 反代延迟 | +2-5ms |

| HTTPS 握手 | ~50ms |

| WebSocket 延迟 | +5-10ms |

并发 1000 个 HTTPS 请求时,Caddy CPU 占用约 60%,足够覆盖中小团队使用。如果要扛 10K+ 并发,建议前面加 Cloudflare 或在前置 Nginx。

跟 Traefik 比怎么选

| 特性 | Caddy | Traefik |

|——|——-|———|

| 配置难度 | ⭐ 极简 | ⭐⭐⭐ 较复杂 |

| HTTPS 自动证书 | ✅ | ✅ |

| Docker 集成 | ⚠️ 需手写 Caddyfile | ✅ 自动发现 |

| 仪表盘 | ❌ | ✅ 内置 Web UI |

| 多服务管理 | 适合少量 | 适合大量微服务 |

| 资源占用 | ~30MB | ~80MB |

选 Caddy 的场景:1-5 个服务、追求最简配置、不需要复杂路由规则
选 Traefik 的场景:10+ 个微服务、需要动态配置、想要可视化仪表盘


🔥 关注LC智趣厅,本地 AI 部署的”最后一公里”系列。


— END —
LC 智趣厅 · 科技与生活的交点
ihygg.cn

Scroll to Top
微信公众号:LC智趣厅

扫码关注微信公众号
LC智趣厅