簡體   English   中英

如何在 Docker Postgres 的腳本中創建用戶/數據庫

[英]How to create User/Database in script for Docker Postgres

我一直在嘗試通過創建自定義用戶和數據庫來為開發 postgres 實例設置容器。 我正在使用官方的 postgres docker 圖像 在文檔中,它指示您在/docker-entrypoint-initdb.d/文件夾中插入 bash 腳本,以使用任何自定義參數設置數據庫。

我的 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 logs -f db (db 是我的容器名稱)得到的錯誤是:

createuser:無法連接到數據庫 postgres:無法連接到服務器:沒有這樣的文件或目錄

似乎/docker-entrypoint-initdb.d/文件夾中的命令在 postgres 啟動之前正在執行。 我的問題是,如何使用官方的 postgres 容器以編程方式設置用戶/數據庫? 有沒有辦法用腳本做到這一點?

編輯 - 自2015年7月23日起

官方postgres /docker-entrypoint-initdb.d/ 鏡像將運行/docker-entrypoint-initdb.d/文件夾中的.sql腳本。

所以你需要的是創建以下sql腳本:

init.sql

CREATE USER docker;
CREATE DATABASE docker;
GRANT ALL PRIVILEGES ON DATABASE docker TO docker;

並將其添加到Dockerfile中:

Dockerfile

FROM library/postgres
COPY init.sql /docker-entrypoint-initdb.d/

但是從2015年7月8日開始, 如果你只需要創建一個用戶和數據庫 ,就可以更容易地使用POSTGRES_USERPOSTGRES_PASSWORDPOSTGRES_DB環境變量:

docker run -e POSTGRES_USER=docker -e POSTGRES_PASSWORD=docker -e POSTGRES_DB=docker library/postgres

或者使用Dockerfile:

FROM library/postgres
ENV POSTGRES_USER docker
ENV POSTGRES_PASSWORD docker
ENV POSTGRES_DB docker

適用於2015年7月23日之前的圖片

postgres Docker圖像的文檔來看 ,據說

[...]它將在該目錄[ /docker-entrypoint-initdb.d ]中找到任何* .sh腳本,以便在啟動服務之前進行進一步的初始化

這里重要的是“在開始服務之前” 這意味着您的腳本make_db.sh將在postgres服務啟動之前執行,因此錯誤消息“無法連接到數據庫postgres”

之后還有另一個有用的信息:

如果您需要在初始化過程中執行SQL命令,強烈建議使用Postgres單用戶模式。

同意這在初看時可能有點神秘。 它說的是你的初始化腳本應該在執行其操作之前以單一模式啟動postgres服務。 因此,您可以按照以下方式更改make_db.ksh腳本,它可以讓您更接近您想要的內容:

注意 ,這在最近的提交中已經改變 這將適用於最新的變化:

export PGUSER=postgres
psql <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

以前,需要使用--single模式:

gosu postgres postgres --single <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

通過使用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"

文件: Docker/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;

文件: Docker/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

使用 docker compose 有一個簡單的替代方案(無需創建 Dockerfile)。 只需創建一個 init-database.sh:

#!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
    CREATE USER docker;
    CREATE DATABASE my_project_development;
    GRANT ALL PRIVILEGES ON DATABASE my_project_development TO docker;
    CREATE DATABASE my_project_test;
    GRANT ALL PRIVILEGES ON DATABASE my_project_test TO docker;
EOSQL

並在卷部分引用它:

version: '3.4'

services:
  postgres:
    image: postgres
    restart: unless-stopped
    volumes:
      - postgres:/var/lib/postgresql/data
      - ./init-database.sh:/docker-entrypoint-initdb.d/init-database.sh
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - 5432:5432

volumes:
  postgres:

您現在可以將.sql文件放在init目錄中:

來自文檔

如果您想在從這個映像派生的映像中進行其他初始化,請在/docker-entrypoint-initdb.d下添加一個或多個* .sql或* .sh腳本(必要時創建目錄)。 在入口點調用initdb創建默認的postgres用戶和數據庫之后,它將運行任何* .sql文件,並在該目錄中找到任何* .sh腳本,以便在啟動服務之前進行進一步的初始化。

因此,復制.sql文件將起作用。

我在啟動服務之后將自定義命令添加到CMD中引發的環境中...我沒有使用postgres,而是使用Oracle:

#set up var with noop command
RUN export POST_START_CMDS=":"
RUN mkdir /scripts
ADD script.sql /scripts
CMD service oracle-xe start; $POST_START_CMDS; tail -f /var/log/dmesg

並開始

docker run -d ... -e POST_START_CMDS="su - oracle -c 'sqlplus @/scripts/script' " <image>

使用 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

這將創建啟動時提到的用戶和數據庫

在創建用戶之前,您需要運行數據庫。 為此,您需要多個流程。 您可以在shell腳本的子shell(&)中啟動postgres,也可以使用supervisord之類的工具來運行postgres,然后運行任何初始化腳本。

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

您可以使用以下命令:

docker exec -it yournamecontainer psql -U postgres -c "CREATE DATABASE mydatabase ENCODING 'LATIN1' TEMPLATE template0 LC_COLLATE 'C' LC_CTYPE 'C';"

docker exec -it yournamecontainer psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE postgres TO postgres;"

這是我的docke-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

以下是您需要考慮的兩件事:

  1. docker-entrypoint-initdb.d僅在您的數據字典為空時有效。 因此,如果您有卷,請務必刪除它們docker-compose down --volumes

  2. init.sql而不是docke-compose.yml中創建您的用戶和數據庫。 docker-compose.yml中,您應該指定postgres用戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM