atelier-api — das Backend
atelier-api ist der Server hinter der App: Login, Team-Cloud, Storage und gemeinsames Bauen. Eine Instanz reicht fürs ganze Team. Diese Seite zeigt dir, wie du sie selbst hostest.
Überblick
atelier-api ist ein schlanker Bun-Service mit MongoDB als Datenbank. Assets liegen in einem Content-Addressed Store auf der Platte (per SHA-256 adressiert, dedupliziert). Standardmäßig lauscht der Server auf Port 3095.
- Discord-Login mit Freigabe-Workflow (pending → approved).
- Versionierte Pack-Revisionen, resumable Uploads, Team-Locks über WebSocket.
- Registry-Lane mit Service-Token, damit Webseiten veröffentlichte Packs abfragen können.
- Web-Admin-Dashboard unter
/admin— Logs, Speicher, Build-Downloads und fxmanifest-Overrides.
Quellcode & Issues: atelier-api auf GitHub.
Voraussetzungen
- Bun (1.x) — zum Starten des Servers.
- MongoDB — eine eigene Instanz oder MongoDB Atlas.
- Eine Discord-Anwendung für den Login (kostenlos im Discord Developer Portal).
- Persistenter Speicher für die Assets — siehe Storage & Volume.
Lokal starten
cd atelier-api bun install cp .env.example .env.local # Werte ausfüllen bun run dev # mit Auto-Reload # Läuft? Health-Check: curl http://127.0.0.1:3095/health
Environment-Variablen
Konfiguriert wird über .env.local (lokal) bzw. die Umgebung des Hosters. Die wichtigsten Variablen:
| Variable | Beschreibung |
|---|---|
| MONGODB_URI | Pflicht — Connection-String zu MongoDB (z. B. mongodb+srv://…). |
| MONGODB_DB_NAME | Datenbankname (frei wählbar), Standard atelier. |
| ATELIER_JWT_SECRET | Pflicht — Secret zum Signieren der Tokens (lang & zufällig). |
| ATELIER_SERVICE_TOKEN | Pflicht — Token für die Service-Lane (Registry für Webseiten). |
| ATELIER_PUBLIC_ORIGIN | Öffentliche Basis-URL des Servers (in Produktion https://…). |
| ATELIER_DISCORD_CLIENT_ID | Client-ID deiner Discord-Anwendung. |
| ATELIER_DISCORD_CLIENT_SECRET | Client-Secret deiner Discord-Anwendung. |
| ATELIER_ADMIN_DISCORD_IDS | Komma-Liste von Discord-IDs, die automatisch Admin sind. |
| ATELIER_STORAGE_ROOT | Pfad für die Assets — muss persistent sein (Default ./data). |
| PORT | HTTP-Port, Standard 3095. |
| HOST | Bind-Adresse — in Produktion 0.0.0.0. |
| ATELIER_BUILD_CONCURRENCY | Parallele Server-Builds, Standard 2. |
Secrets nie committen
ATELIER_JWT_SECRET und ATELIER_SERVICE_TOKEN sollten lang und zufällig sein (z. B. openssl rand -hex 32) und gehören nur in die Umgebung — niemals ins Repo. Die vollständige Liste inkl. Defaults steht in .env.example.Discord-OAuth & Freigabe
Discord-Anwendung anlegen
- 1Im Discord Developer Portal eine neue Application erstellen (Name z. B. „atelier").
- 2Unter OAuth2 Client-ID und Client-Secret in deine Env übernehmen (
ATELIER_DISCORD_CLIENT_ID/ATELIER_DISCORD_CLIENT_SECRET). - 3Als Redirects beide exakt eintragen — einen für die Desktop-App, einen fürs Web-Admin-Dashboard:Lokal also
{ATELIER_PUBLIC_ORIGIN}/api/v1/auth/discord/callback {ATELIER_PUBLIC_ORIGIN}/admin/callbackhttp://127.0.0.1:3095/api/v1/auth/discord/callbackbzw.http://127.0.0.1:3095/admin/callback. Der Scopeidentifywird automatisch angefragt.
Freigabe-Workflow
Neue Mitglieder landen als pending und müssen einmalig freigeschaltet werden. Discord-IDs in ATELIER_ADMIN_DISCORD_IDS sind automatisch Admin und freigegeben — diese Admins schalten dann alle weiteren direkt in der App frei.
pending— angemeldet, aber für Cloud-Aktionen gesperrt.approved— voller Zugriff auf Packs, Sync und Builds.locked— gesperrt, alle Geräte-Anmeldungen werden widerrufen.
Storage & Volume
Alle hochgeladenen Dateien liegen unter ATELIER_STORAGE_ROOT in einem Content- Addressed Store. Die MongoDB speichert nur die Metadaten und Verweise (per SHA-256).
cas/ finalisierte Assets (unveränderlich, per Hash) tmp/ laufende Uploads builds/ zwischengespeicherte Build-Artefakte
Das Volume MUSS persistent sein
asset_not_found. Lege ATELIER_STORAGE_ROOT immer auf ein persistentes Volume und sichere es regelmäßig. Nach einem Wipe müssen Besitzer ihre Packs neu hochladen.Deployment (Dokploy)
atelier-api bringt ein Dockerfile mit (oven/bun) und lässt sich so überall als Container betreiben. Mit Dokploy in Kürze:
- 1In Dokploy eine neue Application aus dem atelier-api-Repository (oder dem Docker-Image) anlegen.
- 2Die Environment-Variablen setzen — insbesondere
MONGODB_URI,ATELIER_JWT_SECRET,ATELIER_SERVICE_TOKEN, die beiden Discord-Werte undHOST=0.0.0.0. - 3Ein persistentes Volume an
ATELIER_STORAGE_ROOTmounten (z. B./data). Das ist der wichtigste Schritt — ohne ihn verlierst du beim nächsten Deploy alle Assets. - 4Eine Domain zuweisen und Port
3095freigeben. Trage dieselbe öffentliche HTTPS-URL alsATELIER_PUBLIC_ORIGINein und hinterlege sie als Discord-Redirect. - 5Deployen und mit
GET /healthprüfen.
docker run -d --name atelier-api \ -p 3095:3095 \ -v atelier-data:/data \ --env-file .env \ atelier-api
Admin-Dashboard (Web)
Der Server bringt unter /admin ein eigenes Web-Dashboard mit — Login nur für die Discord-IDs aus ATELIER_ADMIN_DISCORD_IDS. Die Anmeldung läuft über einen eigenen Discord-Web-Flow (getrennt von der Desktop-App), die Session steckt in einem HttpOnly-Cookie, und der Admin-Status wird bei jedem Request neu geprüft.
- Übersicht — Speichergröße (CAS/Builds/tmp) und Kennzahlen (Assets, Packs, Revisionen, Builds, Nutzer).
- Logs — Server-Logs live (SSE) plus Aktivitäts-Protokoll.
- Packs & Builds — Server-Builds pro Revision erzeugen oder neu bauen und die fertigen Pakete als ZIP herunterladen.
- fxmanifest — pro Pack den Resource-Namen und ein
fxmanifest.lua-Template überschreiben. Greift beim nächsten Server-Build; ohne Override bleibt alles byte-identisch zum Desktop-Build. - Nutzer — freischalten und sperren.
Voraussetzung
{ATELIER_PUBLIC_ORIGIN}/admin/callback (siehe Discord-OAuth). Danach erreichbar unter {ATELIER_PUBLIC_ORIGIN}/admin.Endpoint-Übersicht
Alle Endpoints liegen unter /api/v1. Nutzer-Endpoints brauchen einen Bearer- Token (aus dem Login), die Registry-Lane einen Service-Token. Die wichtigsten Gruppen:
| Gruppe | Zweck |
|---|---|
| auth / device | Discord-Login, Token-Tausch und -Erneuerung, Logout. |
| me / devices | Eigenes Profil und angemeldete Geräte verwalten. |
| admin | Mitglieder auflisten, freischalten, sperren, Rollen setzen. |
| /admin (Web) | Browser-Dashboard: Übersicht, Logs, Build-Downloads, fxmanifest — Cookie-Login, nur Admins. |
| uploads / assets | Resumable Chunk-Uploads und Asset-Download (mit Range/ETag). |
| packs / revisions | Packs, Mitglieder und versionierte Revisionen. |
| locks | Advisory-Locks pro Drawable (TTL, Heartbeat). |
| builds | Server-Builds in die Queue stellen und Artefakte abrufen. |
| registry | Service-Lane: veröffentlichte Packs für Webseiten (Service-Token). |
| ws | WebSocket für Presence, Locks und Live-Status. |
Health & Service-Token
GET /health. Webseiten sprechen die Registry per Header x-fg-service-token an. Server-Builds enthalten keine binären YMTs (die entstehen im Desktop-Build) — sie dienen Vorschau und Verteilung.