如何在Dockerfile中正确配置PostgreSQL以替代现有启动脚本?
解决PostgreSQL Dockerfile初始化用户失败的问题
问题背景
原本通过以下脚本启动PostgreSQL容器并完成用户配置:
docker run --name $CONTAINER_NAME -p 5432:5432 -e POSTGRES_PASSWORD=mypass -e POSTGRES_DB=mydb -d postgres:13.5-alpine # 人工等待数据库启动完成 sleep 10 docker exec $CONTAINER_NAME bash -c "psql --username postgres --command \"CREATE USER foo WITH SUPERUSER ENCRYPTED PASSWORD 'bar';\""
改用Dockerfile实现时,编写了如下内容却出现连接错误:
FROM postgres:13.5-alpine EXPOSE 5432 ENV POSTGRES_DB mydb ENV POSTGRES_PASSWORD mypass CMD psql --username postgres --command "CREATE USER foo WITH SUPERUSER ENCRYPTED PASSWORD 'bar';"
错误信息:
psql: error: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
错误原因
官方PostgreSQL镜像的默认CMD是启动数据库服务,自定义的CMD覆盖了这个默认行为,导致容器启动后只执行psql命令,根本没有启动PostgreSQL服务,自然无法连接。
正确配置方案
官方PostgreSQL镜像提供了初始化脚本机制:将需要执行的SQL或Shell脚本放到容器内的/docker-entrypoint-initdb.d/目录下,镜像的入口脚本会在数据库第一次启动并就绪后,自动执行这些脚本。
步骤1:创建初始化SQL脚本
新建文件init-user.sql,内容为创建用户的SQL命令:
CREATE USER foo WITH SUPERUSER ENCRYPTED PASSWORD 'bar';
步骤2:编写正确的Dockerfile
FROM postgres:13.5-alpine EXPOSE 5432 ENV POSTGRES_DB mydb ENV POSTGRES_PASSWORD mypass # 将初始化脚本复制到镜像的初始化目录 COPY init-user.sql /docker-entrypoint-initdb.d/
验证效果
构建镜像并启动容器:
docker build -t my-postgres . docker run --name my-postgres -p 5432:5432 -d my-postgres
容器启动后,会自动执行init-user.sql中的命令,无需人工等待或额外docker exec操作,完全实现原脚本的配置效果。
内容的提问来源于stack exchange,提问作者User1291
相关产品推荐
相关产品推荐

