add intro documentation and user guide

This commit is contained in:
Tanmay Deep Sharma
2025-05-29 19:29:32 +05:30
parent f429db89b4
commit 7808634432
203 changed files with 8020 additions and 7794 deletions
@@ -1,416 +1,100 @@
---
title: Chatwoot CTL (cwctl)
description: Command-line tool for managing Chatwoot installations with ease
title: Chatwoot CTL
description: CLI tool to install and manage a self hosted Chatwoot Linux installation
sidebarTitle: Chatwoot CTL
---
# Chatwoot CTL (cwctl)
## Introduction
Chatwoot CTL (`cwctl`) is a command-line tool that simplifies the management of your Chatwoot installation. It provides convenient commands for common administrative tasks like upgrades, restarts, console access, and log viewing.
Chatwoot CTL(`cwctl`) is CLI tool to install and manage a self hosted Chatwoot Linux installation.
## Installation
`cwctl` aims to abstract away the common bash interactions with a Chatwoot installation and provide an easy to use syntax. This is not intended to be a full replacement.
### Automatic Installation
If you are running a Chatwoot v2.7.0 instance or later, `cwctl` would have been already installed for you as part of installation.
`cwctl` is automatically installed when you use the Linux installation script (v2.7.0+):
Check if `cwctl` is already installed by
```bash
wget https://get.chatwoot.app/linux/install.sh
chmod +x install.sh
./install.sh --install
cwctl --version
```
### Manual Installation
If `cwctl` is not present, follow the steps below to install Chatwoot CTL.
If you have an older installation or need to install `cwctl` separately:
### Install or Upgrade Chatwoot CTL
If you used an older version of install script(< 2.0), you will not have `cwctl` in your PATH. To install/upgrade Chatwoot CTL,
```bash
# Download and install cwctl
wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl
chmod +x /usr/local/bin/cwctl
# Verify installation
wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl && chmod +x /usr/local/bin/cwctl
cwctl --help
```
<Note>
The manual installation requires root access to install `cwctl` to `/usr/local/bin`.
The above command requires root access to install `cwctl` to `/usr/local/bin`.
</Note>
## Available Commands
### Help
### Help and Version
To learn more about the options supported by `cwctl`,
```bash
# Display help information
cwctl --help
cwctl -h
# Show version information
cwctl --version
cwctl -v
sudo cwctl --help
```
### Installation Management
### Upgrading to a newer version of Chatwoot
Whenever a new version of Chatwoot is released, use the following steps to upgrade your instance.
```bash
# Install Chatwoot (same as running install.sh --install)
cwctl --install
# Upgrade to the latest version
cwctl --upgrade
# Restart Chatwoot services
cwctl --restart
cwctl -r
sudo cwctl --upgrade
```
### Console and Debugging
<Note>
This will upgrade your Chatwoot instance to the latest stable release. If you are running a custom branch in production do not use this to upgrade.
</Note>
### Setup Nginx with SSL after installation
To set up Nginx with SSL after initial setup(if you answered `no` to webserver/SSL setup during the first install)
<Note>
Please add an A record pointing to your Chatwoot instance IP before proceeding.
</Note>
```bash
# Access Rails console
cwctl --console
cwctl -c
# View web server logs
cwctl --logs web
cwctl -l web
# View worker logs
cwctl --logs worker
cwctl -l worker
# View all logs
cwctl --logs
cwctl -l
sudo cwctl --webserver
```
### Service Management
### Restart Chatwoot
```bash
# Check service status
cwctl --status
cwctl -s
# Stop Chatwoot services
cwctl --stop
# Start Chatwoot services
cwctl --start
```
## Detailed Command Usage
### Upgrading Chatwoot
The upgrade command handles the complete upgrade process:
```bash
cwctl --upgrade
```
This command performs the following steps:
1. Switches to the chatwoot user
2. Navigates to the Chatwoot directory
3. Pulls the latest code from the master branch
4. Updates Ruby version if needed
5. Installs/updates dependencies (bundle, pnpm)
6. Precompiles assets
7. Runs database migrations
8. Updates systemd service files
9. Restarts services
<Warning>
Always backup your database before upgrading:
```bash
# Create a backup before upgrading
sudo -u postgres pg_dump chatwoot_production > chatwoot_backup_$(date +%Y%m%d).sql
```
</Warning>
### Console Access
Access the Rails console for debugging and administration:
```bash
cwctl --console
```
This opens an interactive Ruby console where you can:
```ruby
# Check application version
Rails.application.config.version
# List all accounts
Account.all
# Find a specific user
User.find_by(email: 'admin@example.com')
# Check system statistics
Account.count
User.count
Conversation.count
# Clear cache
Rails.cache.clear
```
### Log Management
View real-time logs for troubleshooting:
```bash
# Web server logs (Rails application)
cwctl -l web
# Worker logs (Sidekiq background jobs)
cwctl -l worker
# All logs (both web and worker)
cwctl -l
```
### Service Management
Control Chatwoot services:
```bash
# Check if services are running
cwctl --status
# Restart all services (web + worker)
cwctl --restart
# Stop all services
cwctl --stop
# Start all services
cwctl --start
```
## Configuration
### Environment Variables
`cwctl` respects the same environment variables as your Chatwoot installation. Key variables include:
```bash
# Chatwoot installation directory
CHATWOOT_DIR="/home/chatwoot/chatwoot"
# Rails environment
RAILS_ENV="production"
# Database configuration
DATABASE_URL="postgresql://..."
# Redis configuration
REDIS_URL="redis://..."
```
### Custom Installation Paths
If Chatwoot is installed in a non-standard location, you can specify the path:
```bash
# Set custom Chatwoot directory
export CHATWOOT_DIR="/opt/chatwoot"
cwctl --restart
```
## Troubleshooting
### Common Issues
<Accordion title="cwctl command not found">
If `cwctl` is not found, ensure it's installed and in your PATH:
```bash
# Check if cwctl exists
which cwctl
# If not found, install it
wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl
chmod +x /usr/local/bin/cwctl
# Add to PATH if needed
echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```
</Accordion>
<Accordion title="Permission denied errors">
Ensure you have the necessary permissions:
```bash
# Run with sudo if needed
sudo cwctl --restart
# Or ensure your user is in the chatwoot group
sudo usermod -a -G chatwoot $USER
```
</Accordion>
<Accordion title="Service restart failures">
If services fail to restart, check the logs:
### Running Rails Console
```bash
# Check systemd status
sudo systemctl status chatwoot.target
sudo systemctl status chatwoot-web.1.service
sudo systemctl status chatwoot-worker.1.service
# View detailed logs
sudo journalctl -u chatwoot-web.1.service -f
sudo journalctl -u chatwoot-worker.1.service -f
sudo cwctl --console
```
</Accordion>
### Debug Mode
### Viewing Logs
For verbose output during operations:
For Chatwoot web(rails) server logs use,
```bash
# Enable debug mode
export CWCTL_DEBUG=1
cwctl --upgrade
sudo cwctl --logs web
```
### Manual Operations
If `cwctl` fails, you can perform operations manually:
For Chatwoot worker(sidekiq) server logs use,
```bash
# Manual upgrade process
sudo -i -u chatwoot
cd chatwoot
git checkout master && git pull
rvm use 3.3.3 --default
bundle install
pnpm install
RAILS_ENV=production bundle exec rake assets:precompile
RAILS_ENV=production bundle exec rake db:migrate
exit
# Restart services manually
sudo systemctl restart chatwoot.target
sudo cwctl --logs worker
```
## Best Practices
### Version
### Regular Maintenance
To check the version of Chatwoot CTL,
```bash
# Weekly upgrade check
cwctl --upgrade
# Daily log monitoring
cwctl -l | grep ERROR
# Monthly service restart
cwctl --restart
```
### Backup Before Operations
```bash
# Create backup script
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
sudo -u postgres pg_dump chatwoot_production > "/backup/chatwoot_$DATE.sql"
cwctl --upgrade
```
### Monitoring
```bash
# Check service health
cwctl --status
# Monitor logs for errors
cwctl -l | grep -E "(ERROR|FATAL|Exception)"
# Check disk space before upgrades
df -h /home/chatwoot
```
## Integration with System Tools
### Systemd Integration
`cwctl` works seamlessly with systemd:
```bash
# These commands are equivalent
cwctl --restart
sudo systemctl restart chatwoot.target
cwctl --status
sudo systemctl status chatwoot.target
```
### Cron Jobs
Automate maintenance tasks:
```bash
# Add to crontab
# Weekly upgrade (Sundays at 2 AM)
0 2 * * 0 /usr/local/bin/cwctl --upgrade
# Daily restart (to clear memory leaks)
0 3 * * * /usr/local/bin/cwctl --restart
```
### Monitoring Scripts
```bash
#!/bin/bash
# Health check script
if ! cwctl --status > /dev/null 2>&1; then
echo "Chatwoot services are down, attempting restart..."
cwctl --restart
# Send alert notification
fi
```
## Advanced Usage
### Custom Commands
You can extend `cwctl` functionality by creating wrapper scripts:
```bash
#!/bin/bash
# custom-cwctl.sh - Extended cwctl with additional features
case "$1" in
--backup)
echo "Creating backup..."
sudo -u postgres pg_dump chatwoot_production > "backup_$(date +%Y%m%d).sql"
;;
--health-check)
echo "Performing health check..."
curl -f http://localhost:3000/api || echo "Health check failed"
;;
*)
cwctl "$@"
;;
esac
```
### Environment-Specific Operations
```bash
# Development environment
RAILS_ENV=development cwctl --console
# Staging environment
RAILS_ENV=staging cwctl --restart
```
---
`cwctl` simplifies Chatwoot administration by providing a unified interface for common tasks. Use it regularly to maintain your installation and troubleshoot issues efficiently.
sudo cwctl --version
```
+115 -482
View File
@@ -1,572 +1,205 @@
---
title: Docker Deployment Guide
description: Complete guide to deploy Chatwoot using Docker containers for production environments.
title: Docker Chatwoot Production deployment guide
description: Deploy Chatwoot using Docker containers for production environments
sidebarTitle: Docker
---
Docker provides a consistent, portable way to deploy Chatwoot across different environments. This guide covers production deployment using Docker Compose with best practices for security, performance, and maintenance.
## Pre-requisites
## Prerequisites
Before proceeding, make sure you have the latest version of `docker` and `docker-compose` installed.
Before starting, ensure you have:
- Docker 20.10+ installed
- Docker Compose 2.0+ installed
- At least 4GB RAM and 2 CPU cores
- Domain name with DNS configured (recommended)
- Basic understanding of Docker concepts
### Version Check
Verify your Docker installation:
As of now [at the time of writing this doc], we recommend a version equal to or higher than the following.
```bash
$ docker --version
Docker version 25.0.4, build 1a576c5
Docker version 20.10.10, build b485636
$ docker compose version
Docker Compose version v2.24.7
Docker Compose version v2.14.1
```
<Note>
Container names use dashes instead of underscores by default with newer Docker Compose versions. If using an older version, replace `-` with `_` and use `docker-compose` instead of `docker compose`.
Container name uses dashes instead of underscores by default with new docker/compose versions. If you are using an older version of docker/compose, replace `-` with `_`. Also, use `docker-compose` instead of `docker compose`.
</Note>
## Quick Start
## Steps to deploy Chatwoot using docker-compose
### 1. Install Docker
### 1. Install Docker on your VM
**Ubuntu/Debian:**
```bash
# Update package index
apt-get update && apt-get upgrade -y
# Install Docker
# example in ubuntu
apt-get update
apt-get upgrade
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Install Docker Compose plugin
apt install docker-compose-plugin
# Add user to docker group (optional)
sudo usermod -aG docker $USER
```
**CentOS/RHEL:**
```bash
# Install Docker
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Start Docker service
sudo systemctl start docker
sudo systemctl enable docker
```
### 2. Download Configuration Files
### 2. Download the required files
```bash
# Create project directory
mkdir chatwoot && cd chatwoot
# Download environment template
# Download the env file template
wget -O .env https://raw.githubusercontent.com/chatwoot/chatwoot/develop/.env.example
# Download Docker Compose configuration
# Download the Docker compose template
wget -O docker-compose.yaml https://raw.githubusercontent.com/chatwoot/chatwoot/develop/docker-compose.production.yaml
```
### 3. Configure Environment
### 3. Configure environment variables
Edit the `.env` file with your settings:
Tweak the `.env` and `docker-compose.yaml` according to your preferences. Refer to the available [environment variables](/docs/self-hosted/configuration/environment-variables). You could also remove the dependant services like `Postgres`, `Redis` etc., in favor of managed services configured via environment variables.
```bash
# update redis and postgres passwords
nano .env
# update docker-compose.yaml same postgres pass
nano docker-compose.yaml
```
**Essential configurations:**
```env
# Database Configuration
POSTGRES_PASSWORD=your_secure_postgres_password
REDIS_PASSWORD=your_secure_redis_password
# Application Configuration
SECRET_KEY_BASE=your_secret_key_base_64_chars_long
FRONTEND_URL=https://your-domain.com
# Email Configuration (required for notifications)
MAILER_SENDER_EMAIL=noreply@your-domain.com
SMTP_ADDRESS=smtp.your-provider.com
SMTP_PORT=587
SMTP_USERNAME=your-smtp-username
SMTP_PASSWORD=your-smtp-password
SMTP_AUTHENTICATION=plain
SMTP_ENABLE_STARTTLS_AUTO=true
# File Storage (optional - defaults to local)
ACTIVE_STORAGE_SERVICE=local
# For S3: ACTIVE_STORAGE_SERVICE=amazon
# AWS_ACCESS_KEY_ID=your_access_key
# AWS_SECRET_ACCESS_KEY=your_secret_key
# AWS_REGION=us-east-1
# AWS_BUCKET=your-bucket-name
```
### 4. Update Docker Compose
Edit `docker-compose.yaml` to match your `.env` passwords:
```yaml
services:
postgres:
environment:
- POSTGRES_PASSWORD=your_secure_postgres_password # Match .env
redis:
command: ["sh", "-c", "redis-server --requirepass your_secure_redis_password"]
```
### 5. Initialize Database
### 4. Prepare the database
```bash
# Prepare the database
docker compose run --rm rails bundle exec rails db:chatwoot_prepare
```
### 6. Start Services
### 5. Start the services
```bash
# Start all services in background
docker compose up -d
# Check service status
docker compose ps
```
### 7. Verify Installation
### 6. Access your installation
Your Chatwoot installation is complete. Please note that the containers are not exposed to the internet and they only bind to the localhost. Setup something like Nginx or any other proxy server to proxy the requests to the container.
If you want to verify whether the installation is working, try `curl -I localhost:3000/api` to see if it returns `200`. Also, you could temporarily drop the `127.0.0.1:3000:3000` for rails to `3000:3000` in the compose file to access your instance at `http://<your-external-ip>:3000`. It's recommended to revert this change back and use Nginx or some proxy server in the front.
## Additional Steps
1. Have an `Nginx` web server acting as a reverse proxy for Chatwoot installation. So that you can access Chatwoot from `https://chat.yourdomain.com`
2. Run `docker compose run --rm rails bundle exec rails db:chatwoot_prepare` whenever you decide to update the Chatwoot images to handle the migrations.
### Configure Nginx and Let's Encrypt
#### 1. Configure Nginx to serve as a frontend proxy
```bash
# Check if Chatwoot is responding
curl -I localhost:3000/api
# Should return: HTTP/1.1 200 OK
sudo apt-get install nginx
cd /etc/nginx/sites-enabled
nano yourdomain.com.conf
```
## Production Configuration
#### 2. Use the following Nginx config
### Docker Compose Setup
Here's a complete production-ready `docker-compose.yaml`:
```yaml
version: '3.8'
services:
base: &base
image: chatwoot/chatwoot:latest
env_file: .env
volumes:
- ./data/storage:/app/storage
depends_on:
- postgres
- redis
rails:
<<: *base
container_name: chatwoot-rails
command: ["sh", "-c", "bundle exec rails s -b 0.0.0.0 -p 3000"]
ports:
- "127.0.0.1:3000:3000"
environment:
- NODE_ENV=production
- RAILS_ENV=production
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api"]
interval: 30s
timeout: 10s
retries: 3
sidekiq:
<<: *base
container_name: chatwoot-sidekiq
command: ["sh", "-c", "bundle exec sidekiq -C config/sidekiq.yml"]
restart: unless-stopped
healthcheck:
test: ["CMD", "pgrep", "-f", "sidekiq"]
interval: 30s
timeout: 10s
retries: 3
postgres:
image: postgres:14-alpine
container_name: chatwoot-postgres
restart: unless-stopped
ports:
- "127.0.0.1:5432:5432"
volumes:
- ./data/postgres:/var/lib/postgresql/data
environment:
- POSTGRES_DB=chatwoot
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=your_secure_postgres_password
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 10s
retries: 3
redis:
image: redis:7-alpine
container_name: chatwoot-redis
restart: unless-stopped
command: ["sh", "-c", "redis-server --requirepass your_secure_redis_password"]
ports:
- "127.0.0.1:6379:6379"
volumes:
- ./data/redis:/data
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval: 30s
timeout: 10s
retries: 3
volumes:
postgres_data:
redis_data:
storage_data:
```
### Nginx Reverse Proxy
Create `/etc/nginx/sites-available/chatwoot.conf`:
Use the following Nginx config after replacing the `yourdomain.com` in `server_name`.
```nginx
server {
server_name your-domain.com;
# Point upstream to Chatwoot App Server
set $upstream 127.0.0.1:3000;
# Nginx strips out underscore in headers by default
# Chatwoot relies on underscore in headers for API
underscores_in_headers on;
# Increase client max body size for file uploads
client_max_body_size 50M;
location /.well-known {
alias /var/www/ssl-proof/chatwoot/.well-known;
}
location / {
proxy_pass_header Authorization;
proxy_pass http://$upstream;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_buffering off;
proxy_read_timeout 36000s;
proxy_redirect off;
}
listen 80;
server_name <yourdomain.com>;
# Point upstream to Chatwoot App Server
set $upstream 127.0.0.1:3000;
# Nginx strips out underscore in headers by default
# Chatwoot relies on underscore in headers for API
# Make sure that the config is set to on.
underscores_in_headers on;
location /.well-known {
alias /var/www/ssl-proof/chatwoot/.well-known;
}
location / {
proxy_pass_header Authorization;
proxy_pass http://$upstream;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on; # Optional
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_buffering off;
client_max_body_size 0;
proxy_read_timeout 36000s;
proxy_redirect off;
}
listen 80;
}
```
Enable the site and configure SSL:
#### 3. Verify and reload Nginx config
```bash
# Enable site
sudo ln -s /etc/nginx/sites-available/chatwoot.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# Install Certbot and get SSL certificate
sudo apt install certbot python3-certbot-nginx
sudo mkdir -p /var/www/ssl-proof/chatwoot/.well-known
sudo certbot --webroot -w /var/www/ssl-proof/chatwoot/ -d your-domain.com -i nginx
nginx -t
systemctl reload nginx
```
## Advanced Configuration
#### 4. Run Let's Encrypt to configure SSL certificate
### Environment Variables
Key environment variables for production:
```bash
apt install certbot
apt-get install python3-certbot-nginx
mkdir -p /var/www/ssl-proof/chatwoot/.well-known
certbot --webroot -w /var/www/ssl-proof/chatwoot/ -d yourdomain.com -i nginx
```
```env
# Application
RAILS_ENV=production
NODE_ENV=production
SECRET_KEY_BASE=generate_64_character_secret
FRONTEND_URL=https://your-domain.com
#### 5. Access your installation
# Database
DATABASE_URL=postgresql://postgres:password@postgres:5432/chatwoot
REDIS_URL=redis://redis:6379/0
REDIS_PASSWORD=your_redis_password
Your Chatwoot installation should be accessible from the `https://yourdomain.com` now.
# Email
MAILER_SENDER_EMAIL=noreply@your-domain.com
SMTP_ADDRESS=smtp.your-provider.com
SMTP_PORT=587
SMTP_USERNAME=your_username
SMTP_PASSWORD=your_password
SMTP_AUTHENTICATION=plain
SMTP_ENABLE_STARTTLS_AUTO=true
## Steps to build images yourself
# File Storage
ACTIVE_STORAGE_SERVICE=amazon
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_REGION=us-east-1
AWS_BUCKET=your-bucket-name
We publish our base images to the Docker hub. You should be able to build your Chatwoot web/worker images from these base images.
# Security
FORCE_SSL=true
RAILS_LOG_TO_STDOUT=true
### Web
# Performance
RAILS_MAX_THREADS=5
WEB_CONCURRENCY=2
```dockerfile
FROM chatwoot/chatwoot:latest
RUN chmod +x docker/entrypoints/rails.sh
ENTRYPOINT ["docker/entrypoints/rails.sh"]
CMD bundle exec bundle exec rails s -b 0.0.0.0 -p 3000
```
### Resource Limits
Add resource limits to your `docker-compose.yaml`:
```yaml
services:
rails:
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '1.0'
memory: 1G
### Worker
sidekiq:
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
postgres:
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
redis:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
```dockerfile
FROM chatwoot/chatwoot:latest
RUN chmod +x docker/entrypoints/rails.sh
ENTRYPOINT ["docker/entrypoints/rails.sh"]
CMD bundle exec sidekiq -C config/sidekiq.yml
```
### Logging Configuration
The app servers will run available on port `3000`. Ensure the images connect to the same database and Redis servers. Provide the configuration for these services via [environment variables](/docs/self-hosted/configuration/environment-variables).
Configure centralized logging:
### Initial database setup
```yaml
services:
rails:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
To set up the database for the first time, you must run `rails db:chatwoot_prepare`. You may get errors if you try to run `rails db:migrate` at this point.
sidekiq:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
```
## Upgrading
## Maintenance Operations
If you're not using the `latest` or `latest-ce` tag, you first need to change the desired tag in your docker-compose file.
### Upgrading Chatwoot
After that you can pull the new image and start using them:
```bash
# Pull latest images
docker compose pull
# Stop services
docker compose down
# Start with new images
docker compose up -d
```
# Run database migrations
Finally you may need to update the database:
```bash
docker compose run --rm rails bundle exec rails db:chatwoot_prepare
```
### Backup and Restore
**Database Backup:**
```bash
# Create backup
docker compose exec postgres pg_dump -U postgres chatwoot > backup_$(date +%Y%m%d_%H%M%S).sql
# Restore backup
docker compose exec -T postgres psql -U postgres chatwoot < backup_file.sql
```
**File Storage Backup:**
```bash
# Backup storage directory
tar -czf storage_backup_$(date +%Y%m%d_%H%M%S).tar.gz ./data/storage/
```
### Monitoring and Logs
**View logs:**
```bash
# All services
docker compose logs -f
# Specific service
docker compose logs -f rails
docker compose logs -f sidekiq
# Last 100 lines
docker compose logs --tail=100 rails
```
**Monitor resources:**
```bash
# Container stats
docker stats
# Service health
docker compose ps
```
### Rails Console Access
## Running Rails Console
```bash
# Access Rails console
docker compose exec rails bundle exec rails console
# Run one-off commands
docker compose run --rm rails bundle exec rails runner "puts User.count"
docker exec -it $(basename $(pwd))-rails-1 sh -c 'RAILS_ENV=production bundle exec rails c'
```
## Troubleshooting
## Chatwoot CE edition docker images
### Common Issues
**1. Permission Issues:**
```bash
# Fix file permissions
sudo chown -R 1000:1000 ./data/
```
**2. Database Connection Issues:**
```bash
# Check database connectivity
docker compose exec rails bundle exec rails db:version
```
**3. Memory Issues:**
```bash
# Check memory usage
docker stats --no-stream
```
**4. SSL Certificate Issues:**
```bash
# Renew certificates
sudo certbot renew --dry-run
```
### Performance Optimization
**1. Database Optimization:**
```sql
-- Connect to database
docker compose exec postgres psql -U postgres chatwoot
-- Check slow queries
SELECT query, mean_time, calls
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;
```
**2. Redis Optimization:**
```bash
# Check Redis memory usage
docker compose exec redis redis-cli info memory
```
### Security Hardening
**1. Network Security:**
```yaml
# Add to docker-compose.yaml
networks:
chatwoot:
driver: bridge
internal: true
services:
rails:
networks:
- chatwoot
- default # Only rails needs external access
```
**2. Secrets Management:**
```bash
# Use Docker secrets for sensitive data
echo "your_secret_password" | docker secret create postgres_password -
```
## Community Edition vs Enterprise
This guide covers Chatwoot Community Edition (CE). For Enterprise features:
**CE Docker Tags:**
- `chatwoot/chatwoot:latest-ce` (latest CE)
- `chatwoot/chatwoot:v2.3.2-ce` (specific version CE)
**Enterprise Features:**
- Advanced reporting and analytics
- SAML SSO integration
- Advanced automation rules
- Priority support
---
<Warning>
Always test upgrades in a staging environment before applying to production. Keep regular backups of your database and file storage.
</Warning>
<Note>
For high-availability deployments, consider using Docker Swarm or Kubernetes instead of Docker Compose.
</Note>
If you want to run Chatwoot CE edition, replace the docker image tag with equivalent foss version tag. Docker tag for current `master` would be `latest-ce`. Version specific tags would follow the pattern `v*-ce`. For example the docker ce edition tag for Chatwoot `v2.3.2` would be `v2.3.2-ce`.
@@ -1,537 +1,234 @@
---
title: Kubernetes Deployment
description: Deploy Chatwoot on Kubernetes using Helm charts for scalable, production-ready installations
title: Deploy Chatwoot on Kubernetes using Helm Charts
description: Deploy Chatwoot on Kubernetes using our official Helm charts
sidebarTitle: Kubernetes
---
# Kubernetes Deployment Guide
This guide will help you to deploy a production ready Chatwoot instance with Helm Charts.
Deploy Chatwoot on Kubernetes using our official Helm charts for a scalable, production-ready installation.
## Prerequisites
Before deploying Chatwoot on Kubernetes, ensure you have:
- **Kubernetes cluster** (v1.19+) with sufficient resources
- **Helm 3.x** installed and configured
- **kubectl** configured to access your cluster
- **Ingress controller** (nginx, traefik, etc.) for external access
- **Cert-manager** (optional, for automatic SSL certificates)
### Minimum Resource Requirements
- **CPU**: 2 cores minimum (4+ cores recommended)
- **Memory**: 4GB RAM minimum (8GB+ recommended)
- **Storage**: 20GB persistent storage for PostgreSQL
- **Nodes**: 3+ nodes for high availability
## Quick Start
### 1. Add Chatwoot Helm Repository
To quickly try out the charts, follow the two steps below. For a production deployment, please make sure to pass in the required arguments to helm using your custom `values.yaml` file.
```bash
helm repo add chatwoot https://chatwoot.github.io/charts
helm install chatwoot chatwoot/chatwoot
```
<iframe frameborder="0" scrolling="no" marginheight="0" marginwidth="0"width="100%" height="443" type="text/html" src="https://www.youtube-nocookie.com/embed/o1jnYfy8CCo"></iframe>
## Prerequisites
- Kubernetes 1.16+
- Helm 3.1.0+
- PV provisioner support in the underlying infrastructure
The helm installation will create 3 "Persistent Volume Claims" for redis, rails and postgres. Setup up a default "Storage Class" (for automatic PV) or create 3 "Persistent Volumes" with the size of 8GB, before installing chatwoot. If the "Persistent Volume Claims" do not claim the "Persistent Volumes", leave storageClassName blank (inside the PV .yaml files).
## Installing the chart
To install the chart with the release name `chatwoot`, use the following. To deploy it in `chatwoot` namespace, pass `-n chatwoot` to the command.
```bash
helm install chatwoot chatwoot/chatwoot -f <your-custom-values.yaml> #-n chatwoot
```
The command deploys Chatwoot on the Kubernetes cluster in the default configuration. The [parameters](#parameters) section lists the parameters that can be configured during installation.
<Tip>
List all releases using `helm list`
</Tip>
## Uninstalling the chart
To uninstall/delete the `chatwoot` deployment:
```bash
helm delete chatwoot
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
<Note>
Persistent volumes are not deleted automatically. They need to be removed manually.
</Note>
## Parameters
### Chatwoot Image parameters
| Name | Description | Value |
| ------------------- | ---------------------------------------------------- | ---------------------- |
| `image.repository` | Chatwoot image repository | `chatwoot/chatwoot` |
| `image.tag` | Chatwoot image tag (immutable tags are recommended) | `v2.16.0` |
| `image.pullPolicy` | Chatwoot image pull policy | `IfNotPresent` |
### Chatwoot Environment Variables
| Name | Type | Default Value |
| ------------------------------------ | ------------------------------------------------------------------- | ---------------------------------------------------------- |
| `env.ACTIVE_STORAGE_SERVICE` | Storage service. `local` for disk. `amazon` for s3. | `"local"` |
| `env.ASSET_CDN_HOST` | Set if CDN is used for asset delivery. | `""` |
| `env.INSTALLATION_ENV` | Sets chatwoot installation method. | `"helm"` |
| `env.ENABLE_ACCOUNT_SIGNUP` | `true` : default option, allows sign ups, `false` : disables all the end points related to sign ups, `api_only`: disables the UI for signup but you can create sign ups via the account apis. | `"false"` |
| `env.FORCE_SSL` | Force all access to the app over SSL, default is set to false. | `"false"` |
| `env.FRONTEND_URL` | Replace with the URL you are planning to use for your app. | `"http://0.0.0.0:3000/"` |
| `env.IOS_APP_ID` | Change this variable only if you are using a custom build for mobile app. | `"6C953F3RX2.com.chatwoot.app"` |
| `env.ANDROID_BUNDLE_ID` | Change this variable only if you are using a custom build for mobile app. | `"com.chatwoot.app"` |
| `env.ANDROID_SHA256_CERT_FINGERPRINT`| Change this variable only if you are using a custom build for mobile app. | `"AC:73:8E:DE:EB:5............"` |
| `env.MAILER_SENDER_EMAIL` | The email from which all outgoing emails are sent. | `""` |
| `env.RAILS_ENV` | Sets rails environment. | `"production"` |
| `env.RAILS_MAX_THREADS` | Number of threads each worker will use. | `"5"` |
| `env.SECRET_KEY_BASE` | Used to verify the integrity of signed cookies. Ensure a secure value is set. | `replace_with_your_super_duper_secret_key_base` |
| `env.SENTRY_DSN` | Sentry data source name. | `""` |
| `env.SMTP_ADDRESS` | Set your smtp address. |`""` |
| `env.SMTP_AUTHENTICATION` | Allowed values: `plain`,`login`,`cram_md5` | `"plain"` |
| `env.SMTP_ENABLE_STARTTLS_AUTO` | Defaults to true. | `"true"` |
| `env.SMTP_OPENSSL_VERIFY_MODE` | Can be: `none`, `peer`, `client_once`, `fail_if_no_peer_cert` | `"none"` |
| `env.SMTP_PASSWORD` | SMTP password | `""` |
| `env.SMTP_PORT` | SMTP port | `"587"` |
| `env.SMTP_USERNAME` | SMTP username | `""` |
| `env.USE_INBOX_AVATAR_FOR_BOT` | Bot customizations | `"true"` |
### Email setup for conversation continuity (Incoming emails)
| Name | Type | Default Value |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `env.MAILER_INBOUND_EMAIL_DOMAIN` | This is the domain set for the reply emails when conversation continuity is enabled. | `""` |
| `env.RAILS_INBOUND_EMAIL_SERVICE` | Set this to appropriate ingress channel with regards to incoming emails. Possible values are `relay`, `mailgun`, `mandrill`, `postmark` and `sendgrid`. | `""` |
| `env.RAILS_INBOUND_EMAIL_PASSWORD` | Password for the email service. | `""` |
| `env.MAILGUN_INGRESS_SIGNING_KEY` | Set if using mailgun for incoming conversations. | `""` |
| `env.MANDRILL_INGRESS_API_KEY` | Set if using mandrill for incoming conversations. | `""` |
### Postgres variables
| Name | Type | Default Value |
| ----------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------ |
| `postgresql.enabled` | Set to `false` if using external postgres and modify the below variables. | `true` |
| `postgresql.auth.database` | Chatwoot database name | `chatwoot_production` |
| `postgresql.postgresqlHost` | Postgres host. Edit if using external postgres. | `""` |
| `postgresql.auth.postgresPassword` | Postgres password. Edit if using external postgres. | `postgres` |
| `postgresql.postgresqlPort` | Postgres port | `5432` |
| `postgresql.auth.username` | Postgres username. | `postgres` |
### Redis variables
| Name | Type | Default Value |
| ----------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------- |
| `redis.auth.password` | Password used for internal redis cluster | `redis` |
| `redis.enabled` | Set to `false` if using external redis and modify the below variables. | `true` |
| `redis.host` | Redis host name | `""` |
| `redis.port` | Redis port | `""` |
| `redis.password` | Redis password | `""` |
| `env.REDIS_TLS` | Set to `true` if TLS(`rediss://`) is required | `false` |
| `env.REDIS_SENTINELS` | Redis Sentinel can be used by passing list of sentinel host and ports. | `""` |
| `env.REDIS_SENTINEL_MASTER_NAME` | Redis sentinel master name is required when using sentinel. | `""` |
### Logging variables
| Name | Type | Default Value |
| ----------------------------------- | ------------------------------------------------------------------- | ---------------------------------------------------------- |
| `env.RAILS_LOG_TO_STDOUT` | string | `"true"` |
| `env.LOG_LEVEL` | string | `"info"` |
| `env.LOG_SIZE` | string | `"500"` |
### Third party credentials
| Name | Type | Default Value |
| ----------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------- |
| `env.S3_BUCKET_NAME` | S3 bucket name | `""` |
| `env.AWS_ACCESS_KEY_ID` | Amazon access key ID | `""` |
| `env.AWS_REGION` | Amazon region | `""` |
| `env.AWS_SECRET_ACCESS_KEY` | Amazon secret key ID | `""` |
| `env.FB_APP_ID` | For facebook channel https://www.chatwoot.com/docs/facebook-setup | `""` |
| `env.FB_APP_SECRET` | For facebook channel | `""` |
| `env.FB_VERIFY_TOKEN` | For facebook channel | `""` |
| `env.SLACK_CLIENT_ID` | For slack integration | `""` |
| `env.SLACK_CLIENT_SECRET` | For slack integration | `""` |
| `env.TWITTER_APP_ID` | For twitter channel | `""` |
| `env.TWITTER_CONSUMER_KEY` | For twitter channel | `""` |
| `env.TWITTER_CONSUMER_SECRET` | For twitter channel | `""` |
| `env.TWITTER_ENVIRONMENT` | For twitter channel | `""` |
### Autoscaling
| Name | Type | Default Value |
| ----------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------- |
| `web.hpa.enabled` | Horizontal Pod Autoscaling for Chatwoot web | `false` |
| `web.hpa.cputhreshold` | CPU threshold for Chatwoot web | `80` |
| `web.hpa.minpods` | Minimum number of pods for Chatwoot web | `1` |
| `web.hpa.maxpods` | Maximum number of pods for Chatwoot web | `10` |
| `web.replicaCount` | No of web pods if hpa is not enabled | `1` |
| `worker.hpa.enabled` | Horizontal Pod Autoscaling for Chatwoot worker | `false` |
| `worker.hpa.cputhreshold` | CPU threshold for Chatwoot worker | `80` |
| `worker.hpa.minpods` | Minimum number of pods for Chatwoot worker | `2` |
| `worker.hpa.maxpods` | Maximum number of pods for Chatwoot worker | `10` |
| `worker.replicaCount` | No of worker pods if hpa is not enabled | `1` |
## Install with custom parameters
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
```bash
helm install my-release \
--set env.FRONTEND_URL="chat.yourdomain.com"\
chatwoot/chatwoot
```
The above command sets the Chatwoot server frontend URL to `chat.yourdoamain.com`.
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
```bash
helm install my-release -f values.yaml chatwoot/chatwoot
```
<Tip>
You can use the default `values.yaml` file.
</Tip>
## Postgres
PostgreSQL is installed along with the chart if you choose the default setup. To use an external Postgres DB, please set `postgresql.enabled` to `false` and set the variables under the Postgres section above.
## Redis
Redis is installed along with the chart if you choose the default setup. To use an external Redis DB, please set `redis.enabled` to `false` and set the variables under the Redis section above.
## Autoscaling
To enable horizontal pod autoscaling, set `web.hpa.enabled` and `worker.hpa.enabled` to `true`. Also make sure to uncomment the values under, `resources.limits` and `resources.requests`. This assumes your k8s cluster is already having a metrics-server. If not, deploy metrics-server with the following command.
```bash
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
```
## Upgrading
Do `helm repo update` and check the version of charts that is going to be installed. Helm charts follows semantic versioning and so if the MAJOR version is different from your installed version, there might be breaking changes. Please refer to the changelog before upgrading.
```bash
# update helm repositories
helm repo update
# list your current installed version
helm list
# show the latest version of charts that is going to be installed
helm search repo chatwoot
```
### 2. Create Namespace
```bash
kubectl create namespace chatwoot
```
### 3. Install with Default Values
```bash
helm install chatwoot chatwoot/chatwoot \
--namespace chatwoot \
--set ingress.enabled=true \
--set ingress.hosts[0].host=chatwoot.yourdomain.com \
--set ingress.hosts[0].paths[0].path=/ \
--set ingress.hosts[0].paths[0].pathType=Prefix
```
## Production Configuration
### Custom Values File
Create a `values.yaml` file for production deployment:
```yaml
# values.yaml
replicaCount: 3
image:
repository: chatwoot/chatwoot
tag: "latest"
pullPolicy: IfNotPresent
env:
RAILS_ENV: production
NODE_ENV: production
FRONTEND_URL: "https://chatwoot.yourdomain.com"
FORCE_SSL: "true"
# Database Configuration
postgresql:
enabled: true
auth:
postgresPassword: "your-secure-password"
database: "chatwoot_production"
primary:
persistence:
enabled: true
size: 50Gi
storageClass: "fast-ssd"
metrics:
enabled: true
# Redis Configuration
redis:
enabled: true
auth:
enabled: true
password: "your-redis-password"
master:
persistence:
enabled: true
size: 10Gi
metrics:
enabled: true
# Ingress Configuration
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
hosts:
- host: chatwoot.yourdomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: chatwoot-tls
hosts:
- chatwoot.yourdomain.com
# Resource Limits
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
# Horizontal Pod Autoscaler
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
# Storage Configuration
persistence:
enabled: true
storageClass: "fast-ssd"
size: 20Gi
# Service Configuration
service:
type: ClusterIP
port: 3000
# Worker Configuration
worker:
enabled: true
replicaCount: 2
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
# Monitoring
serviceMonitor:
enabled: true
namespace: monitoring
```
### Deploy with Custom Configuration
```bash
helm install chatwoot chatwoot/chatwoot \
--namespace chatwoot \
--values values.yaml
```
## External Dependencies
### Using External PostgreSQL
```yaml
postgresql:
enabled: false
env:
DATABASE_URL: "postgresql://username:password@postgres-host:5432/chatwoot_production"
```
### Using External Redis
```yaml
redis:
enabled: false
env:
REDIS_URL: "redis://redis-host:6379/0"
```
### Using Cloud Storage
```yaml
env:
# AWS S3
ACTIVE_STORAGE_SERVICE: "amazon"
S3_BUCKET_NAME: "your-chatwoot-bucket"
AWS_ACCESS_KEY_ID: "your-access-key"
AWS_SECRET_ACCESS_KEY: "your-secret-key"
AWS_REGION: "us-east-1"
# Google Cloud Storage
# ACTIVE_STORAGE_SERVICE: "google"
# GCS_PROJECT: "your-project"
# GCS_BUCKET: "your-bucket"
```
## High Availability Setup
### Multi-Zone Deployment
```yaml
# Spread pods across availability zones
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- chatwoot
topologyKey: topology.kubernetes.io/zone
# Node selection
nodeSelector:
node-type: "application"
# Tolerations for dedicated nodes
tolerations:
- key: "dedicated"
operator: "Equal"
value: "chatwoot"
effect: "NoSchedule"
```
### Database High Availability
```yaml
postgresql:
enabled: true
architecture: replication
auth:
replicationPassword: "replication-password"
primary:
persistence:
enabled: true
size: 100Gi
readReplicas:
replicaCount: 2
persistence:
enabled: true
size: 100Gi
```
## Security Configuration
### Network Policies
```yaml
# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: chatwoot-network-policy
namespace: chatwoot
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: chatwoot
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 3000
egress:
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: postgresql
ports:
- protocol: TCP
port: 5432
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: redis
ports:
- protocol: TCP
port: 6379
```
### Pod Security Standards
```yaml
securityContext:
runAsNonRoot: true
runAsUser: 1001
fsGroup: 1001
seccompProfile:
type: RuntimeDefault
containerSecurityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
capabilities:
drop:
- ALL
```
## Monitoring and Observability
### Prometheus Monitoring
```yaml
serviceMonitor:
enabled: true
labels:
app: chatwoot
interval: 30s
scrapeTimeout: 10s
path: /metrics
# Custom metrics
env:
PROMETHEUS_EXPORTER: "true"
PROMETHEUS_EXPORTER_PORT: "9394"
```
### Logging Configuration
```yaml
# Structured logging
env:
LOG_LEVEL: "info"
LOG_FORMAT: "json"
# Log aggregation with Fluentd/Fluent Bit
annotations:
fluentbit.io/parser: "json"
fluentbit.io/exclude: "false"
```
### Health Checks
```yaml
livenessProbe:
httpGet:
path: /api
port: 3000
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /api
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
```
## Backup and Disaster Recovery
### Database Backup
```yaml
# CronJob for database backup
apiVersion: batch/v1
kind: CronJob
metadata:
name: chatwoot-db-backup
namespace: chatwoot
spec:
schedule: "0 2 * * *" # Daily at 2 AM
jobTemplate:
spec:
template:
spec:
containers:
- name: postgres-backup
image: postgres:15
command:
- /bin/bash
- -c
- |
pg_dump $DATABASE_URL | gzip > /backup/chatwoot-$(date +%Y%m%d-%H%M%S).sql.gz
# Upload to S3 or other storage
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: chatwoot-secrets
key: database-url
volumeMounts:
- name: backup-storage
mountPath: /backup
volumes:
- name: backup-storage
persistentVolumeClaim:
claimName: backup-pvc
restartPolicy: OnFailure
```
## Upgrading Chatwoot
### Rolling Update
```bash
# Update to latest version
helm upgrade chatwoot chatwoot/chatwoot \
--namespace chatwoot \
--values values.yaml
# Update to specific version
helm upgrade chatwoot chatwoot/chatwoot \
--namespace chatwoot \
--values values.yaml \
--set image.tag="v2.15.0"
```
### Database Migration
```bash
# Run migrations after upgrade
kubectl exec -it deployment/chatwoot -n chatwoot -- \
bundle exec rails db:migrate RAILS_ENV=production
#if it is major version update, refer to the changelog before proceeding
helm upgrade chatwoot chatwoot/chatwoot -f <your-custom-values>.yaml
```
## Troubleshooting
### Common Issues
### pod has unbound immediate PersistentVolumeClaims
Make sure the "Persistent Volume Claims" can be satisfied. Refer to [prerequisites](#prerequisites).
### ActionController::InvalidAuthenticityToken HTTP Origin header
<Tip>
**Pod Startup Issues**: Check resource limits and node capacity
```bash
kubectl describe pod <pod-name> -n chatwoot
kubectl top nodes
```
</Tip>
<Warning>
**Database Connection Issues**: Verify database credentials and network policies
```bash
kubectl logs deployment/chatwoot -n chatwoot
kubectl exec -it deployment/chatwoot -n chatwoot -- nc -zv postgres-host 5432
```
</Warning>
### Debug Commands
```bash
# Check pod status
kubectl get pods -n chatwoot
# View logs
kubectl logs -f deployment/chatwoot -n chatwoot
# Access pod shell
kubectl exec -it deployment/chatwoot -n chatwoot -- /bin/bash
# Check service endpoints
kubectl get endpoints -n chatwoot
# Describe ingress
kubectl describe ingress chatwoot -n chatwoot
ActionController::InvalidAuthenticityToken HTTP Origin header (https://mydomain.com) didn't match request.base_url (http://mydomain.com)
```
### Performance Tuning
```yaml
# Optimize for high traffic
env:
RAILS_MAX_THREADS: "20"
WEB_CONCURRENCY: "4"
SIDEKIQ_CONCURRENCY: "25"
resources:
limits:
cpu: 4000m
memory: 8Gi
requests:
cpu: 2000m
memory: 4Gi
# Database connection pooling
env:
DATABASE_POOL_SIZE: "25"
```
## Best Practices
### Resource Management
- Set appropriate resource requests and limits
- Use horizontal pod autoscaling for dynamic scaling
- Monitor resource usage and adjust as needed
### Security
- Use network policies to restrict traffic
- Enable pod security standards
- Regularly update container images
- Use secrets for sensitive configuration
### Monitoring
- Enable Prometheus metrics collection
- Set up alerting for critical metrics
- Monitor application and infrastructure health
- Use distributed tracing for complex issues
### Backup
- Implement automated database backups
- Test backup restoration procedures
- Store backups in multiple locations
- Document recovery procedures
---
This Kubernetes deployment guide provides a solid foundation for running Chatwoot in production. Customize the configuration based on your specific requirements and infrastructure setup.
If you are recieving the above error when trying to access the superadmin panel, configure your ingress controller to forward the protocol of the origin request. For `nginx` ingress, you can do this by setting the `proxy_set_header X-Forwarded-Proto https;` config. Refer this [issue](https://github.com/chatwoot/chatwoot/issues/5506) to learn more.
+109 -597
View File
@@ -1,675 +1,187 @@
---
title: Linux VM Deployment Guide
description: Complete guide to deploy Chatwoot on Linux virtual machines using the automated installation script.
title: Production deployment guide for Linux VM
description: Deploy Chatwoot on Ubuntu 24.04 LTS using the automated installation script
sidebarTitle: Linux VM
---
This guide covers deploying Chatwoot on Linux virtual machines using our automated installation script. This method is ideal for traditional server environments and provides full control over the installation process.
## Deploying to Linux VM
## Prerequisites
This guide will help you install **Chatwoot** on **Ubuntu 24.04 LTS**. We have prepared a deployment script for you to run. Refer to the script and feel free to make changes accordingly to the operating system if you are on a non-Ubuntu system.
Before starting, ensure you have:
<iframe width="100%" height="443" src="https://www.youtube-nocookie.com/embed/vu_61D1VFAk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
- Ubuntu 20.04 LTS or later (recommended)
- At least 4GB RAM and 2 CPU cores
- 50GB+ available disk space
- Root or sudo access
- Domain name with DNS configured (optional but recommended)
- SMTP server for email notifications
## Steps to install
### Supported Operating Systems
<Note>
If you plan to use a domain with chatwoot, please add an A record before proceeding. Refer to the `Configuring the installation domain` section below.
</Note>
| OS | Version | Status |
|---|---|---|
| **Ubuntu** | 20.04 LTS, 22.04 LTS, 24.04 LTS | ✅ Recommended |
| **Debian** | 10, 11, 12 | ✅ Supported |
| **CentOS** | 8, 9 | ✅ Supported |
| **RHEL** | 8, 9 | ✅ Supported |
| **Amazon Linux** | 2 | ✅ Supported |
## Quick Installation
### 1. Download Installation Script
### 1. Create an install.sh file
```bash
# Download the installation script
wget https://get.chatwoot.app/linux/install.sh
# Make it executable
chmod +x install.sh
```
### 2. Run Installation
### 2. Execute the script
The script will take care of the initial **Chatwoot** setup.
```bash
# Run the installation script
./install.sh --install
```
The script will:
- Install all required dependencies
- Set up PostgreSQL and Redis
- Install Ruby, Node.js, and other runtime dependencies
- Clone and configure Chatwoot
- Set up systemd services
- Configure Nginx (if domain is provided)
- Set up SSL with Let's Encrypt (if domain is provided)
### 3. Access your installation
### 3. Domain Configuration (Optional)
**Chatwoot** Installation will now be accessible at `http://{your_ip_address}:3000` or if you opted for domain setup, it will be at `https://chatwoot.mydomain.com`.
If you have a domain name:
<Note>
This will also install the Chatwoot CLI(`cwctl`) starting with Chatwoot v2.7.0. Use `cwctl --help` to learn more.
</Note>
1. **Create DNS A Record**: Point your domain to your server's IP address
2. **During installation**: Enter `yes` when prompted about domain setup
3. **Enter your domain**: The script will configure Nginx and SSL automatically
## Configuring The installation Domain
### 4. Access Your Installation
1. Create an `A` record for `chatwoot.mydomain.com` on your domain management system and point it towards the installation IP address.
2. Continue with the installation script by entering `yes` when prompted about domain setup.
3. Enter your domain. The script will take care of configuring Nginx and SSL via LetsEncrypt.
4. Your Chatwoot installation should be accessible from `https://chatwoot.mydomain.com` now.
- **With domain**: `https://your-domain.com`
- **Without domain**: `http://your-server-ip:3000`
## Configure the required environment variables
**Default login credentials:**
```
URL: https://your-domain.com
Email: john@acme.inc
Password: Password1!
```
For your Chatwoot installation to properly function, you would need to configure the essential environment variables like `FRONTEND_URL`, Mailer, and a cloud storage config. Refer **[Environment variables](/docs/self-hosted/configuration/environment-variables)** for the full list.
## Manual Installation
For more control over the installation process, you can install manually:
### 1. System Preparation
### 1. Login as chatwoot user and edit the .env file
```bash
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install essential packages
sudo apt install -y curl wget gnupg2 software-properties-common apt-transport-https ca-certificates lsb-release
```
### 2. Install Dependencies
**PostgreSQL:**
```bash
# Install PostgreSQL
sudo apt install -y postgresql postgresql-contrib
# Start and enable PostgreSQL
sudo systemctl start postgresql
sudo systemctl enable postgresql
# Create database and user
sudo -u postgres psql << EOF
CREATE DATABASE chatwoot;
CREATE USER chatwoot WITH ENCRYPTED PASSWORD 'your_secure_password';
GRANT ALL PRIVILEGES ON DATABASE chatwoot TO chatwoot;
ALTER USER chatwoot CREATEDB;
\q
EOF
```
**Redis:**
```bash
# Install Redis
sudo apt install -y redis-server
# Configure Redis
sudo sed -i 's/^# requirepass foobared/requirepass your_redis_password/' /etc/redis/redis.conf
# Start and enable Redis
sudo systemctl start redis-server
sudo systemctl enable redis-server
```
**Ruby (using RVM):**
```bash
# Install RVM
curl -sSL https://get.rvm.io | bash -s stable
source ~/.rvm/scripts/rvm
# Install Ruby
rvm install 3.3.3
rvm use 3.3.3 --default
```
**Node.js:**
```bash
# Install Node.js 20.x
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# Install pnpm
npm install -g pnpm
```
**Additional Dependencies:**
```bash
# Install build tools and libraries
sudo apt install -y git build-essential libssl-dev libreadline-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev libyaml-dev libsqlite3-dev libgdbm-compat-dev libncurses5-dev libreadline6-dev
# Install ImageMagick for image processing
sudo apt install -y imagemagick libmagickwand-dev
# Install FFmpeg for media processing
sudo apt install -y ffmpeg
```
### 3. Install Chatwoot
```bash
# Create chatwoot user
sudo adduser --disabled-login --gecos "" chatwoot
# Switch to chatwoot user
# Login as chatwoot user
sudo -i -u chatwoot
# Clone Chatwoot repository
git clone https://github.com/chatwoot/chatwoot.git
cd chatwoot
# Checkout latest stable version
git checkout master
# Install Ruby dependencies
bundle install
# Install Node.js dependencies
pnpm install
# Copy environment file
cp .env.example .env
```
### 4. Configure Environment
Edit the `.env` file:
```bash
nano .env
```
**Essential configurations:**
### 2. Update environment variables
```env
# Database Configuration
DATABASE_URL=postgresql://chatwoot:your_secure_password@localhost:5432/chatwoot
Refer **[Environment variables](/docs/self-hosted/configuration/environment-variables)** and update the required variables. Save the `.env` file.
# Redis Configuration
REDIS_URL=redis://localhost:6379/0
REDIS_PASSWORD=your_redis_password
### 3. Restart the Chatwoot server
# Application Configuration
SECRET_KEY_BASE=generate_a_64_character_secret_key
FRONTEND_URL=https://your-domain.com
# Email Configuration
MAILER_SENDER_EMAIL=noreply@your-domain.com
SMTP_ADDRESS=smtp.your-provider.com
SMTP_PORT=587
SMTP_USERNAME=your-smtp-username
SMTP_PASSWORD=your-smtp-password
SMTP_AUTHENTICATION=plain
SMTP_ENABLE_STARTTLS_AUTO=true
# File Storage (optional)
ACTIVE_STORAGE_SERVICE=local
# For S3: ACTIVE_STORAGE_SERVICE=amazon
# AWS_ACCESS_KEY_ID=your_access_key
# AWS_SECRET_ACCESS_KEY=your_secret_key
# AWS_REGION=us-east-1
# AWS_BUCKET=your-bucket-name
# Security
FORCE_SSL=true
RAILS_ENV=production
NODE_ENV=production
```
### 5. Setup Database
<Note>
If you have Chatwoot CLI(`cwctl`) installed, use `cwctl -r`.
</Note>
```bash
# Prepare the database
RAILS_ENV=production bundle exec rails db:chatwoot_prepare
# Precompile assets
RAILS_ENV=production bundle exec rails assets:precompile
sudo systemctl restart chatwoot.target
```
### 6. Configure Systemd Services
## Upgrading to a newer version of Chatwoot
Create systemd service files:
Whenever a new version of Chatwoot is released, use the following steps to upgrade your instance.
**Web Service (`/etc/systemd/system/chatwoot-web.1.service`):**
```ini
[Unit]
Description=Chatwoot web server
After=network.target
<Note>
If you have Chatwoot CLI(`cwctl`) installed, use `cwctl --upgrade` to upgrade your Chatwoot installation.
</Note>
[Service]
Type=simple
User=chatwoot
WorkingDirectory=/home/chatwoot/chatwoot
Environment=RAILS_ENV=production
Environment=BUNDLE_GEMFILE=/home/chatwoot/chatwoot/Gemfile
ExecStart=/home/chatwoot/.rvm/bin/rvm default do bundle exec rails server -b 0.0.0.0 -p 3000 -e production
Restart=always
RestartSec=1
To install `cwctl`, refer [this](#install-or-upgrade-chatwoot-cli) section below.
[Install]
WantedBy=multi-user.target
```
<Note>
If you are on an older version of Chatwoot(< 2.7), follow the manual upgrade steps below if you face errors with `cwctl`.
</Note>
**Worker Service (`/etc/systemd/system/chatwoot-worker.1.service`):**
```ini
[Unit]
Description=Chatwoot sidekiq worker
After=network.target
[Service]
Type=simple
User=chatwoot
WorkingDirectory=/home/chatwoot/chatwoot
Environment=RAILS_ENV=production
Environment=BUNDLE_GEMFILE=/home/chatwoot/chatwoot/Gemfile
ExecStart=/home/chatwoot/.rvm/bin/rvm default do bundle exec sidekiq -C config/sidekiq.yml
Restart=always
RestartSec=1
[Install]
WantedBy=multi-user.target
```
**Target Service (`/etc/systemd/system/chatwoot.target`):**
```ini
[Unit]
Description=Chatwoot services
Wants=chatwoot-web.1.service chatwoot-worker.1.service
[Install]
WantedBy=multi-user.target
```
Enable and start services:
```bash
# Reload systemd
sudo systemctl daemon-reload
# Enable and start Chatwoot services
sudo systemctl enable chatwoot.target
sudo systemctl start chatwoot.target
# Check status
sudo systemctl status chatwoot.target
```
### 7. Configure Nginx
Install and configure Nginx:
Run the following steps on your VM. Make changes based on your OS if you are on a non-Ubuntu system.
```bash
# Install Nginx
sudo apt install -y nginx
# Create Nginx configuration
sudo nano /etc/nginx/sites-available/chatwoot
```
**Nginx configuration:**
```nginx
server {
server_name your-domain.com;
# Point upstream to Chatwoot App Server
set $upstream 127.0.0.1:3000;
# Nginx strips out underscore in headers by default
# Chatwoot relies on underscore in headers for API
underscores_in_headers on;
# Increase client max body size for file uploads
client_max_body_size 50M;
location /.well-known {
alias /var/www/ssl-proof/chatwoot/.well-known;
}
location / {
proxy_pass_header Authorization;
proxy_pass http://$upstream;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_buffering off;
proxy_read_timeout 36000s;
proxy_redirect off;
}
listen 80;
}
```
Enable the site:
```bash
# Enable site
sudo ln -s /etc/nginx/sites-available/chatwoot /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Restart Nginx
sudo systemctl restart nginx
```
### 8. Setup SSL with Let's Encrypt
```bash
# Install Certbot
sudo apt install -y certbot python3-certbot-nginx
# Create directory for SSL verification
sudo mkdir -p /var/www/ssl-proof/chatwoot/.well-known
# Get SSL certificate
sudo certbot --webroot -w /var/www/ssl-proof/chatwoot/ -d your-domain.com -i nginx
# Test automatic renewal
sudo certbot renew --dry-run
```
## Chatwoot CLI (cwctl)
Starting with Chatwoot v2.7.0, the installation includes the Chatwoot CLI for easier management:
### Installation
If you don't have `cwctl` installed:
```bash
# Download and install cwctl
sudo wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl
sudo chmod +x /usr/local/bin/cwctl
# Verify installation
cwctl --help
```
### Usage
```bash
# Restart Chatwoot services
cwctl -r
# Upgrade Chatwoot
cwctl --upgrade
# Access Rails console
cwctl -c
# View logs
cwctl -l web # Web server logs
cwctl -l worker # Worker logs
# Get help
cwctl --help
```
## Maintenance Operations
### Upgrading Chatwoot
**Using cwctl (recommended):**
```bash
cwctl --upgrade
```
**Manual upgrade:**
```bash
# Switch to chatwoot user
# Login as Chatwoot user
sudo -i -u chatwoot
# Navigate to the Chatwoot directory
cd chatwoot
# Pull latest changes
# Pull the latest version of the master branch
git checkout master && git pull
# Update Ruby version if needed
# Ensure the ruby version is upto date
rvm install "ruby-3.3.3"
rvm use 3.3.3 --default
# Update dependencies
bundle install
pnpm install
bundle
pnpm i
# Precompile assets
RAILS_ENV=production bundle exec rails assets:precompile
# Recompile the assets
rake assets:precompile RAILS_ENV=production
# Run database migrations
RAILS_ENV=production bundle exec rails db:migrate
# Migrate the database schema
RAILS_ENV=production bundle exec rake db:migrate
# Exit to root user
# Switch back to root user
exit
# Update systemd service files
sudo cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/
sudo cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/
sudo cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/
# Copy the updated targets
cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service
cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service
cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target
# Reload and restart services
sudo systemctl daemon-reload
sudo systemctl restart chatwoot.target
# Reload systemd files
systemctl daemon-reload
# Restart the chatwoot server
systemctl restart chatwoot.target
```
### Backup and Restore
## Running Rails Console
**Database Backup:**
```bash
# Create backup
sudo -u postgres pg_dump chatwoot > chatwoot_backup_$(date +%Y%m%d_%H%M%S).sql
# Restore backup
sudo -u postgres psql chatwoot < chatwoot_backup_file.sql
```
**File Storage Backup:**
```bash
# Backup storage directory
sudo tar -czf chatwoot_storage_$(date +%Y%m%d_%H%M%S).tar.gz /home/chatwoot/chatwoot/storage/
```
**Complete System Backup:**
```bash
# Create backup script
cat > /home/chatwoot/backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/backup/chatwoot/$(date +%Y%m%d_%H%M%S)"
mkdir -p $BACKUP_DIR
# Database backup
sudo -u postgres pg_dump chatwoot > $BACKUP_DIR/database.sql
# Application files
tar -czf $BACKUP_DIR/application.tar.gz /home/chatwoot/chatwoot/
# Storage files
tar -czf $BACKUP_DIR/storage.tar.gz /home/chatwoot/chatwoot/storage/
# Environment file
cp /home/chatwoot/chatwoot/.env $BACKUP_DIR/
echo "Backup completed: $BACKUP_DIR"
EOF
chmod +x /home/chatwoot/backup.sh
```
### Monitoring and Logs
**View logs:**
```bash
# Web server logs
sudo journalctl -u chatwoot-web.1.service -f
# Worker logs
sudo journalctl -u chatwoot-worker.1.service -f
# Nginx logs
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
# PostgreSQL logs
sudo tail -f /var/log/postgresql/postgresql-*.log
```
**System monitoring:**
```bash
# Check service status
sudo systemctl status chatwoot.target
# Check resource usage
htop
df -h
free -h
# Check database connections
sudo -u postgres psql -c "SELECT count(*) FROM pg_stat_activity;"
```
### Rails Console Access
<Note>
If you have Chatwoot CLI(`cwctl`) installed, use `cwctl -c`.
</Note>
```bash
# Using cwctl
cwctl -c
# Manual access
# Login as Chatwoot user
sudo -i -u chatwoot
# Navigate to the Chatwoot directory
cd chatwoot
RAILS_ENV=production bundle exec rails console
# start rails console
RAILS_ENV=production bundle exec rails c
```
## Viewing Logs
<Note>
If you have Chatwoot CLI(`cwctl`) installed, use `cwctl -l web` or `cwctl -l worker`.
</Note>
Run the following commands in your ubuntu shell
```bash
# logs from the rails server
journalctl -u chatwoot-web.1.service -f
# logs from sidekiq
journalctl -u chatwoot-worker.1.service -f
```
## Install or Upgrade Chatwoot CLI
If you used an older version of install script(< 2.0), you will not have `cwctl` in your PATH. To install/upgrade Chatwoot CLI,
```bash
wget https://get.chatwoot.app/linux/install.sh -O /usr/local/bin/cwctl && chmod +x /usr/local/bin/cwctl
cwctl --help
```
<Note>
The above command requires root access to install `cwctl` to `/usr/local/bin`.
</Note>
## Troubleshooting
### Common Issues
### If precompile fails
If the asset precompilation step fails with `ActionView::Template::Error (Webpacker can't find application.css in /home/chatwoot/chatwoot/public/packs/manifest.json)` or if you face issues while restarting the server, try the following command and restart the server.
**1. Asset Precompilation Fails:**
```bash
# Clear and rebuild assets
sudo -i -u chatwoot
cd chatwoot
RAILS_ENV=production bundle exec rails assets:clean assets:clobber assets:precompile
RAILS_ENV=production rake assets:clean assets:clobber assets:precompile
```
**2. Database Connection Issues:**
```bash
# Check PostgreSQL status
sudo systemctl status postgresql
# Test database connection
sudo -u postgres psql -c "SELECT version();"
# Check database configuration
sudo -i -u chatwoot
cd chatwoot
RAILS_ENV=production bundle exec rails db:version
```
**3. Permission Issues:**
```bash
# Fix file permissions
sudo chown -R chatwoot:chatwoot /home/chatwoot/chatwoot/
```
**4. Service Won't Start:**
```bash
# Check service logs
sudo journalctl -u chatwoot-web.1.service --no-pager
sudo journalctl -u chatwoot-worker.1.service --no-pager
# Check configuration
sudo systemctl status chatwoot.target
```
### Performance Optimization
**1. Database Optimization:**
```sql
-- Connect to database
sudo -u postgres psql chatwoot
-- Check database size
SELECT pg_size_pretty(pg_database_size('chatwoot'));
-- Check slow queries (if pg_stat_statements is enabled)
SELECT query, mean_time, calls
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;
```
**2. System Optimization:**
```bash
# Increase file limits for chatwoot user
echo "chatwoot soft nofile 65536" | sudo tee -a /etc/security/limits.conf
echo "chatwoot hard nofile 65536" | sudo tee -a /etc/security/limits.conf
# Optimize PostgreSQL configuration
sudo nano /etc/postgresql/*/main/postgresql.conf
# Adjust shared_buffers, effective_cache_size, work_mem based on available RAM
```
### Security Hardening
**1. Firewall Configuration:**
```bash
# Install and configure UFW
sudo ufw enable
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
```
**2. Fail2ban Setup:**
```bash
# Install Fail2ban
sudo apt install -y fail2ban
# Configure Fail2ban for SSH
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
```
**3. Regular Updates:**
```bash
# Create update script
cat > /home/chatwoot/update_system.sh << 'EOF'
#!/bin/bash
sudo apt update
sudo apt upgrade -y
sudo apt autoremove -y
sudo apt autoclean
EOF
chmod +x /home/chatwoot/update_system.sh
# Add to crontab for weekly updates
echo "0 2 * * 0 /home/chatwoot/update_system.sh" | sudo crontab -
```
---
<Warning>
Always test upgrades in a staging environment before applying to production. Keep regular backups of your database and application files.
</Warning>
<Note>
For high-availability deployments, consider setting up multiple servers with load balancing and database replication.
</Note>
This command would clear the existing compiled assets and would recompile all the assets. Read more about it [here](https://edgeguides.rubyonrails.org/command_line.html#bin-rails-assets)