如何无需指定端口访问Docker部署的Flask API路由?
问题
我有一个包含/callapi1和/callapi2两个路由的Flask API,通过Docker部署。为了并发处理请求,我用命令docker-compose up -d --build --scale app=2扩展服务器,Flask API由Gunicorn提供服务。
现在运行Docker实例时,服务器实例被分配随机端口,必须指定具体端口才能访问API,比如:
response = requests.post("http://127.0.0.1:54471/callapi1", json=img_data) response = requests.post("http://127.0.0.1:54472/callapi1", json=img_data)
我希望配置Docker和Nginx,实现无需指定端口即可访问API,比如:
http://localhost/callapi1http://localhost/callapi2
当前的Docker Compose文件:
version: '4' services: app: build: context: app ports: - "5000" nginx: image: nginx:latest volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - app ports: - "80:80"
nginx.conf文件内容:
events { worker_connections 1000; } http { upstream flask_app { server app:5000; } server { listen 80; location / { proxy_pass http://app:5000; } } }
解决方案
1. 修改Docker Compose配置
不需要给app服务暴露端口到宿主机(Nginx会在Docker内部网络访问它),同时修正版本号(Docker Compose无4版本,使用稳定的3.8):
version: '3.8' services: app: build: context: app expose: - "5000" # 仅在Docker内部网络暴露5000端口,无需映射到宿主机 nginx: image: nginx:latest volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - app ports: - "80:80"
2. 更新Nginx配置实现负载均衡
调整nginx.conf,让Nginx自动识别所有app实例,并添加必要的代理头:
events { worker_connections 1000; } http { # Docker DNS会自动解析app服务的所有运行实例 upstream flask_app { server app:5000; } server { listen 80; server_name localhost; location / { proxy_pass http://flask_app; # 传递请求头,确保Flask能获取正确的客户端信息 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } }
3. 重新部署服务
执行以下命令重启服务:
docker-compose down docker-compose up -d --build --scale app=2
4. 验证访问
现在直接通过http://localhost/callapi1或http://localhost/callapi2即可访问API,无需指定端口。Nginx会自动采用轮询策略将请求分发到多个app实例,实现并发处理。
内容的提问来源于stack exchange,提问作者mojojojo
相关产品推荐
相关产品推荐

