Ephemere Review App Container pro Pull Request mit Docker
AI generated
FROM
RUN
Docker · Review Apps · CI/CD
Ephemere Review Apps
ein Container Stack pro Pull Request

Eine ephemere Review App entsteht automatisch, sobald ein Pull Request geöffnet wird, und verschwindet spurlos, sobald er gemerged oder geschlossen wird. Docker Compose baut dafür pro Branch einen eigenen, isolierten Stack, erreichbar über eine dynamische Subdomain, ganz ohne manuelles Umgebungs-Management.

17 Min. Lesezeit Docker Compose · dynamische Subdomains · Cleanup GitLab Review Apps · Traefik

1. Was eine ephemere Review App leistet

Eine ephemere Review App ist eine vollständige, isolierte Instanz der Anwendung, die automatisch für einen einzelnen Pull Request entsteht und ebenso automatisch wieder verschwindet, sobald dieser Pull Request nicht mehr relevant ist. Der Kerngedanke: Statt sich eine geteilte Staging-Umgebung zu teilen, in der sich Änderungen verschiedener Branches gegenseitig überschreiben, bekommt jeder Pull Request seinen eigenen, vollständig unabhängigen Container-Stack mit eigener Datenbank, eigenem Cache und eigener erreichbarer URL.

Der Nutzen einer ephemeren Review App zeigt sich vor allem im Review-Prozess selbst. Ein Reviewer muss den Code nicht mehr nur lesen, sondern kann die tatsächliche Änderung in einer laufenden Umgebung anklicken, testen und mit Produktdesignern oder Product Ownern teilen, ohne selbst etwas lokal auszuchecken. Gerade bei visuellen Änderungen an einem Shop-Frontend oder bei komplexen Formular-Workflows ersetzt eine kurze Testrunde in einer echten Umgebung stundenlanges Code-Lesen.

Technisch basiert eine ephemere Review App in den meisten Setups auf Docker Compose, das den kompletten Anwendungsstack, Webserver, Anwendung, Datenbank und gegebenenfalls Cache, in einem eigenen Compose-Projekt pro Branch startet. Die CI-Pipeline übernimmt dabei die komplette Lebenszyklus-Verwaltung: Aufbau bei jedem Push auf den Pull-Request-Branch, Aktualisierung bei weiteren Commits, und vollständiger Abriss beim Merge oder Schließen.

2. Ein Compose-Setup pro Pull Request generieren

Damit mehrere ephemere Review Apps gleichzeitig auf demselben CI-Runner oder Host laufen können, muss jedes Compose-Projekt eindeutig benannt und isoliert sein. Docker Compose unterstützt das über den -p-Parameter (Projektname), der als Präfix für Container-, Netzwerk- und Volume-Namen dient. Wird der Projektname aus der Pull-Request-Nummer abgeleitet, etwa review-pr-482, kollidieren mehrere parallel laufende Review Apps nie miteinander.

Ports dürfen bei mehreren gleichzeitig laufenden ephemeren Review Apps auf demselben Host niemals fest im Compose-File stehen. Stattdessen bindet man Container entweder an zufällig zugewiesene Host-Ports oder, deutlich sauberer, an ein gemeinsames Netzwerk, in dem ein Reverse Proxy anhand von Hostnamen statt Ports routet. Letzteres skaliert deutlich besser, wenn mehr als eine Handvoll Pull Requests gleichzeitig offen sind.


# docker-compose.review.yml -- template rendered per pull request
services:
  app:
    image: registry.example.com/myapp:${CI_COMMIT_SHA}
    environment:
      APP_ENV: review
      DATABASE_URL: mysql://app:app@db:3306/app
    networks: [review-network]
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.pr-${PR_NUMBER}.rule=Host(`pr-${PR_NUMBER}.review.example.com`)"

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: app
    networks: [review-network]
    tmpfs:
      - /var/lib/mysql  # ephemeral storage -- no cleanup of data files needed

networks:
  review-network:
    name: review-pr-${PR_NUMBER}

3. Dynamisches Routing: eine Subdomain pro Branch

Reviewer sollen eine ephemere Review App mit einem einzigen Klick erreichen können, ohne Ports oder IP-Adressen zu kennen. Ein Reverse Proxy wie Traefik löst das elegant über Labels: Jeder App-Container bekommt beim Start ein Traefik-Label mit einer Routing-Regel, die auf einer eindeutigen Subdomain basiert, üblicherweise abgeleitet aus der Pull-Request-Nummer, etwa pr-482.review.example.com. Traefik erkennt neue Container automatisch über die Docker-Provider-Integration und aktualisiert sein Routing ohne Neustart.

Für ephemere Review Apps mit HTTPS empfiehlt sich ein Wildcard-Zertifikat für die Review-Domain, etwa *.review.example.com, statt für jeden Pull Request ein eigenes Zertifikat auszustellen. Traefik kann Wildcard-Zertifikate über den DNS-01-Challenge-Modus von Let's Encrypt automatisch verwalten, was den gesamten Zertifikatsprozess von der Pull-Request-Lebensdauer entkoppelt.

4. Datenbanken isolieren, ohne für jeden PR Fixtures neu zu bauen

Eine eigene, isolierte Datenbank pro ephemerer Review App ist Pflicht, damit Testdaten unterschiedlicher Pull Requests sich niemals vermischen. Der naheliegende Ansatz, für jeden Pull Request einen komplett leeren Datenbank-Container zu starten und dann ein vollständiges Produktions-Backup einzuspielen, ist bei größeren Datenmengen aber zu langsam, um in wenigen Minuten eine nutzbare Review App bereitzustellen.

Schneller funktioniert das Vorladen eines kompakten, anonymisierten Seed-Datensatzes in ein Docker Volume oder Image, das dann als Ausgangspunkt für jede neue ephemere Review App dient. Ein solches Seed-Image wird einmalig aus einem repräsentativen Datenauszug gebaut und in der Registry versioniert, sodass der eigentliche Start jeder Review App nur noch das Kopieren eines fertigen Datenbank-Volumes erfordert, statt Migrationen und Fixtures live auszuführen.


#!/usr/bin/env bash
# seed-review-db.sh -- fast database seeding for ephemeral review apps
set -euo pipefail

PR_NUMBER="${1:?Usage: seed-review-db.sh <pr-number>}"
VOLUME_NAME="review-pr-${PR_NUMBER}-db"

echo "[seed] Creating isolated volume for PR #${PR_NUMBER}"
docker volume create "${VOLUME_NAME}"

# Copy a pre-built, anonymized seed dataset into the fresh volume
docker run --rm \
  -v "${VOLUME_NAME}:/var/lib/mysql" \
  -v review-seed-data:/seed:ro \
  alpine sh -c "cp -a /seed/. /var/lib/mysql/"

echo "[seed] Volume ${VOLUME_NAME} ready in seconds, not minutes"

5. Aufbau und Abriss in der CI-Pipeline automatisieren

Der komplette Lebenszyklus einer ephemeren Review App muss über CI-Pipeline-Trigger gesteuert werden, nicht über manuelle Eingriffe. GitLab CI bietet dafür das native environment-Konzept mit on_stop-Jobs, die automatisch ausgeführt werden, sobald ein Merge Request geschlossen oder gemerged wird. GitHub Actions erreicht dasselbe über einen Workflow, der auf das closed-Event eines Pull Requests reagiert.

Wichtig bei der Automatisierung von ephemeren Review Apps ist, dass der Stop-Job zuverlässig läuft, selbst wenn der zugehörige Deploy-Job zuvor fehlgeschlagen ist. Ein Review-App-Stack, der halb aufgebaut wurde und dann nie wieder abgerissen wird, weil der Cleanup-Job an eine erfolgreiche vorherige Pipeline gekoppelt war, sammelt sich über Wochen zu erheblichem Ressourcen-Müll an.


# .gitlab-ci.yml -- ephemeral review app with automatic teardown
deploy-review:
  stage: deploy
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    url: https://pr-$CI_MERGE_REQUEST_IID.review.example.com
    on_stop: stop-review
  script:
    - export PR_NUMBER=$CI_MERGE_REQUEST_IID
    - envsubst < docker-compose.review.yml > compose.rendered.yml
    - docker compose -p review-pr-$PR_NUMBER -f compose.rendered.yml up -d
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

stop-review:
  stage: deploy
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    action: stop
  script:
    - docker compose -p review-pr-$CI_MERGE_REQUEST_IID down -v
  when: manual
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

6. Labels und Metadaten für zuverlässiges Cleanup

Selbst mit einem gut konfigurierten on_stop-Job bleiben gelegentlich verwaiste Ressourcen zurück, etwa wenn ein Runner während des Cleanups abstürzt. Für ephemere Review Apps empfiehlt sich deshalb ein zusätzlicher, zeitgesteuerter Aufräum-Job, der alle Container und Volumes mit einem bestimmten Label identifiziert und nach Ablauf einer maximalen Lebensdauer automatisch entfernt, unabhängig vom Pipeline-Status des ursprünglichen Pull Requests.

Ein konsistentes Label-Schema ist dafür Voraussetzung: Jeder Container einer ephemeren Review App bekommt beim Start ein Label wie review-app=true zusammen mit der Pull-Request-Nummer und dem Erstellungszeitpunkt. Ein täglich laufender Cron-Job filtert dann per docker ps --filter "label=review-app=true" alle betroffenen Ressourcen und entfernt jene, deren Erstellungszeitpunkt eine definierte Frist, etwa 14 Tage, überschreitet.

7. Ressourcenverbrauch und Limits bei vielen parallelen PRs

Je aktiver ein Team arbeitet, desto mehr ephemere Review Apps laufen gleichzeitig, und jede davon belegt CPU, Arbeitsspeicher und Speicherplatz auf dem Review-Host. Ohne Limits kann ein einzelner ressourcenhungriger Pull Request alle anderen Review Apps auf demselben Host verlangsamen. Für jeden Service im Compose-File sollten deshalb deploy.resources.limits gesetzt werden, auch wenn Compose diese außerhalb von Swarm nur als Empfehlung an die Docker Engine weitergibt, nicht als harte Kubernetes-artige Garantie.

Zusätzlich empfiehlt sich eine Obergrenze für die Anzahl gleichzeitig laufender ephemerer Review Apps pro Host. Erreicht ein Team diese Grenze, kann die Pipeline ältere, inaktive Review Apps automatisch stoppen, bevor eine neue gestartet wird, statt den Host durch unbegrenztes Wachstum zu überlasten. Diese Grenze lässt sich einfach über einen Zähler-Job realisieren, der vor jedem Deploy die Anzahl laufender Review-App-Netzwerke prüft.

8. Typische Fehler bei ephemeren Review Apps

Der häufigste Fehler beim Aufbau von ephemeren Review Apps ist, produktionsnahe Secrets in die Review-Umgebung zu kopieren, etwa echte Zahlungsdienst-Zugangsdaten oder echte Kunden-E-Mail-Konfiguration. Reviewer testen typischerweise mit unbedachten Eingaben, und eine Review App, die versehentlich echte E-Mails verschickt oder echte Zahlungen anstößt, verursacht handfeste Probleme außerhalb der eigentlichen Testumgebung.


# WRONG: production secrets leaking into a review app
docker compose -p review-pr-482 --env-file .env.production up -d

# RIGHT: dedicated, sandboxed secrets for every review app
docker compose -p review-pr-482 --env-file .env.review-sandbox up -d
# .env.review-sandbox points to test payment gateways, mail catchers, etc.

Ein zweiter verbreiteter Fehler ist, den Cleanup-Job nicht robust gegen Teilausfälle zu gestalten. Wenn ein docker compose down mangels Berechtigungen fehlschlägt oder der Runner während des Vorgangs neu startet, bleibt eine ephemere Review App unbemerkt aktiv. Ein regelmäßiger, unabhängiger Aufräum-Job auf Basis von Labels und Alter fängt genau solche Teilausfälle ab, statt sich allein auf den Erfolg des ursprünglichen Stop-Jobs zu verlassen.

9. Review Apps im Vergleich zu geteilten Staging-Umgebungen

Die folgende Tabelle stellt geteilte Staging-Umgebungen den ephemeren Review Apps pro Pull Request gegenüber.

Aspekt Geteiltes Staging Ephemere Review App Konsequenz
Isolation zwischen Branches Keine, Änderungen überschreiben sich Vollständig, ein Stack pro PR Kein gegenseitiges Überschreiben mehr
Verfügbarkeit für Review Warteschlange bei vielen PRs Sofort und parallel verfügbar Schnelleres Feedback im Review
Lebensdauer Dauerhaft, manuell gepflegt An PR-Lebenszyklus gekoppelt Kein manueller Reset nötig
Ressourcenverbrauch Konstant, auch ungenutzt Nur während PR aktiv ist Geringere Dauerkosten
Setup-Aufwand Gering, einmalig Höher, aber einmalig automatisiert Lohnt sich ab wenigen parallelen PRs

Der Mehraufwand beim initialen Aufbau von ephemeren Review Apps amortisiert sich, sobald ein Team regelmäßig mit mehreren parallel offenen Pull Requests arbeitet. Die Zeitersparnis durch sofort verfügbare, konfliktfreie Testumgebungen übersteigt den Automatisierungsaufwand meist bereits nach den ersten Wochen produktiven Einsatzes.

Mironsoft

Review Apps, Container-Automatisierung und Deployment-Infrastruktur

Review Apps pro Pull Request einrichten?

Wir bauen ephemere Review-App-Pipelines mit Docker Compose, dynamischem Routing und zuverlässigem Cleanup, damit jeder Pull Request seine eigene, sofort testbare Umgebung bekommt.

Compose-Templates

Pro-PR-Stacks mit isolierten Netzwerken und Volumes aufsetzen

Dynamisches Routing

Traefik-basiertes Subdomain-Routing inklusive Wildcard-TLS einrichten

Cleanup-Automatisierung

Label-basierte Aufräum-Jobs gegen verwaiste Ressourcen implementieren

10. Zusammenfassung

Eine ephemere Review App pro Pull Request löst das grundlegende Problem geteilter Staging-Umgebungen: Änderungen verschiedener Branches überschreiben sich nicht mehr gegenseitig, und jeder Reviewer bekommt eine sofort erreichbare, isolierte Testumgebung. Docker Compose mit projektbasierter Isolation, dynamischem Routing über Traefik und vorgeladenen Seed-Datenbanken macht den Aufbau schnell genug, um pro Pull Request praktikabel zu sein.

Der entscheidende Erfolgsfaktor liegt im zuverlässigen Abriss: Ohne robuste, labelbasierte Cleanup-Automatisierung sammeln sich verwaiste Container und Volumes an, die Ressourcen binden und Kosten verursachen. Wer den kompletten Lebenszyklus, vom Aufbau bei jedem Push bis zum garantierten Abriss beim Schließen des Pull Requests, konsequent in die CI-Pipeline integriert, gewinnt einen der wirkungsvollsten Hebel für schnelleres, konfliktfreies Code-Review.

Ephemere Review Apps — Das Wichtigste auf einen Blick

Ein Stack pro PR

Compose-Projektname aus der PR-Nummer ableiten, damit parallele Review Apps nie kollidieren.

Dynamisches Routing

Traefik-Labels und Wildcard-TLS machen jede Review App über eine eigene Subdomain erreichbar.

Schnelles Seeding

Vorgeladene, anonymisierte Datensätze statt Live-Migrationen pro Review App.

Labelbasiertes Cleanup

Zeitgesteuerter Aufräum-Job als Absicherung gegen fehlgeschlagene on_stop-Jobs.

11. FAQ: Ephemere Review App Container pro Pull Request

1Was ist eine ephemere Review App?
Eine isolierte Instanz pro Pull Request, die automatisch entsteht und beim Schließen wieder verschwindet.
2Wie werden mehrere Review Apps isoliert?
Über einen eindeutigen Compose-Projektnamen pro Pull Request, meist basierend auf der PR-Nummer.
3Wie ist eine Review App erreichbar?
Über Traefik-Labels, die automatisch eine eigene Subdomain pro Pull Request routen.
4Wie werden Datenbanken schnell befüllt?
Mit einem vorgeladenen, anonymisierten Seed-Datensatz statt Live-Migrationen.
5Wie wird der Lebenszyklus automatisiert?
Über CI-Trigger für Aufbau, Aktualisierung und einen on_stop-Job für den Abriss.
6Was tun bei fehlgeschlagenem Cleanup?
Ein zeitgesteuerter, labelbasierter Aufräum-Job als zusätzliche Absicherung.
7Dürfen Produktions-Secrets genutzt werden?
Nein, immer dedizierte, sandboxed Zugangsdaten für Review Apps verwenden.
8Wie werden Ressourcenlimits gesetzt?
Über deploy.resources.limits pro Service, plus Obergrenze für parallele Review Apps.
9Unterschied zu geteiltem Staging?
Vollständig isoliert und an den PR-Lebenszyklus gekoppelt, kein gegenseitiges Überschreiben.
10Welches Tool für dynamisches Routing?
Traefik, wegen automatischer Container-Erkennung und labelbasiertem Routing.