Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Merkurcode/nauto-console/llms.txt
Use this file to discover all available pages before exploring further.
Docker Deployment
Deploy Chatwoot using Docker and Docker Compose for a containerized, portable deployment. This is ideal for development, testing, and production environments that use container orchestration.
Prerequisites
- Docker Engine 20.10+
- Docker Compose v2.0+
- 4GB+ RAM available
- 20GB+ disk space
Install Docker
# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add your user to docker group
sudo usermod -aG docker $USER
newgrp docker
Install Docker Compose
# Docker Compose is included with Docker Desktop
# For Linux servers:
sudo apt-get install docker-compose-plugin
# Verify installation
docker compose version
Quick Start
1. Clone the Repository
git clone https://github.com/chatwoot/chatwoot.git
cd chatwoot
Copy the example environment file:
Edit .env with your configuration:
# Generate a secure secret key
SECRET_KEY_BASE=$(openssl rand -hex 64)
# Update these values in .env
SECRET_KEY_BASE=<your-generated-key>
FRONTEND_URL=http://localhost:3000
REDIS_PASSWORD=<secure-password>
POSTGRES_PASSWORD=<secure-password>
3. Start Services
Chatwoot will be available at http://localhost:3000.
Docker Compose Configuration
Here’s the production-ready docker-compose.yaml configuration:
version: '3'
services:
rails:
image: chatwoot/chatwoot:latest
command: bundle exec rails s -p 3000 -b 0.0.0.0
ports:
- '3000:3000'
env_file: .env
environment:
- NODE_ENV=production
- RAILS_ENV=production
- INSTALLATION_ENV=docker
depends_on:
- postgres
- redis
volumes:
- ./data/storage:/app/storage
sidekiq:
image: chatwoot/chatwoot:latest
command: bundle exec sidekiq -C config/sidekiq.yml
env_file: .env
environment:
- NODE_ENV=production
- RAILS_ENV=production
depends_on:
- postgres
- redis
volumes:
- ./data/storage:/app/storage
postgres:
image: pgvector/pgvector:pg16
restart: always
ports:
- '5432:5432'
volumes:
- postgres:/var/lib/postgresql/data
environment:
- POSTGRES_DB=chatwoot
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
redis:
image: redis:alpine
restart: always
command: ["sh", "-c", "redis-server --requirepass \"$REDIS_PASSWORD\""]
env_file: .env
volumes:
- redis:/data/redis
ports:
- '6379:6379'
volumes:
postgres:
redis:
Production Deployment
For production deployments with Nginx reverse proxy:
1. Docker Compose with Nginx
Create docker-compose.production.yml:
version: '3'
services:
nginx:
image: nginx:alpine
ports:
- '80:80'
- '443:443'
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./ssl:/etc/nginx/ssl:ro
- ./data/storage:/app/storage:ro
depends_on:
- rails
rails:
image: chatwoot/chatwoot:latest
command: bundle exec rails s -p 3000 -b 0.0.0.0
env_file: .env
environment:
- NODE_ENV=production
- RAILS_ENV=production
- RAILS_SERVE_STATIC_FILES=false
- INSTALLATION_ENV=docker
depends_on:
- postgres
- redis
volumes:
- ./data/storage:/app/storage
sidekiq:
image: chatwoot/chatwoot:latest
command: bundle exec sidekiq -C config/sidekiq.yml
env_file: .env
environment:
- NODE_ENV=production
- RAILS_ENV=production
depends_on:
- postgres
- redis
volumes:
- ./data/storage:/app/storage
postgres:
image: pgvector/pgvector:pg16
restart: always
volumes:
- postgres:/var/lib/postgresql/data
environment:
- POSTGRES_DB=chatwoot
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
redis:
image: redis:alpine
restart: always
command: ["sh", "-c", "redis-server --requirepass \"$REDIS_PASSWORD\""]
env_file: .env
volumes:
- redis:/data/redis
volumes:
postgres:
redis:
2. Nginx Configuration
Create nginx.conf:
upstream backend {
server rails:3000;
keepalive 32;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name your-domain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
client_max_body_size 50M;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300s;
}
location /assets/ {
alias /app/public/assets/;
expires max;
add_header Cache-Control public;
}
}
3. Generate SSL Certificates
Using Let’s Encrypt:
# Install certbot
sudo apt-get install certbot
# Generate certificates
sudo certbot certonly --standalone -d your-domain.com
# Copy certificates
mkdir -p ssl
sudo cp /etc/letsencrypt/live/your-domain.com/fullchain.pem ssl/
sudo cp /etc/letsencrypt/live/your-domain.com/privkey.pem ssl/
sudo chown -R $USER:$USER ssl/
4. Start Production Stack
docker compose -f docker-compose.production.yml up -d
Database Setup
After starting the containers, prepare the database:
# Run migrations and seed data
docker compose exec rails bundle exec rails db:chatwoot_prepare
Using Pre-built Images
Chatwoot publishes official Docker images:
services:
rails:
image: chatwoot/chatwoot:latest # Latest stable
# or
image: chatwoot/chatwoot:v4.0.0 # Specific version
# or
image: chatwoot/chatwoot:develop # Development branch
Building Custom Images
To build your own image with customizations:
1. Review the Dockerfile
Chatwoot uses a multi-stage build:
# Pre-build stage
FROM ruby:3.4.4-alpine3.21 AS pre-builder
ARG BUNDLE_WITHOUT="development:test"
ARG RAILS_ENV=production
ARG NODE_OPTIONS="--max-old-space-size=4096 --openssl-legacy-provider"
ENV BUNDLE_PATH="/gems"
ENV BUNDLER_VERSION=2.5.16
# Install dependencies
RUN apk update && apk add --no-cache \
build-base postgresql-dev git curl nodejs npm
WORKDIR /app
# Install Ruby dependencies
COPY Gemfile Gemfile.lock ./
RUN bundle install
# Install Node dependencies
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm i
# Copy application code
COPY . /app
# Precompile assets
RUN SECRET_KEY_BASE=precompile_placeholder \
bundle exec rake assets:precompile
# Final stage
FROM ruby:3.4.4-alpine3.21
RUN apk add --no-cache \
postgresql-client imagemagick vips
COPY --from=pre-builder /gems/ /gems/
COPY --from=pre-builder /app /app
WORKDIR /app
EXPOSE 3000
2. Build Custom Image
# Build the image
docker build -t my-chatwoot:latest .
# Use in docker-compose
services:
rails:
image: my-chatwoot:latest
build:
context: .
dockerfile: docker/Dockerfile
Environment Variables
Key environment variables for Docker deployment:
# Application
SECRET_KEY_BASE=<64-char-hex>
FRONTEND_URL=https://your-domain.com
RAILS_ENV=production
NODE_ENV=production
INSTALLATION_ENV=docker
# Database
POSTGRES_HOST=postgres
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=<password>
POSTGRES_DATABASE=chatwoot
# Redis
REDIS_URL=redis://redis:6379
REDIS_PASSWORD=<password>
# Rails
RAILS_LOG_TO_STDOUT=true
RAILS_SERVE_STATIC_FILES=true
RAILS_MAX_THREADS=5
Persistent Storage
Using Volumes
Mount volumes for persistent data:
services:
rails:
volumes:
# User uploads
- ./data/storage:/app/storage
# Logs (optional)
- ./data/logs:/app/log
Using S3 for Storage
For production, use S3-compatible storage:
# In .env
ACTIVE_STORAGE_SERVICE=amazon
S3_BUCKET_NAME=my-chatwoot-uploads
AWS_ACCESS_KEY_ID=<access-key>
AWS_SECRET_ACCESS_KEY=<secret-key>
AWS_REGION=us-east-1
Management Commands
View Logs
# All services
docker compose logs -f
# Specific service
docker compose logs -f rails
docker compose logs -f sidekiq
Access Rails Console
docker compose exec rails bundle exec rails console
Run Database Migrations
docker compose exec rails bundle exec rails db:migrate
Restart Services
# Restart all
docker compose restart
# Restart specific service
docker compose restart rails
Stop Services
Update Chatwoot
# Pull latest images
docker compose pull
# Restart with new images
docker compose up -d
# Run migrations
docker compose exec rails bundle exec rails db:migrate
Backup & Restore
Backup Database
# Create backup
docker compose exec postgres pg_dump -U postgres chatwoot > backup.sql
# Or use docker exec
docker exec chatwoot-postgres-1 pg_dump -U postgres chatwoot > backup.sql
Restore Database
# Restore from backup
docker compose exec -T postgres psql -U postgres chatwoot < backup.sql
Backup Volumes
# Backup storage volume
docker run --rm \
-v chatwoot_postgres:/data \
-v $(pwd):/backup \
alpine tar czf /backup/postgres-backup.tar.gz /data
Resource Limits
Set resource limits for production:
services:
rails:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
sidekiq:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
Health Checks
Add health checks to your services:
services:
rails:
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
postgres:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
redis:
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval: 10s
timeout: 3s
retries: 5
Troubleshooting
Container won’t start
Check logs:
docker compose logs rails
Database connection errors
Verify PostgreSQL is running:
docker compose ps postgres
docker compose exec postgres psql -U postgres -c "SELECT 1;"
Permission errors
Fix volume permissions:
sudo chown -R 1000:1000 ./data
Out of memory
Increase Docker memory limit in Docker Desktop settings or:
# Linux: Edit /etc/docker/daemon.json
{
"default-runtime": "runc",
"default-memory": "4g"
}
Next Steps