381 Stimmen

Wie erstellt man Benutzer/Datenbank im Skript für Docker Postgres

Ich habe versucht, einen Container für eine Entwicklungs-Postgres-Instanz einzurichten, indem ich einen benutzerdefinierten Benutzer & Datenbank erstelle. Ich verwende das offizielle Postgres Docker-Image. In der Dokumentation wird darauf hingewiesen, dass ein Bash-Skript in den /docker-entrypoint-initdb.d/-Ordner eingefügt werden muss, um die Datenbank mit benutzerdefinierten Parametern einzurichten.

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/

Der Fehler, den ich von den docker logs -f db (db ist mein Containername) erhalte, ist:

createuser: konnte keine Verbindung zur Datenbank postgres herstellen: konnte keine Verbindung zum Server herstellen: Keine Datei oder Verzeichnis

Es scheint, dass die Befehle innerhalb des /docker-entrypoint-initdb.d/-Ordners ausgeführt werden, bevor Postgres gestartet wird. Meine Frage ist, wie richte ich einen Benutzer/Datenbank programmatisch mit dem offiziellen Postgres-Container ein? Gibt es einen Weg, dies mit einem Skript zu tun?

12voto

haojie Punkte 665

Dies ist meine docker-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

Hier sind zwei Dinge, die Sie beachten müssen:

  1. docker-entrypoint-initdb.d funktioniert nur, wenn Ihr Datenverzeichnis leer ist. Wenn Sie also Volumes haben, stellen Sie sicher, dass Sie sie löschen docker-compose down --volumes.

  2. Erstellen Sie Ihren Benutzer und die Datenbank in der init.sql anstatt in der docke-compose.yml. In der docker-compose.yml sollten Sie den Benutzer postgres angeben.

10voto

Mit dem neuesten Postgres-Image (ID: b262c8b2fb54) und Docker-Version 20.10.6 sieht das Docker-Compose wie folgt aus:

version: '2'

services:
  app:
    # die Details der App
  db:
    image: 'postgres'
    container_name: book-shop-db-postgres
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=bookshop-db

Dies wird den Benutzer und die Datenbanken erstellen, wie oben erwähnt, während des Starts

8voto

Rondo Punkte 3100

Ich füge benutzerdefinierte Befehle zu einer Umgebung hinzu, die in einer CMD aufgerufen wird, nachdem Dienste gestartet wurden... Ich habe es nicht mit Postgres gemacht, sondern mit Oracle:

# Setze Variable mit Noop-Befehl
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 starte mit

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

.

4voto

seanmcl Punkte 9672

Sie müssen die Datenbank vor dem Erstellen der Benutzer ausführen. Dafür benötigen Sie mehrere Prozesse. Sie können entweder postgres in einem Subshell (&) im Shell-Skript starten oder ein Tool wie supervisord verwenden, um postgres auszuführen und dann Initialisierungsskripte auszuführen.

Ein Leitfaden zu supervisord und Docker https://docs.docker.com/articles/using_supervisord/

1voto

Anis Benna Punkte 823

Basierend auf den vorherigen Antworten hatte ich ein Dump aus einer Datenbank mit dem Namen ecomm-db.sql, wobei ecomm-db der tatsächliche Datenbankname ist, den ich in einen lokalen Docker-Container importieren wollte.

Die Datei ecomm-db.sql enthielt bereits einen Benutzer namens admin, auf den sie verwies, mit Anweisungen wie ALTER TABLE public."Products" OWNER TO admin;

Der Weg, alles zum Laufen zu bringen, ist:

  • Erstellen Sie den Benutzer admin und die Datenbank ecomm-db (unter Verwendung von POSTGRES_USER und POSTGRES_DB in Docker Compose)
  • Erstellen Sie ein Skript role.sh, das alle Berechtigungen für die neu erstellte ecomm-db dem Benutzer admin
  • Initialisieren Sie den Container mit dem Skript role.sh und der Datei ecomm-db.sql

Es ist nicht erforderlich, ein neues Dockerfile zu erstellen

  • docker-compose.yml

    services: postgres: image: postgres ports:

    • 5432:5432 networks:
    • postgres-net environment:
    • POSTGRES_USER=admin
    • POSTGRES_PASSWORD=password
    • POSTGRES_DB=ecomm-db volumes:
    • postgres-vol:/var/lib/postgresql/data
    • ./init/role.sh:/docker-entrypoint-initdb.d/role.sh # Reihenfolge ist wichtig
    • ./init/ecomm-db.sql:/docker-entrypoint-initdb.d/data.sql # Containername ist beliebig healthcheck: test: [ "CMD-SHELL", "pg_isready" ] interval: 10s timeout: 5s retries: 5 logging: options: max-size: 10m max-file: "3"
  • init/role.sh

    !/bin/bash

    set -e

    psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL GRANT ALL PRIVILEGES ON DATABASE ecomm-db TO admin; EOSQL

  • init/ecomm-db.sh (Auszug)

    -- -- PostgreSQL-Datenbankdump

    -- Dump von Datenbankversion 13.7 (Ubuntu 13.7-1.pgdg20.04+1) -- Erstellt von pg_dump-Version 13.7 (Ubuntu 13.7-1.pgdg20.04+1)

    ...

    ALTER TABLE public."Products" OWNER TO admin; ...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X