it-swarm.com.de

So erstellen Sie einen Benutzer / eine Datenbank in einem Skript für Docker Postgres

Ich habe versucht, einen Container für eine postgres-Entwicklungsinstanz einzurichten, indem ich einen benutzerdefinierten Benutzer und eine benutzerdefinierte Datenbank erstellt habe. Ich verwende das offizielles Postgres Docker-Bild . In der Dokumentation werden Sie angewiesen, ein Bash-Skript in das /docker-entrypoint-initdb.d/ Ordner zum Einrichten der Datenbank mit benutzerdefinierten Parametern.

Mein Bash-Skript: 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/

Den Fehler bekomme ich vom docker logs -f db (db ist mein Containername) ist:

createuser: Verbindung zur Datenbank konnte nicht hergestellt werden postgres: Verbindung zum Server konnte nicht hergestellt werden: Keine solche Datei oder kein solches Verzeichnis

Es scheint, dass die Befehle innerhalb der /docker-entrypoint-initdb.d/ Ordner werden ausgeführt, bevor Postgres gestartet wird. Meine Frage ist, wie richte ich einen Benutzer/eine Datenbank programmgesteuert unter Verwendung des offiziellen Postgres-Containers ein? Gibt es eine Möglichkeit, dies mit einem Skript zu tun?

168
pech0rin

EDIT - seit dem 23. Juli 2015

Das offizielles Postgres Docker Image wird .sql Skripte in der /docker-entrypoint-initdb.d/ Mappe.

Sie müssen also nur das folgende SQL-Skript erstellen:

init.sql

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

und füge es in dein Dockerfile ein:

Dockerfile

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

Aber seit dem 8. Juli 2015 ist es einfacher, einen Benutzer und eine Datenbank zu erstellen, als nur das POSTGRES_USER, POSTGRES_PASSWORD und POSTGRES_DB Umgebungsvariablen:

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

oder mit einem Dockerfile:

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

für Bilder, die älter als der 23. Juli 2015 sind

Von der Dokumentation des postgres Docker-Bildes wird gesagt, dass

[...] es wird ein beliebiges * .sh-Skript in diesem Verzeichnis [/docker-entrypoint-initdb.d], um vor dem Starten des Dienstes eine weitere Initialisierung durchzuführen

Wichtig ist hier "vor dem Start des Dienstes". Dies bedeutet, dass Ihr Skript make_db.sh ausgeführt wird, bevor der postgres-Dienst gestartet wird, daher die Fehlermeldung "Konnte keine Verbindung zur Datenbank postgres herstellen".

Danach gibt es eine weitere nützliche Information:

Wenn Sie im Rahmen Ihrer Initialisierung SQL-Befehle ausführen müssen, wird die Verwendung des Postgres-Einzelbenutzermodus dringend empfohlen.

Einigermaßen kann dies auf den ersten Blick etwas rätselhaft sein. Es heißt, dass Ihr Initialisierungsskript den postgres-Dienst im Einzelmodus starten sollte, bevor Sie seine Aktionen ausführen. Sie könnten also Ihr make_db.ksh Skript wie folgt ändern und es sollte Sie näher an das bringen, was Sie wollen:

[~ # ~] beachte [~ # ~] , dies hat sich kürzlich geändert im folgenden Commit . Dies funktioniert mit der neuesten Änderung:

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

Zuvor war die Verwendung von --single Modus wurde benötigt:

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

Sie können jetzt .sql-Dateien in das init-Verzeichnis einfügen:

Aus den Dokumenten

Wenn Sie in einem von diesem Image abgeleiteten Image eine zusätzliche Initialisierung durchführen möchten, fügen Sie unter /docker-entrypoint-initdb.d ein oder mehrere * .sql- oder * .sh-Skripts hinzu (erstellen Sie das Verzeichnis, falls erforderlich). Nachdem der Entypoint initdb aufgerufen hat, um den Standardbenutzer und die Standarddatenbank von postgres zu erstellen, werden alle * .sql-Dateien ausgeführt und alle in diesem Verzeichnis gefundenen * .sh-Skripten als Quelle für die weitere Initialisierung verwendet, bevor der Dienst gestartet wird.

Das Kopieren Ihrer .sql-Datei in wird also funktionieren.

15
m0meni

Ich füge benutzerdefinierte Befehle zu einer Umgebung hinzu, die in einer CMD nach dem Starten von Diensten aufgerufen wurde ... Ich habe es nicht mit postgres gemacht, sondern mit 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

und beginne mit

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

.

8
Rondo

Die Datenbank muss ausgeführt werden, bevor Sie die Benutzer erstellen. Dafür benötigen Sie mehrere Prozesse. Sie können postgres entweder in einer Subshell (&) im Shell-Skript starten oder ein Tool wie supervisord verwenden, um postgres auszuführen und dann alle Initialisierungsskripten auszuführen.

Eine Anleitung für Supervisord und Docker https://docs.docker.com/articles/using_supervisord/

3
seanmcl

Sie können diese Befehle verwenden:

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