Deploy Twenty CRM
Salesforce Alternative: Build your Enterprise CRM at AI Speed
twenty-worker
Just deployed
Just deployed
/var/lib/postgresql/data
Redis
Just deployed
/data
twenty
Just deployed
twenty-storage
Bucket
Just deployed

Deploy and Host Twenty CRM on Railway
Twenty is an open-source CRM built to replace Salesforce and HubSpot: a fast React interface over a metadata-driven Postgres model, where a custom object added in the UI instantly gains REST and GraphQL endpoints, no migration needed. Teams self-host Twenty CRM because the customer database is the asset and AGPL-3.0 means no per-seat licence.
Run Twenty CRM on Railway from the official twentycrm/twenty:v2.26.1 image, split into the two processes upstream expects. twenty is the API server with the frontend bundled in — the only public service, binding NODE_PORT 3000, health-checked at /healthz. twenty-worker runs the same image as a BullMQ queue worker, with no domain. Behind them: managed Postgres, managed Redis and a twenty-storage bucket. No volumes anywhere.

Getting Started with Twenty CRM on Railway
There are no default credentials: the first account registered on your domain becomes the workspace owner. Sign up on /welcome, name the workspace and upload a logo — that upload proves the bucket is wired, landing in object storage rather than on disk. Skip the marketplace and team-invite steps — no SMTP ships by default, so invitations only reach the log. You land on the Companies view with seed records; create one to exercise the server, Postgres and the worker's cron queue at once. Then open Settings → Security, turn off Invite by Link, and set EMAIL_SMTP_*.

About Hosting Twenty CRM
Self-host Twenty CRM when contact data is regulated, when per-seat pricing scales worse than headcount, or when the CRM must be queryable like any service you run.
- Custom objects and fields with no SQL migration — the GraphQL schema regenerates at runtime.
- Table, Kanban and record views with filters, sorts and saved views.
- Workflow automation on record changes, schedules, manual runs or webhooks.
- Email and calendar sync from Google Workspace or Microsoft 365 onto records.
- REST and GraphQL APIs, webhooks, OAuth and roles, generated per workspace.
Server and worker are one image doing two jobs: the server owns schema setup and migrations, the worker owns email sync, workflow runs and cron. Both need one identical ENCRYPTION_KEY — it encrypts secrets at rest and signs sessions.
Why Deploy Twenty CRM on Railway
Five resources, one project:
- Pinned
v2.26.1image on both app services — nolatestdrift. - Managed Postgres and Redis wired by reference variable.
- Object storage preconfigured, so no volume is needed.
- Worker split out, with migrations and cron disabled.
- HTTPS domain and a
/healthzcheck on the public service.
Common Use Cases
- Sales pipeline of record — companies, people and opportunities in Kanban stages, replacing a spreadsheet or a seat-metered CRM.
- Product-to-CRM sync — push signups, trials and usage into custom objects over the REST API.
- Regulated customer data — keep restricted contact records on infrastructure you control.
- Internal ops database — vendors, applicants or assets as custom objects, with views and an API.
Dependencies for Twenty CRM
twenty—twentycrm/twenty:v2.26.1, NestJS server with the React frontend bundled in. Leave the start command empty so the image'sentrypoint.shruns: it does database setup, migrations and cron registration beforenode dist/main. BindsNODE_PORT, notPORT.twenty-worker— same image, started with/app/entrypoint.sh node dist/queue-worker/queue-workerbecause a start command replaces theENTRYPOINT.DISABLE_DB_MIGRATIONS=trueandDISABLE_CRON_JOBS_REGISTRATION=trueleave the server sole schema owner.Postgres— workspaces, records, custom object definitions and encrypted secrets. Setup creates onlyuuid-osspandunaccent, both trusted on Postgres 13+, so stock managed Postgres is enough.Redis— BullMQ backend for every queue, plus the server cache. Leavemaxmemoryunset: the resultingnoevictionpolicy is what BullMQ requires — an evicting Redis drops jobs.twenty-storage— S3-compatible object storage, selected withSTORAGE_TYPE=s3.
Object storage is required, not optional: upstream's compose shares one volume between server and worker, but a Railway volume belongs to one service, so split processes could not read each other's files. It holds profile pictures and app-registry assets too.
Twenty CRM Environment Variables Reference
| Variable | What it does |
|---|---|
NODE_PORT | Port the app binds; set PORT to match |
SERVER_URL | Public base URL for links, emails, OAuth redirects |
PG_DATABASE_URL / REDIS_URL | Workspace database; queue and cache backend |
ENCRYPTION_KEY | Encrypts secrets, signs sessions; stable and shared |
STORAGE_TYPE / STORAGE_S3_* | Switch file storage from disk to the bucket |
DISABLE_DB_MIGRATIONS | Worker only, so migrations have one owner |
TRUST_PROXY | Adds Railway's 100.64.0.0/10 edge so X-Forwarded-Proto works |
Deployment Dependencies
Source: twentyhq/twenty, AGPL-3.0, 45k+ GitHub stars. Node.js runtime inside the published image; docs at docs.twenty.com. Postgres 13+ and Redis 6+.
Hardware Requirements for Self-Hosting Twenty CRM
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU across the stack | 4 vCPU |
| RAM | 2 GB total | 4 GB for the server + worker pair |
| Storage | No volume on either app service | Bucket grows with attachments |
| Runtime | Postgres 13+, Redis 6+ | Postgres 18, Redis 8 |
The server idles near 290 MB and the worker near 270 MB, but both spike past 1 GB during migrations and cron bursts, so headroom matters more than average draw. Give the first /healthz check a long timeout — that boot runs migrations.
Self-Hosting Twenty CRM with Docker
Upstream ships an installer that writes a .env, generates an encryption key and starts a four-container Compose stack. The following is a shell command.
bash <(curl -sL https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/scripts/install.sh)
Closer to this template — external Postgres, Redis and S3:
docker run -d --name twenty -p 3000:3000 \
-e NODE_PORT=3000 -e SERVER_URL="https://crm.example.com" \
-e PG_DATABASE_URL="postgres://twenty:PASSWORD@postgres:5432/twenty" \
-e REDIS_URL="redis://redis:6379" \
-e ENCRYPTION_KEY="$(openssl rand -base64 32)" \
-e STORAGE_TYPE=s3 -e STORAGE_S3_NAME=twenty -e STORAGE_S3_REGION=us-east-1 \
-e STORAGE_S3_ENDPOINT="https://s3.example.com" \
-e STORAGE_S3_ACCESS_KEY_ID=KEY -e STORAGE_S3_SECRET_ACCESS_KEY=SECRET \
twentycrm/twenty:v2.26.1
The worker reuses that environment verbatim, adds both disable flags, and overrides the command with /app/entrypoint.sh node dist/queue-worker/queue-worker.
How Much Does Twenty CRM Cost to Self-Host?
The community edition is free and open source under AGPL-3.0 with no user cap, record cap or feature gate, so self-hosting Twenty CRM costs infrastructure only — the five resources here and nothing else. Twenty's own cloud starts at $9 per user per month, or $19 for the tier adding SSO, row-level permissions and audit logs. Against HubSpot at roughly $90 a seat and Salesforce at $25–$165, the point of Twenty CRM vs Salesforce is that licence cost disappears and only compute remains.
FAQ
What is Twenty CRM?
An open-source, AGPL-3.0 CRM and Salesforce alternative built on Postgres, with UI-defined custom objects, pipelines, workflow automation and generated APIs.
What does this Railway template deploy?
The twenty server on port 3000 with a /healthz check, a twenty-worker on the same image, managed Postgres, managed Redis and a storage bucket. No volumes.
Why does self-hosted Twenty CRM need object storage instead of a volume?
Server and worker read and write the same files, and a Railway volume cannot be shared. STORAGE_TYPE=s3 points both at one bucket and keeps them stateless.
What are the default login credentials for self-hosted Twenty CRM?
None. The first account registered becomes the workspace owner — sign up immediately, then disable open signup under Settings → Security. Mail goes to the log until EMAIL_SMTP_* is set, so there is no password recovery before that.
How do I query self-hosted Twenty CRM from my own code?
Create an API key under Settings → APIs & Webhooks and call the workspace's REST or GraphQL endpoint with it as a bearer token. Custom objects appear in both immediately.
Template Content
twenty-worker
twentycrm/twenty:v2.26.1Redis
redis:8.2.1twenty
twentycrm/twenty:v2.26.1twenty-storage
Bucket