self hosted - nself-org/nchat GitHub Wiki
Complete guide for deploying nself-chat on your own infrastructure with automatic SSL and minimal configuration.
- Quick Start
- Requirements
- One-Line Installation
- Manual Installation
- Configuration
- SSL/TLS Setup
- Backup and Restore
- Updates and Upgrades
- Monitoring
- Troubleshooting
The fastest way to get nself-chat running on your own server:
# One-line installation (installs everything)
curl -fsSL https://raw.githubusercontent.com/yourusername/nself-chat/main/scripts/self-hosted-install.sh | bashThis will:
- Install Docker and Docker Compose if needed
- Download and configure nself-chat
- Set up SSL with Let's Encrypt
- Start all services
- Configure automatic backups
| Resource | Minimum | Recommended | Notes |
|---|---|---|---|
| CPU | 2 cores | 4+ cores | More cores = better real-time performance |
| RAM | 4 GB | 8+ GB | 8GB recommended for 50+ concurrent users |
| Disk | 20 GB | 50+ GB SSD | SSD highly recommended for database |
| Network | 100 Mbps | 1 Gbps | Upload speed matters for video calls |
| OS | Ubuntu 20.04+ | Ubuntu 22.04 LTS | Also supports Debian, CentOS, RHEL |
- Docker: 24.0+
- Docker Compose: 2.20+
-
Domain name: Required for SSL (e.g.,
chat.example.com) - Ports open: 80, 443, 3000
- Ubuntu 20.04 LTS or newer (recommended)
- Debian 11 or newer
- CentOS 8 or newer
- RHEL 8 or newer
- Fedora 36 or newer
- Amazon Linux 2023
| Provider | Instance Type | Monthly Cost (approx) | Notes |
|---|---|---|---|
| DigitalOcean | Premium 4GB | $24/month | Best value for small teams |
| Hetzner | CPX21 | €8.46/month | Excellent price/performance |
| AWS | t3.medium | $30-40/month | Use with reserved instances |
| Google Cloud | e2-medium | $25-35/month | Good integration options |
| Linode | 4GB Dedicated | $24/month | Reliable performance |
| Vultr | 4GB High Frequency | $24/month | Fast NVMe storage |
curl -fsSL https://raw.githubusercontent.com/yourusername/nself-chat/main/scripts/self-hosted-install.sh | bashThe installer will prompt you for:
-
Domain name (e.g.,
chat.example.com) - Email address (for Let's Encrypt SSL)
- Admin email (for nself-chat owner account)
- Company/Organization name
- Enable monitoring (optional Grafana/Prometheus)
For automation, provide all values as environment variables:
curl -fsSL https://raw.githubusercontent.com/yourusername/nself-chat/main/scripts/self-hosted-install.sh | \
DOMAIN=chat.example.com \
[email protected] \
[email protected] \
COMPANY_NAME="Acme Inc" \
ENABLE_MONITORING=true \
bash -s -- --non-interactiveThe installer sets up:
- Docker Engine (if not present)
- Docker Compose (if not present)
- nself-chat application
- PostgreSQL database with backups
- Hasura GraphQL engine
- Nhost Auth service
- MinIO for file storage
- Redis for caching
- Nginx reverse proxy
- Certbot for SSL certificates
- Automatic backup cron job
- Monitoring stack (if enabled)
If you prefer manual control, follow these steps:
Ubuntu/Debian:
# Update packages
sudo apt-get update
# Install dependencies
sudo apt-get install -y \
ca-certificates \
curl \
gnupg \
lsb-release
# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set up repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Enable and start Docker
sudo systemctl enable docker
sudo systemctl start docker
# Add current user to docker group
sudo usermod -aG docker $USER
newgrp dockerCentOS/RHEL:
# 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 -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Start Docker
sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker $USER
newgrp docker# Create installation directory
sudo mkdir -p /opt/nself-chat
cd /opt/nself-chat
# Download latest release
VERSION=$(curl -s https://api.github.com/repos/yourusername/nself-chat/releases/latest | grep tag_name | cut -d '"' -f 4)
curl -L https://github.com/yourusername/nself-chat/archive/refs/tags/${VERSION}.tar.gz | tar xz --strip-components=1
# Or clone from git
git clone https://github.com/yourusername/nself-chat.git .# Copy production environment file
cp .env.production.example .env.production
# Edit configuration
nano .env.productionRequired environment variables:
# Domain Configuration
DOMAIN=chat.example.com
[email protected]
# Application
NEXT_PUBLIC_APP_NAME=nchat
NEXT_PUBLIC_ENV=production
# Database
POSTGRES_PASSWORD=$(openssl rand -base64 32)
POSTGRES_DB=nchat
# Hasura
HASURA_ADMIN_SECRET=$(openssl rand -base64 32)
HASURA_JWT_SECRET=$(openssl rand -base64 32)
# Auth
AUTH_CLIENT_URL=https://chat.example.com
AUTH_SERVER_URL=https://chat.example.com/auth
# Storage
MINIO_ROOT_PASSWORD=$(openssl rand -base64 32)
# Email (SMTP)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
[email protected]
SMTP_PASS=your-smtp-password
[email protected]
# Admin Account
[email protected]
ADMIN_PASSWORD=$(openssl rand -base64 16)
COMPANY_NAME="Your Company"Option A: Let's Encrypt (Automatic)
# Install Certbot
sudo apt-get install -y certbot
# Get certificate
sudo certbot certonly --standalone \
--preferred-challenges http \
--email ${SSL_EMAIL} \
--agree-tos \
--no-eff-email \
-d ${DOMAIN}
# Set up auto-renewal
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timerOption B: Custom Certificate
# Place your certificates
sudo mkdir -p /etc/ssl/nchat
sudo cp your-cert.crt /etc/ssl/nchat/cert.pem
sudo cp your-key.key /etc/ssl/nchat/key.pem
sudo chmod 600 /etc/ssl/nchat/key.pem# Start all services
docker compose -f docker-compose.production.yml up -d
# Check status
docker compose -f docker-compose.production.yml ps
# View logs
docker compose -f docker-compose.production.yml logs -f# Run migrations
docker compose -f docker-compose.production.yml exec nchat pnpm db:migrate
# Seed initial data
docker compose -f docker-compose.production.yml exec nchat pnpm db:seed# Check all services are healthy
docker compose -f docker-compose.production.yml ps
# Test application
curl https://chat.example.com/api/health
# Access in browser
open https://chat.example.comUFW (Ubuntu):
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enableFirewalld (CentOS/RHEL):
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reloadPoint your domain to your server:
A Record: chat.example.com → YOUR_SERVER_IP
AAAA Record: chat.example.com → YOUR_SERVER_IPv6 (if available)
nself-chat requires SMTP for:
- User invitations
- Password resets
- Email verification
- Notifications
Recommended SMTP providers:
| Provider | Setup Complexity | Free Tier | Notes |
|---|---|---|---|
| Resend | Easy | 100/day | Modern, developer-friendly |
| SendGrid | Easy | 100/day | Reliable, good docs |
| Mailgun | Medium | 5,000/month | Powerful, pay-as-go |
| AWS SES | Medium | 62,000/month (EC2) | Cheapest at scale |
| Postmark | Easy | Free trial | Excellent deliverability |
Example SMTP configuration (SendGrid):
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASS=SG.your-api-key-here
[email protected]Default storage backend is MinIO (S3-compatible). For larger deployments, consider:
AWS S3:
STORAGE_BACKEND=s3
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_REGION=us-east-1
AWS_BUCKET=nchat-storageCloudflare R2:
STORAGE_BACKEND=r2
R2_ACCOUNT_ID=your-account-id
R2_ACCESS_KEY_ID=your-access-key
R2_SECRET_ACCESS_KEY=your-secret-key
R2_BUCKET=nchat-storageEdit docker-compose.production.yml to adjust resource limits:
services:
nchat:
deploy:
resources:
limits:
cpus: '2.0'
memory: 4G
reservations:
cpus: '1.0'
memory: 2GThe installation script automatically configures Let's Encrypt. Manual setup:
# Install Certbot
sudo apt-get install -y certbot python3-certbot-nginx
# Get certificate
sudo certbot certonly --nginx \
-d chat.example.com \
--email [email protected] \
--agree-tos \
--no-eff-email
# Certificates are stored in:
# /etc/letsencrypt/live/chat.example.com/fullchain.pem
# /etc/letsencrypt/live/chat.example.com/privkey.pemLet's Encrypt certificates expire every 90 days. Set up auto-renewal:
# Create renewal script
sudo tee /etc/cron.monthly/renew-ssl << 'EOF'
#!/bin/bash
certbot renew --quiet
docker compose -f /opt/nself-chat/docker-compose.production.yml restart nginx
EOF
sudo chmod +x /etc/cron.monthly/renew-sslThe production configuration includes:
- TLS 1.2+ only (no SSLv3, TLS 1.0, TLS 1.1)
- Strong cipher suites (Perfect Forward Secrecy)
- HSTS headers (HTTP Strict Transport Security)
- OCSP stapling (faster certificate validation)
- A+ SSL Labs rating
Verify your SSL configuration:
# Test SSL
curl -I https://chat.example.com
# Check SSL Labs rating
open https://www.ssllabs.com/ssltest/analyze.html?d=chat.example.comThe installer sets up automatic daily backups. Manual configuration:
# Create backup directory
sudo mkdir -p /var/backups/nself-chat
# Create backup script
sudo tee /usr/local/bin/backup-nchat << 'EOF'
#!/bin/bash
set -e
BACKUP_DIR="/var/backups/nself-chat"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="nchat-backup-${TIMESTAMP}.tar.gz"
cd /opt/nself-chat
# Backup database
docker compose -f docker-compose.production.yml exec -T postgres \
pg_dump -U postgres nchat | gzip > ${BACKUP_DIR}/db-${TIMESTAMP}.sql.gz
# Backup volumes
docker compose -f docker-compose.production.yml exec -T nchat \
tar czf - /app/public/uploads > ${BACKUP_DIR}/uploads-${TIMESTAMP}.tar.gz
# Backup configuration
cp .env.production ${BACKUP_DIR}/env-${TIMESTAMP}.backup
# Create combined backup
tar czf ${BACKUP_DIR}/${BACKUP_FILE} \
${BACKUP_DIR}/db-${TIMESTAMP}.sql.gz \
${BACKUP_DIR}/uploads-${TIMESTAMP}.tar.gz \
${BACKUP_DIR}/env-${TIMESTAMP}.backup
# Clean up individual files
rm ${BACKUP_DIR}/db-${TIMESTAMP}.sql.gz
rm ${BACKUP_DIR}/uploads-${TIMESTAMP}.tar.gz
rm ${BACKUP_DIR}/env-${TIMESTAMP}.backup
# Delete backups older than 30 days
find ${BACKUP_DIR} -name "nchat-backup-*.tar.gz" -mtime +30 -delete
echo "Backup completed: ${BACKUP_FILE}"
EOF
sudo chmod +x /usr/local/bin/backup-nchat
# Schedule daily backups (2 AM)
echo "0 2 * * * root /usr/local/bin/backup-nchat >> /var/log/nchat-backup.log 2>&1" | \
sudo tee /etc/cron.d/nchat-backup# Run backup script
sudo /usr/local/bin/backup-nchat
# Backups are stored in
ls -lh /var/backups/nself-chat/# Stop services
cd /opt/nself-chat
docker compose -f docker-compose.production.yml down
# Extract backup
BACKUP_FILE="/var/backups/nself-chat/nchat-backup-20260131_020000.tar.gz"
tar xzf ${BACKUP_FILE} -C /tmp/
# Restore database
gunzip < /tmp/var/backups/nself-chat/db-*.sql.gz | \
docker compose -f docker-compose.production.yml exec -T postgres \
psql -U postgres nchat
# Restore uploads
tar xzf /tmp/var/backups/nself-chat/uploads-*.tar.gz -C /
# Restore configuration (if needed)
cp /tmp/var/backups/nself-chat/env-*.backup .env.production
# Start services
docker compose -f docker-compose.production.yml up -d
echo "Restore completed"AWS S3:
# Install AWS CLI
sudo apt-get install -y awscli
# Configure AWS
aws configure
# Upload to S3
aws s3 sync /var/backups/nself-chat/ s3://your-backup-bucket/nchat/Backblaze B2:
# Install B2 CLI
sudo pip3 install b2
# Configure B2
b2 authorize-account YOUR_KEY_ID YOUR_APPLICATION_KEY
# Upload to B2
b2 sync /var/backups/nself-chat/ b2://your-backup-bucket/nchat/Rsync to Remote Server:
# Set up SSH key authentication first
rsync -avz --delete \
/var/backups/nself-chat/ \
backup-server:/backups/nchat/Use the update script:
sudo /usr/local/bin/update-nchatcd /opt/nself-chat
# Backup before updating
sudo /usr/local/bin/backup-nchat
# Pull latest version
git fetch --tags
git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
# Update environment file if needed
cp .env.production .env.production.backup
# Compare with .env.production.example for new variables
# Rebuild images
docker compose -f docker-compose.production.yml build --no-cache
# Stop services
docker compose -f docker-compose.production.yml down
# Run database migrations
docker compose -f docker-compose.production.yml up -d postgres
sleep 10
docker compose -f docker-compose.production.yml run --rm nchat pnpm db:migrate
# Start all services
docker compose -f docker-compose.production.yml up -d
# Check status
docker compose -f docker-compose.production.yml psIf an update fails:
cd /opt/nself-chat
# Stop services
docker compose -f docker-compose.production.yml down
# Checkout previous version
git checkout v1.0.0 # Replace with previous version tag
# Restore from backup
sudo /usr/local/bin/restore-nchat /var/backups/nself-chat/nchat-backup-TIMESTAMP.tar.gz
# Start services
docker compose -f docker-compose.production.yml up -dSubscribe to release notifications:
# GitHub releases (requires GitHub CLI)
gh repo watch yourusername/nself-chat --releases
# Or set up email notifications in GitHub settingsCheck service health:
# Service status
docker compose -f docker-compose.production.yml ps
# Resource usage
docker stats
# View logs
docker compose -f docker-compose.production.yml logs -f nchat
# Check specific service
docker compose -f docker-compose.production.yml logs -f postgresInstall monitoring stack with Grafana and Prometheus:
# Enable monitoring during installation
ENABLE_MONITORING=true ./scripts/self-hosted-install.sh
# Or manually enable
cd /opt/nself-chat
docker compose -f docker-compose.production.yml \
-f docker-compose.monitoring.yml up -dAccess monitoring dashboards:
- Grafana: https://chat.example.com/grafana (admin/admin)
- Prometheus: https://chat.example.com/prometheus
- cAdvisor: https://chat.example.com/cadvisor
Pre-configured dashboards include:
-
System Overview
- CPU, memory, disk usage
- Network I/O
- Container health
-
Application Metrics
- Request rate
- Response times
- Error rates
- Active users
-
Database Metrics
- Connection pool
- Query performance
- Cache hit rates
- Disk I/O
-
Storage Metrics
- File upload rates
- Storage usage
- Object counts
Configure email alerts in Grafana:
- Go to Alerting > Contact Points
- Add email notification channel
- Set up alert rules for:
- High CPU usage (>80%)
- High memory usage (>90%)
- Disk space low (<10%)
- Database connection failures
- Application errors
Basic log viewing:
# Real-time logs
docker compose -f docker-compose.production.yml logs -f
# Last 100 lines
docker compose -f docker-compose.production.yml logs --tail=100
# Filter by service
docker compose -f docker-compose.production.yml logs -f nchat
# Search logs
docker compose -f docker-compose.production.yml logs | grep ERRORAdvanced logging (Loki + Grafana):
Enable in monitoring stack for centralized log aggregation and search.
See Self-Hosted Troubleshooting Guide for detailed solutions.
# Run diagnostic script
sudo /usr/local/bin/diagnose-nchat
# Check all services
docker compose -f docker-compose.production.yml ps
# Check logs for errors
docker compose -f docker-compose.production.yml logs --tail=50 | grep -i error
# Test connectivity
curl -I https://chat.example.com/api/health
# Check disk space
df -h
# Check memory
free -h
# Check Docker
docker info# Check logs
docker compose -f docker-compose.production.yml logs
# Check port conflicts
sudo netstat -tulpn | grep -E ':(80|443|3000|5432|8080)'
# Restart services
docker compose -f docker-compose.production.yml restart# Check certificate
sudo certbot certificates
# Renew manually
sudo certbot renew --force-renewal
# Restart nginx
docker compose -f docker-compose.production.yml restart nginx# Check database is running
docker compose -f docker-compose.production.yml ps postgres
# Test connection
docker compose -f docker-compose.production.yml exec postgres \
psql -U postgres -d nchat -c "SELECT version();"
# Restart database
docker compose -f docker-compose.production.yml restart postgres# Check memory usage
free -h
docker stats
# Increase swap
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab# Check disk usage
df -h
# Clean Docker
docker system prune -a --volumes
# Remove old backups
find /var/backups/nself-chat -mtime +30 -delete
# Check logs size
du -sh /var/lib/docker/containers/*/*-json.log# Identify culprit
docker stats
# Check application logs
docker compose -f docker-compose.production.yml logs nchat | tail -100
# Restart services
docker compose -f docker-compose.production.yml restart- Check documentation: https://docs.nself.chat
- Search issues: https://github.com/yourusername/nself-chat/issues
- Ask community: https://discord.gg/nself
- File a bug: https://github.com/yourusername/nself-chat/issues/new
Generate diagnostic bundle for support:
sudo /usr/local/bin/diagnose-nchat --bundle
# Uploads diagnostic bundle to: /tmp/nchat-diagnostics-TIMESTAMP.tar.gzThe bundle includes:
- Service status
- Recent logs
- Configuration (sanitized)
- System information
- Resource usage
- Change default passwords
# Generate strong passwords
HASURA_ADMIN_SECRET=$(openssl rand -base64 32)
POSTGRES_PASSWORD=$(openssl rand -base64 32)
# Update .env.production
nano .env.production
# Restart services
docker compose -f docker-compose.production.yml up -d- Enable firewall
# UFW
sudo ufw enable
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp- Set up fail2ban
sudo apt-get install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban- Regular updates
# System updates
sudo apt-get update && sudo apt-get upgrade -y
# Application updates
sudo /usr/local/bin/update-nchat- Monitor logs
# Set up log monitoring
docker compose -f docker-compose.production.yml logs -f | grep -i "error\|warning\|fail"- Two-factor authentication: Enable in admin panel
- IP whitelisting: Configure in nginx
- Rate limiting: Enabled by default
- DDoS protection: Consider Cloudflare
- Database encryption: Enable at-rest encryption
- Secrets management: Use Docker secrets or Vault
# Edit PostgreSQL configuration
docker compose -f docker-compose.production.yml exec postgres \
bash -c 'cat >> /var/lib/postgresql/data/postgresql.conf << EOF
# Performance tuning
shared_buffers = 1GB
effective_cache_size = 3GB
maintenance_work_mem = 256MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
work_mem = 16MB
min_wal_size = 1GB
max_wal_size = 4GB
EOF'
# Restart database
docker compose -f docker-compose.production.yml restart postgres# Increase Node.js memory limit
echo "NODE_OPTIONS=--max-old-space-size=4096" >> .env.production
# Enable production mode
echo "NODE_ENV=production" >> .env.production
# Restart application
docker compose -f docker-compose.production.yml restart nchat# Configure Redis for caching
docker compose -f docker-compose.production.yml exec redis \
redis-cli CONFIG SET maxmemory 1gb
docker compose -f docker-compose.production.yml exec redis \
redis-cli CONFIG SET maxmemory-policy allkeys-lruSmall Team (1-25 users):
- Server: $24/month (DigitalOcean 4GB)
- Storage: Included
- Bandwidth: Included
- Email: Free (100/day SendGrid)
- Total: ~$25/month
Medium Team (25-100 users):
- Server: $48/month (DigitalOcean 8GB)
- Storage: $5/month (100GB)
- Bandwidth: Included
- Email: Free (100/day SendGrid)
- Total: ~$55/month
Large Team (100-500 users):
- Server: $96/month (DigitalOcean 16GB)
- Storage: $20/month (500GB)
- Bandwidth: $10/month
- Email: $30/month (SendGrid)
- Total: ~$160/month
Comparison to SaaS:
| Users | Self-Hosted | Slack | Savings |
|---|---|---|---|
| 25 | $25/mo | $200/mo | $2,100/year |
| 50 | $55/mo | $400/mo | $4,140/year |
| 100 | $55/mo | $800/mo | $8,940/year |
| 500 | $160/mo | $4,000/mo | $46,080/year |
After successful installation:
- Complete setup wizard: https://chat.example.com/setup
- Configure authentication: Email, Google, GitHub, etc.
- Customize branding: Logo, colors, theme
- Invite team members: Admin panel → Users → Invite
- Set up integrations: Slack, GitHub, Jira, etc.
- Configure backups: Test restore procedure
- Enable monitoring: Set up alerts
- Review security: SSL, firewall, 2FA
- Documentation: https://docs.nself.chat
- GitHub: https://github.com/yourusername/nself-chat
- Discord Community: https://discord.gg/nself
- Support: [email protected]
- Security: [email protected]
Last Updated: January 31, 2026 Version: 1.0.0 Maintainer: nself-chat Team