自定义网络中的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'启动服务。
额外排查建议
- 重新构建镜像并启动容器后,检查容器状态:
确认docker psmy-app-container处于Up状态。 - 查看容器日志,确认服务正常启动:
正常情况下会看到类似docker logs my-app-containerRunning on http://0.0.0.0:5000的日志。 - 测试主机端口连通性:
或用# MacOS/Linux nc -zv localhost 8080curl查看详细请求过程:curl -v http://localhost:8080/users
内容的提问来源于stack exchange,提问作者SA.93
相关产品推荐
相关产品推荐

