J'utilise docker-compose pour déployer un multiconteneur python Flask. J'ai du mal à comprendre comment créer des tables dans la base de données postgresql pendant la construction) donc je n'ai pas à les ajouter manuellement avec psql.
Mon fichier docker-compose.yml est:
web:
restart: always
build: ./web
expose:
- "8000"
links:
- postgres:postgres
volumes:
- /usr/src/flask-app/static
env_file: .env
command: /usr/local/bin/gunicorn -w 2 -b :8000 app:app
nginx:
restart: always
build: ./nginx/
ports:
- "80:80"
volumes:
- /www/static
volumes_from:
- web
links:
- web:web
data:
restart: always
image: postgres:latest
volumes:
- /var/lib/postgresql
command: "true"
postgres:
restart: always
image: postgres:latest
volumes_from:
- data
ports:
- "5432:5432"
Je ne veux pas avoir à entrer psql pour taper:
CREATE DATABASE my_database;
CREATE USER this_user WITH PASSWORD 'password';
GRANT ALL PRIVILEGES ON DATABASE "my_database" to this_user;
\i create_tables.sql
J'apprécierais des conseils sur la façon de créer les tableaux.
Je ne veux pas avoir à entrer psql pour taper
Vous pouvez simplement utiliser le mécanisme d'initialisation intégré du conteneur:
COPY init.sql /docker-entrypoint-initdb.d/10-init.sql
Cela garantit que votre sql est exécuté après le démarrage correct du serveur DB.
Jetez un oeil à leur point d'entrée script . Il fait quelques préparatifs pour démarrer correctement psql et examine /docker-entrypoint-initdb.d/
répertoire pour les fichiers se terminant par .sh
, .sql
et .sql.gz
.
10-
dans le nom de fichier est dû au fait que les fichiers sont traités dans l'ordre ASCII. Vous pouvez nommer vos autres fichiers init comme 20-create-tables.sql
et 30-seed-tables.sql.gz
par exemple et assurez-vous qu'ils sont traités dans l'ordre dont vous avez besoin.
Notez également que l'invocation de la commande ne le fait pas spécifie la base de données. Gardez cela à l'esprit si, par exemple, vous migrez vers docker-compose et votre .sql
les fichiers ne spécifient pas non plus DB.
Cependant, vos fichiers seront traités au premier démarrage du conteneur au stade build
. Étant donné que Docker Compose arrête les images puis les reprend, il n'y a presque aucune différence, mais s'il est crucial pour vous d'initialiser la base de données au stade build
, je suggère de continuer à utiliser la méthode init intégrée en appelant /docker-entrypoint.sh
à partir de votre dockerfile puis nettoyage à /docker-entrypoint-initdb.d/
répertoire.
cela n'a pas fonctionné pour moi avec l'approche COPY dans Dockerfile. Mais j'ai réussi à exécuter mon fichier init.sql en ajoutant:
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
dans mon docker-compose.yml. init.sql était dans le même catalogue que mon docker-compose.yml. J'ai jeté un œil à la solution ici: https://Gist.github.com/vrulevskyi/307b08abddc9568cf8f9c1b429c1ab56
Je créerais les tables dans le cadre du processus de construction. Créez un nouveau Dockerfile
dans un nouveau répertoire ./database/
FROM postgres:latest
COPY . /fixtures
WORKDIR /fixtures
RUN /fixtures/setup.sh
./database/setup.sh
ressemblerait à ceci:
#!/bin/bash
set -e
/etc/init.d/postgresql start
psql -f create_fixtures.sql
/etc/init.d/postgresql stop
Mettez votre utilisateur de création, créez une base de données, créez une table sql (et toute autre donnée de luminaire) dans un create_fixtures.sql
fichier dans le ./database/
répertoire.
et enfin votre service postgres
changera pour utiliser build
:
postgres:
build: ./database/
...
Remarque: Parfois, vous aurez besoin d'un sleep 5
(ou mieux encore un script à interroger et à attendre que postgresql démarre) après le /etc/init.d/postgresql start
ligne. D'après mon expérience, le script init ou le client psql gère cela pour vous, mais je sais que ce n'est pas le cas avec mysql, donc j'ai pensé que je l'appellerais.