如何在docker-compose运行的Postgres初始化脚本中使用环境变量?
解决PostgreSQL初始化脚本环境变量不生效问题
PostgreSQL官方镜像会直接执行docker-entrypoint-initdb.d目录下的.sql文件,但不会解析${USER_EMAIL}这类Shell风格的环境变量,这就是变量无法生效的核心原因。以下是两种可行的解决方案:
方法1:模板文件+Shell脚本替换变量
- 将原
fill_tables.sql重命名为fill_tables.sql.template,内容保持不变:
insert into user (email) values ('${USER_EMAIL}');
- 创建
fill_tables.sh脚本,用于替换变量并执行SQL:
#!/bin/sh # 替换模板中的环境变量,再传递给psql执行 envsubst < /docker-entrypoint-initdb.d/fill_tables.sql.template | psql -U "$POSTGRES_USER" -d "$POSTGRES_DB"
- 给Shell脚本添加可执行权限:
chmod +x ./sql/fill_tables.sh
- 修改
docker-compose.yml,添加USER_EMAIL环境变量并挂载相关文件:
version: '3.7' services: postgres: image: postgres:10.5 restart: always environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - USER_EMAIL=your-target-email@example.com # 设置你需要的邮箱值 - POSTGRES_DB=postgres # 可选:指定数据库名,默认与POSTGRES_USER同名 logging: options: max-size: 10m max-file: "3" ports: - '5438:5432' volumes: - ./postgres-data:/var/lib/postgresql/data - ./sql/create_tables.sql:/docker-entrypoint-initdb.d/create_tables.sql - ./sql/fill_tables.sh:/docker-entrypoint-initdb.d/fill_tables.sh - ./sql/fill_tables.sql.template:/docker-entrypoint-initdb.d/fill_tables.sql.template
方法2:直接在Shell脚本中编写带变量的SQL
如果不需要模板文件,也可以直接将SQL写在Shell脚本里,让Shell自动替换变量:
#!/bin/sh psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" <<EOF insert into user (email) values ('${USER_EMAIL}'); EOF
同样给脚本添加可执行权限,然后在docker-compose.yml中挂载该脚本,并配置USER_EMAIL环境变量即可。
关键注意事项
- 脚本必须拥有可执行权限,否则容器启动时不会执行它。
- 如果使用非默认数据库名,务必在环境变量中指定
POSTGRES_DB。
内容的提问来源于stack exchange,提问作者Carlos Gonzalez
相关产品推荐
相关产品推荐

