Railway

Deploy Hexclave | Self-hosted Auth + Storage

Self-hosted auth, teams, analytics, and file uploads with built-in S3.

Deploy Hexclave | Self-hosted Auth + Storage

minio-init

minio/mc:latest

Just deployed

Just deployed

Just deployed

Just deployed

hexclave-proxy

caddy:2-alpine

Just deployed

/var/lib/postgresql/data

Just deployed

Hexclave (self-hosted)

About Hosting Hexclave

Hexclave is an open-source "user infrastructure" platform: authentication, teams, and analytics for your app. This template runs Hexclave's official all-in-one server image (dashboard + API in one container) on Railway, alongside the Postgres and ClickHouse databases it needs — plus a MinIO S3 bucket so file uploads (profile pictures, session recordings, and deployment artifacts) work out of the box.

Common Use Cases

  • Running your own auth server for a SaaS product without depending on Hexclave Cloud
  • Prototyping or testing Hexclave's authentication, teams, and analytics features in an environment you fully control
  • Self-hosting user infrastructure for compliance or data-residency reasons

Dependencies for Hexclave Hosting

  • Postgres — stores hexclave's own data (projects, users, teams). Included in this template.
  • ClickHouse — stores the analytics data hexclave's dashboard reads. Included in this template.
  • MinIO — an S3-compatible object store that holds file uploads: profile pictures (public bucket) and session recordings / deployment source (private bucket). Included in this template, exposed on its own public domain so the browser can upload and download directly via presigned URLs.
  • minio-init — a one-shot job that creates the two storage buckets and makes the public one readable, then stops. Seeing it "stopped" or "complete" after deploy is normal; it only needs to run once.
  • hexclave-cron — a small scheduled job that calls hexclave's internal maintenance endpoints (email queue, external DB sync) every 5 minutes over Railway's private network, since the Docker image doesn't run its own scheduler. Included in this template.
  • hexclave-proxy — a Caddy reverse proxy that routes traffic by path: the dashboard at / and the API at /api/*. Included in this template. Exposes a single public domain so users don't have to manually generate two separate ports and paste their URLs.

Why Deploy Hexclave on Railway?

Railway generates the Postgres, ClickHouse, and MinIO passwords for you and wires every service together automatically, so you get a working auth/teams/analytics backend — with file uploads — without hand-managing separate pieces of infrastructure. Railway's private networking keeps the cron job's calls to hexclave's internal endpoints off the public internet. The proxy service handles public routing so the dashboard and API are available immediately on deploy with zero manual domain setup.

Deploy and Host Hexclave on Railway

Click deploy. This template deploys with a single public domain already configured — the dashboard and API are both served through the hexclave-proxy service, one at the root, the other under /api/. No manual domain setup is required. Note that the hexclave service takes a few minutes to boot on first deploy (it seeds the database and prepares the app), and you'll see a "still starting up" message at the URL until it's ready. Visit the dashboard URL generated on the hexclave-proxy service and sign in with the seeded admin account: the email you set in HEXCLAVE_SEED_INTERNAL_PROJECT_USER_EMAIL, and the password in HEXCLAVE_SEED_INTERNAL_PROJECT_USER_PASSWORD (check that service's Variables tab if you left it auto-generated).

File storage (MinIO)

File uploads are handled by the bundled MinIO service, exposed on its own public domain because the browser uploads and downloads files directly via presigned URLs. That upload/download traffic flows over MinIO's public endpoint rather than Railway's private network, which counts as egress — this is normal for browser file uploads and modest for typical auth-platform use (avatars, the occasional session recording). It's all wired automatically; there's nothing to configure.

Using a custom domain

By default the dashboard and API are served on the auto-generated *.up.railway.app domain on the hexclave-proxy service. To use your own domain (e.g. auth.yourcompany.com), hexclave needs to be told its new public URL and to trust it — this takes a few steps because the app bakes its URL into the frontend and stores its trusted domains in the database:

  1. On the hexclave-proxy service, open Settings -> Networking -> Custom Domain and add your domain targeting port 8080. Create the CNAME record Railway shows you at your DNS provider, and wait for it to verify.
  2. On the hexclave service, set both NEXT_PUBLIC_HEXCLAVE_DASHBOARD_URL and NEXT_PUBLIC_HEXCLAVE_API_URL to https://your-domain (your custom domain, no trailing slash).
  3. Register the domain as trusted: temporarily set HEXCLAVE_SKIP_SEED_SCRIPT to false on the hexclave service and redeploy it. This re-runs the seed, which adds your domain to hexclave's trusted-domains list (it keeps the old railway.app domain trusted too). The seed will log an "Environment configuration overrides cannot be changed in a development environment" error and the service will restart a few times — that is expected here and does not affect the domain update.
  4. Once the domain has been added (about a minute), set HEXCLAVE_SKIP_SEED_SCRIPT back to true and redeploy the hexclave service one more time for a clean boot. Your dashboard is now available at your custom domain, and the original railway.app URL keeps working as a fallback. (These steps are only needed because of the upstream seed-script limitation noted below; if you never add a custom domain, you can ignore all of this.)

Known limitations

  • After your first deploy, set HEXCLAVE_SKIP_SEED_SCRIPT to true. On its first boot the app seeds the database and creates your admin account. But the image's seed script crashes the container if it runs a second time (an upstream bug), so on the first restart or redeploy the hexclave service will crash-loop with an error about "Environment configuration overrides cannot be changed in a development environment." The fix: open the hexclave service's Variables, set HEXCLAVE_SKIP_SEED_SCRIPT to true, and redeploy. Note this is a different variable from the HEXCLAVE_SEED_INTERNAL_* settings — only HEXCLAVE_SKIP_SEED_SCRIPT stops the crash.
  • Email and webhooks aren't configured out of the box. Password verification codes need HEXCLAVE_EMAILABLE_API_KEY/SMTP configured for real delivery; webhooks need a Svix key. See hexclave's self-host docs for those variables.
  • External DB sync runs inline (HEXCLAVE_EXTERNAL_DB_SYNC_DIRECT=true) instead of through Upstash QStash, which this template doesn't set up. Fine for most self-hosted use; configure QStash yourself if you need queued/retryable delivery.

Template Content

minio-init

minio/mc:latest

hexclave-proxy

caddy:2-alpine

More templates in this category

View Template
Keycloak
Keycloak template with keywind theme + apple and discord providers

beuz
758
View Template
lua-protector
Test deployed my project first

trianaq765-cmd's Project
34
View Template
bknd
Feature-rich yet lightweight backend

10