我正在尝试在Docker容器中设置PostgreSQL。我需要创建两个用户和多个数据库。
Frame
pgdb/
Dockerfile
sql/
ext_cfuncs/
sprocs/
init.sql
db_init_data_globals.sql
...
FROM library/postgres:9.6
COPY sql /docker-entrypoint-initdb.d/
我能够成功构建图像。当我运行docker run -it`时,这里是控制台输出的片段:
-- ##############################################
-- # #
-- # 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;
为什么找不到文件****************************************************
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
?它与init.sql在同一个文件夹中!
另外,为什么每次db_init_data_globals.sql
命令时都会创建数据库,表等?我认为初始化是在容器的构建过程中完成的吗?
答案 0 :(得分:1)
我怀疑您的错误是由\i
命令的行为引起的:
\ i或\ include filename
从文件文件名中读取输入和 像在键盘上输入一样执行它。
从library/postgres:9.6 docker-entrypoint.sh file可以看出,.sql
文件是使用psql -f
(作为脚本)执行的。每个包含的文件is expected to be in psql's current working directory。
您应该使用\ir
:
\ ir或\ include_relative filename
\ir
命令类似于\i
, 但以不同方式解析相对文件名。执行时 在交互模式下,这两个命令的行为相同。 但是,何时 从脚本调用,\ir
解释相对于。的文件名 脚本所在的目录,而不是当前目录 工作目录。
来源:Postgres doc。
如果您需要使用旧版本的Postgres,check this answer。