PostgreSQL:Dockerfile 从入口脚本创建用户和数据库

3

I have a Dockerfile

COPY ./docker-entrypoint.sh /

RUN chmod +x /docker-entrypoint.sh

USER postgres

ENTRYPOINT ["/docker-entrypoint.sh"]

最初的回答中提到的docker-entrypoint.sh是什么?
#!/bin/sh

# Before PostgreSQL can function correctly, the database cluster must be initialized:
initdb -D /var/lib/postgres/data


#start postgres server
/usr/bin/postgres -D /var/lib/postgres/data &


# create a user or role
psql -d postgres -c "CREATE USER someuser WITH PASSWORD 'jkhkjah';" 

# create database 

psql -d postgres -c "CREATE DATABASE dockertest OWNER 'someuser';"

它没有创建someuser和dockertest数据库。怎么办?最初的回答是:

你能提供完整的Dockerfile(或者至少是基础镜像)吗?它为什么不工作,是在启动过程中出现错误还是在数据库日志中有错误?还是它根本没有任何反应,但镜像本身是正常工作的? - Pierre B.
图片可以正常使用。如果也尝试在后台启动PostgreSQL,但是PostgreSQL需要时间来启动。那么如何在PostgreSQL启动后才运行“create user”和“create database”命令? - Santhosh
1个回答

6

请查看官方Docker postgresql镜像

它的工作流程如下:

  1. 执行docker-entrypoint.sh
  2. 启动postgresql服务器

因此,您需要像这样修改您的Dockerfile:

COPY ./docker-entrypoint.sh /

RUN chmod +x /docker-entrypoint.sh

USER postgres

ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 5432
CMD ["postgres"]

然后按照以下方式修改您的docker-entrypoint.sh文件:

#!/bin/sh

# Before PostgreSQL can function correctly, the database cluster must be initialized:
initdb -D /var/lib/postgres/data

# internal start of server in order to allow set-up using psql-client
# does not listen on external TCP/IP and waits until start finishes
pg_ctl -D "/var/lib/postgres/data" -o "-c listen_addresses=''" -w start

# create a user or role
psql -d postgres -c "CREATE USER someuser WITH PASSWORD 'jkhkjah';" 

# create database 
psql -v ON_ERROR_STOP=1 -d postgres -c "CREATE DATABASE dockertest OWNER 'someuser';"

# stop internal postgres server
pg_ctl -v ON_ERROR_STOP=1 -D "/var/lib/postgres/data" -m fast -w stop

exec "$@"

我认为你的主要错误是在后台启动了postgresql。
/usr/bin/postgres -D /var/lib/postgres/data &

立即开始执行查询,甚至在服务器启动之前。

我还建议在psql中添加-v ON_ERROR_STOP=1参数,以查看详细信息并在发生错误时停止过程。


1
为什么我们要同时启动和停止服务器。 - Santhosh
我需要运行Postgres,因为当我使用Docker Compose时,我的Django容器需要访问它。 - Santhosh
首先,只有在“技术启动”阶段才会开始准备数据库,此时您的数据库还没有准备好接受连接,因为其模式尚未正确设置。其次是“生产”启动阶段,在此阶段中,模式已经准备就绪,我们可以开始接受连接。 - Sergey Parfenov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接