如何使用Traefik反向代理宿主机上已运行的Node.js服务
问题根因
你遇到的配置报错是因为loadBalancer是Traefik内部的动态路由配置字段,不属于Docker Compose的服务配置规则,所以Docker识别不了这个字段直接报错。
另外你当前只开启了Traefik的Docker provider,这个provider只能自动发现Docker内部运行的容器服务,没法直接指向宿主机上运行在3000端口的Node进程,需要额外开启文件provider配置外部服务。
方案1:直接代理宿主机3000端口的Node服务
步骤1:修改docker-compose.yml
删掉你原来写的整个node-server服务段,修改reverse-proxy的配置如下:
services: reverse-proxy: image: traefik:v2.4 container_name: "traefik" command: - "--api.insecure=true" - "--api.dashboard=true" - "--api.debug=true" - "--providers.docker=true" - "--log.LEVEL=DEBUG" - "--entryPoints.web.address=:80" - "--entryPoints.websecure.address=:443" - "--providers.docker.exposedbydefault=false" # 新增:开启文件provider,加载外部服务配置 - "--providers.file=true" - "--providers.file.filename=/etc/traefik/dynamic-config.yml" - "--certificatesresolvers.myresolver.acme.httpchallenge=true" - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web" - "--certificatesresolvers.myresolver.acme.email=xxxx@xxx.com" - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" ports: - "443:443" - "80:80" - "8080:8080" volumes: - "./letsencrypt:/letsencrypt" - "/var/run/docker.sock:/var/run/docker.sock:ro" # 新增:挂载动态配置文件到容器内 - "./dynamic-config.yml:/etc/traefik/dynamic-config.yml" # Linux系统需要加这行,让容器可以通过host.docker.internal访问宿主机,Windows/Mac可省略 extra_hosts: - "host.docker.internal:host-gateway"
步骤2:创建动态配置文件
和docker-compose.yml同目录下新建dynamic-config.yml,内容如下:
http: # 全局HTTPS跳转中间件 middlewares: redirect-to-https: redirectScheme: scheme: https permanent: true # 路由规则 routers: # HTTP跳转路由 redirs: rule: "hostregexp(`{host:.+}`)" entryPoints: - web middlewares: - redirect-to-https # Node服务路由 node-server: rule: "Host(`xxxxxx.com`)" entryPoints: - websecure tls: certResolver: myresolver service: node-server # 外部服务定义,指向宿主机3000端口 services: node-server: loadBalancer: servers: - url: "http://host.docker.internal:3000/"
注意事项
- 你的Node进程启动时要监听
0.0.0.0而不是127.0.0.1,否则Docker容器无法访问宿主机的3000端口 - 如果服务器开启了防火墙,确保3000端口允许本地访问
方案2:将Node服务放入Docker容器运行(可选)
你提到的Node进程依赖父目录自定义模块的问题,可以通过目录挂载或者构建时COPY解决,不需要修改现有代码结构:
简单示例Dockerfile(放在Node服务根目录)
FROM node:18-alpine WORKDIR /app # 复制父目录的自定义模块到容器内(根据你的实际路径调整) COPY ../your-custom-module /app/your-custom-module COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["node", "index.js"] # 如果要保留pm2托管也可以全局安装pm2后用pm2启动
然后在docker-compose.yml里新增node服务段,Traefik可以直接通过Docker provider自动发现这个服务,不需要额外配置文件,你之前参考的教程里的配置就可以直接用。
内容的提问来源于stack exchange,提问作者Geert-Jan
相关产品推荐
相关产品推荐

