[bash] Docker Postgres 용 스크립트에서 사용자 / 데이터베이스를 만드는 방법

사용자 정의 사용자 및 데이터베이스를 만들어 개발 postgres 인스턴스에 대한 컨테이너를 설정하려고했습니다. 공식 postgres 도커 이미지를 사용하고 있습니다. 문서에서 /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"

도커 파일

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 일부터

공식 포스트 그레스 고정 표시기 이미지 실행 .sql스크립트는에있는 /docker-entrypoint-initdb.d/폴더.

따라서 필요한 것은 다음 SQL 스크립트를 작성하는 것입니다.

init.sql

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

Dockerfile에 추가하십시오.

도커 파일

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

그러나 2015 년 7 월 8 일 이후 로 사용자와 데이터베이스를 작성 하기 만하면 POSTGRES_USER, POSTGRES_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-entrypoint-initdb.d서비스를 시작하기 전에 추가 초기화를 수행하기 위해 해당 디렉토리 [ ] 에서 찾은 * .sh 스크립트를 소싱합니다.

여기서 중요한 것은 “서비스를 시작하기 전에” 입니다. 이는 postgres 서비스가 시작되기 전에 make_db.sh 스크립트 가 실행되므로 “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


답변

이제 .sql 파일을 init 디렉토리에 넣을 수 있습니다.

문서에서

이 이미지에서 파생 된 이미지에서 추가 초기화를 수행하려면 /docker-entrypoint-initdb.d 아래에 하나 이상의 * .sql 또는 * .sh 스크립트를 추가하십시오 (필요한 경우 디렉토리 작성). 진입 점이 기본 postgres 사용자 및 데이터베이스를 작성하기 위해 initdb를 호출 한 후 서비스를 시작하기 전에 추가 초기화를 수행하기 위해 * .sql 파일을 실행하고 해당 디렉토리에있는 * .sh 스크립트를 소싱합니다.

따라서 .sql 파일을 복사하면 작동합니다.


답변

사용하여 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


답변

서비스를 시작한 후 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>

.


답변

이 명령을 사용할 수 있습니다 :

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;"


답변

사용자를 작성하기 전에 데이터베이스를 실행해야합니다. 이를 위해 여러 프로세스가 필요합니다. 쉘 스크립트의 서브 쉘 (&)에서 postgres를 시작하거나 supervisord와 같은 도구를 사용하여 postgres를 실행 한 다음 초기화 스크립트를 실행할 수 있습니다.

감독자 및 도커 가이드 https://docs.docker.com/articles/using_supervisord/


답변

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: