You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Traefik配置:实现HTTPS终止并反向代理React应用

Traefik反向代理实现HTTPS入口+内部HTTP通信配置方案

核心架构说明

客户端通过HTTPS://your-domain.com访问,Traefik在443端口接收请求后,以HTTP协议转发到内部的React前端(5000端口)及其他后端服务,所有内部服务保持HTTP通信,无需感知HTTPS。


1. 完整docker-compose.yml配置

version: '3.8'

# 自定义内部网络,确保所有服务互通
networks:
  traefik-network:
    external: false

services:
  # Traefik反向代理服务
  traefik:
    image: traefik:v2.10
    container_name: traefik
    command:
      # 开启Docker自动发现
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --providers.docker.network=traefik-network
      # 配置入口点:80用于Let's Encrypt挑战,443用于HTTPS访问
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      # 开启ACME证书自动签发(Let's Encrypt)
      - --certificatesresolvers.myresolver.acme.httpchallenge=true
      - --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
      - --certificatesresolvers.myresolver.acme.email=your-email@domain.com  # 替换为你的邮箱
      - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
      # 开启Dashboard(可选,需配置访问规则)
      - --api.dashboard=true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      # 挂载Docker sock让Traefik获取容器信息
      - /var/run/docker.sock:/var/run/docker.sock:ro
      # 持久化证书存储
      - ./traefik-letsencrypt:/letsencrypt
    networks:
      - traefik-network
    labels:
      # 配置Dashboard的HTTPS访问规则(可选)
      - traefik.enable=true
      - traefik.http.routers.dashboard.entrypoints=websecure
      - traefik.http.routers.dashboard.rule=Host(`traefik.your-domain.com`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`))
      - traefik.http.routers.dashboard.tls.certresolver=myresolver
      - traefik.http.routers.dashboard.service=api@internal

  # React前端服务
  react-app:
    image: your-react-image:latest  # 替换为你的React镜像
    container_name: react-app
    environment:
      - REACT_APP_API_URL=/api  # 用相对路径,避免硬编码协议和域名
    networks:
      - traefik-network
    labels:
      - traefik.enable=true
      # 配置前端路由:匹配主域名
      - traefik.http.routers.react.entrypoints=websecure
      - traefik.http.routers.react.rule=Host(`your-domain.com`)
      - traefik.http.routers.react.tls.certresolver=myresolver
      # 强制Traefik用HTTP转发到React的5000端口
      - traefik.http.services.react.loadbalancer.server.port=5000
      - traefik.http.services.react.loadbalancer.server.scheme=http

  # Nginx后端服务(处理API请求)
  nginx:
    image: your-nginx-image:latest  # 替换为你的Nginx镜像
    container_name: nginx-backend
    networks:
      - traefik-network
    labels:
      - traefik.enable=true
      # 配置API路由:匹配域名+ /api前缀
      - traefik.http.routers.api.entrypoints=websecure
      - traefik.http.routers.api.rule=Host(`your-domain.com`) && PathPrefix(`/api`)
      - traefik.http.routers.api.tls.certresolver=myresolver
      # 转发到Nginx内部HTTP端口(默认80)
      - traefik.http.services.api.loadbalancer.server.port=80
      - traefik.http.services.api.loadbalancer.server.scheme=http
    # 其他Nginx配置:挂载配置文件等,根据你的需求添加
    volumes:
      - ./nginx-conf:/etc/nginx/conf.d

  # Laravel-Echo-Server(WebSocket服务)
  laravel-echo:
    image: oanhnn/laravel-echo-server:latest  # 或你的自定义镜像
    container_name: laravel-echo
    environment:
      - REDIS_HOST=redis
      - AUTH_HOST=http://nginx  # 内部用HTTP访问Nginx
    networks:
      - traefik-network
    labels:
      - traefik.enable=true
      # 配置WebSocket路由
      - traefik.http.routers.echo.entrypoints=websecure
      - traefik.http.routers.echo.rule=Host(`your-domain.com`) && PathPrefix(`/socket.io`)
      - traefik.http.routers.echo.tls.certresolver=myresolver
      - traefik.http.routers.echo.service=echo
      # WebSocket需要指定升级协议
      - traefik.http.routers.echo.middlewares=echo-websocket
      - traefik.http.middlewares.echo-websocket.headers.customrequestheaders.Connection=upgrade
      - traefik.http.middlewares.echo-websocket.headers.customrequestheaders.Upgrade=websocket
      # 转发到Echo Server的端口(默认6001)
      - traefik.http.services.echo.loadbalancer.server.port=6001
      - traefik.http.services.echo.loadbalancer.server.scheme=http

  # Redis服务
  redis:
    image: redis:alpine
    container_name: redis
    networks:
      - traefik-network
    # 可选:持久化Redis数据
    volumes:
      - ./redis-data:/data

  # PHP-FPM服务
  php-fpm:
    image: your-php-fpm-image:latest  # 替换为你的PHP-FPM镜像
    container_name: php-fpm
    networks:
      - traefik-network
    volumes:
      - ./laravel-code:/var/www/html

2. 关键配置要点

  • 强制HTTP转发:所有服务的traefik.http.services.xxx.loadbalancer.server.scheme=http必须明确配置,这是解决后端被强制HTTPS问题的核心——Traefik默认可能尝试HTTPS转发,导致后端HTTP服务报错。
  • 网络隔离:所有服务加入同一个自定义网络traefik-network,避免默认网络的通信问题,同时无需暴露服务端口到宿主机(Traefik会自动转发)。
  • 前端API请求:React前端的API地址必须用相对路径(如/api/user),或使用协议相对URL(如//your-domain.com/api/user),确保客户端HTTPS请求能被Traefik正确转发到内部HTTP的Nginx。
  • 证书配置:Traefik通过ACME自动获取Let's Encrypt证书,需确保域名已解析到VDS公网IP,且80/443端口在防火墙/安全组中开放(80用于HTTP-01挑战验证域名所有权)。
  • 持久化存储:Traefik的证书目录、Redis数据、代码目录等需挂载到宿主机,避免容器重启后数据丢失。

3. 验证步骤

  1. 启动所有服务:docker-compose up -d
  2. 查看Traefik日志:docker logs traefik,确认证书正常签发
  3. 访问https://your-domain.com,检查React前端是否正常加载
  4. 测试API请求:在前端触发API调用,查看Nginx/PHP-FPM日志,确认请求以HTTP方式到达后端

内容的提问来源于stack exchange,提问作者dedops

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:36:29