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

自定义网络中的Docker容器无法从主机访问,寻求解决方案

问题:Flask容器无法从主机访问,容器间通信正常

我创建了两个Docker镜像并运行,一个是用于测试的简单Flask应用,另一个是PostgreSQL数据库。容器间通信正常(已在Flask容器内用curl测试),但主机(MacOS和Ubuntu)无法通过localhost:8080、127.0.0.1:8080或自定义网络IP访问Flask容器,请求无法到达,也无法查看容器日志排查问题。已检查防火墙,更换端口均无效。


相关代码与配置

app.py

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:postgres@my-postgres-container:5432/db'

db = SQLAlchemy(app)

migrate = Migrate(app, db)

class MyUser(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True, nullable=False)

@app.route('/users', methods=['POST'])
def create_user():
    data = request.get_json()
    new_user = MyUser(name=data['name'])
    db.session.add(new_user)
    db.session.commit()
    return jsonify({'message': 'New user created!'})

@app.route('/users', methods=['GET'])
def get_all_users():
    users = MyUser.query.all()
    output = []
    for user in users:
        user_data = {'id': user.id, 'name': user.name}
        output.append(user_data)
    return jsonify({'users': output})

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

Dockerfile-app

FROM python:3.8-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 5000

ENTRYPOINT ["bash", "-c"]
CMD ["flask db init && flask db migrate && flask db upgrade && flask run"]

Dockerfile-db

FROM postgres:latest

ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD postgres
ENV POSTGRES_DB db

EXPOSE 5432

CMD ["postgres"]

requirements.txt

alembic==1.13.1
blinker==1.7.0
click==8.1.7
Flask==3.0.2
Flask-Migrate==4.0.7
Flask-SQLAlchemy==3.1.1
itsdangerous==2.1.2
Jinja2==3.1.3
Mako==1.3.2
MarkupSafe==2.1.5
psycopg2-binary==2.9.9
SQLAlchemy==2.0.29
typing_extensions==4.10.0
Werkzeug==3.0.1

运行命令

docker network create my-network
docker volume create my-volume
docker build -t my-postgres -f Dockerfile-db .
docker run -d -p 5432:5432 --name my-postgres-container --network my-network -v my-volume:/var/lib/postgresql/data my-postgres
docker build -t my-app -f Dockerfile-app .
docker run -d -p 8080:5000 --name my-app-container --network my-network my-app

问题原因与解决方法

核心问题:Flask服务绑定地址错误

你的Dockerfile-app中用flask run启动服务,但默认情况下flask run会绑定127.0.0.1,导致仅容器内部可访问。即使app.py中if __name__ == '__main__'块指定了host='0.0.0.0',但这个代码块没有被执行——因为你是通过flask run命令启动服务,而非直接运行python app.py。

解决步骤

方法1:修改启动命令指定host参数

将Dockerfile-app中的CMD改为:

CMD ["flask db init && flask db migrate && flask db upgrade && flask run --host=0.0.0.0"]

这样flask run会明确绑定0.0.0.0,允许外部访问。

方法2:通过环境变量指定绑定地址

在Dockerfile-app中添加环境变量:

ENV FLASK_RUN_HOST=0.0.0.0

保持原CMD不变,Flask会自动读取该环境变量绑定到0.0.0.0。

方法3:直接运行app.py

修改Dockerfile-app的ENTRYPOINT和CMD:

ENTRYPOINT []
CMD ["python", "app.py"]

这样会直接执行app.py中的if __name__ == '__main__'块,使用你指定的host='0.0.0.0'启动服务。

额外排查建议

  1. 重新构建镜像并启动容器后,检查容器状态:
    docker ps
    
    确认my-app-container处于Up状态。
  2. 查看容器日志,确认服务正常启动:
    docker logs my-app-container
    
    正常情况下会看到类似Running on http://0.0.0.0:5000的日志。
  3. 测试主机端口连通性:
    # MacOS/Linux
    nc -zv localhost 8080
    
    或用curl查看详细请求过程:
    curl -v http://localhost:8080/users
    

内容的提问来源于stack exchange,提问作者SA.93

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 20:43:27