CMS für Astro: Sveltia CMS + Forgejo
Inhaltsverzeichnis
Git-basierte Content-Verwaltung für Static Sites
Wer statische Websites mit Astro, Hugo oder Jekyll betreibt, steht früher oder später vor der Frage: Wie verwalte ich Content effizient, ohne jedes Mal manuell Markdown-Dateien in der IDE zu editieren und zu committen?
Eine Antwort findet man in Git-basierten Content Management Systemen, die eine grafische Oberfläche bieten, aber im Hintergrund weiterhin Git als Single Source of Truth nutzen.
Für mich war ein wichtiger Punkt, dass ich meinen Blog auch unterwegs vom Smartphone aus über ein schlankes, responsives CMS verwalten kann.
Dieses Tutorial beschreibt die Integration von Sveltia CMS, einem modernen und schlanken CMS, in einen Astro‑Blog. Die volle Kontrolle behalten wir durch ein selbstgehostetes Forgejo als Git‑Backend; das Deployment erfolgt über meine Coolify‑Instanz.
Warum Sveltia CMS?
Sveltia CMS ist ein Fork von Netlify CMS, der sich jedoch weiterentwickelt hat und mehrere Vorteile bietet:
- Aktive Entwicklung: Während Netlify CMS kaum noch gepflegt wird, entwickelt sich Sveltia stetig weiter
- Bessere Performance: Schlankerer Code, schnellere Ladezeiten
- Moderne UI: Aufgeräumteres Interface mit Dark Mode Support
- API-Kompatibilität: Unterstützt die gleichen Backends wie Netlify CMS (GitHub, GitLab, Gitea/Forgejo)
- Gitea/Forgejo Support: Native Unterstützung für selbst gehostete Git-Instanzen
2. Voraussetzungen
Bevor wir starten, stellt sicher, dass folgende Voraussetzungen erfüllt sind:
- Docker & Docker Compose v2
- Traefik Setup
- Eine Webseite mit Astro Framework
- Optional: Coolify Instanz
Architektur-Überblick
Das System besteht aus drei Hauptkomponenten:
- Astro Static Site – Der Blog selbst, generiert aus Markdown-Dateien
- Sveltia CMS – Eine Web-UI, die direkt in die Astro-Site integriert wird (Route
/admin) - Forgejo – Selbst gehostete Git-Instanz als Backend
- Coolify - Open Source Alternative zu Vercel oder Netlify (Optional)
Der Workflow sieht folgendermaßen aus:
Editor schreibt Artikel in Sveltia CMS
↓
Sveltia speichert Änderungen via Git API in Forgejo
↓
Webhook triggert Build-Pipeline (z.B. Coolify, Vercel, Netlify)
↓
Astro generiert statische Site aus aktualisierten Markdown-Dateien
Teil 1. Forgejo mit Docker und Traefik aufsetzen
Bevor wir Sveltia CMS konfigurieren können, benötigen wir eine funktionierende Forgejo-Instanz. Ich gehe davon aus, dass Traefik bereits läuft – falls nicht, schau dir meinen Traefik Setup Guide an.
1.1 Forgejo einrichten
Erstelle das Projektverzeichnis:
mkdir -p /opt/containers/forgejo
cd /opt/containers/forgejo
Erstelle die docker-compose.yaml:
---
services:
server:
image: codeberg.org/forgejo/forgejo:9.0.3
container_name: forgejo
restart: unless-stopped
ports:
- "2222:22" # SSH-Port für Git-Operationen
volumes:
- ./forgejo:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
labels:
# Traefik aktivieren
- "traefik.enable=true"
# HTTPS Router
- "traefik.http.routers.forgejo.entrypoints=websecure"
- "traefik.http.routers.forgejo.rule=Host(`git.example.com`)"
- "traefik.http.routers.forgejo.tls=true"
- "traefik.http.routers.forgejo.tls.certresolver=cloudflare"
# Service-Konfiguration
- "traefik.http.routers.forgejo.service=forgejo"
- "traefik.http.services.forgejo.loadbalancer.server.port=3000"
# Middleware (siehe Teil 1.3 für CORS-Konfiguration)
- "traefik.http.routers.forgejo.middlewares=cors-forgejo@file,geoblock-de@file,crowdsec-bouncer@file"
# Netzwerk
- "traefik.docker.network=frontend"
networks:
- frontend
networks:
frontend:
external: true
Wichtig: Passe git.example.com an deine Domain an.
Starte Forgejo:
docker compose up -d
1.2 Forgejo initialisieren
Öffne https://git.example.com im Browser und führe die Ersteinrichtung durch:

- Datenbank: SQLite ist ausreichend für kleine bis mittlere Instanzen
- Server-Domain:
git.example.com - SSH Server Port:
2222(da wir im Container auf Port 22 mappen) - Base URL:
https://git.example.com - Administrator-Account: Erstelle deinen Admin-User
Nach der Ersteinrichtung ist Forgejo einsatzbereit. Erstelle nun ein Repository für deinen Blog.
1.3 CORS-Konfiguration für Sveltia CMS
Sveltia CMS greift per JavaScript aus dem Browser auf die Forgejo API zu. Dafür benötigen wir CORS-Header (Cross-Origin Resource Sharing), sonst blockiert der Browser die Anfragen mit einem Fehler wie:
Network error when attempting to fetch resources
CORS in Forgejo aktivieren
Bearbeite die Datei /opt/containers/forgejo/forgejo/gitea/conf/app.ini und füge hinzu:
[cors]
ENABLED = true
ALLOW_DOMAIN = *
METHODS = GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
MAX_AGE = 10m
ALLOW_CREDENTIALS = true
HEADERS = Content-Type,User-Agent,Authorization,Accept,X-Requested-With
X_FRAME_OPTIONS = SAMEORIGIN
Sicherheitshinweis: ALLOW_DOMAIN = * erlaubt Zugriffe von allen Domains. In Produktionsumgebungen solltest du hier nur deine Blog-Domain(s) eintragen:
ALLOW_DOMAIN = https://blog.example.com,https://www.blog.example.com
CORS-Middleware in Traefik
Zusätzlich fügen wir eine Traefik-Middleware hinzu, um konsistente CORS-Header zu garantieren. Erstelle die Datei /opt/containers/traefik/config/conf.d/forgejo-cors.yaml:
http:
middlewares:
cors-forgejo:
headers:
accessControlAllowMethods:
- GET
- HEAD
- POST
- PUT
- PATCH
- DELETE
- OPTIONS
accessControlAllowOriginList:
- "*" # In Produktion: spezifische Domains nutzen
accessControlAllowCredentials: true
accessControlAllowHeaders:
- "*"
accessControlExposeHeaders:
- "*"
accessControlMaxAge: 600
addVaryHeader: true
Die Middleware wird bereits in der docker-compose.yaml referenziert (siehe Label oben).
Starte Forgejo und Traefik neu:
docker compose restart
Teil 2: OAuth-App in Forgejo erstellen
Sveltia CMS authentifiziert sich über OAuth 2.0 an Forgejo. Dafür benötigen wir eine OAuth-Applikation.

2.1 OAuth-App registrieren
- Melde dich bei Forgejo an (
https://git.example.com) - Navigiere zu Einstellungen → Anwendungen
- Scrolle zu OAuth2-Anwendungen verwalten
- Klicke auf Neue OAuth2-Anwendung erstellen
Konfiguration:
- Anwendungsname:
Sveltia CMS - Weiterleitungs-URI:
https://blog.example.com/admin/,, http://localhost:4321/admin(deine Blog-Domain mit/admin/am Ende!) - Vertraulicher Client: Abwählen
Klicke auf Anwendung erstellen.
2.2 Client ID notieren
Nach der Erstellung erhältst du eine Client ID (UUID-Format). Diese benötigen wir später für die Astro-Konfiguration.
Wichtig: Die Client ID wird nur einmal angezeigt. Notiere sie dir sicher.
Teil 3: Sveltia CMS in Astro integrieren
3.1 Paket installieren
Installiere den offiziellen Astro-Loader für Sveltia CMS:
npm install astro-loader-sveltia-cms
3.2 Content Collection konfigurieren
Astro 5 nutzt das neue Content Layer API. Definiere deine Blog-Collection in src/content.config.ts:
import { defineCollection, z } from "astro:content";
import { sveltiaLoader } from "astro-loader-sveltia-cms/loader";
const blogs = defineCollection({
loader: sveltiaLoader("blogs"),
schema: z.object({
slug: z.string(),
title: z.string(),
description: z.string(),
date: z.date(),
author: z.string(),
tags: z.array(z.string()),
featured: z.boolean(),
image: z.string().optional(),
draft: z.boolean().optional(),
}),
});
export const collections = { blogs };
3.3 Astro-Konfiguration erweitern
Bearbeite astro.config.mjs und füge die Sveltia-Integration hinzu:
import { defineConfig } from "astro/config";
import sveltia from "astro-loader-sveltia-cms";
export default defineConfig({
integrations: [
sveltia({
route: "/admin",
title: "Blog CMS",
config: {
backend: {
name: "gitea",
repo: "username/blog-content", // Dein Forgejo-Repository
base_url: "https://git.example.com",
api_root: "https://git.example.com/api/v1",
app_id: "424f35b7-a9f4-4597-bfef-38631351dd2f", // Deine OAuth Client ID
},
media_folder: "public/images/posts",
public_folder: "/images/posts",
collections: [
{
name: "blogs",
label: "Blog Posts",
label_singular: "Blog Post",
folder: "src/blog",
create: true,
path: "{{slug}}/index",
slug: "{{slug}}",
format: "yaml-frontmatter",
fields: [
{ label: "Slug", name: "slug", widget: "string" },
{ label: "Titel", name: "title", widget: "string" },
{ label: "Beschreibung", name: "description", widget: "text" },
{ label: "Datum", name: "date", widget: "datetime" },
{ label: "Autor", name: "author", widget: "string", default: "Tobias" },
{
label: "Tags",
name: "tags",
widget: "list",
hint: "Drücke Enter nach jedem Tag"
},
{ label: "Featured", name: "featured", widget: "boolean", default: false },
{ label: "Draft", name: "draft", widget: "boolean", default: false, required: false },
{
label: "Hero Image",
name: "image",
widget: "string",
required: false,
hint: "z.B. /images/posts/mein-post.png"
},
{ label: "Inhalt", name: "body", widget: "markdown" },
],
},
],
},
}),
],
site: "https://blog.example.com",
output: "static",
});
Wichtige Parameter:
backend.repo: Formatowner/repository-name(wie auf Forgejo)backend.app_id: Die OAuth Client ID aus Teil 2media_folder: Wo Bilder gespeichert werden (im Repository)public_folder: Öffentlicher URL-Pfad zu den Bildern
3.4 Dev-Server testen
Starte den Astro-Dev-Server:
npm run dev
Öffne http://localhost:4321/admin im Browser. Du solltest jetzt die Sveltia CMS-Oberfläche sehen.

Klicke auf Login with Gitea – du wirst zu Forgejo weitergeleitet, authentifizierst dich dort, und wirst zurück zum CMS geleitet. Jetzt kannst du Blog-Posts erstellen, bearbeiten und löschen – alles wird direkt in dein Git-Repository committed.


Teil 4: Deployment und CI/CD
4.1 Production Build
Für Production baue die Site:
npm run build
Die fertige Site liegt in dist/. Das Admin-Interface wird automatisch unter /admin verfügbar sein.
4.2 Webhook für Auto-Deploy (Optional)
Wenn du Coolify, Vercel oder ähnliche Plattformen nutzt, kannst du einen Webhook einrichten, der bei jedem Push automatisch ein neues Deployment triggert:
- In Forgejo: Repository → Einstellungen → Webhooks
- Webhook hinzufügen → Forgejo
- Payload URL: Deine Coolify/Vercel Webhook-URL
- Content Type:
application/json - Events:
Pushaktivieren - Token: Dein Coolify Auth Token
Jetzt wird bei jedem gespeicherten Blog-Post automatisch die Website neu gebaut.
Mein Fazit
Wer bereit ist, etwas Betriebsaufwand zu investieren, erhält hier eine robuste, wartungsfreundliche Alternative zu cloud‑basierten Diensten. Mit Forgejo als Git‑Backend und Coolify fürs Deployment lässt sich Sveltia CMS sauber in einen Astro‑Workflow integrieren: schlankes UI, Git‑Versionierung und ein direkter Commit‑Flow sorgen für Transparenz und Kontrolle.
Weiterführende Ressourcen
- Sveltia CMS Dokumentation
- Astro Content Collections
- Forgejo Dokumentation
- Traefik Middleware Reference
Hinweis: Dieser Artikel basiert auf Astro v6, Sveltia CMS v0.146.10 und Forgejo v13.0.3 (März 2026). Bei neueren Versionen können sich Details ändern.