Docker构成postgresql服务 - 在构建期间无法创建用户和数据库?

时间:2017-05-05 18:07:51

标签: postgresql docker docker-compose psql

我浪费了整整一天的时间,并且说我不会对应该是一项简单的任务的不必要的复杂性留下深刻的印象 - 这将是一种严重的轻描淡写。

好的,从我的胸口开始,我正在使用docker-machine,docker-compose,postgresql和redis构建一个django应用程序 - 按照this tutorial

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

我已将@dnephin的答案用于similar question,并按如下方式修改了我的代码:

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

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时,构建将通过 psql > 向 psql 导入SQL fixtures文件进行运动然后 barfs p>

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

我试图用useless documentation on docker for postgresql service来解决这个问题 - 但是没有找到。

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:4)

在构建时无法使用卷。您可以在脚本中创建/var/lib/postgresql/data,但VOLUME /var/lib/postgresql/data图像会覆盖postgres:9.6

在您的情况下:只需使用以下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

以下是我测试的完整日志,可以确认其有效:

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

答案 1 :(得分:1)

官方postgresql docker镜像会在容器的第一次启动时自动导入脚本。因此,如果使用init sql脚本将目录挂载到容器路径'/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

如果您需要特定的db用户或数据库,还可以使用环境变量自定义postgresql容器。

请点击此处的“环境变量”部分:https://hub.docker.com/_/postgres/

答案 2 :(得分:0)

尝试使用此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"

答案 3 :(得分:0)

运行psql时尝试显式用户:

psql -U postgres -f create_fixtures.sql