Docker Compose中MySQL初始化脚本环境变量无法展开问题求助
问题:Docker Compose部署MySQL时SQL初始化脚本无法展开环境变量
使用Docker Compose部署MySQL服务,尝试通过环境变量配置初始化用户,相关配置如下:
Docker Compose配置片段:
mysql: image: mysql:latest env_file: - ./env/mysql ports: - "3306:3306" volumes: - ./init:/docker-entrypoint-initdb.d logging: &logger driver: syslog options: tag: "{{.DaemonName}}(image={{.ImageName}};name={{.Name}};id={{.ID}})"
env/mysql文件中已定义MYSQL_USER字段,初始化脚本init/01.sql包含语句:
GRANT ALL ON *.* TO '${MYSQL_USER}'@'%';
执行时出现错误:
ERROR 1410 (42000) at line 5: You are not allowed to create a user with GRANT.
将变量替换为实际值(如GRANT ALL ON *.* TO 'user'@'%';)则可正常运行,推测环境变量未被正确展开,被当作字面量处理。
解决方案
MySQL官方镜像的docker-entrypoint-initdb.d目录只会直接执行SQL脚本,不会自动展开脚本中的环境变量,可通过以下方式处理:
方法1:用Shell脚本代替SQL脚本,手动替换变量
将init/01.sql重命名为init/01.sh,修改内容为:
#!/bin/bash set -e mysql -u root -p"${MYSQL_ROOT_PASSWORD}" <<-EOSQL GRANT ALL ON *.* TO '${MYSQL_USER}'@'%'; FLUSH PRIVILEGES; EOSQL
给脚本添加执行权限:
chmod +x init/01.sh
容器启动时,shell脚本会读取环境变量并替换后执行SQL语句。注意需确保env/mysql中同时定义MYSQL_ROOT_PASSWORD,脚本需要用root权限连接执行授权。
方法2:自定义Entrypoint脚本处理SQL变量替换
若想继续使用SQL脚本,可自定义entrypoint脚本先替换变量再执行:
- 创建自定义entrypoint脚本
entrypoint.sh:
#!/bin/bash set -e # 替换SQL脚本中的指定环境变量 for file in /docker-entrypoint-initdb.d/*.sql; do envsubst '${MYSQL_USER}' < "$file" > "$file.tmp" && mv "$file.tmp" "$file" done # 调用官方镜像的原始entrypoint exec /usr/local/bin/docker-entrypoint.sh "$@"
- 修改Docker Compose配置,挂载并指定自定义entrypoint:
mysql: image: mysql:latest env_file: - ./env/mysql ports: - "3306:3306" volumes: - ./init:/docker-entrypoint-initdb.d - ./entrypoint.sh:/usr/local/bin/custom-entrypoint.sh entrypoint: ["/usr/local/bin/custom-entrypoint.sh"] logging: &logger driver: syslog options: tag: "{{.DaemonName}}(image={{.ImageName}};name={{.Name}};id={{.ID}})"
- 给自定义entrypoint脚本添加执行权限:
chmod +x entrypoint.sh
额外提示
官方MySQL镜像本身会通过MYSQL_USER、MYSQL_PASSWORD环境变量自动创建用户并授予默认权限,若仅需基础用户创建,无需手动编写GRANT语句;只有需要额外权限配置时,才需要自定义脚本。
内容的提问来源于stack exchange,提问作者Amid
相关产品推荐
相关产品推荐

