web-dev-qa-db-fra.com

Utilisation de docker-compose pour créer des tables dans la base de données postgresql

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.

26
blahblahblah

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.

29
Daerdemandt

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

14
Victor Di

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.

9
dnephin