Kamal läuft nicht auf Ihrem VPS. Es ist ein Deployment-Werkzeug, das Sie auf Ihrem eigenen Rechner oder CI-Runner installieren und das sich per SSH mit dem Server verbindet. Basecamp hat es entwickelt, um Rails-Anwendungen ohne Kubernetes auszuliefern, aber es deployt alles, was sich in ein Docker-Image bauen lässt.
Dieser Unterschied ändert, wonach Sie suchen. Der VPS ist Kamals Ziel und muss deshalb groß genug für Ihre Anwendung, deren Datenbanken und einige Tage an Image-Versionen sein. Kamal selbst belegt auf dem Server nichts.
Was Kamal tatsächlich auf dem Server ablegt
kamal setup verbindet sich per SSH (standardmäßig als root, authentifiziert über Ihren SSH-Key) und führt drei Schritte aus: Docker installieren, falls es fehlt, die deklarierten Accessories starten, dann die App deployen. Danach laufen auf dem Host:
- kamal-proxy — ein kleiner HTTP-Proxy, der die Ports 80 und 443 belegt, Let’s-Encrypt-Zertifikate bezieht und eingehende Anfragen während eines Deploys zurückhält, bis der neue Container bereit ist.
- Ihre App-Container — ein Satz pro Rolle aus
config/deploy.yml. - Accessories — die Postgres-, Redis- oder sonstigen Dienste, die Sie in der Konfiguration aufgeführt haben.
Kamal selbst ist ein Gem (gem install kamal, aktuell 2.12.0) und hinterlässt keinen Daemon.
Voraussetzungen
Bevor Sie beginnen, brauchen Sie:
- Einen VPS mit frischer Linux-Installation und root-Zugang per SSH-Key (Ubuntu 24.04 ist eine vernünftige Wahl)
- Eine Container-Registry, aus der Ihr Server ziehen kann — Docker Hub, GitHub Container Registry oder die Ihres Anbieters
- Ruby lokal für
gem install kamal; ohne Ruby lässt sich Kamal alternativ aus einem Container-Image heraus betreiben, mit einigen Einschränkungen - Ein funktionierendes
Dockerfilefür Ihre Anwendung
Die Wahl des VPS-Anbieters
Da der Server nur Container ausführt, zählen vor allem Netzwerkqualität, Reserve beim Speicherplatz und wie schnell Sie einen Host neu aufsetzen können:
| Anbieter | Preis | Merkmale | Affiliate-Link |
|---|---|---|---|
| Contabo VPS | 5,99 EUR/Monat | 400 GB Speicher fangen große Images und lange Rollback-Historie ab | Contabo VPS |
| Hetzner Cloud | 5,49 EUR/Monat | 2 vCPU / 4 GB / 40 GB NVMe, Snapshots für schnelles Neuaufsetzen | Hetzner Cloud |
| DigitalOcean | 6 USD/Monat | Beste Dokumentation und API, um den Host selbst zu skripten | DigitalOcean |
| Vultr | 5 USD/Monat | Große Regionsauswahl, um die App nah an ihren Nutzern zu platzieren | Vultr |
| Linode | 5 USD/Monat | Kalkulierbare Preise, unkomplizierte Netzwerkeinrichtung | Linode |
Einen vollständigen Überblick bietet unser großer VPS-Vergleich.
DigitalOcean ist hier der einfachste Einstieg, weil die Dokumentation genau die Host-Arbeit abdeckt, die Kamal Ihnen nicht abnimmt: Firewall-Regeln, Swap und automatische Updates.
Den Server vorbereiten
- Den VPS aufsetzen mit einem minimalen Ubuntu-24.04-Image und hinterlegtem SSH-Key.
- Prüfen, dass root per SSH funktioniert, denn so verbindet sich Kamal standardmäßig:
ssh root@ihre-vps-ip
- Nur das Nötige öffnen. kamal-proxy terminiert TLS auf dem Server, die Ports 22, 80 und 443 genügen also:
ufw allow 22,80,443/tcp && ufw enable
Docker müssen Sie nicht selbst installieren. Kamal installiert es beim ersten kamal setup, falls es fehlt.
Kamal installieren und die Konfiguration schreiben
Auf Ihrem eigenen Rechner, im Verzeichnis Ihrer Anwendung:
gem install kamal
kamal init
kamal init legt config/deploy.yml an. Eine minimal funktionierende Konfiguration braucht einen Service-Namen, ein Image und mindestens einen Host:
service: myapp
image: your-registry-user/myapp
servers:
web:
hosts:
- 203.0.113.10
registry:
username: your-registry-user
password:
- KAMAL_REGISTRY_PASSWORD
proxy:
ssl: true
host: app.example.com
Secrets liegen in .kamal/secrets, das Kamal beim Deploy liest. Zuerst sucht es .kamal/secrets-common, danach .kamal/secrets:
KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
Halten Sie diese Datei aus der Versionsverwaltung heraus und ziehen Sie den Wert aus Ihrer Shell-Umgebung oder einem Passwortmanager.
Der erste Deploy
kamal setup
Dieser eine Befehl installiert Docker, startet Accessories, baut und pusht Ihr Image und fährt die App hoch. Jeder weitere Deploy lautet:
kamal deploy
Was auf dem Host läuft, zeigt:
kamal app containers
Wo das Image gebaut wird
Standardmäßig baut Kamal lokal, auf dem Rechner, von dem aus Sie es aufrufen, und pusht dann in die Registry. Der Server zieht nur. Ist Ihr Notebook arm64 und der VPS amd64, legen Sie entweder die Zielarchitektur fest oder verweisen Kamal auf einen Remote-Builder:
builder:
arch: amd64
remote: ssh://[email protected]
Cross-Builds über Emulation sind so langsam, dass es bei jedem Deploy auffällt. Ist der VPS Ihre einzige amd64-Maschine, kann er zugleich als Builder dienen — dann dimensionieren Sie ihn aber für einen Docker-Build und nicht bloß für den Betrieb der App, was meist einen Tarif höher bedeutet.
Den Speicherplatz dimensionieren
Kamal behält alte Container und Images auf dem Server, damit kamal rollback eine frühere Version starten kann, ohne erneut aus der Registry zu ziehen. Standardmäßig räumt es sie nach drei Tagen auf. Rechnen Sie mit den Daten Ihrer Anwendung plus etwa drei Tagen Image-Versionen samt gemeinsamer Basis-Layer.
Ein 1 GB großes Image, mehrmals täglich deployt, liegt bequem auf Hetzners 40 GB NVMe. Ein 3 GB großes Image füllt eine 25-GB-Platte binnen einer Woche, und eine volle Platte bricht den nächsten Deploy ab, nicht den laufenden — weshalb das Problem leicht übersehen wird, bis es dringend ist.
Umschalten ohne Downtime
kamal-proxy leitet den Traffic erst auf den neuen Container um, sobald dieser GET /up mit einer 200 beantwortet. Daraus folgt zweierlei:
- Ihre App braucht einen
/up-Endpunkt. Rails bringt einen mit, andere Frameworks brauchen meist ein paar Zeilen. - Der Endpunkt darf erst dann 200 liefern, wenn die App wirklich Anfragen bedienen kann. Antwortet er, bevor die Datenbankverbindungen stehen, landen Nutzer zu früh auf dem neuen Container.
Besteht der Health-Check nie, läuft der Deploy in einen Timeout und Kamal lässt den alten Container weiter ausliefern.
Das Deployment absichern
- Kamal verbindet sich per SSH als root, deaktivieren Sie also die Passwort-Authentifizierung vollständig und setzen Sie auf Keys.
- Lassen Sie TLS von kamal-proxy erledigen. Ein zweiter Reverse Proxy davor verkompliziert nur den Zertifikatspfad.
- Richten Sie auf 4-GB-Hosts Swap ein. Während eines Deploys laufen alter und neuer Container kurzzeitig gleichzeitig, und ein Host, der dabei zu swappen beginnt, wird langsam genug, um den Health-Check-Timeout zu reißen.
- Halten Sie das Registry-Passwort in
.kamal/secretsstatt inconfig/deploy.yml, das eingecheckt wird.
Abschließende Hinweise
- Rufen Sie
kamal deployaus der CI auf, sobald der manuelle Weg funktioniert. Die Konfiguration bleibt identisch, nur die Quelle der Secrets ändert sich. kamal rollback [version]ist sofort erledigt, solange das alte Image noch auf der Platte liegt. Prüfen Sie mitkamal app containers, ob es ein Rollback-Ziel überhaupt noch gibt.- Eine zweite App auf demselben Host unterstützt Kamal 2 — kamal-proxy routet nach Hostname, jede App braucht also nur einen eigenen
service-Namen undproxy.host.
Mehr zur Wahl des darunterliegenden Servers finden Sie in unserem großen VPS-Vergleich.
Frequently asked questions
Läuft Kamal auf dem VPS oder auf meinem eigenen Rechner?
Kamal läuft auf Ihrem Rechner oder Ihrem CI-Runner. Es ist ein Ruby-Gem, das sich per SSH mit dem Server verbindet, Docker installiert, falls es fehlt, und Ihre Container startet. Auf dem VPS bleiben nur kamal-proxy sowie Ihre App- und Accessory-Container zurück, niemals Kamal selbst.
Wie viel Speicherplatz braucht ein VPS als Kamal-Ziel?
Planen Sie die Daten Ihrer Anwendung plus rund drei Tage Image-Versionen ein, denn Kamal behält alte Container und Images für Rollbacks und räumt sie standardmäßig nach drei Tagen auf. Ein 1 GB großes Image passt bei mehreren Deploys pro Tag bequem auf 40 GB, ein 3 GB großes auf 25 GB nicht.
Warum läuft mein Kamal-Deploy in einen Timeout und wird zurückgerollt?
kamal-proxy leitet den Traffic erst um, wenn der neue Container GET /up mit einer 200 beantwortet. Fehlt dieser Endpunkt in Ihrer Anwendung, oder liefert er noch einen Fehler, während die App startet, besteht der Health-Check nie und Kamal kehrt zum vorherigen Container zurück.