J'ai essayé de configurer un conteneur pour une instance de développement postgres en créant un utilisateur et une base de données personnalisés. J'utilise le image officielle de docker postgres . Dans la documentation, il vous est demandé d'insérer un script bash dans le dossier /docker-entrypoint-initdb.d/
pour configurer la base de données avec tous les paramètres personnalisés.
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/
L'erreur que je reçois du docker logs -f db
(la base de données est le nom de mon conteneur) est la suivante:
createuser: impossible de se connecter à la base de données postgres: impossible de se connecter au serveur: aucun fichier ou répertoire de ce type
Il semble que les commandes à l'intérieur du dossier /docker-entrypoint-initdb.d/
soient en cours d'exécution avant le démarrage de postgres. Ma question est la suivante: comment configurer par programme un utilisateur/une base de données à l’aide du conteneur officiel Postgres? Est-il possible de faire cela avec un script?
Le image officielle de docker postgres exécutera les scripts .sql
situés dans le dossier /docker-entrypoint-initdb.d/
.
Donc, tout ce dont vous avez besoin est de créer le script SQL suivant:
init.sql
CREATE USER docker;
CREATE DATABASE docker;
GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
et l'ajouter dans votre Dockerfile:
Dockerfile
FROM library/postgres
COPY init.sql /docker-entrypoint-initdb.d/
Mais depuis le 8 juillet 2015, si tout ce dont vous avez besoin est de créer un utilisateur et une base de données , il est plus facile de simplement utiliser le POSTGRES_USER
, POSTGRES_PASSWORD
et POSTGRES_DB
variables d'environnement:
docker run -e POSTGRES_USER=docker -e POSTGRES_PASSWORD=docker -e POSTGRES_DB=docker library/postgres
ou avec un fichier Docker:
FROM library/postgres
ENV POSTGRES_USER docker
ENV POSTGRES_PASSWORD docker
ENV POSTGRES_DB docker
De la documentation de l’image postgres Docker , on dit que
[...] il recherchera tout script * .sh trouvé dans ce répertoire [
/docker-entrypoint-initdb.d
] pour procéder à une autre initialisation avant de démarrer le service
Ce qui est important ici est "avant de démarrer le service" . Cela signifie que votre script make_db.sh sera exécuté avant le démarrage du service postgres. Par conséquent, le message d'erreur "n'a pas pu se connecter à la base de données postgres" .
Après cela, il y a une autre information utile:
Si vous devez exécuter des commandes SQL dans le cadre de votre initialisation, l’utilisation du mode mono-utilisateur de Postgres est vivement recommandée.
D'accord, cela peut être un peu mystérieux au premier regard. Cela dit, votre script d'initialisation doit démarrer le service postgres en mode simple avant de faire ses actions. Vous pouvez donc modifier votre script make_db.ksh comme suit et vous rapprocher de ce que vous voulez:
NOTE, cela a changé récemment dans le commit suivant . Cela fonctionnera avec le dernier changement:
export PGUSER=postgres
psql <<- EOSQL
CREATE USER docker;
CREATE DATABASE docker;
GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL
Auparavant, l'utilisation du mode --single
était requise:
gosu postgres postgres --single <<- EOSQL
CREATE USER docker;
CREATE DATABASE docker;
GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL
Vous pouvez maintenant placer des fichiers .sql dans le répertoire init:
Si vous souhaitez effectuer une initialisation supplémentaire dans une image dérivée de celle-ci, ajoutez un ou plusieurs scripts * .sql ou * .sh sous /docker-entrypoint-initdb.d (en créant le répertoire si nécessaire). Une fois que le point d'entrée appelle initdb pour créer l'utilisateur et la base de données postgres par défaut, il exécute tous les fichiers * .sql et source tous les scripts * .sh trouvés dans ce répertoire pour procéder à une autre initialisation avant de démarrer le service.
Donc, copier votre fichier .sql fonctionnera.
J'ajoute des commandes personnalisées à un environnement évoqué dans un CMD après le démarrage de services ... Je ne l'ai pas fait avec postgres, mais avec 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
et commence avec
docker run -d ... -e POST_START_CMDS="su - Oracle -c 'sqlplus @/scripts/script' " <image>
.
La base de données doit être en cours d'exécution avant de créer les utilisateurs. Pour cela, vous avez besoin de plusieurs processus. Vous pouvez soit démarrer postgres dans un sous-shell (&) dans le script Shell, soit utiliser un outil tel que supervisord pour exécuter postgres, puis exécuter tout script d'initialisation.
Guide de supervision et de menu fixe https://docs.docker.com/articles/using_supervisord/
Vous pouvez utiliser ces commandes:
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;"