Infrastruktur

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.

Christoph Dietrich2026-04-2813 Min. Lesezeit

CI/CD Pipeline für SaaS-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 Actions (Free Tier)€0*
GitHub Team€19/User
GitLab Premium€29/User
GitLab Self-Hosted~€15 (Server)

*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:

  1. PR wird erstellt
  2. CI baut ein Docker Image mit dem PR-Branch
  3. Image wird auf dem Staging-Server unter einer Subdomain deployed: pr-42.staging.ihredomain.de
  4. Link wird als PR-Kommentar gepostet
  5. 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:

  • .env Dateien 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:

  1. Lint + Format Check
  2. Unit Tests
  3. Build (Docker Image)
  4. Preview Deployment (optional)

Bei Merge auf develop/staging:

  1. Alle obigen Schritte
  2. Integration Tests gegen Staging-Datenbank
  3. Deploy auf Staging-Umgebung
  4. Slack-Notification

Bei Release-Tag:

  1. Alle obigen Schritte
  2. Docker Image taggen und in Registry pushen
  3. Deploy auf Produktion
  4. Health Check nach Deployment
  5. 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

  1. Keine Pipeline am Anfang: "Wir machen CI/CD später" wird zu "Wir deployen seit 2 Jahren manuell"
  2. Zu komplexe Pipeline: Starten Sie minimal. Lint, Test, Build, Deploy. Alles andere kommt später
  3. Keine Staging-Umgebung: Direkt auf Produktion zu deployen ohne Staging ist russisches Roulette
  4. Secrets im Code: Einmal committed, immer in der Git-History. git-secrets als Pre-Commit-Hook nutzen
  5. 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

Bereit loszulegen?

Buchen Sie ein kostenloses Erstgespräch.

Erstgespräch buchen

Wir suchen Senior Engineers

100% Remote, DACH

Wir respektieren Ihre Privatsphäre

Diese Website verwendet Cookies für essentielle Funktionen und optional für Analyse und Marketing. Datenschutzerklärung