Deploy Chatwoot | Intercom Alternative, Sidekiq Worker + 2FA Included
Intercom alternative: live chat, email, WhatsApp. Worker included, 2FA on.
postgres
Just deployed
/var/lib/postgresql
chatwoot
Just deployed
/app/storage
redis
Just deployed
/data
Just deployed
/app/storage
Deploy and Host Chatwoot on Railway
Chatwoot is an open-source customer engagement platform — a self-hosted alternative to Intercom, Zendesk and Freshdesk. It gives your team one shared inbox for live chat, email, WhatsApp, Instagram, Facebook, SMS, Telegram and API channels, with contact records, canned responses, labels, automations, macros, campaigns and reporting on top.
This template deploys a complete four-service Chatwoot stack: the Rails web app, a Sidekiq background worker, PostgreSQL with pgvector, and Redis — each on its own persistent volume.
About Hosting Chatwoot
Chatwoot is not a single container. The Rails app serves the dashboard and the widget, but everything that happens after a message arrives — outgoing email notifications, campaign sends, IMAP polling, automation rules, scheduled jobs, conversation cleanup, report rollups — runs in a separate Sidekiq worker process against Redis. A Chatwoot deploy without that worker looks healthy and quietly never sends a notification email.
This template runs both, from one pinned image (chatwoot/chatwoot:v4.16.2-ce, wrapped as ghcr.io/bon5co/chatwoot-railway). The wrapper bakes every platform-known setting into the image, so the deploy form has nothing you have to fill in — every variable arrives with a generated value. On the first deploy the entrypoint waits for Postgres, runs rails db:chatwoot_prepare (create + schema load + seed), then serves on Railway's injected $PORT bound to ::; on later deploys the same command just runs pending migrations. The worker waits for that schema to exist before it starts, so nothing crash-loops through the first boot.
Two security defaults differ from a stock install, deliberately:
- Public sign-ups are closed (
ENABLE_ACCOUNT_SIGNUP=false). A fresh Chatwoot on a public URL otherwise lets any stranger who finds it register an account. You still create the first administrator normally —/installation/onboardingis a separate route and is open until you complete it. - MFA/2FA works out of the box. Chatwoot only enables two-factor auth when all three
ACTIVE_RECORD_ENCRYPTION_*keys are set; this template generates all three per deploy.
Postgres uses the pgvector image because Chatwoot's Captain AI features need the vector extension, and Redis persists with an append-only file so queued jobs survive a restart. Sizing: the Rails service is the memory-hungry one (~700 MB–1 GB idle), Sidekiq ~400 MB, Postgres and Redis are small.
Why Deploy Chatwoot 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 Chatwoot 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 — web, worker, Postgres and Redis wired together, no
docker-compose.ymlto debug and no.envto assemble. - Nothing to configure — every variable is pre-filled; secrets, the database password and the frontend URL are generated from your Railway domain at deploy time.
- Background jobs actually run — the Sidekiq worker is part of the template, so email notifications, campaigns, IMAP inboxes and automations work the day you deploy.
- Locked down by default — closed sign-ups, per-deploy secrets, 2FA-ready encryption keys, and private networking between the app and its datastores.
- Your data stays yours — conversations, contacts and attachments live on your own volumes, with no per-seat SaaS bill.
Common Use Cases
- Customer support inbox — a shared team inbox over live chat, email and WhatsApp, replacing a per-seat Intercom or Zendesk subscription.
- Sales and lead capture — put the chat widget on your marketing site, route conversations to agents, and track contacts through their whole history.
- Support for an internal or regulated product — self-host the transcripts and contact data on infrastructure you control instead of a third-party SaaS.
Dependencies for Chatwoot Hosting
- PostgreSQL with pgvector (included in this template) on a volume at
/var/lib/postgresql. - Redis (included) on a volume at
/data, for the Sidekiq queues and the app cache. - A Sidekiq worker service (included) — required for email, campaigns, automations and scheduled jobs.
- An SMTP provider — Chatwoot needs outbound email for agent invitations, password resets and notifications. Set
SMTP_ADDRESS,SMTP_PORT,SMTP_USERNAME,SMTP_PASSWORDandMAILER_SENDER_EMAILon both thechatwootandworkerservices after deploying.
Deployment Dependencies
- Chatwoot — upstream customer engagement platform (MIT for the community edition)
- Chatwoot self-hosted documentation — configuration and environment variable reference
- chatwoot/chatwoot Docker image — the upstream image this template pins (
v4.16.2-ce) - bon5co/chatwoot-railway — the open-source Railway wrapper image (Dockerfile + entrypoint) this template deploys
Implementation Details
After the deploy finishes, open your Railway domain and you land on /installation/onboarding to create the super administrator — name, email, password, company. That form is the only setup step.
Verify the stack is healthy at any time:
curl https:///api
# {"version":"4.16.2","timestamp":"...","queue_services":"ok","data_services":"ok"}
queue_services: ok means Redis and the worker path are wired, data_services: ok means Postgres is. Both are checked by the template's healthcheck on /api.
To add the chat widget to a site, create an Inbox of type Website in the dashboard and paste the generated script tag. To turn public sign-ups back on, set ENABLE_ACCOUNT_SIGNUP=true on the chatwoot service. Attachments are stored on the app's volume by default; for larger installs point ACTIVE_STORAGE_SERVICE at S3 (or a Railway MinIO service) so the web and worker services share one object store.
Template Content