docker-entrypoint-initdb.d'中的Docker PostgreSQL初始化脚本无法导入文件

我正在尝试在Docker容器中设置PostgreSQL。 我需要创build两个用户和多个数据库。

目录结构

pgdb/ Dockerfile sql/ ext_cfuncs/ sprocs/ init.sql db_init_data_globals.sql ... 

Dockerfile的内容

 FROM library/postgres:9.6 COPY sql /docker-entrypoint-initdb.d/ 

init.sql

 -- ############################################## -- # # -- # Create users # -- # # -- ############################################## -- Create superuser -- need to be a superuser n order to create functions in C etc CREATE ROLE dbuser1 ENCRYPTED PASSWORD '<redacted>' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN; -- Create dbuser2 CREATE ROLE dbuser2 ENCRYPTED PASSWORD '<redacted'; CREATE DATABASE refglobals WITH ENCODING 'UTF8' TEMPLATE template0; GRANT ALL PRIVILEGES ON DATABASE refglobals TO dbuser2; GRANT ALL PRIVILEGES ON DATABASE refglobals TO dbuser1; -- Import refglobals and news initial data \c refglobals; \i db_init_data_globals.sql; # Create database to be used as template for other databases CREATE DATABASE foobar WITH ENCODING 'UTF8' TEMPLATE template0; \c foobar; CREATE LANGUAGE 'plpgsql'; CREATE EXTENSION quantile; -- # enable python in database -- # http://www.vertabelo.com/blog/technical-articles/playing-around-with-python-in-postgresql -- # /github.com/ihuston/plpython_examples/blob/master/simple_examples.sql CREATE PROCEDURAL LANGUAGE 'plpythonu' HANDLER plpython_call_handler; UPDATE pg_language SET lanpltrusted = true WHERE lanname LIKE 'plpythonu'; \i db_schema_foobar.sql; \i ext_cfuncs/funcs_scanners_internal.sql; 

我能够成功地build立图像。 当我运行docker run -it`,这里是控制台输出的一个片段:

 **************************************************** WARNING: No password has been set for the database. This will allow anyone with access to the Postgres port to access your database. In Docker's default configuration, this is effectively any other container on the same system. Use "-e POSTGRES_PASSWORD=password" to set it in "docker run". **************************************************** waiting for server to start....LOG: could not bind IPv6 socket: Cannot assign requested address HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry. LOG: database system was shut down at 2017-09-27 20:37:08 UTC LOG: MultiXact member wraparound protections are now enabled LOG: autovacuum launcher started LOG: database system is ready to accept connections done server started ALTER ROLE /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/create_databases.sql CREATE ROLE CREATE ROLE CREATE DATABASE GRANT GRANT You are now connected to database "refglobals" as user "postgres". psql:/docker-entrypoint-initdb.d/init.sql:19: db_init_data_globals.sql: No such file or directory 

为什么找不到文件db_init_data_globals.sql ? 它与init.sql在同一个文件夹中!

另外,为什么每次run命令时都会创build数据库,表等? 我认为初始化是在build造集装箱期间完成的?

我怀疑你的错误是由\i命令的行为引起的:

\ i或\ include文件名

从文件的文件名中读取input,并像在键盘上input一样执行它。

从库/ postgres中可以看到:9.6 docker-entrypoint.sh文件 , .sql文件是使用psql -f (作为脚本)执行的。 预计每个包含的文件都在psql的当前工作目录中 。

你应该使用\ir

\ ir或\ include_relative文件名

\ir命令与\i类似,但以不同的方式parsing相对文件名。 在交互模式下执行时,这两个命令的行为是相同的。 但是,从脚本调用时, \ir将解释与脚本所在的目录相关的文件名,而不是当前的工作目录

来源: Postgres文档 。

如果你需要使用老版本的Postgres, 请检查这个答案 。