Supposons que j'exécute la commande suivante dans un script:

#!/usr/bin/env bash

docker run --name mydb --rm -e POSTGRES_PASSWORD=kgalli -e POSTGRES_USER=kgalli -p "9999:5432" -v $PWD/db:/opt -d postgres

Lorsque j'exécute ensuite la commande suivante pour créer une base de données, cela fonctionne très bien.

docker exec -e PGPASSWORD=kgalli mydb psql -U kgalli -d template1 -c "CREATE DATABASE kgalli_test WITH OWNER kgalli ENCODING 'UTF8' LC_COLLATE = 'en_US.utf8' LC_CTYPE = 'en_US.utf8';"

Cependant, lorsque j'ajoute cette ligne au script ci-dessus, le script démarre non seulement le serveur postgres, mais crée également la base de données, il échoue.

Je ne comprends pas vraiment pourquoi j'obtiens l'erreur suivante:

psql: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

Je sais que je peux demander à docker postgres image de créer une base de données au démarrage. Mais ce n'est en fait pas ce que je veux réaliser. J'utilise juste ceci comme exemple pour comprendre le problème.

0
kgalli 27 janv. 2019 à 17:33

3 réponses

Meilleure réponse

Lorsque vous l'exécutez dans un script, cela se produit probablement trop rapidement. La commande docker run … revient immédiatement, puis docker exec … tente d'utiliser PostgreSQL alors que le serveur de base de données est encore en cours de démarrage. Vous devez attendre qu'il soit prêt avant de créer la base de données supplémentaire.

Cela dit, l 'image postgres a des fonctionnalités dans son script de point d'entrée pour exécuter des scripts d'initialisation personnalisés. Vous pouvez placer votre instruction CREATE DATABASE … dans un fichier ou une configuration .sql et la monter dans /docker-entrypoint-initdb.d dans le conteneur. Le conteneur postgres l'exécutera automatiquement lorsque le serveur de base de données sera prêt.

La documentation à ce sujet semble avoir disparu, mais vous pouvez voir l'implémentation dans docker-entrypoint.sh.

1
King Chung Huang 27 janv. 2019 à 18:22

La commande docker run d'abord creates une couche de conteneur inscriptible sur l'image spécifiée, puis starts à l'aide de la commande spécifiée.

La commande docker exec exécute une nouvelle commande dans un conteneur en cours d'exécution. Si le conteneur est suspendu, la commande docker exec échouera avec une erreur

$ docker pause test

test

$ docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS               NAMES
1ae3b36715d2        ubuntu:latest       "bash"              17 seconds ago      Up 16 seconds (Paused)                       test

$ docker exec test ls

FATA[0000] Error response from daemon: Container test is paused, unpause the container before exec

$ echo $?
1

(ref.1) (ref.2)

0
Mayur 27 janv. 2019 à 15:05

En utilisant docker run, vous démarrez un nouveau conteneur, en utilisant docker exec, vous exécutez une commande dans un conteneur déjà en cours d'exécution

1
c4f4t0r 27 janv. 2019 à 14:43