Jak utworzyć użytkownika / bazę danych w skrypcie dla Docker Postgres

Próbowałem skonfigurować kontener dla wystąpienia deweloperskiego postgres, tworząc niestandardową bazę danych użytkownika. Używam oficjalnego obrazu postgres docker . W dokumentacji instruuje Cię, aby wstawić skrypt bash do folderu /docker-entrypoint-initdb.d/, aby skonfigurować bazę danych z dowolnymi parametrami niestandardowymi.

Mój skrypt Basha: 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/

Błąd, który otrzymuję z docker logs -f db (db to moja nazwa kontenera) to:

Createuser: nie można połączyć się z bazą danych postgres: nie można połączyć się z serwerem: nie ma takiego pliku lub katalogu

Wygląda na to, że polecenia wewnątrz folderu /docker-entrypoint-initdb.d/ są wykonywane przed uruchomieniem postgres. Moje pytanie brzmi, jak ustawić użytkownika/bazę danych programowo przy użyciu oficjalnego kontenera postgres? Czy jest jakiś sposób, aby to zrobić ze scenariuszem?

Author: Soviut, 2014-10-28

4 answers

Edycja-od 23 lipca 2015

Oficjalny obraz postgres docker uruchomi .sql Skrypty Znalezione w folderze /docker-entrypoint-initdb.d/.

Wystarczy więc utworzyć następujący skrypt sql:

init.sql

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

I dodaj go do pliku Dockerfile:

Dockerfile

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

Ale od 8 lipca 2015 roku, jeśli wystarczy utworzyć użytkownika i bazę danych , łatwiej jest po prostu skorzystać z POSTGRES_USER, POSTGRES_PASSWORD i POSTGRES_DB zmienne środowiskowe:

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

Lub z Dockerfile:

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

Dla zdjęć starszych niż 23 lipca 2015

Z dokumentacji obrazu postgres Docker mówi się, że

[...] wywoła dowolny skrypt*. sh znaleziony w tym katalogu [/docker-entrypoint-initdb.d], aby wykonać dalszą inicjalizację przed uruchomieniem usługi

Ważne jest "przed uruchomieniem usługi" . Oznacza to, że Twój skrypt make_db.sh zostanie wykonane przed uruchomieniem usługi postgres, stąd komunikat o błędzie "nie można połączyć się z bazą danych postgres" .

Potem jest jeszcze jedna przydatna informacja:

Jeśli musisz wykonać polecenia SQL w ramach inicjalizacji, zalecane jest użycie trybu pojedynczego użytkownika Postgres.

Zgadzam się, że to może być trochę tajemnicze na pierwszy rzut oka. To, co mówi Jest to, że Twój skrypt inicjalizacyjny powinien uruchomić usługę postgres w trybie pojedynczym przed wykonaniem jej działań. Więc możesz zmienić swój make_db.KSH skrypt w następujący sposób i powinien zbliżyć cię do tego, co chcesz:

Uwaga , to zmieniło się ostatnio w następującym commicie. Będzie to działać z ostatnią zmianą:

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

Poprzednio wymagane było użycie trybu --single:

gosu postgres postgres --single <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL
 231
Author: Thomasleveil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-26 14:22:30

Możesz teraz umieścić .pliki sql w katalogu init:

From the docs

Jeśli chcesz wykonać dodatkową inicjalizację w obrazie pochodzącym z tego obrazu, Dodaj jeden lub więcej *.skrypty sql lub *.SH pod /Docker-entrypoint-initdb.d (utworzenie katalogu w razie potrzeby). Gdy entrypoint wywoła initdb, aby utworzyć domyślnego użytkownika i bazę danych postgres, uruchomi się dowolny *.pliki sql i źródła dowolnych skryptów*. sh znalezionych w tym katalogu, aby zrobić dalej inicjalizacja przed uruchomieniem usługi.

Więc Kopiuj swoje .plik sql w będzie działać.

 11
Author: m0meni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-29 16:42:44

Dodaję własne polecenia do środowiska wywołanego w CMD po uruchomieniu usług... Nie zrobiłem tego z postgres, ale z 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

I zacznij od

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

.

 5
Author: Rondo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-28 03:13:55

Musisz mieć uruchomioną bazę danych przed utworzeniem użytkowników. Do tego potrzebujesz wielu procesów. Możesz albo uruchomić postgres w subshell (&) w skrypcie powłoki, albo użyć narzędzia takiego jak supervisord, aby uruchomić postgres, a następnie uruchomić dowolne Skrypty inicjalizacyjne.

A guide to supervisord and docker https://docs.docker.com/articles/using_supervisord/

 3
Author: seanmcl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-28 00:39:41