Docker Compose部署PostgreSQL时初始化脚本‘文件未找到’问题排查
解决PostgreSQL Docker容器初始化脚本"required file not found"问题
问题场景
通过Docker Compose部署PostgreSQL 11.20-alpine容器,将本地./scripts目录挂载到容器内/docker-entrypoint-initdb.d/,期望执行init-a.sh(创建角色、数据库并分配权限)、init-b.sh(恢复backup.dump备份),但日志提示init-a.sh文件找不到,修改目录和文件名后问题仍存在。
排查与解决步骤
1. 确认挂载路径与文件存在性
- 确保
./scripts目录与Docker Compose文件在同一目录下,且目录内确实存在init-a.sh、init-b.sh和backup.dump - 执行
ls -l ./scripts检查本地文件是否存在,避免拼写错误
2. 修复文件权限
- 本地脚本必须拥有可执行权限,执行命令:
chmod +x ./scripts/init-a.sh ./scripts/init-b.sh - 确保本地目录和文件的权限允许Docker读取(避免用root权限创建后容器无法访问)
3. 检查Docker Compose挂载配置
确保volumes配置正确,示例如下:
version: '3.8' services: postgres: image: postgres:11.20-alpine environment: POSTGRES_PASSWORD: your_db_password volumes: # 挂载本地脚本目录到容器初始化目录 - ./scripts:/docker-entrypoint-initdb.d # 持久化数据库数据 - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" volumes: postgres_data:
4. 验证容器内挂载状态
启动容器后,执行以下命令查看容器内初始化目录的文件:
docker exec -it <你的容器名> ls -l /docker-entrypoint-initdb.d/
如果看不到文件,说明挂载路径错误,需修正Compose中的相对路径(比如用绝对路径测试:/home/user/scripts:/docker-entrypoint-initdb.d)
5. 修正脚本shebang
Alpine镜像使用ash shell,脚本开头需指定正确的shebang:
#!/bin/sh
避免使用#!/bin/bash(Alpine默认未安装bash)
正确脚本示例
init-a.sh
#!/bin/sh set -e # 用默认postgres超级用户执行数据库初始化 psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL CREATE ROLE app_user WITH LOGIN PASSWORD 'app_user_pass'; CREATE DATABASE app_db; GRANT ALL PRIVILEGES ON DATABASE app_db TO app_user; EOSQL
init-b.sh
#!/bin/sh set -e # 恢复backup.dump到指定数据库 pg_restore -v --username "$POSTGRES_USER" --dbname app_db /docker-entrypoint-initdb.d/backup.dump
关键注意事项
- 初始化脚本仅在第一次创建数据库卷时执行,若之前已启动过容器,需先删除数据卷再重启:
docker volume rm <你的项目名>_postgres_data - 脚本执行顺序按文件名排序,确保
init-a.sh在init-b.sh之前执行(已按文件名前缀保证) - 确认
backup.dump是PostgreSQL 11兼容的备份文件,避免版本不兼容导致恢复失败
内容的提问来源于stack exchange,提问作者Alexandre Gonçalves Lopes
相关产品推荐
相关产品推荐

