Omnigent on Railway
Deploy Omnigent to Railway. Railway pulls the pre-built image, runs it next to
a managed Postgres, and serves it over HTTPS on *.up.railway.app.
Railway is not yet a true one-click. Unlike Render's
render.yaml(fully declarative — Postgres, port, and env all wired automatically), a barerailway.tomlleaves several things to wire by hand (steps below). A real one-click experience needs a published Railway template that pre-wires the Postgres reference,HOST, and target port — tracked as a follow-up. Until then, use the manual steps here. (Render is the smoother path today.)
What gets provisioned
- omnigent — web service that pulls
ghcr.io/omnigent-ai/omnigent-serverviadeploy/docker/Dockerfile.prebuilt, served onhttps://<project>.up.railway.app. - Postgres — Railway-managed PostgreSQL plugin you add to the project.
Railway links its
DATABASE_URLinto the app as a reference to the database instance's variable (largely automatic), but the value can lag on the first deploy — see step 2.
Artifact storage uses the container's local filesystem by default (ephemeral
across redeploys). For persistence, add a Railway Volume mounted at
/data/artifacts.
Optional: external Neon Postgres. Instead of the Railway plugin, you can point
DATABASE_URLat a Neon database (pg.new) — e.g. for Neon's serverless scale-to-zero or branching. Tradeoff: you lose the integrated provisioning (a separate signup + connection string) and add some cross-provider latency, so the Railway plugin stays the simpler default.
Setup (built-in accounts — the default)
Defaults to the accounts auth provider: multi-user, no external IdP. The
steps below are validated end-to-end:
- Deploy from the repo — New Project → Deploy from GitHub repo → this repo.
Railway reads
railway.tomland pulls the image. Add a Postgres plugin to the project. - Database — Railway links the Postgres
DATABASE_URLinto the app as a reference to the db instance's variable (largely automatic when you add the plugin). If the first deploy errors withDATABASE_URL is required, the reference value simply hadn't propagated yet — redeploy and it resolves. (To confirm, the app service should have aDATABASE_URLvariable referencing the Postgres service, e.g.${{Postgres.DATABASE_URL}}.) - Get the admin password from the first-boot Deploy logs (printed once;
idempotent — later boots don't reprint):
It's also written to
✓ Created initial admin account (accounts auth provider). password: <generated>/data/admin-credentials. - Open the URL, log in as
admin, invite teammates from Members.
HOSTis handled automatically. Railway injectsHOST=[::], which a socket bind can't use and which Railway's IPv4 edge can't reach; the entrypoint detects Railway and coerces it to0.0.0.0, so no manualHOSTvariable is needed. If the generated domain returns "Application failed to respond," Railway's port auto-detect picked the wrong port — open Settings → Networking and set the domain's target port to thePORTRailway injected (shown in the boot log asUvicorn running on …:<port>).
The cookie secret is auto-minted and
OMNIGENT_ACCOUNTS_BASE_URLis auto-detected fromRAILWAY_PUBLIC_DOMAIN, so those don't need setting. To pin a known admin password, setOMNIGENT_ACCOUNTS_INIT_ADMIN_PASSWORDbefore first boot.
Use your own IdP instead (OIDC)
Prefer GitHub / Google / Okta login over built-in accounts? Switch the provider
in the service Variables. OIDC requires HTTPS — Railway provides it
automatically on *.up.railway.app. If you set a custom domain, point it at
your project before completing these steps.
GitHub OAuth (simplest to register)
-
Go to
github.com/settings/developers→ New OAuth App.- Homepage URL:
https://<project>.up.railway.app - Authorization callback URL:
https://<project>.up.railway.app/auth/callback - Click Register application, then Generate a new client secret.
- Homepage URL:
-
In your Railway project, open the omnigent service → Variables and add:
Variable Value OMNIGENT_AUTH_PROVIDERoidcOMNIGENT_OIDC_ISSUERhttps://github.comOMNIGENT_OIDC_CLIENT_IDyour GitHub OAuth client ID OMNIGENT_OIDC_CLIENT_SECRETyour GitHub OAuth client secret OMNIGENT_OIDC_REDIRECT_URIhttps://<project>.up.railway.app/auth/callbackOMNIGENT_OIDC_COOKIE_SECREToutput of openssl rand -hex 32 -
Railway redeploys automatically. Visit the URL — you'll be redirected to GitHub to log in.
Google Workspace
| Variable | Value |
|---|---|
OMNIGENT_AUTH_PROVIDER |
oidc |
OMNIGENT_OIDC_ISSUER |
https://accounts.google.com |
OMNIGENT_OIDC_CLIENT_ID |
…apps.googleusercontent.com |
OMNIGENT_OIDC_CLIENT_SECRET |
your client secret |
OMNIGENT_OIDC_REDIRECT_URI |
https://<project>.up.railway.app/auth/callback |
OMNIGENT_OIDC_COOKIE_SECRET |
output of openssl rand -hex 32 |
OMNIGENT_OIDC_ALLOWED_DOMAINS |
example.com (critical — see note below) |
Important: Without
OMNIGENT_OIDC_ALLOWED_DOMAINS, any Google account can log in when the OAuth consent screen is "External." Always restrict to your domain.
Generic OIDC (Okta, Auth0, Keycloak, Entra ID)
Set OMNIGENT_OIDC_ISSUER to your IdP's base URL (the one that publishes
/.well-known/openid-configuration). The rest of the variables are the same
as above.
Custom domain
In your Railway project, open Settings → Domains → Add domain. Point your DNS A/AAAA record at the Railway-assigned address. Railway provisions a Let's Encrypt cert automatically.
Update OMNIGENT_OIDC_REDIRECT_URI to use the custom domain after DNS
propagates.
Upgrading
Railway redeploys automatically when a new image tag is pushed to GHCR (if you've configured a webhook) or on demand:
- In the Railway dashboard, open the omnigent service.
- Click Deploy → Latest to pull the newest
:latestimage.
Cost
Railway Hobby plan: ~$5/month base + per-minute CPU/memory usage. A lightly loaded Omnigent instance (few concurrent users) typically stays under $10–15/month total including the Postgres plugin.
Publishing the template
One-time setup done by the repo owner after the repository is public:
- Go to
railway.com/new/templateand click Create template. - Point it at
github.com/omnigent-ai/omnigent. - Select the Postgres plugin.
- Pre-fill default env vars with descriptions for the optional OIDC fields.
- Click Publish. Copy the generated deploy URL and update the badge at the
top of this file and in
deploy/README.md.