---
title: "Deploy Chatwoot (Sidekiq Worker)"
description: "Intercom alternative with a dedicated Sidekiq worker and shared storage"
category: "Other"
url: https://railway.com/deploy/chatwoot-sidekiq-worker
---

# Deploy Chatwoot (Sidekiq Worker)

Intercom alternative with a dedicated Sidekiq worker and shared storage

**[Deploy Chatwoot (Sidekiq Worker) on Railway](https://railway.com/template/chatwoot-sidekiq-worker)**

- **Creator:** darseen
- **Category:** Other

## Template content

### Sidekiq https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/chatwoot.svg

- **Image:** chatwoot/chatwoot:v4.16.2-ce
- **Start command:** `bundle exec sidekiq -C config/sidekiq.yml`

### Postgres https://devicons.railway.com/i/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

### Rails https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/chatwoot.svg

- **Image:** chatwoot/chatwoot:v4.16.2-ce
- **Start command:** `/bin/sh -c "rm -f tmp/pids/server.pid; bundle exec rails db:chatwoot_prepare && exec bundle exec rails s -p $PORT -b 0.0.0.0"`
- **Health check:** /api
- **Public domain:** Yes

### Redis https://devicons.railway.com/i/redis.svg

- **Image:** redis:8.2.1
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ && exec docker-entrypoint.sh redis-server --requirepass $REDIS_PASSWORD --save 60 1 --dir $RAILWAY_VOLUME_MOUNT_PATH"`

## Buckets

- **Bucket**

## Documentation

# 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](https://github.com/chatwoot/chatwoot) — upstream project
- [Chatwoot environment variables](https://www.chatwoot.com/docs/self-hosted/configuration/environment-variables/) — every setting this template exposes
- [Chatwoot production compose](https://github.com/chatwoot/chatwoot/blob/develop/docker-compose.production.yaml) — the split-service topology this template implements
- [Railway Storage Buckets](https://docs.railway.com/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.



## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — [Jul'26] Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/chatwoot-sidekiq-worker
