Payload CMS für unter fünf Euro selbst hosten: Mein Setup mit Coolify und Hetzner

Payload CMS überzeugt auf ganzer Linie – das habe ich in diesem Blogbeitrag bereits ausführlich erklärt. Aber die schönste CMS-Lösung nützt nichts, wenn das Hosting ein Vermögen kostet oder man sich komplett in die Hände der Cloud-Anbieter begibt.
Payload Cloud verlangt 20 Dollar pro Monat. Vercel wird bei größeren Projekten schnell teuer. Beides sind solide Optionen, aber nicht jeder will oder kann sich das leisten. Dazu kommt: Wer selbst hostet, behält die volle Kontrolle. Über Daten, Standort, Backups – alles.
Ich hoste meine Payload-Projekte seit Monaten auf Hetzner mit Coolify für 4,75 Euro im Monat. Das Setup läuft stabil, ist schnell und kostet einen Bruchteil der Cloud-Alternativen.
Nebenbei: Dieser Blog und die gesamte Website laufen auf einem Hetzner CX22 – ein praktischer Beweis dafür, dass das Setup auch in der Realität zuverlässig funktioniert.
Das ist kein One-Click-Setup. Es gibt eine Lernkurve, aber sobald man die einmal hinter sich hat, ist es deutlich einfacher als gedacht. Wer sich schon an Payload CMS herangewagt hat, schafft auch das Self-Hosting. Hier die komplette Anleitung – mit allen Hürden, die mir begegnet sind.
Die Kombi: Hetzner, Coolify, Resend
Hetzner ist unschlagbar günstig. 4,75 Euro für einen VPS mit 2 GB RAM bekommt man anderswo nicht. Dazu kommt ein wichtiger Punkt: Ich kann selbst entscheiden, wo meine Daten liegen. Gerade in den aktuellen politischen Zeiten mit Trump und der unklaren Datenschutz-Situation in den USA ist das ein echter Vorteil. Europäische Server, europäisches Recht, keine Überraschungen.
Coolify ist quasi Vercel für den eigenen Server. Docker-Deployments, automatische SSL-Zertifikate, Git-Integration. Das Beste: Es ist Open Source und komplett kostenlos. Ich habe früher alles manuell mit Docker Compose und nginx gemacht. Funktioniert, ist aber mühsam zu warten. Coolify nimmt mir den größten Teil der Arbeit ab.
Für E-Mails nutze ich Resend. 3.000 E-Mails pro Monat kostenlos, danach günstige Preise, und die API ist simpel. Ein weiterer Vorteil: Resend hat Server in Irland, bleibt also auch bei den E-Mails in Europa.

Die aktuellen Preise bei Hetzner (Stand Juni 2025)
Server bei Hetzner aufsetzen
Der kleinste VPS reicht: CPX11 für 4,75 Euro. 2 vCPU AMD, 2 GB RAM, 40 GB NVMe SSD. Für kleinere Payload-Projekte ausreichend, bei Bedarf kann man hochskalieren.
Ubuntu 22.04 als Betriebssystem wählen. SSH-Key hinterlegen statt Passwort-Login. Falls kein SSH-Key vorhanden:
ssh-keygen -t ed25519 -C "[email protected]"
Coolify installieren
Die Installation ist unkompliziert:
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
Das Script installiert Docker, richtet Coolify ein und startet alle Services. Nach wenigen Minuten ist die Oberfläche unter http://server-ip:8000 erreichbar. Beim ersten Aufruf einen Admin-Account erstellen und optional 2FA aktivieren.
Domain und SSL einrichten
In Coolify unter "Settings" > "Configuration" die Domain eintragen. Wichtig: Die DNS-Records müssen bereits korrekt gesetzt sein – A-Record auf die Server-IP.
Coolify generiert automatisch Let's Encrypt-Zertifikate. Das funktioniert meist ohne Probleme. Falls doch, liegt es meist an falsch konfigurierten DNS-Einträgen.

So sieht das Dashboard von Coolify aus.
Payload-Projekt deployen
Der große Vorteil von Coolify: Man braucht keine eigene Dockerfile. Coolify nutzt Nixpacks, das automatisch erkennt, um was für ein Projekt es sich handelt, und die entsprechende Build-Konfiguration erstellt. Das funktioniert mit Node.js-Projekten out-of-the-box.
Falls Nixpacks bei Payload-Projekten Probleme macht (was gelegentlich vorkommt), kann man auf eine eigene Dockerfile umstellen. Hier ist eine bewährte Dockerfile für Payload CMS, die gut funktioniert.
# Base image
FROM node:23-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Install latest corepack to fix signature issues
RUN npm install -g corepack@latest && corepack enable
# Copy lockfiles and configs
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./
# Copy source code
COPY . .
# Install dependencies based on the lockfile
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi
# Build stage
FROM base AS builder
WORKDIR /app
# Copy dependencies from previous stage
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Install pnpm globally for Payload operations
RUN npm install -g pnpm --unsafe-perm
# Run database migrations
RUN pnpm payload migrate:status || echo "No pending migrations found."
RUN pnpm payload migrate || echo "No migrations to apply."
# Build the application
RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then pnpm generate:importmap && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi
# Run postbuild script (optional)
RUN pnpm run postbuild || echo "Postbuild script failed."
# Production image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
# Create user
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copy public assets
COPY --from=builder /app/public ./public
# Prepare .next directory and set permissions
RUN mkdir .next && chown nextjs:nodejs .next
# Copy standalone app and static files with correct ownership
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
# Start server (created by `next build` in standalone mode)
CMD ["node", "server.js"]
In Coolify ein neues Projekt erstellen und mit dem Git-Repository verbinden. GitHub, GitLab oder selbstgehostete Git-Server funktionieren alle. Auto-Deploy bei Git-Push ist verfügbar.
DNS-Konfiguration für die Website-Verfügbarkeit
Die schönste Payload-Installation bringt nichts, wenn sie im digitalen Nirgendwo verschwindet. DNS muss vor der SSL-Einrichtung in Coolify stehen – sonst scheitert Let's Encrypt an der Domain-Validierung. Standard-Vorgehen: A-Record beim Domain-Provider erstellen, Name auf @ für die Hauptdomain oder coolify für eine Subdomain, Wert ist die Hetzner-Server-IP. Für Subdomains wie coolify.deinedomain.com einfach weitere A-Records mit demselben Ziel erstellen.
Wer bereits Cloudflare nutzt, kann sich A-Records sparen und auf Cloudflare Tunnels setzen. Server-IP bleibt verborgen, DDoS-Schutz inklusive, und es funktioniert sogar ohne öffentliche IP. In Coolify gibt es eine fertige Cloudflared-Vorlage – einfach das Service erstellen, Tunnel-Token eintragen, fertig. Bei Cloudflare dann Public Hostnames für jede gewünschte Subdomain anlegen: coolify.deinedomain.com zeigt auf localhost:8000, app.deinedomain.com auf localhost:80. Wichtiger Hinweis: In den Domain-Einstellungen http:// verwenden, Cloudflare übernimmt das HTTPS automatisch. SSL/TLS in Cloudflare auf "Full" stellen, sonst gibt es Redirect-Schleifen zwischen Cloudflare und Coolify.
Persistent Storage einrichten
Vor dem Deployment gibt es einen entscheidenden Schritt: Persistent Storage einrichten. Ohne das verlierst du alle hochgeladenen Dateien (Bilder, Dokumente, etc.) bei jedem neuen Deployment. In den Anwendungseinstellungen gehst du zum "Storage"-Tab und fügst ein persistentes Volume hinzu.
Für den Zielpfad verwendest du /app/media oder /app/uploads (je nachdem, wo Payload deine Uploads speichert). Das Basisverzeichnis im Container ist /app, wenn du also Dateien in einem Storage-Verzeichnis speichern musst, definierst du den vollständigen Pfad beginnend mit /app/. Du kannst entweder ein Docker Volume (von Coolify verwaltet) oder ein Bind Mount (eigener Host-Pfad wie /data/deine-app/media) verwenden.
Das sorgt dafür, dass deine Mediendateien Deployments und Container-Neustarts überleben.
Der erste Build dauert etwas länger, danach geht es deutlich schneller.
Wichtige Environment-Variablen:
- DATABASE_URL: postgres://user:password@postgres:5432/payload (die Zugangsdaten bekommst du nach der Datenbank-Erstellung in Coolify)
- PAYLOAD_SECRET: Langer, zufälliger String (mindestens 32 Zeichen)
- PAYLOAD_PUBLIC_SERVER_URL: https://deine-domain.com
- RESEND_API_KEY: Dein Resend API-Key
In Coolify musst du zusätzlich eine PostgreSQL-Datenbank erstellen. Das geht über "Resources" > "Databases" > "PostgreSQL". Coolify generiert automatisch sichere Zugangsdaten, die du dann in deiner Anwendung verwenden kannst. Der erste Build dauert etwas länger, danach geht es deutlich schneller.
E-Mails mit Resend
Bei Resend einen Account erstellen und API-Key generieren. In der Payload-Config eintragen:
import { resendAdapter } from '@payloadcms/email-resend'
export default buildConfig({
email: resendAdapter({
defaultFromAddress: '[email protected]',
defaultFromName: 'Projektname',
apiKey: process.env.RESEND_API_KEY,
}),
})
Die Domain bei Resend verifizieren, sonst landen E-Mails im Spam.
Analytics mit Umami
Wer seine Website-Statistiken im Blick behalten möchte, ohne Google Analytics zu verwenden, findet mit Umami eine perfekte Alternative. Das Open-Source-Tool ist datenschutzfreundlich, benötigt keine Cookies und ist komplett DSGVO-konform.
In Coolify lässt sich Umami mit einem Klick installieren: Einfach eine neue Ressource erstellen und Umami aus der Service-Liste auswählen. Coolify richtet automatisch alles ein, inklusive der benötigten PostgreSQL-Datenbank.
Nach dem Start mit admin/umami anmelden, Website hinzufügen, Tracking-Code einbauen – fertig. Die Daten bleiben auf deinem eigenen Server und niemand sonst hat Zugriff darauf. Das ist besonders in Zeiten verschärfter Datenschutzbestimmungen ein klarer Vorteil gegenüber externen Analytics-Diensten.
CI/CD mit GitHub
Coolify bietet nahtlose GitHub-Integration. Du kannst entweder die GitHub App nutzen oder einen Deploy Key einrichten. Mit der GitHub App bekommst du automatische Deployments bei jedem Push und sogar Preview-Deployments für Pull Requests.
Für private Repositories brauchst du einen GitHub Token oder Deploy Key. Coolify zeigt dir in der Oberfläche genau, welchen SSH-Key du in den GitHub-Einstellungen hinterlegen musst. Einmal eingerichtet, deployed Coolify automatisch bei jedem Git-Push.
Ein wichtiger Hinweis zum Build-Process: Bei größeren Payload-Projekten kann es vorkommen, dass der Build-Vorgang den kleinen CPX11-Server überlastet. Die Seite bleibt zwar erreichbar, aber die CI-Pipeline schlägt fehl. Das Problem lässt sich einfach lösen, indem man auf den CPX21 (7,55 Euro/Monat) hochskaliert – mit 4 GB RAM und 3 vCPUs hat man dann genug Ressourcen für problemlose Builds.
Performance und Skalierung
Der 2GB-Server schafft problemlos mehrere hundert gleichzeitige Nutzer. Bei steigenden Anforderungen lässt sich bei Hetzner einfach hochskalieren – ohne Neuinstallation oder komplizierte Migration. In der Hetzner Cloud Console kann man die Server-Größe mit wenigen Klicks ändern. Der Server wird kurz gestoppt, bekommt mehr Ressourcen und läuft dann weiter. Das dauert meist nur wenige Minuten.
Coolify bietet grundlegendes Monitoring. Für detailliertere Überwachung kann Uptime Kuma direkt in Coolify installiert werden.
Fazit
Für technisch versierte Nutzer ist das Setup eine gute Alternative zu teuren Cloud-Lösungen. Man spart über 15 Euro pro Monat und behält die volle Kontrolle über die Infrastruktur. Zusätzlich kann man zwischen mehreren europäischen Standorten wählen – Nürnberg, Falkenstein oder Helsinki – je nach Bedarf.
Für absolute Beginner, die noch nie ein Terminal gesehen haben, ist Payload Cloud wahrscheinlich die bessere Wahl. Aber im Grunde ist Coolify sehr einfach zu bedienen. Hat man es einmal durchgeführt, geht es beim nächsten Mal deutlich schneller.
Das Setup ist komplett eigenständig – sowohl die Payload-Anwendung als auch die PostgreSQL-Datenbank laufen auf dem gleichen VPS. Man braucht keine externen Datenbank-Services und zahlt auch keine zusätzlichen Kosten dafür. Mit Hetzner + Coolify + Resend bekommt man eine vollständige, kostengünstige Lösung für unter 5 Euro.