Fly.io Deployment mit Claude Code 2026

Fly.io ist die Developer-freundlichste Plattform für globale App-Deployments — kein Kubernetes-Overhead, trotzdem weltweite Verteilung. Claude Code generiert fly.toml Konfigurationen, Volumes, Secrets und Multi-Region-Setups für jede Anwendung.

🚀
Fly Machines Keine VMs — schnelle Container-Instanzen global
💾
Persistent Volumes SQLite in Production — sicher und performant
🔒
Secrets Management flyctl secrets set — keine .env in Git
🌍
Multi-Region Fly Postgres + LiteFS weltweit repliziert

Wer 2026 eine Webanwendung deployt, will keine Stunden mit Cloud-Konfigurationen verschwenden. Fly.io hat sich als klarer Favorit für Developer etabliert, die schnell global deployen wollen — ohne Kubernetes, ohne komplexe IAM-Rollen, ohne Load-Balancer-Konfiguration von Hand. Claude Code versteht die gesamte Fly.io-Architektur und kann fly.toml-Dateien, Volume-Setups, Secrets-Konfigurationen und Multi-Region-Postgres-Setups in Minuten generieren.

Dieser Guide zeigt, wie du Claude Code als Deployment-Copiloten für Fly.io einsetzt — von der ersten fly.toml bis zum weltweit replizierten Datenbanksetup.


1. Fly.io Grundlagen — Machines, Regions und flyctl

Fly.io unterscheidet sich fundamental von klassischen Cloud-Providern. Der wichtigste Unterschied: Fly arbeitet mit Machines, nicht mit VMs. Eine Fly Machine ist ein leichtgewichtiger Container, der auf Firecracker-MicroVMs basiert und in Millisekunden startet — ideal für serverlose Workloads und globale Deployments.

Grundlagen Fly.io Architektur-Konzepte

Konzept Beschreibung Vergleich
Machine Container-Instanz auf Firecracker-Basis, startet in <500ms AWS Fargate Task, aber schneller
App Logische Gruppe von Machines mit gemeinsamer Konfiguration ECS Service / Heroku App
Region Fly.io hat 30+ Regionen weltweit (ams, fra, sin, lax ...) AWS Availability Zone
Volume Persistenter Block-Storage, an Machine gebunden EBS Volume / Persistent Disk
Anycast IP Globale IP, Traffic wird zur nächsten Region geroutet AWS Global Accelerator

Erste Schritte mit flyctl

Das CLI-Tool flyctl (auch als fly verfügbar) ist das zentrale Werkzeug für alle Fly.io-Operationen. Claude Code kann flyctl-Befehle generieren und erklären:

# flyctl installieren (macOS) brew install flyctl # Linux/WSL curl -L https://fly.io/install.sh | sh # Einloggen fly auth login # Neue App erstellen und initialisieren fly launch # Vorhandene App deployen fly deploy # Logs in Echtzeit fly logs # SSH in laufende Machine fly ssh console # App-Status und Machines anzeigen fly status fly machines list
💡 Claude Code Prompt: "Ich habe eine Node.js Express API in diesem Verzeichnis. Erstelle eine vollständige fly.toml Konfiguration mit Health-Check, Auto-Stop und 512MB RAM. Erkläre jeden Parameter."

fly launch — der erste Deploy

fly launch erkennt automatisch die Anwendungsstruktur (Dockerfile, package.json, requirements.txt) und erstellt eine initiale fly.toml. Claude Code kann diesen Prozess weiter optimieren:

# Fly.io erkennt automatisch: Node.js / Python / Go / Ruby / etc. fly launch --name meine-api --region fra --no-deploy # Danach fly.toml anpassen, dann deployen fly deploy --strategy rolling # Deployment-Strategien: # rolling — schrittweise, ohne Downtime (Standard) # bluegreen — parallel deploy, dann Switchover # canary — X% Traffic auf neue Version # immediate — sofort, mit möglichem kurzen Ausfall

2. fly.toml Konfiguration — [build], [http_service], [env], [mounts]

Die fly.toml ist die zentrale Konfigurationsdatei für jede Fly.io-Anwendung. Sie definiert Build-Prozess, HTTP-Service, Umgebungsvariablen und Storage. Claude Code versteht die komplette fly.toml-Syntax und kann projektspezifische Konfigurationen generieren.

fly.toml Vollständige Beispiel-Konfiguration (Node.js API)

# fly.toml — generiert mit Claude Code app = "meine-api" primary_region = "fra" kill_signal = "SIGTERM" kill_timeout = 30 [build] dockerfile = "Dockerfile" # Alternativ: Buildpacks ohne Dockerfile # builder = "heroku/buildpacks:20" [build.args] NODE_ENV = "production" BUILD_VERSION = "2026-05-06" [env] PORT = "8080" NODE_ENV = "production" LOG_LEVEL = "info" # Keine Secrets hier! Nur nicht-sensitive Werte [http_service] internal_port = 8080 force_https = true auto_stop_machines = "stop" auto_start_machines = true min_machines_running = 0 [http_service.concurrency] type = "requests" hard_limit = 250 soft_limit = 200 [[http_service.checks]] grace_period = "5s" interval = "30s" method = "GET" path = "/health" protocol = "http" timeout = "5s" [[vm]] memory = "512mb" cpu_kind = "shared" cpus = 1

Die [build]-Section im Detail

Der [build]-Block steuert, wie Fly.io deine Anwendung containerisiert:

[build] # Option 1: Eigenes Dockerfile dockerfile = "Dockerfile" # Option 2: Nixpacks (automatische Erkennung) builder = "nixpacks" # Option 3: Spezifisches Image aus Registry image = "ghcr.io/mein-user/meine-app:latest" [build.args] # Docker Build-Args (nur für Build-Phase) PYTHON_VERSION = "3.12" BUNDLE_WITHOUT = "development:test"

Die [http_service]-Section — Traffic und Auto-Scaling

Fly.io bietet eingebautes Auto-Stop und Auto-Start für Machines — ideal für Anwendungen mit variablem Traffic:

[http_service] internal_port = 8080 force_https = true # Auto-Stop: "stop" oder "suspend" (suspend = schneller Restart) auto_stop_machines = "suspend" auto_start_machines = true # Minimum laufende Machines (0 = scale-to-zero) min_machines_running = 1 # Concurrency-Limits für Load-Balancing [http_service.concurrency] type = "connections" # oder "requests" hard_limit = 100 soft_limit = 80 # Custom Headers [[http_service.checks]] grace_period = "10s" interval = "15s" method = "GET" path = "/__health" protocol = "http" timeout = "3s" [http_service.checks.headers] X-Health-Check = "fly"
⚠️ Wichtig: auto_stop_machines = "stop" stoppt die Machine komplett (kalt). "suspend" hält den Memory-State — Restarts dauern nur ~100ms statt mehrerer Sekunden. Für APIs mit niedrigem Traffic ist "suspend" fast immer die bessere Wahl.

3. Persistent Volumes — SQLite in Production mit Fly Volumes

Fly.io Volumes sind persistente Block-Storage-Einheiten, die an eine einzelne Machine in einer spezifischen Region gebunden sind. Das macht sie ideal für SQLite-Datenbanken, lokale Caches und File-Uploads — ohne den Overhead eines externen Datenbankdienstes.

Volumes Volume erstellen und mounten

# Volume erstellen (Region muss mit App-Region übereinstimmen) fly volumes create app_data \ --region fra \ --size 10 \ --app meine-api # Volume auflisten fly volumes list # Volume-Details anzeigen fly volumes show vol_xxxxxxxxx # Volume-Snapshot erstellen (Backup) fly volumes snapshots create vol_xxxxxxxxx # Volume-Größe erweitern (nicht verkleinern!) fly volumes extend vol_xxxxxxxxx --size 20

Volumes in fly.toml einbinden

# fly.toml — Volume Mount Konfiguration [[mounts]] source = "app_data" # Name des Volumes (aus fly volumes create) destination = "/data" # Mount-Pfad im Container # Mehrere Volumes (z.B. DB + Uploads getrennt) [[mounts]] source = "sqlite_db" destination = "/db" [[mounts]] source = "user_uploads" destination = "/uploads"

SQLite in Production — Best Practices mit Fly Volumes

SQLite auf einem Fly Volume ist eine legitime Production-Strategie für viele Anwendungstypen. Claude Code kann das Setup vollständig konfigurieren:

SQLite SQLite + WAL-Mode auf Fly Volume (Node.js Beispiel)

// db.js — SQLite auf Fly Volume mit WAL-Modus const Database = require('better-sqlite3'); const path = require('path'); // /data ist das gemountete Fly Volume const DB_PATH = process.env.DATABASE_PATH || '/data/app.db'; const db = new Database(DB_PATH); // WAL-Mode: bessere Concurrent-Reads, atomare Writes db.pragma('journal_mode = WAL'); db.pragma('synchronous = NORMAL'); db.pragma('foreign_keys = ON'); // Busy-Timeout für konkurrierende Zugriffe db.pragma('busy_timeout = 5000'); module.exports = db;
💡 SQLite vs. Fly Postgres: SQLite auf einem Fly Volume eignet sich hervorragend für Apps mit <10k Writes/Tag und primär Read-Workload. Für Multi-Region-Schreibzugriffe ist Fly Postgres + LiteFS die bessere Wahl (siehe Abschnitt 6).

Volume-Backups und Disaster Recovery

# Automatische Snapshots konfigurieren (via fly.toml) [[mounts]] source = "sqlite_db" destination = "/db" snapshot_retention = 5 # Letzte 5 Snapshots behalten auto_extend_size_threshold = 80 # Bei 80% Auslastung auto-erweitern auto_extend_size_increment = "5GB" --- # Manuelles SQLite-Backup per SSH fly ssh console -C "sqlite3 /db/app.db .dump" > backup_$(date +%Y%m%d).sql # Oder via Python-Script im Container fly ssh console -C "python3 /app/scripts/backup_db.py"

4. Secrets Management — flyctl secrets und sichere Konfiguration

Fly.io bietet ein eingebautes Secrets-Management-System, das deutlich sicherer ist als .env-Dateien in Git-Repositories. Secrets werden verschlüsselt gespeichert und als Umgebungsvariablen in die Machines injiziert — ohne dass sie jemals in Klartext auf der Festplatte landen.

Secrets flyctl secrets — Grundlegende Befehle

# Einzelnes Secret setzen fly secrets set DATABASE_URL="postgresql://user:pass@host/db" # Mehrere Secrets auf einmal fly secrets set \ API_KEY="sk-..." \ JWT_SECRET="super-secret-jwt-key" \ STRIPE_KEY="sk_live_..." # Secrets aus .env-Datei importieren (nur einmalig beim Setup) fly secrets import < .env.production # Secrets auflisten (Werte werden NICHT angezeigt) fly secrets list # Secret löschen fly secrets unset OLD_API_KEY # Deployment ohne Neustart (Secret erst beim nächsten Deploy aktiv) fly secrets set NEW_KEY="value" --stage

.env vs. fly secrets — Ein Vergleich

Kriterium .env Datei (lokal) fly secrets
Sicherheit Risiko bei Git-Commit, Klartext Verschlüsselt, nie im Repository
Rotation Manuell, neues Deploy nötig Automatischer Neustart der Machines
Audit Trail Kein eingebautes Logging Fly.io Dashboard + CLI History
Team-Zugriff Manuell teilen, Sync-Problem Zentral in Fly.io App, Rollen-basiert
CI/CD .env in CI-Secrets hinterlegen FLY_API_TOKEN reicht für Deploy

Secrets in der Anwendung nutzen

Fly Secrets werden als normale Umgebungsvariablen übergeben — kein spezieller SDK nötig:

// Node.js — Secrets als process.env const config = { database: process.env.DATABASE_URL, apiKey: process.env.API_KEY, jwtSecret: process.env.JWT_SECRET, }; # Python — via os.environ import os DATABASE_URL = os.environ["DATABASE_URL"] SECRET_KEY = os.environ["DJANGO_SECRET_KEY"] # Go — via os.Getenv apiKey := os.Getenv("API_KEY") if apiKey == "" { log.Fatal("API_KEY nicht gesetzt") }

Secrets in CI/CD-Pipelines (GitHub Actions)

# .github/workflows/deploy.yml name: Deploy to Fly.io on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: superfly/flyctl-actions/setup-flyctl@master - run: fly deploy --remote-only env: FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} # FLY_API_TOKEN einmalig generieren: fly tokens create deploy --expiry 168h

5. Private Networking — Fly WireGuard, 6PN und interne Service Discovery

Fly.io bietet ein integriertes privates Netzwerk für alle Apps innerhalb einer Organisation. Dieses sogenannte 6PN (6-Plane Network) basiert auf WireGuard und ermöglicht sichere Kommunikation zwischen Fly-Anwendungen — ohne öffentliche IPs oder externe Load-Balancer.

6PN Fly Private Networking — Architektur

Jede Fly Machine bekommt automatisch eine IPv6-Adresse im privaten fdaa::/8 Netzwerk. Alle Apps innerhalb einer Organisation können sich gegenseitig über diese Adressen erreichen — verschlüsselt via WireGuard, ohne Latenz-Overhead durch öffentliches Internet.

Internes DNS — .internal Adressen

Fly.io stellt automatisch DNS-Auflösung für interne Services bereit. Das Muster ist einfach und vorhersehbar:

# DNS-Schema für interne Fly-Services # Format: [qualifier].[app-name].internal # Alle Machines einer App (round-robin) meine-api.internal # Nur Machines in einer spezifischen Region fra.meine-api.internal ams.meine-api.internal # Fly Postgres intern ansprechen meine-db.internal:5432 # Redis-Cluster intern mein-redis.internal:6379 # Von App zu App kommunizieren # KEINE public URL nötig — direkt über .internal DATABASE_URL = "postgresql://user:pass@meine-db.internal:5432/mydb"

WireGuard Tunnel für lokale Entwicklung

Fly.io erlaubt es, den privaten Tunnel auch lokal zu nutzen — ideal für Datenbankzugriff während der Entwicklung:

# WireGuard-Konfiguration für lokalen Tunnel fly wireguard create fra # Peer-Datei exportieren fly wireguard create fra local-dev > fly-wireguard.conf # WireGuard Interface aktivieren (Linux/macOS) sudo wg-quick up fly-wireguard.conf # Jetzt direkt auf interne Services zugreifen: psql "postgresql://postgres:pass@meine-db.internal:5432/mydb" # Tunnel wieder deaktivieren sudo wg-quick down fly-wireguard.conf # Alternativ: fly proxy (kein WireGuard nötig) fly proxy 5432 -a meine-db # Dann: psql postgresql://localhost:5432/mydb

Service Discovery Interne Kommunikation zwischen Fly Apps

# fly.toml — App die interne Services nutzt [env] # Interne URLs — kein SSL-Overhead, direkte Verbindung REDIS_URL = "redis://mein-redis.internal:6379" WORKER_URL = "http://mein-worker.internal:8081" METRICS_URL = "http://mein-metrics.internal:9090" --- // Node.js — Verbindung zu internem Service const axios = require('axios'); // Direkte interne Kommunikation ohne DNS-Latenz async function callWorker(task) { const url = process.env.WORKER_URL + '/process'; return axios.post(url, task, { headers: { 'X-Internal-Token': process.env.INTERNAL_TOKEN } }); }

Fly.io als Service Mesh — wann es sinnvoll ist

Das 6PN-Netzwerk ermöglicht eine Microservices-Architektur ohne externen Service Mesh (Istio/Linkerd):

# Beispiel: Drei-Tier-Architektur auf Fly.io # frontend.toml — öffentlich zugänglich app = "meine-frontend" [http_service] internal_port = 3000 force_https = true [env] API_URL = "http://meine-api.internal:8080" --- # api.toml — intern + öffentlich für externe Clients app = "meine-api" [http_service] internal_port = 8080 [env] DB_URL = "postgresql://user:pass@meine-db.internal:5432/prod" CACHE_URL = "redis://mein-redis.internal:6379" --- # worker.toml — NUR intern, kein öffentlicher Port app = "mein-worker" # Kein [http_service] → nicht öffentlich erreichbar [env] DB_URL = "postgresql://user:pass@meine-db.internal:5432/prod"

6. Multi-Region Deployment — primary_region, Read Replicas und Fly Postgres mit LiteFS

Fly.io glänzt bei Multi-Region-Deployments. Während klassische Cloud-Anbieter komplexe Cross-Region-Setups erfordern, genügen bei Fly.io wenige Konfigurationszeilen. Claude Code kann die gesamte Multi-Region-Strategie inklusive Datenbankreplikation planen und implementieren.

fra (Primary) ams lhr sin nrt lax iad gru syd

Multi-Region App in mehrere Regionen deployen

# fly.toml — Multi-Region Konfiguration app = "meine-api" primary_region = "fra" # Primäre Region für Writes [http_service] internal_port = 8080 force_https = true auto_stop_machines = "suspend" auto_start_machines = true min_machines_running = 1 --- # Machines in anderen Regionen hinzufügen fly machine clone --region ams fly machine clone --region sin fly machine clone --region lax # Machines nach Region auflisten fly machines list # Skalieren: Anzahl Machines pro Region fly scale count 2 --region fra fly scale count 1 --region ams

Fly Postgres — Managed Database mit Multi-Region-Support

# Fly Postgres Cluster erstellen fly postgres create \ --name meine-db \ --region fra \ --vm-size shared-cpu-1x \ --volume-size 10 \ --cluster-size 2 # Postgres an App anhängen (setzt DATABASE_URL Secret) fly postgres attach meine-db --app meine-api # Read Replica in anderer Region erstellen fly machine clone \ --app meine-db \ --region sin \ --config '{"env":{"FLY_REGION":"sin","IS_FOLLOWER":"true"}}' # Failover manuell triggern fly postgres failover --app meine-db # Postgres-Status fly postgres db list --app meine-db fly postgres users list --app meine-db

LiteFS — SQLite Multi-Region-Replikation

LiteFS ist Fly.ios eigene Lösung für SQLite-Replikation über mehrere Regionen. Es ermöglicht SQLite-Writes auf dem Primary und schnelle Reads in jeder Region:

LiteFS SQLite global repliziert — fly.toml + LiteFS-Konfiguration

# fly.toml — LiteFS Setup app = "meine-app" primary_region = "fra" [[mounts]] source = "litefs_data" destination = "/var/lib/litefs" [env] LITEFS_DIR = "/var/lib/litefs" DATABASE_PATH = "/var/lib/litefs/db" --- # litefs.yml — LiteFS Konfiguration fuse: dir: "/var/lib/litefs" data: dir: "/var/lib/litefs/.data" # Consul für Leader-Election (oder Fly Consul) lease: type: consul advertise-url: "http://${HOSTNAME}.vm.${FLY_APP_NAME}.internal:20202" candidate: ${FLY_REGION == PRIMARY_REGION} promote: true consul: url: "http://localhost:8500" key: "app/litefs/primary" exec: - cmd: "/usr/local/bin/node /app/server.js" if-candidate: true --- # Dockerfile — LiteFS + App kombiniert FROM node:20-slim # LiteFS installieren COPY --from=flyio/litefs:0.5 /usr/local/bin/litefs /usr/local/bin/litefs WORKDIR /app COPY package*.json ./ RUN npm ci --production COPY . . # LiteFS als Entrypoint ENTRYPOINT ["litefs", "mount"]

Fly-Replay Header — Write-Forwarding an Primary

Fly.io bietet einen eleganten Mechanismus für Write-Forwarding: Der fly-replay-Header leitet Requests automatisch an die Primary-Region weiter:

// Middleware: Write-Requests an Primary weiterleiten function replayToPrimary(req, res, next) { const primaryRegion = process.env.PRIMARY_REGION || 'fra'; const currentRegion = process.env.FLY_REGION; // Schreibende Methoden prüfen if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)) { if (currentRegion !== primaryRegion) { // Fly.io routet diesen Request automatisch zur Primary-Region res.set('fly-replay', `region=${primaryRegion}`); return res.status(409).json({ message: 'Replaying to primary region', region: primaryRegion }); } } next(); } app.use(replayToPrimary);
💡 Claude Code für Multi-Region: "Ich habe eine Express-API mit SQLite und LiteFS. Erstelle die komplette Multi-Region-Konfiguration mit fly.toml, litefs.yml und dem Replay-Middleware für Write-Forwarding an die fra-Primary-Region."

Monitoring und Observability für Multi-Region-Deployments

# Fly.io eingebaute Metriken abrufen fly metrics show --app meine-api # Logs nach Region filtern fly logs --region fra fly logs --region sin # Machine-spezifische Logs fly logs --machine # Dashboard URL # https://fly.io/apps/meine-api/monitoring # Health-Check Status global fly checks list --app meine-api # Antwortzeiten per Region messen curl -H "fly-prefer-region: sin" https://meine-api.fly.dev/health curl -H "fly-prefer-region: fra" https://meine-api.fly.dev/health

Fly.io mit Claude Code — Produktiv in Minuten

Fly.io hat sich 2026 als eine der leistungsfähigsten Deployment-Plattformen für Developer-Teams etabliert. Die Kombination aus schnellen Machines, integriertem privatem Networking, einfachem Secrets-Management und globalem Postgres macht es zur idealen Plattform für moderne Webanwendungen.

Typischer Claude Code Workflow für Fly.io

1

fly.toml generieren: "Erstelle eine fly.toml für meine FastAPI-App mit Auto-Stop, 256MB RAM und Health-Check auf /health"

2

Dockerfile optimieren: "Optimiere mein Dockerfile für Fly.io — multi-stage build, non-root user, Health-Check"

3

Volumes und SQLite: "Konfiguriere ein Fly Volume für SQLite mit WAL-Mode und automatischen Backups"

4

Secrets migrieren: "Konvertiere meine .env.production in flyctl secrets set Befehle (API-Keys anonymisiert)"

5

Multi-Region: "Füge Read-Replicas in sin und lax hinzu und implementiere Write-Forwarding zum fra-Primary"

Cheatsheet Wichtigste flyctl Befehle auf einen Blick

# === DEPLOYMENT === fly launch # App initialisieren fly deploy # Deployen fly deploy --strategy bluegreen # Zero-Downtime Deploy # === SCALING === fly scale count 3 # 3 Machines fly scale memory 1024 # 1GB RAM fly scale vm shared-cpu-2x # VM-Größe ändern # === VOLUMES === fly volumes create data --size 10 # 10GB Volume fly volumes list # Volumes anzeigen fly volumes snapshots list # Backups anzeigen # === SECRETS === fly secrets set KEY=VALUE # Secret setzen fly secrets list # Secrets auflisten fly secrets unset KEY # Secret löschen # === DEBUGGING === fly ssh console # SSH in Machine fly logs # Echtzeit-Logs fly status # App-Status fly checks list # Health-Checks # === POSTGRES === fly postgres create # DB erstellen fly postgres attach # App verbinden fly proxy 5432 -a meine-db # Lokaler Tunnel

Die Stärke von Claude Code liegt darin, nicht nur einzelne Konfigurationsfragmente zu generieren, sondern die gesamte Deployment-Architektur zu verstehen und aufeinander abzustimmen — von der fly.toml über das LiteFS-Setup bis zur GitHub Actions Pipeline. Claude Code kennt die Fly.io-Dokumentation und aktuellen Best Practices und kann projektspezifische Konfigurationen in Minuten erstellen, die sonst Stunden Recherche erfordern würden.

Deployment-Modul im Kurs

Im Claude Code Mastery Kurs: Fly.io, Railway und Render im Vergleich — vollständige Deployment-Guides für Node.js, Python und Go-Anwendungen.

14 Tage kostenlos testen →