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

NGINX反向代理多容器服务8080端口占用问题排查

问题根因
  • 核心问题是你给se-kpi-sim(Django后端)、se-kpi-sim-ui(Vue前端)、reverse-proxy(Nginx反向代理)三个容器全部配置了network_mode: "host",该模式下所有容器共享宿主机网络命名空间,端口直接绑定宿主机,完全失去Docker网络隔离能力,多个服务抢占同个端口就会触发地址占用报错。
  • 你看到的bind() to 0.0.0.0:8080 failed报错,是Vue UI容器内部服务默认监听8080端口,启动时发现宿主机8080端口已经被其他进程(异常退出残留的容器进程、宿主机其他服务)占用导致的。
  • 现有反向代理配置里的proxy_pass写http://0.0.0.0:端口是错误写法,0.0.0.0是服务绑定监听的地址,不是内网访问的目标地址,就算使用host网络,访问本机服务也应该用127.0.0.1,更合理的方案是放弃host网络,用Docker默认桥接网络走服务名互访。
修复步骤

调整docker-compose配置

移除三个业务/代理容器的network_mode: "host"配置,所有服务加入同一个默认内网,仅给反向代理暴露对外的80端口即可,调整后配置如下:

version: '3.2'
services:
    se-kpi-sim:
        image: test-app:0.0.1
        restart: unless-stopped
        environment:
            MODEL_NAME: "model_final.pickle.dat"
        # 仅Docker内网可访问,不对外暴露端口
        expose:
            - "5000"

    se-kpi-sim-ui:
        image: test-ui:0.0.3
        restart: unless-stopped
        # 仅Docker内网可访问,不对外暴露端口
        expose:
            - "3000"

    reverse-proxy:
        image: test-proxy:0.0.7
        restart: unless-stopped
        # 仅反向代理对外暴露80端口
        ports:
            - "80:80"
        depends_on:
            - se-kpi-sim
            - se-kpi-sim-ui

    database:
        image: postgres
        environment:
            POSTGRES_PASSWORD: password
            POSTGRES_USER: kpi_sim_user
            POSTGRES_DB: kpi_sim
            POSTGRES_HOST_AUTH_METHOD: trust
        # 非调试场景不需要映射数据库端口到宿主机,避免安全风险
        expose:
            - "5432"
        volumes:
            - database:/var/lib/postgresql/data
        restart: unless-stopped

volumes:
    database:

切换到桥接网络后,每个容器有独立的网络栈,UI容器内部监听的8080端口不会和宿主机或其他容器的端口冲突,之前的8080端口占用报错会直接消失。

修正Nginx反向代理配置

把proxy_pass的目标地址从0.0.0.0改成docker-compose对应的服务名,Docker内置DNS会自动把服务名解析到对应容器的内网IP,不需要手动写死IP,补充通用请求头配置方便后端获取真实用户IP,修正后配置如下:

server {
    listen  80;
    listen [::]:80;

    location / {
        proxy_pass http://se-kpi-sim-ui:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    location /predict {
        proxy_pass http://se-kpi-sim:5000/predict;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    location /aggregate {
        proxy_pass http://se-kpi-sim:5000/aggregate;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    location /media/pictures {
        proxy_pass http://se-kpi-sim:5000/media/pictures;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    access_log /opt/bitnami/nginx/logs/anomaly_access.log;
    error_log /opt/bitnami/nginx/logs/anomaly_error.log;
}

清理残留进程后重启服务

在部署目录执行以下命令,清理旧的残留容器、确认端口无占用后重启服务:

# 停止并删除所有旧容器
docker compose down
# 检查关键端口是否被残留进程占用
ss -tulpn | grep -E ':(80|3000|5000|8080)\s'
# 如果有残留进程占用,执行kill -9 对应PID 释放端口
# 后台启动所有服务
docker compose up -d
后续配置说明
  • 当前部署模式下只有反向代理的80端口对外暴露,前端、后端、数据库端口都仅在Docker内网可访问,既避免端口冲突,也能降低服务被攻击的风险。
  • 后续调试完成要开放443端口支持HTTPS时,只需要给reverse-proxy服务增加443:443的端口映射,在Nginx配置里新增443端口监听和证书配置即可,不需要调整其他业务服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:21:17