无需docker-compose实现Docker容器通信(AWS Lightsail部署场景)
问题
我有一个通过docker-compose运行的Flask应用,包含两个服务:Flask应用服务和Nginx服务。现在要部署到AWS Lightsail,但该平台不支持docker-compose,必须分别构建镜像部署。
本地能正常运行Flask服务,但之前由docker-compose自动处理的网络配置现在无法解决——Flask容器和Nginx容器之间的通信有问题。
试过通过docker container inspect <CONTAINER_ID>获取Flask容器IP,硬编码到Nginx的default.conf再重新构建镜像,但这种方式不实用。
此前docker-compose精简配置:
services: nginx-proxy: .... environment: - FLASK_SERVER_ADDR=flask-app:8001 ports: - "8000:80" depends_on: - flask-app .... flask-app: .... command: sh -c "gunicorn -w 4 -b 0.0.0.0:8001 'main.start()'"
Nginx的default.conf引用环境变量:
location / { proxy_pass http://$FLASK_SERVER_ADDR; ... }
尝试用bridge网络构建Nginx镜像:docker build -t nginx-proxy --build-arg FLASK_SERVER_ADDR=${bridge:8001} nginx,但环境变量没生效,运行Nginx容器后报错:no host in upstream "" in /etc/nginx/conf.d/default.conf:7,上游主机为空。
请问不使用docker-compose的情况下,如何让两个容器在同一网络通信?
解决方案
1. 创建自定义Docker桥接网络
默认bridge网络不支持容器名称解析,需创建自定义网络实现容器间的名称访问:
docker network create flask-nginx-network
2. 运行Flask容器并加入自定义网络
启动Flask容器时指定网络和固定容器名称(对应原docker-compose中的flask-app):
docker run -d --name flask-app --network flask-nginx-network <你的Flask镜像名称>
后续Nginx可直接通过flask-app这个名称访问服务,无需依赖动态IP。
3. 调整Nginx的环境变量处理逻辑
Nginx默认不会在启动时自动替换配置文件中的环境变量,需通过envsubst工具实现变量注入,修改Nginx的Dockerfile:
FROM nginx:alpine COPY default.conf /etc/nginx/conf.d/default.conf # alpine镜像需先安装gettext获取envsubst工具 RUN apk add --no-cache gettext # 启动时替换配置中的环境变量,再启动Nginx CMD ["/bin/sh", "-c", "envsubst '$FLASK_SERVER_ADDR' < /etc/nginx/conf.d/default.conf > /etc/nginx/conf.d/default.conf.tmp && mv /etc/nginx/conf.d/default.conf.tmp /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"]
default.conf保持原有写法不变:
location / { proxy_pass http://$FLASK_SERVER_ADDR; # 其他代理配置(如headers、超时设置)... }
4. 构建并运行Nginx容器
无需在构建时传递参数,运行容器时直接注入环境变量并加入同一网络:
# 构建Nginx镜像 docker build -t nginx-proxy ./nginx # 启动Nginx容器,加入自定义网络并设置环境变量 docker run -d --name nginx-proxy --network flask-nginx-network -p 8000:80 -e FLASK_SERVER_ADDR=flask-app:8001 nginx-proxy
这里FLASK_SERVER_ADDR设为flask-app:8001,和原docker-compose配置一致,容器会通过自定义网络自动解析flask-app对应的IP。
5. 验证通信
进入Nginx容器内部测试连通性:
docker exec -it nginx-proxy curl http://flask-app:8001
若能正常返回Flask服务的响应,说明网络通信配置成功。
内容的提问来源于stack exchange,提问作者user1104854

