webentwicklung-frage-antwort-db.com.de

Docker Compose + Rails: Best Practices für die Migration?

Ich habe gerade diesen Artikel über Ausführen einer Rails-Entwicklungsumgebung in Docker verfolgt. Guter Artikel, funktioniert super. Nachdem ich alles eingerichtet hatte, beschloss ich, eine Produktionsumgebung aufzubauen.

TOR:

Ich möchte jedes Mal, wenn mein Docker-Image ausgeführt wird, rake db:create && rake db:migrate.

PROBLEM:

Wenn ich die Schritte zum Erstellen der Datenbank und zum Migrieren verschiebe ...

docker-compose run app rake db:create
docker-compose run app rake db:migrate

... in die Dockerfile ...

RUN rake db:create && rake db:migrate

... das wird einen Fehler werfen ...

could not translate Host name "postgres" to address: Name or service not known

... weil die Host in meinem database.yml...

default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  timeout: 5000
  username: postgres
  Host: postgres
  port: 5432

development:
  <<: *default
  database: Rails_five_development

... wird auf den in meinem docker-compose.yml... angegebenen postgres-Servicenamen gesetzt.

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

... da dies die empfohlene Praxis ist, wie im Artikel gezeigt.

FRAGE:

Wie kann ich jedes Mal, wenn mein Andockbild ausgeführt wird, automatisch rake db:create && rake db:migrateen?

Ich versuche dasselbe zu erreichen wie in dieser Frage

18
João Souza

Von https://docs.docker.com/engine/reference/builder/#cmd :

Wenn Sie möchten, dass Ihr Container jedes Mal dieselbe ausführbare Datei ausführt, sollten Sie ENTRYPOINT in Kombination mit CMD in Betracht ziehen. Siehe ENTRYPOINT

https://docs.docker.com/engine/reference/builder/#entrypoint

tl; dr

Sie können eine entrypoint unter app definieren und dort eine bash-Datei definieren:

app:
  entrypoint: [bin/entry]
  ..

bin/entry file Beispiel:

#!/bin/bash
set -e

rake db:create
rake db:migrate

exec "[email protected]"
19
Ho Man

Bei diesem Ansatz wird die Datenbank erstellt, wenn die Migration nicht erfolgreich durchgeführt werden kann. Außerdem wird vermieden, dass issue den Server nicht starten kann, weil eine PID-Datei zurückgelassen wurde. Erstellen Sie die Datei als 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 "[email protected]"

Die Docker-compose.yml enthält dann:

entrypoint: ["/app/lib/docker-entrypoint.sh"]
command: ["Rails","server","-b","0.0.0.0","-p","3000"]
11
dankohn

Ich benutze ein Makefile:

run:
    docker-compose up -d \
    && docker-compose run web rake db:create

Wenn ich also docker-compose up möchte, mache ich stattdessen make run.

2
davidpm4