Docker容器间环境变量传递求助:Compose配置与Python实现问题
我帮你梳理一套完整的解决方案,从自动获取容器IP、写入.env,到让另一个容器读取变量并在Python中打印,全程用Docker Compose+脚本实现自动化,步骤很清晰:
1. 核心思路说明
Docker容器的IP是启动后动态分配的,没法提前写死在.env里。我们的流程是:先启动目标容器,用脚本获取它的IP并写入.env,再让依赖容器从.env读取这个变量,最后在Python代码中打印出来。
2. 完整文件配置与执行步骤
2.1 先整理项目目录结构
你的项目最终会是这样的:
your-project/ ├── .env # 自动生成/更新的环境变量文件 ├── docker-compose.yml # Compose配置文件 ├── get_container_ip.sh # 自动获取IP并更新.env的脚本 └── app/ ├── Dockerfile # Python服务的构建文件 └── abc.py # 打印IP的Python代码
2.2 编写IP获取脚本 get_container_ip.sh
这个脚本负责启动目标容器、获取IP、更新.env,给它加执行权限后就能一键运行:
#!/bin/bash # 1. 启动目标容器(如果还没启动) docker-compose up -d service-a # 2. 用容器ID获取IP(避免硬编码容器名,更通用) SERVICE_A_CONTAINER_ID=$(docker-compose ps -q service-a) SERVICE_A_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $SERVICE_A_CONTAINER_ID) # 3. 更新.env文件,写入IP变量 echo "SERVICE_A_IP=$SERVICE_A_IP" > .env echo "✅ 成功更新.env,Service A的IP是:$SERVICE_A_IP"
2.3 配置 docker-compose.yml
定义两个服务:service-a是你要获取IP的容器,service-b是要接收IP并打印的Python服务。注意让service-b依赖service-a,并读取.env的变量:
version: '3.8' services: service-a: image: nginx:alpine # 替换成你实际使用的镜像 container_name: service-a networks: - my-internal-network service-b: build: ./app container_name: service-b env_file: - .env # 读取.env中的环境变量 depends_on: - service-a # 确保service-a先启动 networks: - my-internal-network networks: my-internal-network: driver: bridge
2.4 编写Python服务的文件
首先是 app/Dockerfile
用来构建Python运行环境:
FROM python:3.9-slim WORKDIR /app # 复制Python代码到容器内 COPY abc.py . # 启动脚本 CMD ["python", "abc.py"]
然后是 app/abc.py
从环境变量中读取IP并打印:
import os # 从环境变量获取Service A的IP service_a_ip = os.getenv('SERVICE_A_IP') if service_a_ip: print(f"🎉 Service A的IP地址是:{service_a_ip}") else: print("❌ 错误:未获取到SERVICE_A_IP环境变量!")
2.5 一键执行自动化流程
- 给脚本加执行权限:
chmod +x get_container_ip.sh - 运行脚本获取IP并更新
.env:./get_container_ip.sh - 启动Python服务
service-b:docker-compose up -d service-b - 查看
service-b的日志,确认IP打印结果:docker logs service-b
3. 关键注意事项
- 容器名/ID的通用性:脚本里用
docker-compose ps -q service-a获取容器ID,比硬编码容器名(比如your-project_service-a_1)更靠谱,不管你的项目名是什么都能正常工作。 - 依赖启动顺序:
depends_on只保证service-a先启动,但如果service-a需要初始化时间(比如数据库),你可能需要在service-b的启动脚本里加等待逻辑,但如果只是获取IP的话,这个配置足够。 - .env文件权限:确保运行脚本的用户有
.env文件的写入权限,避免权限报错。
内容的提问来源于stack exchange,提问作者zeusking123




