Docker Compose无法从env文件替换变量,求助排查配置问题
在GitHub构建应用镜像并存储为包,将变量配置在Docker Compose文件旁的.env-docker-dev文件中,随后将Docker Compose文件复制到服务器,执行命令:
docker-compose -f ../repo/sdr_app/docker-dev-sdr_core-be-compose.yml up -d
命令执行后,Compose阶段出现多个变量未设置的警告(示例:err: The SDR_APP_CONNECTIONSTRING variable is not set. Defaulting to a blank string.),预期的appsettings.json变量替换未生效。
执行docker-compose -f ../repo/sdr_app/docker-dev-sdr_core-be-compose.yml config命令后,确认部分变量未填充,存在多条变量未设置警告。
Docker Compose文件内容:
version: '3.4' services: be_nginx: environment: - TZ:"Asia/Singapore" image: nginx:latest ports: - "80:80" - "443:443" restart: unless-stopped env_file: - ../repo/sdr_app/.env-docker-dev networks: - ${SDR_NETWORK} volumes: - ./be_nginx:/etc/nginx/conf.d:ro - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro - ./data/certbot/conf:/etc/letsencrypt:ro - ./data/certbot/www:/var/www/certbot:ro command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" sdr_app.api: environment: - ASPNETCORE_ENVIRONMENT=Docker_Dev_DO - TZ=Asia/Singapore - APP_ID=${APP_ID} - SDR_APP_CONNECTIONSTRING=${SDR_APP_CONNECTIONSTRING} - FILE_CACHE_IN_SECONDS=${FILE_CACHE_IN_SECONDS} - DEPLOY_ORIGIN=${DEPLOY_ORIGIN} image: loca.io/uone/sdr_app.api:latest env_file: - ../repo/sdr_app/.env-docker-dev build: context: . dockerfile: SDR_App.Api/Dockerfile networks: - ${SDR_NETWORK} volumes: - "../dev.repo/:/app-volumes/" - "/etc/timezone:/etc/timezone:ro" - "/etc/localtime:/etc/localtime:ro" networks: core-network: name: ${SDR_NETWORK}
env文件(.env-docker-dev)内容:
SDR_NETWORK=core-network COMPOSE_IGNORE_ORPHANS=True SDR_APP_CONNECTIONSTRING=abcdefg
请问Docker Compose文件缺少什么配置导致变量替换失败?
变量替换失败主要由以下几个问题导致,对应修正方案如下:
1. env文件路径解析逻辑错误
Docker Compose加载env_file时,路径是相对于执行docker-compose命令的当前工作目录,而非Compose文件的位置。你指定的../repo/sdr_app/.env-docker-dev路径,若执行命令时的工作目录不正确,会直接导致无法找到env文件,自然无法加载变量。
修正方案:
- 切换到Compose文件所在目录执行命令,或把env文件路径改为绝对路径;
- 或在执行命令时显式用
--env-file参数指定文件位置:
docker-compose --env-file ../repo/sdr_app/.env-docker-dev -f ../repo/sdr_app/docker-dev-sdr_core-be-compose.yml up -d
2. 部分引用变量未在env文件中定义
Compose文件中引用了${APP_ID}、${FILE_CACHE_IN_SECONDS}、${DEPLOY_ORIGIN},但这些变量并未在.env-docker-dev中配置,所以Docker Compose会提示变量未设置并默认空字符串。
修正方案:
将缺失的变量补充到.env-docker-dev文件中,示例:
SDR_NETWORK=core-network COMPOSE_IGNORE_ORPHANS=True SDR_APP_CONNECTIONSTRING=abcdefg APP_ID=your-app-id FILE_CACHE_IN_SECONDS=3600 DEPLOY_ORIGIN=https://your-domain.com
3. TZ环境变量语法错误
be_nginx服务的environment中,TZ:"Asia/Singapore"的写法会把引号当作变量值的一部分,导致配置异常,正确写法应为TZ=Asia/Singapore(不带引号)。
修正方案:
修改be_nginx的环境变量配置:
environment: - TZ=Asia/Singapore
4. 可选:检查Docker Compose版本兼容性
虽然你的Compose文件使用3.4版本(已支持变量替换),但如果服务器上的docker-compose版本过旧,可能存在兼容性问题。可执行docker-compose --version检查版本,建议升级到较新版本。
修改后的完整Compose文件示例:
version: '3.4' services: be_nginx: environment: - TZ=Asia/Singapore image: nginx:latest ports: - "80:80" - "443:443" restart: unless-stopped env_file: - ../repo/sdr_app/.env-docker-dev networks: - ${SDR_NETWORK} volumes: - ./be_nginx:/etc/nginx/conf.d:ro - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro - ./data/certbot/conf:/etc/letsencrypt:ro - ./data/certbot/www:/var/www/certbot:ro command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" sdr_app.api: environment: - ASPNETCORE_ENVIRONMENT=Docker_Dev_DO - TZ=Asia/Singapore - APP_ID=${APP_ID} - SDR_APP_CONNECTIONSTRING=${SDR_APP_CONNECTIONSTRING} - FILE_CACHE_IN_SECONDS=${FILE_CACHE_IN_SECONDS} - DEPLOY_ORIGIN=${DEPLOY_ORIGIN} image: loca.io/uone/sdr_app.api:latest env_file: - ../repo/sdr_app/.env-docker-dev build: context: . dockerfile: SDR_App.Api/Dockerfile networks: - ${SDR_NETWORK} volumes: - "../dev.repo/:/app-volumes/" - "/etc/timezone:/etc/timezone:ro" - "/etc/localtime:/etc/localtime:ro" networks: core-network: name: ${SDR_NETWORK}
内容的提问来源于stack exchange,提问作者JianYA

