Je viens de suivre cet article sur Exécution d’un environnement de développement Rails dans Docker . Bon article, fonctionne très bien. Après avoir tout mis en place, j'ai décidé de continuer et de mettre en place un environnement de production.
OBJECTIF:
Je veux rake db:create && rake db:migrate
chaque fois que mon image de menu fixe est exécutée.
PROBLEME:
Si je déplace les étapes de création et de migration de la base de données ...
docker-compose run app rake db:create
docker-compose run app rake db:migrate
... dans le fichier Docker ...
RUN rake db:create && rake db:migrate
... ça va jeter une erreur ...
could not translate Host name "postgres" to address: Name or service not known
... parce que la Host
dans mon database.yml
...
default: &default
adapter: postgresql
encoding: unicode
pool: 5
timeout: 5000
username: postgres
Host: postgres
port: 5432
development:
<<: *default
database: Rails_five_development
... est défini sur le nom du service postgres
spécifié dans mon docker-compose.yml
...
version: "2"
services:
postgres:
image: postgres:9.5
ports:
- "5432"
app:
build: .
command: Rails server -p 3000 -b '0.0.0.0'
volumes:
- .:/app
ports:
- "3000:3000"
links:
- postgres
... puisque c'est la pratique recommandée par l'article.
QUESTION:
Comment puis-je automatiquement rake db:create && rake db:migrate
chaque fois que mon image de menu fixe est exécutée?
De https://docs.docker.com/engine/reference/builder/#cmd :
Si vous souhaitez que votre conteneur exécute le même exécutable à chaque fois, vous devez envisager d'utiliser ENTRYPOINT en combinaison avec CMD. Voir ENTRYPOINT
https://docs.docker.com/engine/reference/builder/#entrypoint
tl; dr
Vous pouvez définir une entrypoint
sous app et définir un fichier bash ici:
app:
entrypoint: [bin/entry]
..
exemple de fichier bin/entry:
#!/bin/bash
set -e
rake db:create
rake db:migrate
exec "$@"
Cette approche crée la base de données si la migration ne peut pas réussir. Cela évite également le problème [ de ne pas pouvoir démarrer le serveur car un fichier pid a été laissé. Créez le fichier en tant que app/lib/docker-entrypoint.sh
.
#!/bin/sh
# https://stackoverflow.com/a/38732187/1935918
set -e
if [ -f /app/tmp/pids/server.pid ]; then
rm /app/tmp/pids/server.pid
fi
bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup
exec bundle exec "$@"
Le fichier docker-compose.yml comprend alors:
entrypoint: ["/app/lib/docker-entrypoint.sh"]
command: ["Rails","server","-b","0.0.0.0","-p","3000"]
J'utilise un Makefile:
run:
docker-compose up -d \
&& docker-compose run web rake db:create
Donc, maintenant, quand je veux docker-compose up
je ne fais que make run
à la place.