Dokploy
Deploy the node build to a self-hosted Dokploy instance on your own VPS, with Traefik fronting it and the schema migrate riding the start command.
Dokploy is an open-source, self-hosted PaaS that runs on your own VPS via Docker. It runs the standard node build - the same long-running artifact you would run anywhere - and ships Traefik as its built-in reverse proxy, so you do not run your own.
Prerequisites:
- A VPS you control, typically a fresh Ubuntu host.
- A database - self-hosted Postgres, or managed Neon/Supabase.
- A cache - self-hosted Redis, or managed Upstash.
Deploy
Install Dokploy on a clean host, then open the dashboard and create your admin user.
curl -sSL https://dokploy.com/install.sh | shCreate the application and point it at your Git repository, or at a prebuilt image in a registry. Set the build's Dockerfile path to the schema owner: the frontend app's Dockerfile for fullstack, or apps/backend/Dockerfile for separate.
When building the frontend image, provide NEXT_PUBLIC_API_URL=https://yourdomain.com/api as a build-time arg - Next.js bakes it into the browser bundle and a runtime env var cannot fix it later (see Self-hosting with Docker).
pnpm -F @repo/database run deploy to the owner app's start script, and the image's CMD is pnpm start, so migrations run on every container start. No manual migrate step in Dokploy.3000, backend 3010 for separate) and toggle HTTPS so Traefik issues a Let's Encrypt certificate.CMD pnpm start migrates the schema, then boots the server; Traefik routes your domain to it. Its HEALTHCHECK covers the migrate window, so Traefik holds traffic until the container is healthy instead of answering 5xx.Required environment variables
Set these on the Dokploy application before the first deploy. Full list, including OAuth, mail, payments, and storage, in Environment variables.
| Variable | Purpose |
|---|---|
DATABASE_URL | Postgres connection, required by the CMD-time migrate |
REDIS_URL, or UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN | Cache and rate limiting |
BETTER_AUTH_SECRET | Auth signing secret, min 32 chars |
INNGEST_APP_ID, INNGEST_EVENT_KEY, INNGEST_BASE_URL | Background jobs - all three required |
TRUSTED_PROXY | Not needed - Traefik runs on the same host and the backend detects it. Set it only for a CDN in front, per Client IP |
Never deploy a --demo build - its schema step resets the database and force-pushes the schema on every container start.
Separate architecture
Deploy two Dokploy applications - the standalone Hono backend (apps/backend, EXPOSE 3010) and the frontend - each with its own domain. Traefik fronts both: route api.yourdomain.com, or yourdomain.com/api/, to the backend and strip prefixes as needed. Wiring API_URL and TRUSTED_ORIGINS across the two is covered in Separate backend.
Self-hosting with Docker
Build and run the node deploy target as a long-running container from its multi-stage Dockerfile, with a database and cache you provision yourself.
Coolify
Deploy the node target to Coolify, a self-hosted PaaS that builds the standard Docker image on your own VPS and fronts it with its built-in proxy.