Hoe je Claude Code je Ghost-blog laat deployen (DNS, VPS en Ghost API)

Een stapsgewijze handleiding om Claude Code autonoom Cloudflare DNS te laten configureren, een Hetzner VPS op te zetten via SSH, Ghost te deployen met Traefik, en de blog te initialiseren via de Ghost Admin API — met eerlijke kanttekeningen over wat nog steeds een mens vereist.

Hoe je Claude Code je Ghost-blog laat deployen (DNS, VPS en Ghost API)
Ook beschikbaar in het English, Deutsch, Français, Español.

Je hebt een domein. Je hebt een Hetzner-account. Je wilt Ghost draaien op je eigen server met HTTPS, Cloudflare ervoor, en een MySQL-database erachter. Het handmatige pad kost twee uur: server aanmaken, SSH-verbinding maken, Docker Compose configureren, vechten met Let's Encrypt, Traefik debuggen, Ghost initialiseren via een browserformulier.

Er is een ander pad. Geef de klus aan Claude Code. Geef het je inloggegevens en een taakbeschrijving, en het configureert Cloudflare DNS, deployt de stack via SSH, en initialiseert Ghost via de Admin API zonder dat jij een terminal aanraakt. Zo is clawstack.run opgezet.

Dit artikel documenteert precies wat Claude zelfstandig kan doen, wat nog een menselijke klik vereist, en hoe je de overdracht structureert zodat het in één keer werkt.


Wat Claude Code wel en niet kan

Claude Code heeft toegang tot je bestandssysteem, een terminal, en elke API waar je het naar verwijst. Dat dekt het grootste deel van deze deployment. Maar sommige dingen zitten nog achter browser-UI's zonder API-equivalent.

Claude regelt zelfstandig: - Cloudflare DNS A-records aanmaken via de API - .env-bestanden en Docker Compose-configuraties genereren - Via SSH inloggen op de server en commando's uitvoeren - Deployment-bestanden uploaden - Docker-containers starten - Ghost initialiseren via de Admin API (admin-account aanmaken, eerste bericht, sitetitel) - Fouten diagnosticeren door logs te lezen en correcties toe te passen

Dit moet je handmatig doen (eenmalige klikken): - De Hetzner-server aanmaken (geen Hetzner API-sleutel beschikbaar — of je voegt er een toe en Claude regelt dit ook) - De Cloudflare SSL/TLS-modus instellen op Full (Strict) in het dashboard - De Ghost Admin API-sleutel ophalen uit de Ghost admin-UI na de eerste login

Al het andere is automatiseerbaar. De twee handmatige stappen kosten samen minder dan vijf minuten.


Wat je nodig hebt voordat je begint

  • Een domein met DNS beheerd bij Cloudflare
  • Een Cloudflare API-token met Zone / DNS / Edit-rechten, afgebakend op jouw domein
  • Een Hetzner-account (of een andere VPS-provider — pas het IP hieronder aan)
  • Een SSH-wachtwoord of -sleutel voor de server
  • Claude Code lokaal draaiend met bestandssysteem- en Bash-toegang

De SSH-authenticatiemethode maakt niet uit. Claude Code gebruikt wat je hebt — sleutelbestand of wachtwoord via sshpass. Als je een wachtwoord gebruikt, installeer dan eerst sshpass:

sudo apt install sshpass

Stap 1 — Server aanmaken

Ga naar de Hetzner Cloud Console en maak een nieuwe server aan: - Type: CX22 (2 vCPU, 4 GB RAM) — voldoende voor Ghost + MySQL + Traefik - Image: Ubuntu 24.04 - Regio: de dichtstbijzijnde - SSH-sleutel of wachtwoord: naar keuze

Plak in het veld "Cloud config" je cloud-init.yaml. Dit installeert Docker, maakt de deploy-gebruiker aan, configureert UFW, en richt fail2ban in — alles in één keer. Je kunt die van clawstack-configs op GitHub als uitgangspunt gebruiken.

Noteer het IP-adres van de server. Dat is het laatste dat je handmatig hoeft te doen.


Stap 2 — Claude Code de context geven

Maak een CLAUDE.md-bestand aan in je projectmap. Dit is de briefing die Claude leest aan het begin van elke sessie. Voeg toe:

# Deployment Context

## Server
- IP: 203.0.113.42
- SSH user: deploy
- SSH auth: password via sshpass / key at ~/.ssh/mykey

## Domain
- Domain: yourdomain.com
- DNS: Cloudflare (token in .env as CLOUDFLARE_TOKEN)

## Stack
- Ghost 5 + MySQL 8 + Traefik (Docker Compose)
- Compose file: deploy/docker-compose.yml
- Deploy directory on server: /opt/ghost

## Credentials
- All secrets in deploy/.env (never commit)

Maak vervolgens deploy/.env aan met je werkelijke waarden:

DOMAIN=yourdomain.com
ACME_EMAIL=jij@yourdomain.com
CLOUDFLARE_TOKEN=je_cloudflare_dns_token

DB_NAME=ghost
DB_USER=ghost
DB_PASSWORD=genereer_met_openssl_rand_base64_32
DB_ROOT_PASSWORD=genereer_met_openssl_rand_base64_32

MAIL_HOST=smtp.fastmail.com
MAIL_PORT=587
MAIL_USER=jij@fastmail.com
MAIL_PASS=je_app_wachtwoord
MAIL_FROM=noreply@yourdomain.com

Genereer de DB-wachtwoorden lokaal:

openssl rand -base64 32

Stap 3 — DNS configureren

Geef Claude Code deze prompt:

Using the Cloudflare API token in deploy/.env, create the following DNS records
for the domain in .env:
- A record: @ → the server IP in CLAUDE.md
- A record: www → the server IP in CLAUDE.md
- A record: * → the server IP in CLAUDE.md

Use the Cloudflare API at https://api.cloudflare.com/client/v4.
First get the zone ID for the domain, then create each record.
Check for existing records and skip or update as needed.

Claude roept de Cloudflare API aan, haalt de zone-ID op, maakt de records aan, en bevestigt elk record. Het hele proces duurt ongeveer dertig seconden.

Als je e-mailrecords hebt (MX, DKIM, SPF) van een provider zoals FastMail, geef die dan ook aan Claude. Het kan ze in dezelfde ronde aanmaken.

Na DNS-propagatie (meestal minder dan vijf minuten met Cloudflare), stel je de SSL/TLS-modus handmatig in:

Cloudflare Dashboard → yourdomain.com → SSL/TLS → Overzicht → Full (Strict)

Dit is de enige klik die niet geautomatiseerd kan worden met een afgebakend DNS-token.


Stap 4 — De stack deployen

Zodra DNS actief is en de server draait, geef je Claude de deployment-prompt:

Deploy the Ghost stack to the server documented in CLAUDE.md.

1. Upload deploy/docker-compose.yml and deploy/.env to /opt/ghost on the server
2. SSH in and create the traefik/ directory with an empty acme.json (chmod 600)
3. Run: docker compose up -d
4. Wait 30 seconds, then check: docker compose ps
5. Check Ghost logs for any startup errors: docker compose logs --tail=50 ghost
6. If everything looks healthy, report the container statuses

Claude logt via SSH in, uploadt de bestanden, start de containers, en leest de logs. Als er iets misgaat — en bij de eerste deploy is er vaak een klein probleem — diagnosticeert Claude het en past de fix toe. De vijf meest voorkomende fouten zijn gedocumenteerd in Ghost achter Cloudflare en Traefik: de complete werkende setup.

De meest waarschijnlijke fouten: ontbrekend @docker-achtervoegsel bij Traefik-middleware-referenties, verkeerde Cloudflare-token-variabelenaam, of de Docker-netwerknaamprefix die niet overeenkomt met de Compose-projectmapnaam.


Stap 5 — Ghost initialiseren via de Admin API

Ghost wordt geleverd met een eenmalig setup-endpoint. Totdat je het aanroept, is de blog in "niet-geïnitialiseerde" staat — er bestaat geen admin-account. Je kunt dit via de browser doen op /ghost, of Claude het via de API laten doen.

Geef Claude deze prompt:

Initialise Ghost at https://yourdomain.com using the Admin API setup endpoint.
Create an admin account with:
- name: Admin
- email: jij@yourdomain.com
- password: (generate a strong one and tell me what it is)
- blogTitle: Jouw Blog Titel

POST to: https://yourdomain.com/ghost/api/admin/authentication/setup
Check the response for success and report the result.

Claude roept het endpoint aan en geeft de bevestiging terug. Het antwoord bevat een user-object — het admin-account is live.

# Wat Claude onder de motorkap uitvoert:
curl -s -X POST https://yourdomain.com/ghost/api/admin/authentication/setup \
  -H "Content-Type: application/json" \
  -d '{
    "setup": [{
      "name": "Admin",
      "email": "jij@yourdomain.com",
      "password": "JeWachtwoord123!",
      "blogTitle": "Jouw Blog Titel"
    }]
  }'

Als het endpoint een 403 teruggeeft, is Ghost al geïnitialiseerd (iemand was je voor — mogelijk jijzelf toen je de URL in een browser testte). Als het een verbindingsfout geeft, draaien de containers nog niet.


Stap 6 — De Admin API-sleutel ophalen

Log in bij Ghost admin op https://yourdomain.com/ghost met de inloggegevens die Claude zojuist heeft aangemaakt.

Ga naar: Instellingen → Integraties → Aangepaste integratie toevoegen

Geef het een willekeurige naam — "Automation" werkt prima. Ghost toont je een Admin API-sleutel in id:hexsecret-formaat. Sla deze op in deploy/.env als GHOST_ADMIN_KEY.

Vanaf dit punt kan Claude berichten aanmaken, afbeeldingen uploaden, tags beheren en concepten publiceren — volledig via de API, zonder browser.


De setup verifiëren

Zodra alles gedeployd is, vraag je Claude om de verificatiechecklist uit te voeren:

Run the following checks and report the HTTP status code for each:

1. curl -s https://yourdomain.com/ -o /dev/null -w "%{http_code}"   → should be 200
2. curl -s https://www.yourdomain.com/ -o /dev/null -w "%{http_code}"  → should be 301
3. curl -s http://yourdomain.com/ -o /dev/null -w "%{http_code}"    → should be 301
4. curl -sv https://yourdomain.com/ 2>&1 | grep issuer   → should say Let's Encrypt

Also check:
5. docker compose ps   → all containers should be Up
6. docker compose logs traefik | grep -i error   → should be empty

Als stap 1 een 000 teruggeeft of blijft hangen, is er een Traefik-routeringsprobleem. Als het een 301 teruggeeft, is de Ghost-redirectlus actief — zie het Traefik-artikel voor de oplossing. Als stap 4 een Cloudflare-certificaat toont in plaats van Let's Encrypt, is de DNS-01-challenge nog niet voltooid of is de CLOUDFLARE_TOKEN-variabele verkeerd benoemd.


De volledige prompt voor een schone server

Als je de hele klus in één keer aan Claude wilt overdragen — DNS, deployment en Ghost-initialisatie — hier is de prompt. Gaat ervan uit dat CLAUDE.md geschreven is en .env klaarstaat:

Deploy Ghost to the server documented in CLAUDE.md. Do the following in order:

1. Use the Cloudflare API to create A records for @, www, and * pointing to the server IP.
   Check for existing records first; update if present, create if not.

2. Upload deploy/docker-compose.yml and deploy/.env to /opt/ghost on the server.
   Create /opt/ghost/traefik/acme.json with chmod 600.

3. SSH in and run: docker compose up -d
   Wait 45 seconds, then check docker compose ps and docker compose logs ghost.
   Fix any startup errors before continuing.

4. Once all containers are healthy, initialise Ghost via POST to
   /ghost/api/admin/authentication/setup with the credentials below.
   Tell me the password you generate.

5. Confirm the site returns HTTP 200 at https://[DOMAIN]/.
   Report any failures with the relevant log output.

Admin credentials to create:
- email: jij@yourdomain.com
- blogTitle: Jouw Blog Titel

Claude werkt de lijst punt voor punt af, rapporteert de status na elke stap, en stopt om het te vragen als iets een beslissing vereist. Op een schone server met correcte inloggegevens duurt de volledige deployment ongeveer vier minuten.


Een AI gebruiken om de deployment te debuggen

Als er iets kapotgaat tijdens een deployment die Claude uitvoert, is het snelste pad om zowel dit artikel als het Ghost + Traefik + Cloudflare bugs-artikel in het gesprek te plakken. Samen dekken ze elke foutmodus die we zijn tegengekomen. Claude vergelijkt de fout in de logs met de gedocumenteerde patronen en vertelt je precies welk label verkeerd is of welke omgevingsvariabele ontbreekt.


Waar je dit draait

Hetzner CX22 is de machine waar dit op draait. €4,85/maand, twee vCPU's, 4 GB RAM. De deploy-gebruiker heeft standaard geen wachtwoord — cloud-init vergrendelt het — dus Claude authenticeert via sleutel of het tijdelijke wachtwoord dat je instelde bij het aanmaken van de server.

Als het doel een AI-assistent is die de server na de setup autonoom kan beheren — containers herstarten, berichten aanmaken, logs monitoren — xCloud host OpenClaw managed. Je krijgt dezelfde autonome functionaliteit zonder de server zelf te onderhouden. De deployment die in dit artikel wordt beschreven, is wat xCloud onder de motorkap draait.

(Affiliate-links — we ontvangen een kleine vergoeding als je je aanmeldt, zonder extra kosten voor jou.)


Bronnen


Duitse versie (Deutsch)


Metadaten

  • Titel: Ghost mit Claude Code deployen: DNS, VPS und Ghost API automatisiert
  • Slug: claude-code-ghost-deployment-de
  • Beschreibung: Schritt-für-Schritt-Anleitung, um Claude Code Cloudflare DNS konfigurieren, einen Hetzner VPS per SSH einrichten, Ghost mit Traefik deployen und den Blog über die Ghost Admin API initialisieren zu lassen — mit ehrlichen Hinweisen, was noch ein Mensch tun muss.
  • Tags: claude-code, ghost, cloudflare, hetzner, docker, automation, selbst-gehostet, infra
  • Pillar: /openclaw/
  • Language: de
  • Reading Time: 10 min

Inhalt

Du hast eine Domain. Du hast einen Hetzner-Account. Du willst Ghost auf deinem eigenen Server mit HTTPS, Cloudflare davor und einer MySQL-Datenbank dahinter. Der manuelle Weg dauert zwei Stunden: Server erstellen, per SSH einloggen, Docker Compose konfigurieren, mit Let's Encrypt kämpfen, Traefik debuggen, Ghost durch ein Browser-Formular initialisieren.

Es gibt einen anderen Weg. Übergib den Job an Claude Code. Gib ihm deine Zugangsdaten und eine Aufgabenbeschreibung — es konfiguriert Cloudflare DNS, deployt den Stack per SSH und initialisiert Ghost über die Admin API, ohne dass du ein Terminal anfassen musst. So wurde clawstack.run aufgesetzt.

Dieser Post dokumentiert genau, was Claude eigenständig tun kann, was noch einen menschlichen Klick erfordert, und wie du die Übergabe strukturierst, damit es beim ersten Versuch funktioniert.


Was Claude Code kann und was nicht

Claude Code hat Zugriff auf dein Dateisystem, ein Terminal und jede API, auf die du es hinweist. Das deckt den Großteil dieses Deployments ab. Einige Dinge befinden sich aber noch hinter Browser-UIs ohne API-Äquivalent.

Claude erledigt selbstständig: - Cloudflare DNS A-Records per API anlegen - .env-Dateien und Docker Compose Configs erstellen - Per SSH auf den Server zugreifen und Befehle ausführen - Deployment-Dateien hochladen - Docker Container starten - Ghost per Admin API initialisieren (Admin-Account, erster Post, Seitentitel) - Fehler durch Log-Analyse diagnostizieren und beheben

Manuelle Schritte (einmalige Klicks): - Hetzner Server erstellen (oder Hetzner API Key bereitstellen, dann kann Claude das auch) - Cloudflare SSL/TLS-Modus auf Full (Strict) setzen im Dashboard - Ghost Admin API Key aus dem Ghost Admin UI auslesen nach dem ersten Login

Alles andere ist automatisierbar. Die zwei manuellen Schritte dauern zusammen unter fünf Minuten.


Voraussetzungen

  • Eine Domain mit DNS bei Cloudflare
  • Ein Cloudflare API Token mit Zone / DNS / Edit-Berechtigung, auf deine Domain beschränkt
  • Ein Hetzner-Account (oder anderer VPS-Anbieter — IP unten anpassen)
  • SSH-Passwort oder Key für den Server
  • Claude Code lokal mit Dateisystem- und Bash-Zugriff

Die SSH-Authentifizierungsmethode spielt keine Rolle. Claude Code verwendet was du hast — Key-Datei oder Passwort via sshpass. Bei Passwort-Authentifizierung zuerst installieren:

sudo apt install sshpass

Schritt 1 — Server erstellen

In der Hetzner Cloud Console einen neuen Server anlegen: - Typ: CX22 (2 vCPU, 4 GB RAM) — reicht für Ghost + MySQL + Traefik - Image: Ubuntu 24.04 - Region: nächstgelegene - SSH Key oder Passwort: nach Wahl

Im Feld "Cloud config" das cloud-init.yaml einfügen. Das installiert Docker, legt den Deploy-User an, konfiguriert UFW und richtet fail2ban ein. Als Ausgangspunkt eignet sich die Datei aus clawstack-configs auf GitHub.

Die IP-Adresse des Servers notieren. Das ist die letzte manuelle Aktion.


Schritt 2 — Claude Code den Kontext geben

Eine CLAUDE.md-Datei im Projektverzeichnis anlegen. Das ist das Briefing, das Claude zu Beginn jeder Session liest:

# Deployment Context

## Server
- IP: 203.0.113.42
- SSH-User: deploy
- SSH-Auth: Passwort via sshpass / Key unter ~/.ssh/mykey

## Domain
- Domain: yourdomain.com
- DNS: Cloudflare (Token in .env als CLOUDFLARE_TOKEN)

## Stack
- Ghost 5 + MySQL 8 + Traefik (Docker Compose)
- Compose-Datei: deploy/docker-compose.yml
- Deploy-Verzeichnis auf Server: /opt/ghost

## Zugangsdaten
- Alle Secrets in deploy/.env (nie committen)

Dann deploy/.env mit den echten Werten anlegen:

DOMAIN=yourdomain.com
ACME_EMAIL=du@yourdomain.com
CLOUDFLARE_TOKEN=dein_cloudflare_dns_token

DB_NAME=ghost
DB_USER=ghost
DB_PASSWORD=mit_openssl_rand_base64_32_generieren
DB_ROOT_PASSWORD=mit_openssl_rand_base64_32_generieren

MAIL_HOST=smtp.fastmail.com
MAIL_PORT=587
MAIL_USER=du@fastmail.com
MAIL_PASS=dein_app_passwort
MAIL_FROM=noreply@yourdomain.com

DB-Passwörter lokal generieren:

openssl rand -base64 32

Schritt 3 — DNS konfigurieren

Claude Code diesen Prompt geben:

Lege mit dem Cloudflare API Token aus deploy/.env folgende DNS-Records
für die Domain in .env an:
- A-Record: @ → Server-IP aus CLAUDE.md
- A-Record: www → Server-IP aus CLAUDE.md
- A-Record: * → Server-IP aus CLAUDE.md

Cloudflare API: https://api.cloudflare.com/client/v4
Zuerst die Zone-ID für die Domain abrufen, dann jeden Record anlegen.
Vorhandene Records prüfen und ggf. aktualisieren statt doppelt anlegen.

Claude ruft die Cloudflare API auf, ermittelt die Zone-ID, legt die Records an und bestätigt jeden einzelnen. Das dauert etwa dreißig Sekunden.

Nach DNS-Propagation (mit Cloudflare meist unter fünf Minuten) den SSL-Modus manuell setzen:

Cloudflare Dashboard → yourdomain.com → SSL/TLS → Übersicht → Full (Strict)

Das ist der eine Klick, der mit einem beschränkten DNS-Token nicht automatisierbar ist.


Schritt 4 — Stack deployen

Wenn DNS aktiv und der Server bereit ist:

Deploye den Ghost-Stack auf den in CLAUDE.md dokumentierten Server.

1. deploy/docker-compose.yml und deploy/.env nach /opt/ghost hochladen
2. Per SSH einloggen und /opt/ghost/traefik/acme.json anlegen (chmod 600)
3. docker compose up -d ausführen
4. 30 Sekunden warten, dann docker compose ps prüfen
5. Ghost-Logs auf Startfehler prüfen: docker compose logs --tail=50 ghost
6. Bei gesundem Status alle Container-Zustände melden

Claude loggt per SSH ein, lädt die Dateien hoch, startet die Container und liest die Logs. Wenn etwas schiefläuft — beim ersten Deploy oft eine Kleinigkeit — diagnostiziert Claude es und behebt es. Die fünf häufigsten Fehler sind in Ghost hinter Cloudflare und Traefik dokumentiert.


Schritt 5 — Ghost per Admin API initialisieren

Ghost hat einen einmaligen Setup-Endpoint. Bis er aufgerufen wird, existiert kein Admin-Account. Das geht über den Browser unter /ghost oder per API:

Initialisiere Ghost unter https://yourdomain.com über den Admin API Setup-Endpoint.
Admin-Account erstellen:
- name: Admin
- email: du@yourdomain.com
- password: (generiere ein starkes Passwort und teile es mir mit)
- blogTitle: Dein Blog-Titel

POST an: https://yourdomain.com/ghost/api/admin/authentication/setup
Antwort auf Erfolg prüfen und melden.
# Was Claude im Hintergrund ausführt:
curl -s -X POST https://yourdomain.com/ghost/api/admin/authentication/setup \
  -H "Content-Type: application/json" \
  -d '{
    "setup": [{
      "name": "Admin",
      "email": "du@yourdomain.com",
      "password": "DeinPasswort123!",
      "blogTitle": "Dein Blog-Titel"
    }]
  }'

Bij 403: Ghost is al geïnitialiseerd. Bij verbindingsfout: containers draaien nog niet.


Schritt 6 — Admin API Key auslesen

Im Ghost Admin unter https://yourdomain.com/ghost einloggen.

Einstellungen → Integrationen → Eigene Integration hinzufügen

Den Admin API Key im Format id:hexsecret in deploy/.env als GHOST_ADMIN_KEY speichern.

Ab jetzt kann Claude Beiträge erstellen, Bilder hochladen, Tags verwalten und Entwürfe veröffentlichen — ohne Browser.


Setup verifizieren

Folgende Checks ausführen und HTTP-Statuscodes melden:

1. curl -s https://yourdomain.com/ -o /dev/null -w "%{http_code}"        → 200 erwartet
2. curl -s https://www.yourdomain.com/ -o /dev/null -w "%{http_code}"    → 301 erwartet
3. curl -s http://yourdomain.com/ -o /dev/null -w "%{http