我一直试图通过创建自定义用户和数据库来为开发postgres实例设置一个容器。我使用的是官方postgres docker映像。在文档中,它指导你在/docker-entrypoint-initdb中插入一个bash脚本。D /文件夹,使用任何自定义参数设置数据库。

我的bash脚本:make_db.sh

su postgres -c "createuser -w -d -r -s docker"
su postgres -c "createdb -O docker docker"

Dockerfile

FROM library/postgres

RUN ["mkdir", "/docker-entrypoint-initdb.d"]
ADD make_db.sh /docker-entrypoint-initdb.d/

我从docker日志-f db (db是我的容器名)得到的错误是:

postgres:不能连接到服务器:没有这样的文件或目录

看起来/docker-entrypoint-initdb. conf文件中的命令。在postgres启动之前,正在执行D /文件夹。我的问题是,如何使用官方postgres容器以编程方式设置用户/数据库?有什么方法可以用脚本来做到这一点吗?


当前回答

在创建用户之前,需要运行数据库。为此,您需要多个进程。您可以在shell脚本中的subshell(&)中启动postgres,也可以使用类似于supervisor ord的工具来运行postgres,然后运行任何初始化脚本。

superord和docker指南https://docs.docker.com/articles/using_supervisord/

其他回答

使用docker-compose:

假设你有以下目录布局:

$MYAPP_ROOT/docker-compose.yml
           /Docker/init.sql
           /Docker/db.Dockerfile

文件:docker-compose.yml

version: "3.3"
services:
  db:
    build:
      context: ./Docker
      dockerfile: db.Dockerfile
    volumes:
      - ./var/pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

文件:码头工人/ init.sql

CREATE USER myUser;

CREATE DATABASE myApp_dev;
GRANT ALL PRIVILEGES ON DATABASE myApp_dev TO myUser;

CREATE DATABASE myApp_test;
GRANT ALL PRIVILEGES ON DATABASE myApp_test TO myUser;

文件:码头工人/ db。Dockerfile

FROM postgres:11.5-alpine
COPY init.sql /docker-entrypoint-initdb.d/

组合和启动服务:

docker-compose -f docker-compose.yml up --no-start
docker-compose -f docker-compose.yml start

在创建用户之前,需要运行数据库。为此,您需要多个进程。您可以在shell脚本中的subshell(&)中启动postgres,也可以使用类似于supervisor ord的工具来运行postgres,然后运行任何初始化脚本。

superord和docker指南https://docs.docker.com/articles/using_supervisord/

这是我的dock -compose.yml

   postgres:
    image: postgres:latest
    ports:
      - 5432:5432
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ${PROJECTDIR}/init.sql:/docker-entrypoint-initdb.d/1-schema.sql
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_DB=postgres
      - POSTGRES_PASSWORD=postgres

这里有两件事你需要考虑:

docker-entrypoint-initdb。D只在数据字典为空时才能工作。所以如果你有卷,一定要删除它们docker-compose down -volumes。 在init中创建用户和数据库。用SQL代替dock -compose.yml。在docker-compose。Yml,您应该指定postgres用户。

使用Postgres最新的镜像(ID: b262c8b2fb54)和Docker 20.10.6版本,Docker -compose看起来是这样的:

version: '2'

services:
  app:
    # the detail of app
  db:
    image: 'postgres'
    container_name: book-shop-db-postgres
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=bookshop-db

这将创建启动时提到的用户和数据库

你现在可以把.sql文件放在init目录中:

来自文档

如果您想在此图像派生的图像中进行额外的初始化,请添加一个或多个*。/docker-entrypoint-initdb下的SQL或*.sh脚本。D(如果需要,创建目录)。在入口点调用initdb创建默认的postgres用户和数据库之后,它将运行任何*。SQL文件和源目录中找到的任何*.sh脚本,在启动服务之前进行进一步的初始化。

所以复制你的.sql文件就可以了。