paint-brush
Eine vereinfachte Anleitung zur „Dockerazition“ von Ruby und Rails mit der React Front-End-Appvon@forison
347 Lesungen
347 Lesungen

Eine vereinfachte Anleitung zur „Dockerazition“ von Ruby und Rails mit der React Front-End-App

von Addo Boakye Forison13m2024/08/04
Read on Terminal Reader

Zu lang; Lesen

Bei der Dockerisierung kommen zwei Schlüsselkonzepte zum Einsatz: Images und Container. Images dienen als Blaupausen für Container und enthalten alle notwendigen Informationen zum Erstellen eines Containers. Ein Container ist eine Laufzeitinstanz eines Images und besteht aus dem Image selbst, einer Ausführungsumgebung und Laufzeitanweisungen. In diesem Artikel bieten wir eine praktische Anleitung zum Dockerisieren Ihrer Rails- und React-Anwendungen im Detail.
featured image - Eine vereinfachte Anleitung zur „Dockerazition“ von Ruby und Rails mit der React Front-End-App
Addo Boakye Forison HackerNoon profile picture
0-item
1-item

Das Dockerisieren Ihres Ruby on Rails mit einer React-Frontend-Anwendung kann Ihren Entwicklungs-Workflow und Ihren Bereitstellungsprozess erheblich verbessern. Indem Sie eine standardisierte Umgebung für Ihre App erstellen, stellen Sie ein konsistentes Verhalten in verschiedenen Entwicklungs-, Test- und Produktionsphasen und sogar zwischen verschiedenen Systemen sicher. Tatsächlich ist es darauf ausgelegt, Probleme im Zusammenhang mit Systemunterschieden zu minimieren. Diese Anleitung führt Sie durch die wesentlichen Schritte, damit Ihre Rails- und React-App in Docker-Containern reibungslos läuft.

Docker zur Rettung

Warum eine Anwendung dockerisieren?

  • Konsistenz über alle Umgebungen hinweg :
    • Docker stellt sicher, dass die Anwendung unabhängig davon, wo sie bereitgestellt wird, auf dieselbe Weise ausgeführt wird, sei es auf der Maschine eines Entwicklers, in einer Testumgebung oder auf einem Produktionsserver. Diese Konsistenz wird durch die Containerisierung aller Abhängigkeiten und Konfigurationen erreicht.


  • Abhängigkeitsverwaltung :
    • Docker-Container enthalten alle notwendigen Abhängigkeiten, damit die Anwendung ausgeführt werden kann. Das bedeutet, dass Abweichungen in Systembibliotheken oder fehlende Abhängigkeiten auf verschiedenen Systemen die Funktionalität der Anwendung nicht beeinträchtigen.


  • Isolierung :
    • Docker-Container werden isoliert voneinander und vom Hostsystem ausgeführt. Diese Isolierung verhindert Konflikte zwischen verschiedenen Anwendungen und ihren Abhängigkeiten auf demselben System.


  • Portabilität :
    • Docker-Container können problemlos verschoben und auf jedem System ausgeführt werden, das Docker unterstützt, sei es eine lokale Maschine, ein Cloud-Dienst oder ein dedizierter Server. Dies macht die Anwendung in Bezug auf die Bereitstellung äußerst portabel und flexibel.


NB: Kenntnisse der Docker-Syntax sind erforderlich


Bei der Dockerisierung geht es um zwei Schlüsselkonzepte: Images und Container. Images dienen als Blaupausen für Container und enthalten alle notwendigen Informationen zum Erstellen eines Containers, einschließlich Abhängigkeiten und Bereitstellungskonfigurationen. Ein Container ist eine Laufzeitinstanz eines Images und besteht aus dem Image selbst, einer Ausführungsumgebung und Laufzeitanweisungen. Docker legt im Allgemeinen einen Standard für die Auslieferung von Software fest.


Um Docker mit einer einfachen Analogie zu erklären: Stellen Sie sich Container als die Schiffscontainer auf einem Lagerplatz vor, Bilder als die in diesen Containern platzierten Objekte und das Schiff als das System, auf dem die Container laufen.


Wenn Sie Ihre Anwendung einrichten und erstellen, sind bestimmte Umgebungskonfigurationen erforderlich. Sie können beispielsweise keine Rails-Anwendung ausführen, ohne dass auf Ihrem System eine Ruby-Umgebung installiert ist. Ebenso können Sie keine React-Anwendung ohne Node.js ausführen und Sie können keine React-Pakete ohne einen Node-Paketmanager wie npm oder Yarn usw. installieren.


Da der Container isoliert vom System des Benutzers läuft, stellen wir alle diese Pakete in unserem Container zur Verfügung, so wie wir es getan hätten, wenn wir ihn direkt auf unserem System erstellt hätten. Der Container fungiert also als eigenständiges System, wie eine virtuelle Maschine. Es gibt Unterschiede zwischen Docker und virtuellen Maschinen, aber dieses Beispiel dient nur der weiteren Erläuterung.


Lassen Sie uns nun die Rails-Anwendung dockerisieren. Dazu benötigen wir drei Dateien in unserer Rails-Anwendung: eine Dockerfile , eine docker-compose.yml und eine bin/docker-entrypoint . Lassen Sie uns jede dieser Dateien im Detail untersuchen.


NB: Kenntnisse der Docker-Syntax sind erforderlich

Docker-Datei

Das Dockerfile ist eine Blaupause zum Erstellen eines Docker-Containers. Es enthält eine Reihe von Anweisungen, die Docker zum Erstellen eines Images verwendet, das dann zum Ausführen von Containern verwendet werden kann. Lassen Sie uns ein Dockerfile für eine Ruby on Rails- und React-Anwendung aufschlüsseln:

Basisbild

 ARG RUBY_VERSION=3.1.4 FROM ruby:$RUBY_VERSION
  • ARG RUBY_VERSION=3.1.4 : Definiert ein Build-Argument namens RUBY_VERSION mit einem Standardwert von 3.1.4 . Dies kann zur Build-Zeit überschrieben werden.


  • FROM ruby:$RUBY_VERSION : Verwendet das ruby Basisimage mit der durch RUBY_VERSION angegebenen Version. Dadurch wird der Container mit der Ruby-Laufzeitumgebung eingerichtet. Wie bereits erwähnt, muss Ruby installiert sein, um eine Rails-Anwendung ausführen zu können.

2. Abhängigkeiten installieren

 RUN apt-get update -qq && \ apt-get install -y build-essential libvips bash bash-completion libffi-dev tzdata postgresql curl && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man
  • apt-get update -qq : Aktualisiert die Paketliste aus den Repositories, mit -qq für stille Ausgabe.


  • apt-get install -y ... : Installiert verschiedene Pakete:
    • build-essential : Wichtige Pakete zum Erstellen von Software (wie GCC).

    • libvips : Bibliothek zur Bildverarbeitung.

    • bash , bash-completion : Bash-Shell und ihre automatische Vervollständigung.

    • libffi-dev : Bibliothek für Fremdfunktionsschnittstellen.

    • tzdata : Zeitzonendaten.

    • postgresql : PostgreSQL-Datenbankclient.

    • curl : Tool zum Übertragen von Daten von URLs.


  • apt-get clean : Bereinigt das lokale Repository der abgerufenen Paketdateien.


  • rm -rf /var/lib/apt/lists/ /usr/share/doc /usr/share/man : Entfernt Paketlisten und Dokumentation, um die Bildgröße zu reduzieren.

3. Installieren Sie Node.js und Yarn

 RUN curl -fsSL https://deb.nodesource.com/setup_current.x | bash - && \ apt-get install -y nodejs && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && \ apt-get install -y yarn
  • curl -fsSL https://deb.nodesource.com/setup_current.x | bash - : Lädt das NodeSource-Setup-Skript herunter und führt es aus, um Node.js zu installieren.


  • apt-get install -y nodejs : Installiert Node.js.


  • curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - : Fügt den Yarn-GPG-Schlüssel hinzu, um seine Pakete zu überprüfen.


  • echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list : Fügt das Yarn-Repository zur Quellenliste hinzu.


  • apt-get update && apt-get install -y yarn : Aktualisiert die Paketliste und installiert Yarn.

4. Umgebungsvariablen

 ENV NODE_OPTIONS=--openssl-legacy-provider
  • ENV NODE_OPTIONS=--openssl-legacy-provider : Legt eine Umgebungsvariable fest, um die Legacy-OpenSSL-Unterstützung für Node.js zu aktivieren.

5. Arbeitsverzeichnis festlegen

 WORKDIR /rails
  • WORKDIR /rails : Legt das Arbeitsverzeichnis für nachfolgende Anweisungen auf /rails fest.

6. Argumente und Umgebungsvariablen erstellen

 ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV
  • ARG RAILS_ENV : Definiert ein Build-Argument namens RAILS_ENV zum Angeben der Rails-Umgebung (wie development , test , production ).


  • ENV RAILS_ENV=$RAILS_ENV : Setzt die Umgebungsvariable RAILS_ENV auf den Wert des Build-Arguments.

7. Installieren Sie Application Gems

 COPY Gemfile Gemfile.lock ./ RUN bundle install
  • COPY Gemfile Gemfile.lock ./ : Kopiert die Gemfile und Gemfile.lock in das Arbeitsverzeichnis.


  • RUN bundle install : Installiert die im Gemfile angegebenen Ruby-Gems.

8. Installieren Sie Front-End-Abhängigkeiten

 COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile
  • COPY package.json yarn.lock ./ : Kopiert package.json und yarn.lock in das Arbeitsverzeichnis.


  • RUN yarn install --frozen-lockfile : Installiert Front-End-Abhängigkeiten mit Yarn und stellt sicher, dass die genauen Versionen in yarn.lock verwendet werden.

9. Anwendungscode kopieren

 COPY . .
  • COPY . . : Kopiert den gesamten Anwendungscode in das Arbeitsverzeichnis.

10. Bootsnap-Code vorkompilieren

 RUN bundle exec bootsnap precompile --gemfile app/ lib/
  • RUN bundle exec bootsnap precompile --gemfile app/ lib/ : Kompiliert den Bootsnap-Cache vorab, um schnellere Startzeiten von Rails-Anwendungen zu ermöglichen. Bootsnap ist ein Gem, das die Startzeiten von Ruby und Rails beschleunigt, indem aufwändige Berechnungen zwischengespeichert werden.

11. Assets für die Produktion vorkompilieren

 RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi
  • RUN if [ "$RAILS_ENV" = "production" ]; then ... : Führt die Asset-Vorkompilierung nur bedingt aus, wenn RAILS_ENV auf production eingestellt ist. Dieser Schritt ist entscheidend für die Vorbereitung von Assets für eine Produktionsumgebung.

12. Entrypoint-Skript

 COPY bin/docker-entrypoint /rails/bin/ RUN chmod +x /rails/bin/docker-entrypoint
  • COPY bin/docker-entrypoint /rails/bin/ : Kopiert ein benutzerdefiniertes Entrypoint-Skript in den Container.


  • RUN chmod +x /rails/bin/docker-entrypoint : Macht das Entrypoint-Skript ausführbar.

13. Einstiegspunkt und Befehl definieren

 ENTRYPOINT ["/rails/bin/docker-entrypoint"] EXPOSE 5000 // you can use any port of your choice CMD ["./bin/rails", "server"]
  • ENTRYPOINT ["/rails/bin/docker-entrypoint"] : Legt das Entrypoint-Skript fest, das beim Starten des Containers ausgeführt wird. Dieses Skript richtet normalerweise die Umgebung ein, bereitet die Datenbank vor und startet die Anwendung.


  • EXPOSE 5000 : Zeigt an, dass der Container auf Port 5000 lauscht. Dies ist eine Dokumentationsfunktion und veröffentlicht den Port nicht.


  • CMD ["./bin/rails", "server"] : Gibt den Standardbefehl an, der beim Starten des Containers ausgeführt werden soll, nämlich den Rails-Server zu starten.

docker-compose.yml

Die Datei docker-compose.yml wird zum Definieren und Ausführen von Docker-Anwendungen mit mehreren Containern verwendet. Sie ermöglicht Ihnen, die Dienste, Netzwerke und Volumes Ihrer Anwendung in einer einzigen Datei zu konfigurieren. In diesem Fall werden wir zwei Dienste verwenden. Hier ist die Datei docker-compose.yml für die Rails-Anwendung:

1. Datenbankdienst ( db )

 codedb: image: postgres:14.2-alpine container_name: demo-postgres-14.2 volumes: - postgres_data:/var/lib/postgresql/data command: "postgres -c 'max_connections=500'" environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "5432:5432"
  • image: postgres:14.2-alpine : Gibt das für diesen Dienst zu verwendende Docker-Image an. In diesem Fall ist es das PostgreSQL 14.2-Image, das auf der Alpine Linux-Distribution basiert. Alpine-Images sind für ihre geringe Größe bekannt, die dazu beitragen kann, die Gesamtgröße des Images gering zu halten.


  • container_name: demo-postgres-14.2 : Benennt den Container demo-postgres-14.2 . Dieser Name wird verwendet, um in Befehlen und Protokollen auf den Container zu verweisen.


  • volumes :
    • postgres_data:/var/lib/postgresql/data: Mountet ein benanntes Volume postgres_data in /var/lib/postgresql/data innerhalb des Containers. In diesem Verzeichnis speichert PostgreSQL seine Daten und stellt sicher, dass die Datenbankdaten zwischen Containerneustarts erhalten bleiben.


  • command: "postgres -c 'max_connections=500'" : Überschreibt den Standardbefehl des PostgreSQL-Images. Es startet PostgreSQL mit einer Konfigurationsoption, um die maximale Anzahl von Verbindungen auf 500 zu erhöhen.


  • environment :
    • POSTGRES_DB: ${POSTGRES_DB} : Legt den Namen der zu erstellenden Standarddatenbank unter Verwendung der Umgebungsvariable POSTGRES_DB fest.

    • POSTGRES_USER: ${POSTGRES_USER} : Legt unter Verwendung der Umgebungsvariable POSTGRES_USER den Standardbenutzernamen für den Zugriff auf die PostgreSQL-Datenbank fest.

    • POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} : Legt unter Verwendung der Umgebungsvariable POSTGRES_PASSWORD das Kennwort für den Standardbenutzer fest.


  • ports :
    • "5432:5432" : Ordnet Port 5432 auf dem Host Port 5432 im Container zu. Dies ermöglicht den Zugriff auf PostgreSQL auf dem Hostcomputer über Port 5432.

2. Web-Anwendungsdienst ( demo-web )

 codedemo-web: build: context: . args: - RAILS_ENV=${RAILS_ENV} command: "./bin/rails server -b 0.0.0.0" environment: - RAILS_ENV=${RAILS_ENV} - POSTGRES_HOST=${POSTGRES_HOST} - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - RAILS_MASTER_KEY=${RAILS_MASTER_KEY} volumes: - .:/rails - app-storage:/rails/storage depends_on: - db ports: - "3000:3000"
  • build:

    • context: . : Gibt den Build-Kontext für das Docker-Image an. In diesem Fall bezieht sich . auf das aktuelle Verzeichnis. Dies bedeutet, dass Docker die Docker-Datei im aktuellen Verzeichnis verwendet, um das Image zu erstellen.
    • args :
      • RAILS_ENV=${RAILS_ENV} : Übergibt das Build-Argument RAILS_ENV an den Docker-Build-Prozess und ermöglicht Ihnen, die Rails-Umgebung anzugeben (wie etwa development , test oder production ).


  • command: "./bin/rails server -b 0.0.0.0" : Überschreibt den Standardbefehl des Docker-Images. Startet den Rails-Server und bindet ihn an alle Netzwerkschnittstellen ( 0.0.0.0 ), was notwendig ist, damit der Dienst von außerhalb des Containers erreichbar ist.


  • environment:

    • RAILS_ENV=${RAILS_ENV} : Legt die Rails-Umgebung innerhalb des Containers mithilfe der Umgebungsvariable RAILS_ENV fest.

    • POSTGRES_HOST=${POSTGRES_HOST} : Legt die PostgreSQL-Hostadresse fest.

    • POSTGRES_DB=${POSTGRES_DB} : Legt den Datenbanknamen fest.

    • POSTGRES_USER=${POSTGRES_USER} : Legt den PostgreSQL-Benutzer fest.

    • POSTGRES_PASSWORD=${POSTGRES_PASSWORD} : Legt das PostgreSQL-Benutzerkennwort fest.

    • RAILS_MASTER_KEY=${RAILS_MASTER_KEY} : Legt den Rails-Hauptschlüssel fest, der zum Verschlüsseln von Anmeldeinformationen und anderen Geheimnissen verwendet wird.


  • volumes :

    • .:/rails : Mountet das aktuelle Verzeichnis (in dem sich die Datei docker-compose.yml befindet) in /rails innerhalb des Containers. So können Sie Dateien auf Ihrem Host bearbeiten und diese Änderungen im Container widerspiegeln lassen.

    • app-storage:/rails/storage : Mountet ein benanntes Volume app-storage in /rails/storage innerhalb des Containers. Dies wird normalerweise zum Speichern Rails-spezifischer Dateien wie Protokolle, Uploads und zwischengespeicherte Dateien verwendet.


  • depends_on :

    • db : Stellt sicher, dass der demo-web wartet, bis der db Dienst bereit ist, bevor er gestartet wird. Docker Compose handhabt die Reihenfolge der gestarteten Dienste basierend auf dieser Einstellung.
  • ports:

    • "3000:3000" : Ordnet Port 3000 auf dem Host Port 3000 im Container zu. Dadurch können Sie über Port 3000 auf die Rails-Anwendung auf dem Hostcomputer zugreifen.

    Bände

     codevolumes: postgres_data: app-storage:
    • postgres_data : Definiert ein benanntes Volume postgres_data das vom db zum Speichern von PostgreSQL-Daten verwendet wird.
    • app-storage : Definiert einen benannten Volume- app-storage der vom demo-web zum Speichern anwendungsspezifischer Daten wie Uploads und Protokolle verwendet wird.

bin/docker-einstiegspunkt

Das Skript bin/docker-entrypoint ist ein wichtiger Teil der Docker-Einrichtung. Es wird beim Start des Containers ausgeführt und übernimmt normalerweise die Einrichtung der Umgebung, die Vorbereitung der Datenbank und andere Initialisierungsaufgaben, die vor dem Start der Hauptanwendung erforderlich sind. Hier ist ein Beispiel für ein Skript bin/docker-entrypoint und eine detaillierte Erklärung jedes Teils:

Shebang und Beenden bei Fehler

 bashCopy code#!/bin/bash set -e
  • #!/bin/bash : Diese Zeile gibt an, dass das Skript mit der Bash-Shell ausgeführt werden soll.


  • set -e : Dies weist das Skript an, sofort beendet zu werden, wenn ein Befehl einen Exit-Code ungleich Null zurückgibt. Dadurch wird sichergestellt, dass das Skript die Ausführung stoppt, wenn ein Schritt fehlschlägt. Dadurch kann verhindert werden, dass nachfolgende Schritte in einem ungültigen Zustand ausgeführt werden.


Bedingte Datenbankerstellung oder -migration

 # If running the rails server then create or migrate existing database if [ "${*}" == "./bin/rails server" ]; then ./bin/rails db:create ./bin/rails db:prepare fi


  • if [ "${*}" == "./bin/rails server" ]; then ... fi : Diese bedingte Anweisung prüft, ob der an das Skript übergebene Befehl ( "${*}" ) ./bin/rails server ist. Das * ist ein spezieller Parameter, der alle an das Skript übergebenen Positionsparameter enthält.


  • ./bin/rails db

    : Wenn die Bedingung erfüllt ist, versucht dieser Befehl, die Datenbank zu erstellen. Dies entspricht dem Ausführen von rails db:create , wodurch die Datenbank gemäß der Definition in der Datenbankkonfigurationsdatei ( config/database.yml ) eingerichtet wird.


  • ./bin/rails db

    : Dieser Befehl führt rails db:prepare aus, wodurch sichergestellt wird, dass die Datenbank eingerichtet und migriert wird. Er erstellt die Datenbank, wenn sie noch nicht existiert, und führt Migrationen aus, wenn die Datenbank bereits erstellt wurde. Dies ist eine Kombination aus rails db:create und rails db:migrate .

    Ausführen des Hauptprozesses

     bashCopy codeexec "${@}"
    • exec "${@}" : Dies ersetzt den aktuellen Shell-Prozess durch den Befehl, der als Argumente an das Skript übergeben wurde. Das @ -Symbol enthält alle Positionsparameter, die an das Skript übergeben werden. Wenn das Skript beispielsweise mit ./bin/rails server aufgerufen wird, führt diese Zeile ./bin/rails server effektiv als Hauptprozess des Containers aus.

Abschluss

Ein gut gestaltetes Dockerfile ist unerlässlich, um eine zuverlässige und konsistente Umgebung für Ihre Ruby on Rails- und React-Anwendung zu erstellen. Indem Sie das Basisimage definieren, Umgebungsvariablen festlegen und Abhängigkeiten installieren, stellen Sie sicher, dass Ihre Anwendung in verschiedenen Umgebungen reibungslos läuft.


Docker rationalisiert nicht nur Ihren Entwicklungsprozess, sondern verbessert auch die Zuverlässigkeit Ihrer Anwendung in der Produktion. Es gibt Optimierungsbereiche, aber dies ist nur ein allgemeiner Überblick darüber, wie die Rails-Anwendung dockerisiert wird.

Vollständiges Skript für die resultierende Dockerfile , docker-compose.yml und bin/docker-entrypoint

 ARG RUBY_VERSION=3.1.4 FROM ruby:$RUBY_VERSION # Install dependencies RUN apt-get update -qq && \ apt-get install -y build-essential libvips bash bash-completion libffi-dev tzdata postgresql curl && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man # Install Node.js and Yarn RUN curl -fsSL https://deb.nodesource.com/setup_current.x | bash - && \ apt-get install -y nodejs && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && \ apt-get install -y yarn # Set environment variable to enable legacy OpenSSL support ENV NODE_OPTIONS=--openssl-legacy-provider # Rails app lives here WORKDIR /rails # Set environment variable for the build ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV # Install application gems COPY Gemfile Gemfile.lock ./ RUN bundle install # Install frontend dependencies COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile # Copy application code COPY . . # Precompile bootsnap code for faster boot times RUN bundle exec bootsnap precompile --gemfile app/ lib/ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi # Entrypoint prepares the database. COPY bin/docker-entrypoint /rails/bin/ RUN chmod +x /rails/bin/docker-entrypoint # Use an absolute path for the entry point script ENTRYPOINT ["/rails/bin/docker-entrypoint"] # Start the server by default, this can be overwritten at runtime EXPOSE 5000 CMD ["./bin/rails", "server"]


 services: db: image: postgres:14.2-alpine container_name: demo-postgres-14.2 volumes: - postgres_data:/var/lib/postgresql/data command: "postgres -c 'max_connections=500'" environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "5432:5432" demo-web: build: context: . args: - RAILS_ENV=${RAILS_ENV} command: "./bin/rails server -b 0.0.0.0" environment: - RAILS_ENV=${RAILS_ENV} - POSTGRES_HOST=${POSTGRES_HOST} - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - RAILS_MASTER_KEY=${RAILS_MASTER_KEY} volumes: - .:/rails - app-storage:/rails/storage depends_on: - db ports: - "3000:3000" volumes: postgres_data: app-storage:



 #!/bin/bash set -e # If running the rails server then create or migrate existing database if [ "${*}" == "./bin/rails server" ]; then ./bin/rails db:create ./bin/rails db:prepare fi exec "${@}"