Deploy Twenty CRM | Salesforce Alternative, Version-Pinned + Built-In S3
Open-source Salesforce alternative. Worker + S3 included, all pinned.
Just deployed
Just deployed
/data
redis
Just deployed
/data
postgres
Just deployed
/var/lib/postgresql
Just deployed
Deploy and Host Twenty CRM on Railway
Twenty is an open-source CRM — a self-hosted alternative to Salesforce, HubSpot and Attio. It gives your team companies, people, opportunities, notes, tasks and attachments in a fast keyboard-driven UI, with custom objects and fields, saved views, workflow automations, a full GraphQL and REST API, and Gmail/Google Calendar and Microsoft 365 sync.
This template deploys a complete five-service Twenty stack: the API/UI server, a background worker, PostgreSQL, Redis, and a built-in MinIO S3 store — each stateful service on its own persistent volume. Every image is pinned to an exact version, and the deploy form has nothing you have to fill in.
About Hosting Twenty CRM
Twenty is not a single container. The server renders the app and answers the API, but everything that happens in the background — email and calendar sync, workflow automations, cron triggers, imports, workspace clean-up — runs in a separate worker process against Redis. A Twenty deploy without that worker looks perfectly healthy and quietly never runs a workflow.
It also needs shared file storage. Both the server and the worker read and write attachments, profile pictures and workspace logos, and a Railway volume cannot be mounted into two services — so local storage would leave files written by one process invisible to the other. This template runs MinIO inside the stack as the shared S3 backend, on its own volume. Nothing external to sign up for, no bucket to create, no keys to paste.
Three things this template does differently from most Twenty listings:
- Everything is version-pinned. The server and the worker both run
twentycrm/twenty:v2.25.1(wrapped asghcr.io/bon5co/twenty-railway), neverlatest. On Railway each service redeploys independently, solatestlets one of them drift onto a newer build against a database the other has not migrated for — and it means an unrelated restart months from now can silently carry your CRM across a breaking upgrade you did not choose. Upgrading here is an explicit change of tag. - A dedicated
ENCRYPTION_KEYis generated per deploy. Since v2.5 Twenty encrypts at-rest secrets — OAuth tokens, TOTP secrets, signing keys, sensitive config — underENCRYPTION_KEY, and silently falls back toAPP_SECRETwhen it is unset. Upstream's guidance is that new installs should always set a dedicated key, so this one does; the two secrets stay independent andAPP_SECRETcan be rotated without destroying every stored credential. - The worker starts in the right order. On a first deploy all five services boot at once, so the worker waits for the server to create the
coreschema instead of crash-looping against tables that do not exist yet, and it runs with migrations and cron registration disabled so it can never race the server's migration.
Sizing: the server is the memory-hungry service (roughly 1 GB), the worker a few hundred MB, and Postgres, Redis and MinIO are small. Expect to need the Hobby plan or above.
Why Deploy Twenty CRM 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 Twenty CRM 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.
- The whole stack in one click — server, worker, Postgres, Redis and S3 storage wired together, no
docker-compose.ymlto debug and no.envto assemble. - Nothing to configure — every variable arrives pre-filled. Secrets, the database and Redis passwords, the MinIO credentials and the server URL are all generated from your Railway domain at deploy time.
- No surprise upgrades — pinned images mean the version you tested is the version that redeploys.
- Background work actually runs — the worker is part of the template, so workflows, cron triggers and mailbox sync work the day you deploy.
- Your data stays yours — records and attachments live on your own volumes, with no per-seat SaaS bill.
Common Use Cases
- Replacing a per-seat CRM — pipelines, companies, people and notes for a sales team, without a Salesforce or HubSpot subscription.
- A CRM shaped like your business — custom objects and fields, saved views and workflow automations for processes a generic CRM does not model.
- A CRM your own software writes to — Twenty's GraphQL and REST APIs make it usable as a customer database behind your product, with the UI as the human view of it.
Dependencies for Twenty CRM Hosting
- PostgreSQL (included in this template) on a volume at
/var/lib/postgresql. - Redis (included) on a volume at
/data, for the worker's job queues and the app cache. Started with--maxmemory-policy noevictionso queued jobs are never evicted. - A worker service (included) — required for workflows, cron triggers, imports and mailbox sync.
- S3-compatible object storage (included, MinIO) on a volume at
/data, shared by the server and the worker. - An SMTP provider — optional, and not part of the template. Twenty needs outbound email for workspace invitations and password resets. Configure it after deploying under Settings → Admin Panel → Configuration Variables.
Deployment Dependencies
- Twenty — the upstream open-source CRM (AGPL-3.0 for the community edition)
- Twenty self-hosting documentation — configuration and environment variable reference
- twentycrm/twenty Docker image — the upstream image this template pins (
v2.25.1) - bon5co/twenty-railway — the open-source Railway wrapper image (Dockerfile + entrypoint) this template deploys
- MinIO — the S3-compatible object store included for shared file storage
Implementation Details
After the deploy finishes, open your Railway domain. Twenty runs in single-workspace mode, so the first person to sign up creates the workspace and becomes its administrator with full admin-panel access — and sign-ups close behind them. Create that account promptly on a public URL.
Check the stack is healthy at any time:
curl https:///healthz
Everything else is configured in-app under Settings → Admin Panel → Configuration Variables — Google/Microsoft OAuth, SMTP, rate limits and integrations — without redeploying.
Upgrading. Change the image tag on both the twenty and worker services to the same new version (tags at hub.docker.com/r/twentycrm/twenty/tags, or the wrapper's own tags) and redeploy the server first; it applies the upgrade migrations on boot and the worker waits for it. Twenty supports jumping straight from any version at or above v1.22 to the latest release. Back up the Postgres volume first.
A note on the twenty and worker services: they are the same image in two roles. The worker's start command is what selects the worker role — leave it alone unless you know what it does.
Template Content