Docker撰写postgresql服务 – 在构build过程中无法创build用户和数据库?

我浪费了整整一天的时间,并且说我对简单的任务不必要的复杂性印象深刻 – 这完全是轻描淡写的。

好吧,从我的胸前就知道了,我正在用本教程构build一个使用docker-machine,docker-compose,postgresql和redis的django应用程序。

我已经设法使基本教程工作 – 但它不符合我的需要,因为我需要为我的应用程序创build一个用户和一个数据库 – 而不是使用两个“postgres”。

我使用了@dnephin的答案来解决类似的问题 ,并修改了我的代码,如下所示:

我在一个新目录中创build了一个新的Dockerfile ./database/

 FROM postgres:9.6 COPY . /fixtures WORKDIR /fixtures RUN /fixtures/setup.sh 

./database/setup.sh内容:

 #!/bin/bash set -e pg_createcluster 9.6 main --start /etc/init.d/postgresql start su - postgres # makes no effing difference ... psql -f create_fixtures.sql /etc/init.d/postgresql stop 

./database/create_fixtures.sql内容:

 CREATE DATABASE mydatabase WITH ENCODING 'UTF8'; CREATE USER webuser ENCRYPTED PASSWORD 'deadbeefsnaf0' NOSUPERUSER NOCREATEDB NOCREATEROLE; GRANT ALL PRIVILEGES ON mydatabase TO webuser; 

最后我在docker_compose.yml中的postgres服务被修改为使用build:

 postgres: build: ./database/ ... 

当我运行docker-compose build ,构build会通过运动,然后在通过psql导入SQL fixtures文件的位置执行barfs

 frothing@themouth:~/path/to/directory$ docker-compose build redis uses an image, skipping Building postgres Step 1/4 : FROM postgres:9.6 ---> ff0943ecbb3c Step 2/4 : COPY . /fixtures ---> fae19dc88da8 Removing intermediate container 84b860aee55c Step 3/4 : WORKDIR /fixtures ---> aa88438dc69f Removing intermediate container b801ddc3b374 Step 4/4 : RUN /fixtures/setup.sh ---> Running in ca3e89ec2460 Creating new cluster 9.6/main ... config /etc/postgresql/9.6/main data /var/lib/postgresql/9.6/main locale en_US.utf8 socket /var/run/postgresql port 5432 Starting PostgreSQL 9.6 database server: main. psql: FATAL: role "root" does not exist ERROR: Service 'postgres' failed to build: The command '/bin/sh -c /fixtures/setup.sh' returned a non-zero code: 2 

我试图解决这个使用docker for postgresql服务的无用的文档 – 但没有得到的地方。

我该如何解决这个问题?

卷在构build时不可用。 您可以在脚本中创build/var/lib/postgresql/data ,但是它将被postgres:9.6映像中的VOLUME /var/lib/postgresql/data覆盖。

在你的情况下:只需使用下面的docker文件:

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

一旦容器启动,它们会自动执行。 这里是一个例子:

 $ docker run -d --name mydb -p 33306:3306 yourtag $ docker exec -ti mydb psql -U postgres postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges ------------+----------+----------+------------+------------+----------------------- mydatabase | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =Tc/postgres + | | | | | postgres=CTc/postgres+ | | | | | webuser=CTc/postgres postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres (4 rows) 

过时的回答:

你的脚本应该在一个容器上工作除了你必须执行psql这样的夹具:

 su postgres -c "psql -f create_fixtures.sql" 

su --login postgres不起作用,因为postgres不能打开bash或shell。 你可以试试docker run --rm -ti postgres:9.6 bash

对不起,我必须告诉你,你的SQL脚本中还有一个错误:在GRANT ALL PRIVILEGES ON DATABASE mydatabase TO webuser – 关键字DATABASE在这里是必要的。

这是一个完整的日志我如何testing,并可以确认这个作品:

 docker run --rm -ti postgres:9.6 bash root@be03ab1eb704:/# cat > test.sql <<EOF > CREATE DATABASE mydatabase WITH ENCODING 'UTF8'; > CREATE USER webuser ENCRYPTED PASSWORD 'asdf123' NOSUPERUSER NOCREATEDB NOCREATEROLE; > GRANT ALL PRIVILEGES ON DATABASE mydatabase TO webuser; > EOF root@be03ab1eb704:/# pg_createcluster 9.6 main --start Creating new PostgreSQL cluster 9.6/main ... /usr/lib/postgresql/9.6/bin/initdb -D /var/lib/postgresql/9.6/main --auth-local peer --auth-host md5 The files belonging to this database system will be owned by user "postgres". This user must also own the server process. The database cluster will be initialized with locale "en_US.utf8". The default database encoding has accordingly been set to "UTF8". The default text search configuration will be set to "english". Data page checksums are disabled. fixing permissions on existing directory /var/lib/postgresql/9.6/main ... ok creating subdirectories ... ok selecting default max_connections ... 100 selecting default shared_buffers ... 128MB selecting dynamic shared memory implementation ... posix creating configuration files ... ok running bootstrap script ... ok performing post-bootstrap initialization ... ok syncing data to disk ... ok Success. You can now start the database server using: /usr/lib/postgresql/9.6/bin/pg_ctl -D /var/lib/postgresql/9.6/main -l logfile start Ver Cluster Port Status Owner Data directory Log file 9.6 main 5432 online postgres /var/lib/postgresql/9.6/main /var/log/postgresql/postgresql-9.6-main.log root@be03ab1eb704:/# /etc/init.d/postgresql start [ ok ] Starting PostgreSQL 9.6 database server: main. root@be03ab1eb704:/# su postgres -c "psql -f test.sql" CREATE DATABASE CREATE ROLE GRANT root@be03ab1eb704:/# /etc/init.d/postgresql stop [ ok ] Stopping PostgreSQL 9.6 database server: main. root@be03ab1eb704:/# exit exit 

官方postgresql docker镜像在容器的第一次启动时自动导入脚本。 所以,如果你用你的init sql脚本将目录挂载到容器path“/docker-entrypoint-initdb.d/”,它应该运行。

例如,如果您有导入脚本myImport.sql,并且它位于/ opt / import目录中的主机上,那么可以将容器启动时的导入目录挂载到您的postgres映像中,以/docker-entrypoint-initdb.d和sql文件将在初始数据库设置后执行。

 docker run -p $toHostParam:5432 -e POSTGRES_PASSWORD="$dbPwd" \ -e POSTGRES_USER="$dbUser" \ -e POSTGRES_DB="$dbName" \ -e PGDATA=/opt/pgdata \ -v ${dataDir}:/opt/pgdata \ # look here # mount of local import dir -v /opt/import:/docker-entrypoint-initdb.d \ postgres:9.6 

看看这里的postgesql图像启动脚本(从第126行): https : //github.com/docker-library/postgres/blob/master/9.6/docker-entrypoint.sh

如果你想要一个特定的数据库用户或数据库,你也可以使用环境variables定制你的postgresql容器。

查看“环境variables”部分: https : //hub.docker.com/_/postgres/

试试这个setup.sh

 #!/bin/bash set -e pg_createcluster 9.6 main --start su postgres sh -c "/etc/init.d/postgresql start && psql -f create_fixtures.sql && /etc/init.d/postgresql stop" 

运行psql时尝试显式用户:

 psql -U postgres -f create_fixtures.sql