Deploy Chatwoot (Sidekiq Worker)
Intercom alternative with a dedicated Sidekiq worker and shared storage
Sidekiq
Just deployed
Just deployed
/var/lib/postgresql/data
Just deployed
Redis
Just deployed
/data
Bucket
Bucket
Just deployed
Deploy and Host Chatwoot on Railway
Chatwoot is an open-source customer engagement suite — a self-hosted Intercom alternative that pulls live chat, email, WhatsApp, Instagram and Facebook into one shared inbox. This template runs it the way Chatwoot's own production compose file does: the Rails web process and the Sidekiq worker as two separate services instead of one container doing both.
About Hosting Chatwoot
Deploying provisions four services and a storage bucket: a Rails service serving the dashboard, API and chat widget, a Sidekiq service running every background job, Postgres, Redis, and a Railway Storage Bucket that both halves share. The first deploy takes a few minutes while the image pulls and Rails loads the schema; the Sidekiq service restarts a couple of times in the meantime until that schema exists, which is expected and self-healing. Only Rails gets a public domain. When it comes up, open the domain and the installer asks you to create the first admin account.
Common Use Cases
- A support inbox where inbound webhooks, email fetching, campaign sends and report exports must not compete with agent dashboard traffic for CPU
- Teams large enough that Sidekiq needs to scale — or be sized — independently of the web tier
- A fully-owned Intercom or Zendesk replacement, with conversation data in your own Postgres
Dependencies for Chatwoot Hosting
- No external accounts are required. Postgres, Redis and object storage are all provisioned by the template.
- Optional: SMTP credentials (
SMTP_ADDRESS,SMTP_PORT,SMTP_USERNAME,SMTP_PASSWORD) to turn on outgoing email — agent invites, password resets, conversation continuity and export links. Chatwoot runs fine without them; those features just stay dark.
Deployment Dependencies
- Chatwoot — upstream project
- Chatwoot environment variables — every setting this template exposes
- Chatwoot production compose — the split-service topology this template implements
- Railway Storage Buckets — attachment and export storage
Implementation Details
Two services, one image. Both run chatwoot/chatwoot:v4.16.2-ce and differ
only in what they execute:
| Rails | Sidekiq | |
|---|---|---|
| Command | rails s | sidekiq -C config/sidekiq.yml |
| Public domain | yes | no |
| Healthcheck | /api | none |
| Postgres pool | RAILS_MAX_THREADS (5) | SIDEKIQ_CONCURRENCY (10) |
Chatwoot's config/database.yml sizes the connection pool from whichever of
those two is relevant to the process, so splitting the services also stops the
web tier and the job tier from fighting over one pool.
Storage is a bucket, not a disk. This is what makes the split correct. A
Railway volume attaches to exactly one service, so running two services on
Chatwoot's default local storage gives each its own private /app/storage —
and every file one writes is invisible to the other. Contact exports, report
CSVs and email attachments are produced by Sidekiq and downloaded through
Rails, so they would silently 404. Instead this template sets
ACTIVE_STORAGE_SERVICE=s3_compatible and points both services at one Railway
Storage Bucket. Downloads are served as presigned S3 URLs, so the bucket
credentials never reach the browser.
Migrations. Rails starts with db:chatwoot_prepare, which loads the schema
and seeds on an empty database and is a no-op migrate afterwards. Railway has no
equivalent of compose's condition: service_completed_successfully, so Sidekiq
is given restartPolicyType: ALWAYS and no healthcheck: on a cold project it
retries harmlessly until the schema is in place rather than failing the deploy.
Postgres needs pgvector, and Railway's Postgres image ships it — the schema
enables vector alongside pg_trgm, pgcrypto and pg_stat_statements.
Nothing extra to install.
PORT is pinned to 3000. Railway's healthcheck probes the canonical PORT,
so leaving it implicit is the most common cause of a deploy that serves traffic
fine but never goes healthy.
Two-factor auth works out of the box. The three
ACTIVE_RECORD_ENCRYPTION_* keys are generated on Rails and referenced by
Sidekiq rather than regenerated, so encrypted columns stay readable from both
services. Without matching keys, jobs touching a TOTP secret fail.
Scaling Sidekiq. Raise SIDEKIQ_CONCURRENCY for more parallelism inside one
replica, or add replicas for more throughput. Chatwoot's scheduled jobs use
sidekiq-cron, which coordinates through Redis, so multiple replicas will not
double-run them.
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.
Template Content
