Entwicklungsumgebung für Ruby on Rails-Anwendungen mit Docker Compose erstellen
Erfahren Sie, wie Sie mit Docker Compose eine effiziente Entwicklungsumgebung für Ruby on Rails-Anwendungen einrichten können. Unser Tutorial führt Sie durch den Prozess der Containerisierung, der Synchronisierung von Anwendungscodes und der Konfiguration von Datenbanken und Services.
Entwicklung von Anwendungen kann eine komplexe Aufgabe sein, insbesondere wenn es um die Einrichtung von Entwicklungsumgebungen geht. Docker bietet hier eine elegante Lösung, indem es die Kapselung von Anwendungen in Container ermöglicht. Diese Container sind isoliert, portabel und bieten konsistente Umgebungen, was die Entwicklung, Fehlerbehebung und Bereitstellung von Anwendungen erleichtert.
Die Einrichtung umfasst die folgenden Schritte:
- Synchronisieren des Anwendungscodes auf dem Host mit dem Code im Container, um Änderungen während der Entwicklung zu erleichtern.
- Persistieren von Anwendungsdaten zwischen Neustarts der Container.
- Konfiguration von Sidekiq-Workern, um Jobs wie erwartet zu verarbeiten.
Voraussetzungen
Bevor Sie mit diesem Tutorial beginnen, benötigen Sie:
- Eine lokale Entwicklungs- oder Serversystem mit Ubuntu 18.04.
- Docker und Docker Compose installiert gemäß den Anweisungen in den entsprechenden Anleitungen.
Schritt 1: Projekt klonen und Abhängigkeiten hinzufügen
git clone https://github.com/do-community/rails-sidekiq.git rails-docker
cd rails-docker
nano Gemfile
gem ‚pg‘, ‚~>1.1.3′
# Kommentieren Sie sqlite-Gem aus
# gem ’sqlite3′
# Kommentieren Sie spring-watcher-listen-Gem aus
# gem ’spring-watcher-listen‘, ‚~> 2.0.0‘
Schritt 2: Anwendung für PostgreSQL und Redis konfigurieren
nano config/database.yml
default: &default
adapter: postgresql
encoding: unicode
database: <%= ENV[‚DATABASE_NAME‘] %>
username: <%= ENV[‚DATABASE_USER‘] %>
password: <%= ENV[‚DATABASE_PASSWORD‘] %>
port: <%= ENV[‚DATABASE_PORT‘] || ‚5432‘ %>
host: <%= ENV[‚DATABASE_HOST‘] %>
pool: <%= ENV.fetch(„RAILS_MAX_THREADS“) { 5 } %>
timeout: 5000
development:
<<: *default
test:
<<: *default
production:
<<: *default
nano .env
DATABASE_NAME=rails_development
DATABASE_USER=sammy
DATABASE_PASSWORD=shark
DATABASE_HOST=database
REDIS_HOST=redis
Schritt 3: Dockerfile und Einstiegsskripte schreiben
nano Dockerfile
FROM ruby:2.5.1-alpine
ENV BUNDLER_VERSION=2.0.2
RUN apk add –update –no-cache \
binutils-gold \
build-base \
curl \
file \
g++ \
gcc \
git \
less \
libstdc++ \
libffi-dev \
libc-dev \
linux-headers \
libxml2-dev \
libxslt-dev \
libgcrypt-dev \
make \
netcat-openbsd \
nodejs \
openssl \
pkgconfig \
postgresql-dev \
python \
tzdata \
yarn
RUN gem install bundler -v 2.0.2
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle config build.nokogiri –use-system-libraries
RUN bundle check || bundle install
COPY package.json yarn.lock ./
RUN yarn install –check-files
COPY . ./
ENTRYPOINT [„./entrypoints/docker-entrypoint.sh“]
mkdir entrypoints
nano entrypoints/docker-entrypoint.sh
#!/bin/sh
set -e
if [ -f tmp/pids/server.pid ]; then
rm tmp/pids/server.pid
fi
bundle exec rails s -b 0.0.0.0
chmod +x entrypoints/docker-entrypoint.sh
nano entrypoints/sidekiq-entrypoint.sh
#!/bin/sh
set -e
if [ -f tmp/pids/server.pid ]; then
rm tmp/pids/server.pid
fi
bundle exec sidekiq
chmod +x entrypoints/sidekiq-entrypoint.sh
Schritt 4: Definieren von Diensten mit Docker Compose
Mit Docker Compose können wir die für unsere Einrichtung erforderlichen mehreren Container ausführen. Wir werden unsere Kompositions-Dienste in unserer Hauptdatei `docker-compose.yml` definieren. Ein Dienst in Compose ist ein laufender Container, und die Dienstdefinitionen, die Sie in Ihrer `docker-compose.yml`-Datei einschließen, enthalten Informationen darüber, wie jedes Container-Image ausgeführt wird. Das Compose-Tool ermöglicht es Ihnen, mehrere Dienste zu definieren, um Multi-Container-Anwendungen zu erstellen.
Unsere Anwendungseinrichtung wird folgende Dienste umfassen:
- Die Anwendung selbst
- Die PostgreSQL-Datenbank
- Redis
- Sidekiq
Wir werden auch ein Bind-Mount als Teil unserer Einrichtung einschließen, damit alle Änderungen am Code, die wir während der Entwicklung vornehmen, sofort mit den Containern synchronisiert werden, die auf diesen Code zugreifen müssen.
Öffnen Sie die `docker-compose.yml`-Datei:
nano docker-compose.yml
Zuerst fügen Sie die Dienstdefinition für die Anwendung hinzu:
version: ‚3.4‘
services:
app:
build:
context: .
dockerfile: Dockerfile
depends_on:
– database
– redis
ports:
– „3000:3000“
volumes:
– .:/app
– gem_cache:/usr/local/bundle/gems
– node_modules:/app/node_modules
env_file: .env
environment:
RAILS_ENV: development
Die Dienstdefinition für die Anwendung umfasst folgende Optionen:
– Build: Definiert die Konfigurationsoptionen für das Erstellen des Anwendungsbilds.
– Depends On: Legt die Abhängigkeiten fest, die vor dem Starten des App-Dienstes bereitgestellt werden müssen.
– Ports: Mappt den Port 3000 des Hosts auf den Port 3000 des Containers.
– Volumes: Definiert die Volumenmontagen für den App-Service.
– Env File und Environment: Legt Umgebungsvariablen fest, die an den Container übergeben werden.
Als nächstes fügen Sie den folgenden Code unterhalb der Anwendungsdienstdefinition hinzu, um Ihren Datenbankdienst zu definieren:
database:
image: postgres:12.1
volumes:
– db_data:/var/lib/postgresql/data
– ./init.sql:/docker-entrypoint-initdb.d/init.sql
Im Gegensatz zum App-Service zieht der Datenbankdienst ein Postgres-Image direkt von Docker Hub und verwendet das Volume `db_data`, um Anwendungsdaten zwischen Containerstarts zu persistieren.
Fügen Sie dann die Redis-Dienstdefinition hinzu:
redis:
image: redis:5.0.7
Schließlich fügen Sie die Sidekiq-Dienstdefinition hinzu:
sidekiq:
build:
context: .
dockerfile: Dockerfile
depends_on:
– app
– database
– redis
volumes:
– .:/app
– gem_cache:/usr/local/bundle/gems
– node_modules:/app/node_modules
env_file: .env
environment:
RAILS_ENV: development
entrypoint: ./entrypoints/sidekiq-entrypoint.sh
Unser Sidekiq-Dienst ähnelt unserem App-Dienst in einigen Aspekten. Es verwendet denselben Build-Kontext und dasselbe Image, dieselben Umgebungsvariablen und Volumen. Es ist jedoch abhängig von den App-, Redis- und Datenbankdiensten und wird daher als letztes gestartet. Zusätzlich verwendet es einen Entry-Point, der den in der Dockerfile festgelegten Entry-Point überschreibt und den Sidekiq-Dienst startet.
Schritt 5: Volumendefinitionen unterhalb der Sidekiq-Dienstdefinition hinzufügen
volumes:
gem_cache:
db_data:
node_modules:
Unser Top-Level-`volumes`-Schlüssel definiert die Volumina `gem_cache`, `db_data` und `node_modules`. Wenn Docker Volumina erstellt, werden die Inhalte des Volumens in einem Teil des Host-Dateisystems, `/var/lib/docker/volumes/`, gespeichert, das von Docker verwaltet wird. Die Inhalte jedes Volumens werden in einem Verzeichnis unter `/var/lib/docker/volumes/` gespeichert und an jeden Container gemountet, der das Volumen verwendet. Auf diese Weise persistieren die Daten unseres Anwendungsdienstes im `db_data`-Volumen, auch wenn wir den Datenbankdienst entfernen und neu erstellen.
Die fertige Datei sieht folgendermaßen aus:
version: ‚3.4‘
services:
app:
build:
context: .
dockerfile: Dockerfile
depends_on:
– database
– redis
ports:
– „3000:3000“
volumes:
– .:/app
– gem_cache:/usr/local/bundle/gems
– node_modules:/app/node_modules
env_file: .env
environment:
RAILS_ENV: development
database:
image: postgres:12.1
volumes:
– db_data:/var/lib/postgresql/data
– ./init.sql:/docker-entrypoint-initdb.d/init.sql
redis:
image: redis:5.0.7
sidekiq:
build:
context: .
dockerfile: Dockerfile
depends_on:
– app
– database
– redis
volumes:
– .:/app
– gem_cache:/usr/local/bundle/gems
– node_modules:/app/node_modules
env_file: .env
environment:
RAILS_ENV: development
entrypoint: ./entrypoints/sidekiq-entrypoint.sh
volumes:
gem_cache:
db_data:
node_modules:
Speichern und schließen Sie die Datei, wenn Sie mit dem Bearbeiten fertig sind.