如何为Docker服务配置反向代理?

10 人参与

在容器化部署的环境里,单一服务往往只监听内部端口,外部访问必须经过一层统一入口,否则每个容器的 IP 与端口都要暴露在公网,安全与运维成本随之飙升。反向代理恰好填补了这块空白:它把外部请求的域名、路径映射到对应的容器内部地址,实现统一的 TLS 终结、负载均衡以及日志聚合。

反向代理的核心原理

请求到达代理服务器后,代理根据预先配置的规则解析 Host 与 URI,随后在内部网络中建立到目标容器的 TCP 连接,将响应原封不动地返给客户端。整个过程对外部用户透明,且可以在代理层统一管理证书、限流与安全策略。

选型考量

常见的反向代理实现包括 Nginx、Traefik 与 Caddy。Nginx 以成熟的配置语法和丰富的模块生态著称,适合已有熟悉度的团队;Traefik 原生支持 Docker 标签,能在容器启动时自动生成路由;Caddy 则把自动 HTTPS 融入核心,省去手动证书管理的步骤。选型时要衡量配置灵活性、社区活跃度以及与现有 CI/CD 流程的兼容程度。

使用 Nginx 为 Docker 服务配置反向代理

  • 在宿主机上安装 Nginx,确保能够通过 80/443 端口对外提供服务。
  • 为目标容器分配固定的内部网络别名(例如 app.internal),便于 Nginx 在 upstream 中引用。
  • /etc/nginx/conf.d 新建以域名命名的配置文件,定义 server 块并启用 TLS。
  • location 中使用 proxy_pass http://app.internal:8080; 将流量转发至容器。
  • 重新加载 Nginx 配置,验证 curl -I https://your-domain.com 是否返回 200。
# /etc/nginx/conf.d/example.com.conf
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate     /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

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

在 Docker‑Compose 中实现一体化

将 Nginx 本身也容器化后,可以在同一 docker-compose.yml 中声明网络、卷以及证书挂载,实现“代码即基础设施”。下面的片段演示了一个最小化的组合:一个后端服务 webapp 与一个 Nginx 代理 proxy,二者共享自定义网络 internal,并通过卷把证书文件注入到代理容器。

version: "3.8"
services:
  webapp:
    image: myorg/webapp:latest
    networks:
      - internal
    expose:
      - "8080"

  proxy:
    image: nginx:stable-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./ssl:/etc/ssl:ro
    networks:
      - internal

networks:
  internal:
    driver: bridge

只要在 nginx/conf.d 目录放入前文示例的配置文件,执行 docker compose up -d,整个反向代理链路即刻生效,外部访问 HTTPS 时会自动路由到容器内部的业务服务。

参与讨论

10 条评论
  • RadianceOrbit

    Nginx配置挺实用,直接上手。👍

  • 甜心布丁

    Traefik配合Docker标签,自动生成路由,省时省力。

  • 傀儡师语

    Caddy自带HTTPS,适合不想手动管理证书的场景。

  • 虚无回声

    这个proxy_pass的超时怎么设置?

  • 碧落星

    前几天我也把Nginx容器化,网络别名搞定后访问顺畅。

  • 深渊谜语

    配置文件里缩进真是挑人。

  • 奶茶不甜不坏

    看到有人把80端口直接映射,安全感直降。

  • 桥头说书人

    有人把证书直接放在public目录,真是大胆的操作。

  • PixieDustPaws

    整体思路清晰,步骤详细,刚入门的我也能跟着做。

  • 星穹信使

    如果想在同一个Nginx容器里同时代理多个子域,需要怎样写upstream和server块?有没有推荐的写法?