Self-Hosting Guide: Deploy Chatwoot for Customer Support
·OSSAlt Team
chatwootcustomer supportself-hostingdockerguide
Self-Hosting Guide: Deploy Chatwoot for Customer Support
Chatwoot is the open source Intercom and Zendesk alternative. Self-hosting gives you unlimited agents, unlimited conversations, and omnichannel support — website live chat, email, WhatsApp, Facebook, Twitter, Telegram, and more.
Requirements
- VPS with 4 GB RAM minimum (8 GB recommended)
- Docker and Docker Compose
- Domain name (e.g.,
support.yourdomain.com) - 20+ GB disk
- SMTP service for email
Step 1: Clone and Configure
# Download Chatwoot Docker setup
git clone https://github.com/chatwoot/chatwoot.git
cd chatwoot
# Copy environment file
cp .env.example .env
Step 2: Configure Environment
Edit .env:
# App
SECRET_KEY_BASE=your-random-secret-key-here
FRONTEND_URL=https://support.yourdomain.com
DEFAULT_LOCALE=en
# Database
POSTGRES_HOST=postgres
POSTGRES_USERNAME=chatwoot
POSTGRES_PASSWORD=your-strong-password
POSTGRES_DATABASE=chatwoot
# Redis
REDIS_URL=redis://redis:6379
# SMTP
MAILER_SENDER_EMAIL=support@yourdomain.com
SMTP_ADDRESS=smtp.resend.com
SMTP_PORT=587
SMTP_USERNAME=resend
SMTP_PASSWORD=re_your_api_key
SMTP_AUTHENTICATION=plain
SMTP_ENABLE_STARTTLS_AUTO=true
# Storage (local or S3)
ACTIVE_STORAGE_SERVICE=local
Generate secret key:
openssl rand -hex 64
Step 3: Docker Compose Setup
# docker-compose.yml
services:
chatwoot:
image: chatwoot/chatwoot:latest
container_name: chatwoot
restart: unless-stopped
ports:
- "3000:3000"
env_file: .env
environment:
- RAILS_ENV=production
- NODE_ENV=production
volumes:
- chatwoot_storage:/app/storage
depends_on:
- postgres
- redis
command: bundle exec rails s -p 3000 -b 0.0.0.0
sidekiq:
image: chatwoot/chatwoot:latest
container_name: chatwoot-sidekiq
restart: unless-stopped
env_file: .env
environment:
- RAILS_ENV=production
volumes:
- chatwoot_storage:/app/storage
depends_on:
- postgres
- redis
command: bundle exec sidekiq -C config/sidekiq.yml
postgres:
image: postgres:16-alpine
container_name: chatwoot-db
restart: unless-stopped
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=chatwoot
- POSTGRES_USER=chatwoot
- POSTGRES_PASSWORD=your-strong-password
redis:
image: redis:7-alpine
container_name: chatwoot-redis
restart: unless-stopped
volumes:
- redis_data:/data
volumes:
chatwoot_storage:
postgres_data:
redis_data:
Step 4: Initialize and Start
# Start services
docker compose up -d
# Run database migrations
docker exec chatwoot bundle exec rails db:chatwoot_prepare
# Create admin account
docker exec -it chatwoot bundle exec rails console
# In console:
# SuperAdmin.create!(email: 'admin@yourdomain.com', password: 'your-password')
# exit
Step 5: Reverse Proxy (Caddy)
# /etc/caddy/Caddyfile
support.yourdomain.com {
reverse_proxy localhost:3000
}
sudo systemctl restart caddy
Step 6: Set Up Channels
Website Live Chat:
- Settings → Inboxes → Add Inbox → Website
- Set your website domain
- Customize widget appearance
- Copy the widget script:
<script>
(function(d,t) {
var BASE_URL="https://support.yourdomain.com";
var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src=BASE_URL+"/packs/js/sdk.js";
g.defer = true;
g.async = true;
s.parentNode.insertBefore(g,s);
g.onload=function(){
window.chatwootSDK.run({
websiteToken: 'YOUR_WEBSITE_TOKEN',
baseUrl: BASE_URL
})
}
})(document,"script");
</script>
Email Channel:
- Settings → Inboxes → Add Inbox → Email
- Configure IMAP for receiving emails
- Configure SMTP for sending replies
WhatsApp (via 360dialog or Twilio):
- Settings → Inboxes → Add Inbox → WhatsApp
- Enter API key from your WhatsApp Business provider
Additional channels: Facebook, Twitter, Telegram, Line, SMS (via Twilio)
Step 7: Configure Team
- Settings → Agents → invite team members
- Settings → Teams → create teams (Sales, Support, Billing)
- Settings → Automation → set up auto-assignment rules
Useful automations:
| Trigger | Action |
|---|---|
| New conversation | Auto-assign to available agent |
| Message contains "billing" | Assign to Billing team |
| No response in 1 hour | Send reminder to agent |
| Conversation resolved | Send satisfaction survey |
Step 8: Canned Responses
Set up quick responses for common questions:
- Settings → Canned Responses
- Create shortcuts like
/greeting,/pricing,/hours - Agents type the shortcut to insert the full response
Production Hardening
S3 Storage (for file attachments at scale):
ACTIVE_STORAGE_SERVICE=amazon
S3_BUCKET_NAME=your-bucket
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_REGION=us-east-1
Backups:
# Database backup (daily cron)
docker exec chatwoot-db pg_dump -U chatwoot chatwoot > /backups/chatwoot-$(date +%Y%m%d).sql
# File storage backup
docker cp chatwoot:/app/storage /backups/chatwoot-storage-$(date +%Y%m%d)
Updates:
docker compose pull
docker compose up -d
docker exec chatwoot bundle exec rails db:chatwoot_prepare
Monitoring:
- Monitor port 3000 with Uptime Kuma
- Monitor Sidekiq queue depth (Redis)
- Set up disk space alerts
Resource Usage
| Agents | RAM | CPU | Disk |
|---|---|---|---|
| 1-5 | 4 GB | 2 cores | 20 GB |
| 5-20 | 8 GB | 4 cores | 50 GB |
| 20-50 | 16 GB | 8 cores | 100 GB |
VPS Recommendations
| Provider | Spec (10 agents) | Price |
|---|---|---|
| Hetzner | 4 vCPU, 8 GB RAM | €8/month |
| DigitalOcean | 4 vCPU, 8 GB RAM | $48/month |
| Linode | 4 vCPU, 8 GB RAM | $48/month |
Compare customer support platforms on OSSAlt — channels, features, and pricing side by side.