Internal reference — last verified against the live deploy

Mediabase — architecture

How the pieces actually connect: Loopia, the domain, Coolify, the database, and the app. Written from the real deployed system, including the two things that broke and why.

The full picture

HETZNER VPS · 89.167.80.108 containers orchestrated by Coolify (dashboard on :8000) Loopia DNS A record: media → 89.167.80.108 Browser requests media.solutionsskovde.se Coolify proxy (Traefik) terminates SSL, routes by domain App container (Next.js) port 3000, reads DATABASE_URL Postgres container production DB, internal-only /app/public/media bind mount → host directory VPS host filesystem /data/coolify/mediaplatform/media GitHub Vulkanmannen2/mediabase Your Mac scp + ssh mediaplatform Local dev — completely separate your Mac: local Postgres 16 + npm run dev — no connection to production, own copy of the data resolves domain HTTPS request reverse proxy → :3000 Prisma: read/write metadata stream file bytes mounted from scp build & deploy git push
Three flows share this one server: the request path (top, solid), the deploy path (right), and the manual media-upload path (bottom right, dashed — not yet automated).

Walking through each connection

1. Domain → server

Loopia holds one DNS A record: the subdomain media under solutionsskovde.se points at 89.167.80.108, the Hetzner VPS's public IP. That's Loopia's entire job here — it doesn't touch anything after the browser has the IP.

2. Request path

Every request for media.solutionsskovde.se lands on Coolify's built-in proxy (Traefik), which terminates SSL (a Let's Encrypt certificate, auto-renewed) and forwards it to the app container's internal port 3000. There's no separately configured Nginx — Coolify's proxy is the only thing in that role, on purpose (see STACK.md).

3. The app talks to two things

4. Media storage — a bind mount, not the Docker image

public/media/ is deliberately .gitignored — a 600MB video has no business going through GitHub. Instead, Coolify has a directory mount configured on the app: the host path /data/coolify/mediaplatform/media is bind-mounted into the container at /app/public/media. New files land by scp-ing them straight to that host path from your Mac (there's an SSH shortcut for this: ssh mediaplatform).

5. Deploy path

Pushing to main on GitHub doesn't trigger anything by itself yet — deploys happen when you click Deploy in Coolify, which pulls the latest commit and builds a fresh image using Railpack (Coolify's builder), then swaps the running container for the new one.

Two things that broke, and why

Prisma client wasn't generated in production

The build failed with Module not found: '@/app/generated/prisma/client'. Locally, npm install auto-generates the Prisma client via a postinstall hook — but Railpack skips install scripts (a common security/reproducibility default for build platforms), so that hook never ran. Fix: package.json's build script now explicitly runs prisma generate && next build, so generation never depends on an implicit hook.

Media files 404'd even though they existed on disk

After the first file upload, every play button was greyed out — the browser's media requests returned Next.js's own 404 page. The files were confirmed present, correctly permissioned, inside the container. The cause: the app's Node process had already started (and Next.js appears to do its static-asset resolution relative to that running process) before the scp transfer finished writing files into the mounted folder. Restarting the container — no rebuild needed — fixed it immediately. Takeaway: after adding new files to the mounted media folder, restart the app container before expecting them to be servable.

Known manual steps (not yet automated)

Quick reference

ThingWhere
Live sitehttps://media.solutionsskovde.se
Coolify dashboardhttp://89.167.80.108:8000
SSH to the VPSssh mediaplatform (alias in ~/.ssh/config)
SSH key~/.ssh/mediaplatform_hetzner — never committed to git
Production DATABASE_URLCoolify → app → Environment Variables (not in this repo)
Media on the VPS host/data/coolify/mediaplatform/media/
GitHub repogithub.com/Vulkanmannen2/mediabase