CI/CD Pipeline für SaaS-Startups
GitHub Actions vs GitLab CI, Pipeline-Stages, Docker Multi-Stage Builds, Preview Deployments und Secrets Management. Eine praxisnahe Anleitung für DACH-Startups.
Warum CI/CD kein Luxus ist
Viele SaaS-Startups deployen manuell. Jemand führt npm run build auf dem eigenen Rechner aus, kopiert die Dateien per SCP auf den Server und hofft, dass nichts kaputt geht. Das funktioniert bis zum dritten Teammitglied oder bis zum ersten Produktionsfehler, der nicht reproduzierbar ist.
CI/CD (Continuous Integration / Continuous Deployment) automatisiert den gesamten Weg vom Git-Push bis zur Produktion. Jede Änderung wird automatisch getestet, gebaut und deployt. Das klingt nach Overhead, spart aber ab Tag eins Zeit und verhindert eine ganze Kategorie von Fehlerquellen.
4x
Schnellere Releases
Teams mit CI/CD vs. manuelles Deployment
3x
Geringere Fehlerrate
Durch automatisierte Tests vor Deployment
15 Min.
Setup-Zeit
Für eine minimale GitHub Actions Pipeline
Die minimale Pipeline
Bevor wir über Tools diskutieren, hier die vier Stages die jede Pipeline braucht:
Pipeline-Stages (Push bis Produktion)
Lint & Format
Code-Qualität automatisch prüfen
ESLint, Prettier, TypeScript Compiler. Fängt 80% der trivialen Fehler ab.
Test
Unit- und Integrationstests ausführen
Jest, Vitest oder Playwright. Mindestens die kritischen Pfade.
Build
Produktions-Build erstellen
Docker Multi-Stage Build oder npm run build. Artefakte versionieren.
Deploy
Automatisch auf Staging oder Produktion
Staging bei jedem Push auf develop, Produktion bei Tags/Releases.
Jede Stage bricht ab wenn die vorherige fehlschlägt. Das ist der Kern von CI/CD: kein kaputtes Build erreicht Produktion.
GitHub Actions vs GitLab CI
Die zwei relevantesten Optionen für Startups im DACH-Raum. Beide sind ausgereift, beide haben Free Tiers.
GitHub Actions
Preis: 2.000 Minuten/Monat kostenlos (öffentliche Repos unbegrenzt) Runner: GitHub-hosted oder Self-Hosted
GitHub Actions nutzt YAML-Dateien in .github/workflows/. Das Ökosystem an fertigen Actions ist riesig: Tausende vorgefertigte Bausteine für Docker, AWS, Terraform, Slack-Benachrichtigungen.
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm run lint
- run: npm test
- run: npm run build
Stärken:
- Größtes Ökosystem an Actions (Marketplace)
- Nahtlose GitHub-Integration (Status Checks, PR Comments)
- Matrix Builds (Node 18, 20, 22 parallel testen)
- Self-Hosted Runner für sensible Workloads
Schwächen:
- Minuten-basiertes Pricing kann teuer werden
- YAML-Syntax manchmal umständlich
- Debugging von Workflows mäßig komfortabel
GitLab CI
Preis: 400 Minuten/Monat kostenlos Runner: GitLab SaaS oder Self-Hosted
GitLab CI nutzt eine einzelne .gitlab-ci.yml Datei. Docker-native, Auto DevOps für Standard-Projekte, integrierte Container Registry.
Stärken:
- Alles in einer Plattform (Code, CI, Registry, Monitoring)
- Docker-native Pipelines
- Self-Hosted GitLab für maximale Kontrolle
- Auto DevOps für Standard-Setups
- Besseres Pricing bei Self-Hosted
Schwächen:
- Kleineres Ökosystem an vorgefertigten Integrationen
- GitLab SaaS manchmal langsam
- Weniger Free Minutes als GitHub
- Interface kann überladen wirken
Monatliche Kosten (Team mit 5 Entwicklern, ~10.000 CI-Minuten)
*GitHub Free Tier reicht für kleine Teams oft aus. Überschrittene Minuten kosten $0,008/Min.
Docker Multi-Stage Builds
Einer der wichtigsten Bausteine einer guten Pipeline. Multi-Stage Builds halten Ihre Produktions-Images klein und sicher.
# Stage 1: Dependencies installieren
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
# Stage 2: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build
# Stage 3: Produktions-Image
FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/main.js"]
Warum Multi-Stage?
- Dev-Dependencies nicht im Produktions-Image (kleineres Image, weniger Angriffsfläche)
- Build-Cache nutzen (npm ci nur bei package.json-Änderung)
- Non-root User für Sicherheit
- Reproduzierbare Builds (gleicher Output auf jedem Rechner)
Preview Deployments
Einer der größten Produktivitätsgewinne: Jeder Pull Request bekommt automatisch eine eigene URL mit der aktuellen Version. Reviewer, Designer und Produktmanager können Änderungen testen bevor sie gemerged werden.
Vercel und Netlify bieten das out-of-the-box für Frontend-Projekte. Für Backend-Services müssen Sie es selbst aufbauen.
Minimal-Ansatz mit Docker:
- PR wird erstellt
- CI baut ein Docker Image mit dem PR-Branch
- Image wird auf dem Staging-Server unter einer Subdomain deployed:
pr-42.staging.ihredomain.de - Link wird als PR-Kommentar gepostet
- Bei Merge wird die Preview-Umgebung automatisch gelöscht
Dieser Workflow erfordert initiale Einrichtung, spart aber enorm viel Kommunikation. Kein "Kannst du mal auf deinem Branch schauen?" mehr.
Secrets Management
Passwörter, API-Keys und Tokens gehören nicht in den Code. Das klingt offensichtlich, passiert aber regelmäßig.
Regeln:
.envDateien gehören in.gitignore, ausnahmslos- CI/CD Secrets über die Plattform-eigene Verwaltung (GitHub Secrets, GitLab CI Variables)
- Produktions-Secrets über einen Secrets Manager (AWS Secrets Manager, HashiCorp Vault, Doppler)
- Secrets rotieren: API-Keys sollten regelmäßig erneuert werden
GitHub Actions Secrets:
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
API_KEY: ${{ secrets.API_KEY }}
Secrets sind im Log maskiert und können nicht im Klartext ausgelesen werden. Trotzdem: Minimieren Sie die Anzahl der Secrets und verwenden Sie Service Accounts statt persönlicher API-Keys.
Die Minimum-Pipeline
Für ein typisches NestJS/Next.js SaaS-Projekt empfehlen wir diese Pipeline als Ausgangspunkt:
Bei jedem Push auf einen Feature-Branch:
- Lint + Format Check
- Unit Tests
- Build (Docker Image)
- Preview Deployment (optional)
Bei Merge auf develop/staging:
- Alle obigen Schritte
- Integration Tests gegen Staging-Datenbank
- Deploy auf Staging-Umgebung
- Slack-Notification
Bei Release-Tag:
- Alle obigen Schritte
- Docker Image taggen und in Registry pushen
- Deploy auf Produktion
- Health Check nach Deployment
- Rollback wenn Health Check fehlschlägt
Diesen gesamten Workflow einmal aufzusetzen kostet zwei bis drei Tage Entwicklungszeit. Danach läuft er automatisch. Teams, die Infrastruktur-Aufgaben an einen Subscription-Development-Partner delegieren, können das parallel zur Feature-Entwicklung aufbauen, ohne den Sprint zu blockieren.
Häufige Fehler
- Keine Pipeline am Anfang: "Wir machen CI/CD später" wird zu "Wir deployen seit 2 Jahren manuell"
- Zu komplexe Pipeline: Starten Sie minimal. Lint, Test, Build, Deploy. Alles andere kommt später
- Keine Staging-Umgebung: Direkt auf Produktion zu deployen ohne Staging ist russisches Roulette
- Secrets im Code: Einmal committed, immer in der Git-History.
git-secretsals Pre-Commit-Hook nutzen - Flaky Tests ignorieren: Tests die manchmal grün und manchmal rot sind untergraben das Vertrauen in die Pipeline
Fazit
Eine CI/CD Pipeline ist die Grundlage für professionelle Softwareentwicklung. Sie kostet einen Nachmittag für das Basis-Setup und wird sich ab dem ersten Tag amortisieren. Starten Sie mit GitHub Actions (größtes Ökosystem, einfachster Einstieg) und erweitern Sie nach Bedarf.
Die beste Pipeline ist die, die existiert. Perfektion kommt iterativ.
Verwandte Themen
Wir suchen Senior Engineers
100% Remote, DACH