Deploy It's a Plan (Single Host)

Linear and Plane alternative with AI agents, no custom domain needed

Deploy It's a Plan (Single Host)

proxy

caddy:2

Just deployed

attachments

Bucket

Just deployed

Deploy and Host It's a Plan on Railway

It's a Plan is an open-source project tracker in the spirit of Linear and Plane: issues, boards, cycles, initiatives, docs and dashboards, with AI agents that pick up work, chat about it and report back. This template runs the whole stack on the free Railway domain the moment it deploys. No custom domain, no DNS and no variables to fill in.

About Hosting It's a Plan

It's a Plan ships as four images (api, web, worker, Telegram bot) plus Postgres and S3-compatible storage for attachments. The browser needs the web app and the API on one site so the login cookie works. Railway's *.up.railway.app domains are on the Public Suffix List, so a web and an API on two separate Railway subdomains cannot share a session, and sign-in bounces back to the login page.

This template solves that with a small Caddy proxy in front. It serves the web app at / and the API at /api on a single host, which is the "API on a path" mode the It's a Plan docs describe. The session cookie stays host-only (__Host- prefixed) and everything works on the generated domain.

Common Use Cases

  • Issue tracking and sprint planning (cycles) for a product or engineering team
  • A self-hosted Linear or Plane replacement that keeps your data in your own Postgres
  • Letting AI agents triage, plan and work issues next to people, through the built-in agents and the MCP server
  • Project docs, notes and dashboards in the same place as the work

Dependencies for It's a Plan Hosting

  • Postgres 18 (Railway's SSL image, with a volume)
  • A Railway storage bucket for attachments
  • The official ghcr.io/croffasia/itsaplan-* images
  • Caddy 2 (official image) as the single-host proxy

Deployment Dependencies

Implementation Details

Services

ServiceRole
proxyPublic entry point. /api/* goes to api (prefix removed), OAuth discovery documents go to api, everything else goes to web
webNext.js frontend, private
apiElysia API on Bun, private. Runs database migrations on every start
workerWebhooks, notifications, agent schedules and imports
botTelegram bot (long polling). Keep it at one replica
postgresDatabase, with a volume
attachmentsRailway bucket for uploaded files

First run

Open the proxy's URL and click Sign up. The first account becomes the instance admin and gets God mode. There are no default credentials. After that, create a team and a project.

Lock it down once your team has joined: God mode → Authentication → Registration controls open sign-up and invite lifetime.

Configured in the app, not with variables

SMTP or Resend email, AI provider keys, Google sign-in and the Telegram bot token are set in God mode after you sign in. Provider keys are stored encrypted with APP_ENCRYPTION_KEY.

Secrets

BETTER_AUTH_SECRET, APP_ENCRYPTION_KEY, WORKER_INTERNAL_TOKEN and the database password are generated for every deploy. Do not change APP_ENCRYPTION_KEY later, or stored provider keys can no longer be decrypted.

Using your own domain

  1. Add the custom domain to the proxy service (Settings → Networking, port 8080).
  2. On the web service, set APP_URL=https://plan.example.com and API_URL=https://plan.example.com/api. The api reads both from web.
  3. Redeploy web and api.

Updates

The app images track latest, the newest release, with auto updates on between 02:00 and 06:00 UTC. The api applies migrations when it starts. Turn this off or pin a version per service under Settings → Source.

Troubleshooting

  • Sign-in returns to the login page: APP_URL and API_URL on web must be the same host as the one in your browser, with /api on the end of API_URL. Redeploy web and api after changing them.
  • 502 from the proxy straight after the deploy: web or api is still starting. Wait a minute.
  • An attachment uploads but will not open, and web logs show ERR_INVALID_URL ... http://:3000: redeploy the web service so SERVICE_URL_API picks up the api's private address.

Scaling

api, web and worker are stateless. bot must stay at one replica, because Telegram hands each update to only one caller.

Why Deploy It's a Plan on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying It's a Plan on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.


Template Content

More templates in this category

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

codestorm
50
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