在postgres中以单用户模式创build表

我试图从postgres图像创build一个Dockerfile。 回购说,应该通过在/docker-entrypoint-initdb.d/中放置一个shell脚本来处理初始化。 我根据我在网上find的一个例子,把下面的脚本:

#!/bin/bash echo "******CREATING DOCKER DATABASE******" gosu postgres postgres --single <<- EOSQL CREATE DATABASE orpheus; CREATE USER docker WITH ENCRYPTED PASSWORD 'pwd_docker'; GRANT ALL PRIVILEGES ON DATABASE orpheus to docker; CREATE TABLE profiles ( \ profile_id SERIAL UNIQUE PRIMARY KEY, \ user_id integer NOT NULL UNIQUE, \ profile_photo_id integer NOT NULL UNIQUE, \ age integer \ ); CREATE TABLE hidden_user ( \ owner_id integer NOT NULL PRIMARY KEY, \ target_id integer NOT NULL \ ); EOSQL echo "" echo "******DOCKER DATABASE CREATED******" 

反斜杠似乎需要,否则我得到一个parsing错误。 该脚本运行时没有错误,除了CREATE TABLE命令之外的所有命令似乎都有效果。

单用户模式下不支持表创build吗? 如果是这样,是否有一个更好的方式有一个dockerfilebuild立一个图像在Postgres中创build的表?

@a_horse_with_no_name让我在正确的轨道上发表评论。 即使是“推荐”,我也决定放弃单用户模式。 相反,我用pg_ctl启动postgres,加载一些包含我的表创build的sql文件,然后用pg_ctl停止服务器。

我的shell脚本如下所示:

 #!/bin/bash echo "******CREATING DOCKER DATABASE******" echo "starting postgres" gosu postgres pg_ctl -w start echo "bootstrapping the postgres db" gosu postgres psql -h localhost -p 5432 -U postgres -a -f /db/bootstrap.sql echo "initializing tables" gosu postgres psql -h localhost -p 5432 -U postgres -d orpheus -a -f /db/setup.sql echo "stopping postgres" gosu postgres pg_ctl stop echo "stopped postgres" echo "" echo "******DOCKER DATABASE CREATED******" 

如果你想阻止PostgreSQL在你需要执行的任何设置之前被用户访问,那么只需要以回送访问或者只有一个unix套接字来启动PostgreSQL,进行初始化,然后重新启动它以进行一般访问。

我不会说Docker,但是如果你是在一个普通的环境中做这个事情,你可以这样做:

 mkdir -p /db/temp_socket chown -r postgres:postgres /db PGHOST=/db/temp_socket pg_ctl -D /path/to/datadir -o "-c listen_addresses='' -c unix_socket_directories='/db/temp_socket'" -l "/db/dbsetup.log" -w start # Do your work PGHOST=/db/temp_socket psql -f some_script PGHOST=/db/temp_socket pg_ctl -D /path/to/datadir -m fast -w stop pg_ctl -D /path/to/datadir -w start ...normalstartupoptionsblah... 

即启动PostgreSQL不在任何TCP / IP套接字上侦听,并使用非默认的unix_socket_directories 。 做你的设置。 然后使用默认(或已configuration的) unix_socket_directorieslisten_addresses重新启动它,一旦准备好进行一般访问。

相反,你可以:

  • 修改pg_hba.conf只允许你的设置用户访问/只在环回地址/ etc
  • 开始
  • 做你的设置
  • 用生产版本replacepg_hba.conf
  • pg_ctl reloadSELECT pg_reload_conf()加载新设置并允许一般访问

…但是这将允许应用程序连接,然后在设置阶段拒绝他们的authentication; 这可能不是你想要的,并不是所有的应用程序都能正确处理这个问题。

我testing了你的脚本,它几乎工作正常。 使用PostgreSQL 9.4我设法使以下工作:

 gosu postgres postgres --single -jE <<- EOSQL CREATE DATABASE orpheus; EOSQL echo gosu postgres postgres --single -jE orpheus <<- EOSQL CREATE USER docker WITH ENCRYPTED PASSWORD 'pwd_docker'; GRANT ALL PRIVILEGES ON DATABASE orpheus to docker; CREATE TABLE profiles ( profile_id SERIAL UNIQUE PRIMARY KEY, user_id integer NOT NULL UNIQUE, profile_photo_id integer NOT NULL UNIQUE, age integer ); CREATE TABLE hidden_user ( owner_id integer NOT NULL PRIMARY KEY, target_id integer NOT NULL ); EOSQL echo 

基本上我不得不将脚本拆分为两个,因为postgresql抱怨create database不能在多行脚本中使用。 另一个只是在第二个命令上添加数据库名称orpheus