Railway

Deploy Kaneo | Open Source Jira Alternative

Self-hosted Kaneo with Postgres, object storage and a pinned version

Deploy Kaneo | Open Source Jira Alternative

Just deployed

/var/lib/postgresql/data

Just deployed

Uploads

Bucket

Just deployed

Deploy and Host Kaneo on Railway

Kaneo is an open source project management tool — boards, tasks, comments, time tracking and integrations — for teams that want Jira or Linear without the per-seat bill or the hosted account. This template runs Kaneo v2 on Railway with its database, its file storage and its URLs already wired together.

About Hosting Kaneo

Kaneo v2 ships as a single container that runs its API and serves its web client from one origin, so there is no reverse proxy to configure and no CORS to reason about. The template pairs it with a PostgreSQL instance on a persistent volume and a Railway object storage bucket, and sets every variable the two need to find each other over the private network. Nothing is built from source: both images come from upstream, pinned to an exact version.

Four decisions in here are worth knowing about, because they are the difference between this template and a plain docker run.

The version is pinned. Kaneo publishes releases almost daily, and a template that deploys latest hands you a different application every time you redeploy — including schema migrations you did not ask for, at a moment you did not choose. This template pins ghcr.io/usekaneo/kaneo:2.22.0. Upgrading is deliberate: change the tag, redeploy, and the migrations run once on boot.

Sessions survive a redeploy. Kaneo's entrypoint generates a throwaway signing secret when AUTH_SECRET is empty and warns that sessions will not outlive a restart. The template generates the secret once, at deploy time, and keeps it — so a redeploy does not log your whole team out.

The recorded client IP is real, and cannot be forged. Kaneo reads CF-Connecting-IP before anything else when deciding who a request came from. Railway rewrites X-Forwarded-For at its edge but passes CF-Connecting-IP through as the caller sent it, so on a stock deployment any client can dictate the address stored on their session — and rotate it to work around Kaneo's per-IP sign-in rate limiting. The template strips that header in the bundled nginx config before the API ever sees it, and extends TRUSTED_PROXIES with Railway's edge range (100.64.0.0/10) so the address that gets recorded is the visitor's own rather than the Railway point of presence. Both were verified on a live deployment: a request forging either header is still logged from its true address.

Guest sign-in is off. Kaneo enables anonymous guest accounts by default, which is a sensible default for a demo and a poor one for an instance sitting on a public URL. It ships disabled here, and is one variable to turn back on.

Common Use Cases

  • A team board that replaces Jira or Linear: projects, columns, tasks, labels, comments, time entries and activity history, with no seat pricing.
  • Issue tracking wired to your repositories: built-in GitHub and Gitea integrations sync issues and pull requests onto the board; Slack, Discord, Telegram and generic webhooks push notifications out.
  • A private workspace for client work: create your account, switch registration off, and invite collaborators by email only.
  • An MCP-connected backlog: Kaneo exposes a Model Context Protocol endpoint, so an AI assistant can read and update tasks directly.

Dependencies for Kaneo Hosting

Deployment Dependencies

  • Kaneo — the upstream project (source, MIT licensed)
  • PostgreSQL 18 — deployed here as postgres:18.6-alpine on a persistent volume
  • A Railway object storage bucket for images pasted into task descriptions and comments

Implementation Details

Three resources are created: the Kaneo service, a Postgres service with a volume mounted at /var/lib/postgresql/data, and an Uploads bucket.

Kaneo connects to Postgres over Railway's private network. Its client does not require TLS on that hop, so the template uses the plain upstream postgres image rather than an SSL-enabled variant, and the database is never exposed through a public TCP proxy. PGDATA points one level below the volume mount, because the image refuses to initialise into a directory that already contains anything and a fresh Railway volume always contains lost+found.

Database migrations are handled by Kaneo itself. The API waits for Postgres to accept connections — thirty attempts over thirty seconds — then applies pending migrations before serving traffic, so the two services starting in parallel is not a race.

Uploads go to the bucket, not to a disk. Kaneo's API mints a presigned URL and the browser uploads to storage directly, which is why S3_FORCE_PATH_STYLE must stay true: Railway object storage only returns CORS headers on its path-style endpoint, and a virtual-hosted URL would fail in the browser while looking fine from a terminal. Downloads come back through Kaneo's own API after an access check, so the bucket stays private. The upload path was verified end to end on this template — preflight, upload and read-back.

PORT is set to 5173 and must stay there: the nginx config baked into the image listens on that port and never reads $PORT.

Redis is not included. Kaneo only needs it to coordinate several replicas, and this template runs one; the upstream Compose file leaves it commented out for the same reason.

Resource usage and cost

Measured on this template's own deployment: about 400 MB of RAM at rest across both services — roughly 330 MB for Kaneo and 65 MB for Postgres — peaking near 700 MB while the API migrates and boots. CPU is idle between requests. In practice that is somewhere around $5–8 per month on Railway's usage pricing for a small team, plus storage for the volume and whatever you upload to the bucket. A busier instance costs more, but the floor is low because nothing here polls.

After you deploy

  1. Open the URL and create your account — the first one you register is yours.
  2. Set DISABLE_REGISTRATION to true so the instance stops accepting public sign-ups. Workspace invitations keep working.
  3. Optionally configure SMTP if you want invitation emails and email sign-in codes; without it, invitations have to be shared as links.

To upgrade later, change the image tag on the Kaneo service and redeploy. Read the upstream release notes first — Kaneo's migrations run automatically and are not reversible.

Why Deploy Kaneo on Railway?

Railway gives this stack the three things it actually needs and nothing it does not: a private network so the database is never reachable from the internet, a managed object storage bucket so uploads are not tied to a disk that a redeploy can strip, and a volume for Postgres that survives every deployment. There is no cluster to operate, no reverse proxy to write and no certificate to renew — the public domain, TLS and routing come with the service.

Because everything here is upstream images and plain environment variables, you are never locked in. The template is a starting configuration, not a fork: change the tag, point DATABASE_URL at a database you already run, or swap the bucket for any S3-compatible endpoint, and Kaneo carries on.


Template Content

More templates in this category

View Template
Rocky Linux
Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀

codestorm
44
View Template
Foundry Virtual Tabletop
A Self-Hosted & Modern Roleplaying Platform

Lucas
71
View Template
Letta Code Remote
Run a Letta Code agent 24/7. No inbound ports, just deploy.

Letta
51