Deploying (Oracle + Dokploy)
The current deployment target is Oracle Cloud (for testing; the production vendor is not yet chosen), managed with Dokploy (a self-hosted PaaS on Traefik).
Topology
Section titled “Topology”Two ARM instances:
forge- runs Dokploy, both dashboards, and the API.forge-worker- PostgreSQL only, reachable on the private network only.
The API sits with the dashboards on forge, not with the database. This is forced by the same-origin constraint: the API has no CORS and the login cookies are SameSite=Strict and path-scoped, so each dashboard and the API it calls must share one origin (see Auth planes & tenancy).
| Domain | Serves |
|---|---|
app.nexisapi.xyz |
hq dashboard at /, API at /api (path stripped) |
admin.nexisapi.xyz |
platform-admin at /, API at /admin (not stripped) |
All three services listen on container port 8080 (the dashboards run nginx as a non-root user; the API’s Dockerfile sets ASPNETCORE_HTTP_PORTS=8080).
Container prerequisites
Section titled “Container prerequisites”Three code changes made the apps deploy cleanly under Dokploy’s Traefik. All are merged:
- Configurable cookie paths (API). Traefik cannot rewrite a
Set-Cookiepath, so the API emits the cookie at its public path viaAuth__TenantCookiePath/Auth__AdminCookiePath. - Migrate on startup (API).
RunCentralMigrationsOnStartup=trueapplies the central database migrations when the API boots, instead of a separate shell step. - Dashboard Dockerfiles (web). Each dashboard builds from the monorepo root and is served by non-root nginx on port 8080, with a build-time guard on
VITE_API_BASE_URL.
Build arguments
Section titled “Build arguments”VITE_API_BASE_URL is validated as a full URL and inlined at build time:
- hq dashboard:
https://app.nexisapi.xyz/api(the same origin it is served from, with the/apiprefix). - platform-admin:
https://admin.nexisapi.xyz(origin only - the admin client prepends/adminitself).
The make-or-break check
Section titled “The make-or-break check”After deploying, sign in on admin.nexisapi.xyz and reload the page. Staying signed in proves the same-origin plus cookie-path chain is correct end to end. Getting logged out points at the cookie path or the proxy’s strip-path setting.