Railway

Deploy Twenty CRM

Salesforce Alternative: Build your Enterprise CRM at AI Speed

Deploy Twenty CRM

Just deployed

/var/lib/postgresql/data

Just deployed

/data

Just deployed

twenty-storage

Bucket

Just deployed

Twenty CRM logo

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.

Twenty CRM Railway architecture

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_*.

Twenty CRM dashboard screenshot 1 Twenty CRM dashboard screenshot 2 Twenty CRM dashboard screenshot 3

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.1 image on both app services — no latest drift.
  • 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 /healthz check 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

  • twentytwentycrm/twenty:v2.26.1, NestJS server with the React frontend bundled in. Leave the start command empty so the image's entrypoint.sh runs: it does database setup, migrations and cron registration before node dist/main. Binds NODE_PORT, not PORT.
  • twenty-worker — same image, started with /app/entrypoint.sh node dist/queue-worker/queue-worker because a start command replaces the ENTRYPOINT. DISABLE_DB_MIGRATIONS=true and DISABLE_CRON_JOBS_REGISTRATION=true leave the server sole schema owner.
  • Postgres — workspaces, records, custom object definitions and encrypted secrets. Setup creates only uuid-ossp and unaccent, both trusted on Postgres 13+, so stock managed Postgres is enough.
  • Redis — BullMQ backend for every queue, plus the server cache. Leave maxmemory unset: the resulting noeviction policy is what BullMQ requires — an evicting Redis drops jobs.
  • twenty-storage — S3-compatible object storage, selected with STORAGE_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

VariableWhat it does
NODE_PORTPort the app binds; set PORT to match
SERVER_URLPublic base URL for links, emails, OAuth redirects
PG_DATABASE_URL / REDIS_URLWorkspace database; queue and cache backend
ENCRYPTION_KEYEncrypts secrets, signs sessions; stable and shared
STORAGE_TYPE / STORAGE_S3_*Switch file storage from disk to the bucket
DISABLE_DB_MIGRATIONSWorker only, so migrations have one owner
TRUST_PROXYAdds 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

ResourceMinimumRecommended
CPU2 vCPU across the stack4 vCPU
RAM2 GB total4 GB for the server + worker pair
StorageNo volume on either app serviceBucket grows with attachments
RuntimePostgres 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

More templates in this category

View Template
Libredesk - Complete Setup
[Jul'26] Complete self-hosted omnichannel customer support desk.

codestorm
1
View Template
Instatic CMS - Postgres
Design, build and manage powerful static sites from state-of-the-art CMS

Instatic
133
View Template
Strapi
A popular self-hosted CMS

Milo
7.7K