如何仅使用docker-compose文件在docker容器中创建数据库?

时间:2018-02-28 07:37:47

标签: postgresql docker

我正在尝试创建数据库并在我的容器网络中连接到它。我不想将ssh放入一个盒子来创建用户/数据库等,因为这不是一个可扩展或易于分发的过程。

这是我到目前为止所做的:

# docker-compose.yml
db:
    image: postgres:9.4
    volumes:
      - ./db/init.sql:/docker-entrypoint-initdb/10-init.sql
    environment:
      - PGDATA=/tmp
      - PGDATABASE=web
      - PGUSER=docker
      - PGPASSWORD=password

这是我的init.sql文件:

CREATE DATABASE web;
CREATE USER docker WITH PASSWORD 'password';
GRANT ALL PRIVILEGES ON DATABASE web TO docker;

当我启动容器并尝试连接到它时,我收到此错误:

db_1   | FATAL:  role "docker" does not exist
db_1   |  done
db_1   | server started
db_1   | FATAL:  database "web" does not exist
db_1   | psql: FATAL:  database "web" does not exist

第一次发生这种情况时,我试图创建一个这样的角色:

CREATE ROLE docker with SUPERUSER PASSWORD password;
GRANT web TO docker;

但它没有任何效果。更令人困惑的是,当我使用node-postgres连接到数据库时,我收到此错误:

Error: connect ECONNREFUSED

但是如果数据库服务甚至没有上线,怎么能拒绝连接?

简而言之,这些是我试图解决的问题:

  1. 如何仅使用项目中的文件创建数据库(即没有手动命令)?
  2. 如何仅使用项目中的文件创建用户/角色?
  3. 如何连接到此数据库?
  4. 提前谢谢。

2 个答案:

答案 0 :(得分:1)

  

如何仅使用项目中的文件创建数据库(即   没有手动命令)?

您定义的用户和数据库的最小docker-compose.yml配置为:

postgres:
    image: postgres:9.4
    environment:
      - POSTGRES_DB=web
      - POSTGRES_USER=myuser
  

如何仅使用项目中的文件创建用户/角色?

要在数据库初始化时执行脚本,请查看official docs for initdb。 为了帮助您开始快速而肮脏的解决方案,请创建一个新文件,例如init_conf.shdocker-compose.yml

位于同一目录中
#!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB" <<-EOSQL

    CREATE ROLE docker with SUPERUSER PASSWORD 'password';

EOSQL

并将volumes指令添加到docker-compose.yml

volumes:
  - .:/docker-entrypoint-initdb.d

重新创建容器,否则,您将不会触发新的数据库初始化。这意味着,在再次执行docker stop之前,docker rmdocker-compose up是旧的。 STDOUT现在为您提供有关我们新推出的脚本的一些信息。

  

如何连接到此数据库?

通过终端使用docker exec连接到您的数据库:

docker exec -ti folder_postgres_1 psql -U myuser -d web

我的一个生产环境中的docker-compose.yml如下所示:

services:
  postgres:
    logging: &logging
      driver: json-file
      options:
        max-size: "10m"
        max-file: "5"
    build: ./docker/postgres  # path to custom Dockerfile
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - postgres_backup:/backups
    env_file: .env
    restart: always

  # ... other services like web, celery, redis, etc.

Dockerfile

FROM postgres:latest

# ...
COPY *.sh /docker-entrypoint-initdb.d/
# ...

答案 1 :(得分:0)

您使用的环境变量是错误的。试试这个

version: '3.3'

services:  

  db:
    image: postgres:9.4
    restart: always
    environment: 
        - POSTGRES_USER=docker
        - POSTGRES_PASSWORD=password
        - POSTGRES_DB=web
    volumes:
      - db_data:/var/lib/postgresql/data
    # optional port
    ports: ["5555:5432"]

volumes:
  db_data:

然后从任何其他docker-compose服务,您可以访问db:5432上的数据库,如果您还添加端口,则可以从主机访问localhost:5555上的postgres