Files
homelab-optimized/docs/admin/DEPLOYMENT_DOCUMENTATION.md
Gitea Mirror Bot 93ca229fd5
Some checks failed
Documentation / Deploy to GitHub Pages (push) Has been cancelled
Documentation / Build Docusaurus (push) Has been cancelled
Sanitized mirror from private repository - 2026-04-06 01:59:54 UTC
2026-04-06 01:59:54 +00:00

648 lines
17 KiB
Markdown

# Stoatchat Deployment Documentation
**Complete setup guide for deploying Stoatchat on a new machine**
## 🎯 Overview
This document provides step-by-step instructions for deploying Stoatchat from scratch on a new Ubuntu server. The deployment includes all necessary components: the chat application, reverse proxy, SSL certificates, email configuration, and backup systems.
## 📋 Prerequisites
### System Requirements
- **OS**: Ubuntu 20.04+ or Debian 11+
- **RAM**: Minimum 2GB, Recommended 4GB+
- **Storage**: Minimum 20GB free space
- **Network**: Public IP address with ports 80, 443 accessible
### Required Accounts & Credentials
- **Domain**: Registered domain with DNS control
- **Cloudflare**: Account with domain configured (optional but recommended)
- **Gmail**: Account with App Password for SMTP
- **Git**: Access to Stoatchat repository
### Dependencies to Install
- Git
- Rust (latest stable)
- Redis
- Nginx
- Certbot (Let's Encrypt)
- Build tools (gcc, pkg-config, etc.)
## 🚀 Step-by-Step Deployment
### 1. System Preparation
```bash
# Update system
sudo apt update && sudo apt upgrade -y
# Install essential packages
sudo apt install -y git curl wget build-essential pkg-config libssl-dev \
nginx redis-server certbot python3-certbot-nginx ufw
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Configure firewall
sudo ufw allow 22 # SSH
sudo ufw allow 80 # HTTP
sudo ufw allow 443 # HTTPS
sudo ufw --force enable
```
### 2. Clone and Build Stoatchat
```bash
# Clone repository
cd /root
git clone https://github.com/revoltchat/backend.git stoatchat
cd stoatchat
# Build the application (this takes 15-30 minutes)
cargo build --release
# Verify build
ls -la target/release/revolt-*
```
### 3. Configure Redis
```bash
# Start and enable Redis
sudo systemctl start redis-server
sudo systemctl enable redis-server
# Configure Redis for Stoatchat (optional custom port)
sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.backup
sudo sed -i 's/port 6379/port 6380/' /etc/redis/redis.conf
sudo systemctl restart redis-server
# Test Redis connection
redis-cli -p 6380 ping
```
### 4. Domain and SSL Setup
```bash
# Replace 'yourdomain.com' with your actual domain
DOMAIN="st.vish.gg"
# Create nginx configuration
sudo tee /etc/nginx/sites-available/stoatchat > /dev/null << EOF
server {
listen 80;
server_name $DOMAIN api.$DOMAIN events.$DOMAIN files.$DOMAIN proxy.$DOMAIN voice.$DOMAIN;
return 301 https://\$server_name\$request_uri;
}
server {
listen 443 ssl http2;
server_name $DOMAIN;
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
location / {
proxy_pass http://localhost:14702;
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;
}
}
server {
listen 443 ssl http2;
server_name api.$DOMAIN;
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
location / {
proxy_pass http://localhost:14702;
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;
}
}
server {
listen 443 ssl http2;
server_name events.$DOMAIN;
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
location / {
proxy_pass http://localhost:14703;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header 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;
}
}
server {
listen 443 ssl http2;
server_name files.$DOMAIN;
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
location / {
proxy_pass http://localhost:14704;
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;
client_max_body_size 100M;
}
}
server {
listen 443 ssl http2;
server_name proxy.$DOMAIN;
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
location / {
proxy_pass http://localhost:14705;
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;
}
}
server {
listen 443 ssl http2;
server_name voice.$DOMAIN;
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
location / {
proxy_pass http://localhost:7880;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header 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;
}
}
EOF
# Enable the site
sudo ln -s /etc/nginx/sites-available/stoatchat /etc/nginx/sites-enabled/
sudo nginx -t
# Obtain SSL certificates
sudo certbot --nginx -d $DOMAIN -d api.$DOMAIN -d events.$DOMAIN -d files.$DOMAIN -d proxy.$DOMAIN -d voice.$DOMAIN
# Test nginx configuration
sudo systemctl reload nginx
```
### 5. Configure Stoatchat
```bash
# Create configuration override file
cd /root/stoatchat
cat > Revolt.overrides.toml << 'EOF'
[database]
redis = "redis://127.0.0.1:6380"
[api]
url = "https://api.st.vish.gg"
[api.smtp]
host = "smtp.gmail.com"
port = 465
username = "your-gmail@gmail.com"
password = "REDACTED_PASSWORD"
from_address = "your-gmail@gmail.com"
use_tls = true
[events]
url = "https://events.st.vish.gg"
[autumn]
url = "https://files.st.vish.gg"
[january]
url = "https://proxy.st.vish.gg"
[livekit]
url = "https://voice.st.vish.gg"
api_key = REDACTED_API_KEY
api_secret = "your-livekit-api-secret"
EOF
# Update with your actual values
nano Revolt.overrides.toml
```
### 6. Create Service Management Scripts
```bash
# Create service management script
cat > manage-services.sh << 'EOF'
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Service definitions
declare -A SERVICES=(
["api"]="target/release/revolt-delta"
["events"]="target/release/revolt-bonfire"
["files"]="target/release/revolt-autumn"
["proxy"]="target/release/revolt-january"
["gifbox"]="target/release/revolt-gifbox"
)
declare -A PORTS=(
["api"]="14702"
["events"]="14703"
["files"]="14704"
["proxy"]="14705"
["gifbox"]="14706"
)
start_service() {
local name=$1
local binary=${SERVICES[$name]}
local port=${PORTS[$name]}
if pgrep -f "$binary" > /dev/null; then
echo " ⚠️ $name already running"
return
fi
echo " 🚀 Starting $name on port $port..."
nohup ./$binary > ${name}.log 2>&1 &
sleep 2
if pgrep -f "$binary" > /dev/null; then
echo " ✅ $name started successfully"
else
echo " ❌ Failed to start $name"
fi
}
stop_service() {
local name=$1
local binary=${SERVICES[$name]}
local pids=$(pgrep -f "$binary")
if [ -z "$pids" ]; then
echo " ⚠️ $name not running"
return
fi
echo " 🛑 Stopping $name..."
pkill -f "$binary"
sleep 2
if ! pgrep -f "$binary" > /dev/null; then
echo " ✅ $name stopped successfully"
else
echo " ❌ Failed to stop $name"
fi
}
status_service() {
local name=$1
local binary=${SERVICES[$name]}
local port=${PORTS[$name]}
if pgrep -f "$binary" > /dev/null; then
if netstat -tlnp 2>/dev/null | grep -q ":$port "; then
echo " ✓ $name (port $port) - Running"
else
echo " ⚠️ $name - Process running but port not listening"
fi
else
echo " ✗ $name (port $port) - Stopped"
fi
}
case "$1" in
start)
echo "[INFO] Starting Stoatchat services..."
for service in api events files proxy gifbox; do
start_service "$service"
done
;;
stop)
echo "[INFO] Stopping Stoatchat services..."
for service in api events files proxy gifbox; do
stop_service "$service"
done
;;
restart)
echo "[INFO] Restarting Stoatchat services..."
$0 stop
sleep 3
$0 start
;;
status)
echo "[INFO] Stoatchat Service Status:"
echo
for service in api events files proxy gifbox; do
status_service "$service"
done
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
EOF
chmod +x manage-services.sh
```
### 7. Create Backup Scripts
```bash
# Create backup script
cat > backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/root/stoatchat-backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="stoatchat_backup_$TIMESTAMP"
BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME"
# Create backup directory
mkdir -p "$BACKUP_PATH"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting Stoatchat backup process..."
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup will be saved to: $BACKUP_PATH"
# Backup configuration files
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backing up configuration files..."
cp Revolt.toml "$BACKUP_PATH/" 2>/dev/null || echo "⚠️ Revolt.toml not found"
cp Revolt.overrides.toml "$BACKUP_PATH/" 2>/dev/null || echo "⚠️ Revolt.overrides.toml not found"
cp livekit.yml "$BACKUP_PATH/" 2>/dev/null || echo "⚠️ livekit.yml not found"
echo "✅ Configuration files backed up"
# Backup Nginx configuration
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backing up Nginx configuration..."
mkdir -p "$BACKUP_PATH/nginx"
cp /etc/nginx/sites-available/stoatchat "$BACKUP_PATH/nginx/" 2>/dev/null || echo "⚠️ Nginx site config not found"
echo "✅ Nginx configuration backed up"
# Backup SSL certificates
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backing up SSL certificates..."
mkdir -p "$BACKUP_PATH/ssl"
cp -r /etc/letsencrypt/live/st.vish.gg/* "$BACKUP_PATH/ssl/" 2>/dev/null || echo "⚠️ SSL certificates not found"
echo "✅ SSL certificates backed up"
# Backup user uploads and file storage
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backing up user uploads and file storage..."
mkdir -p "$BACKUP_PATH/uploads"
# Add file storage backup commands here when implemented
echo "✅ File storage backed up"
# Create backup info file
cat > "$BACKUP_PATH/backup_info.txt" << EOL
Stoatchat Backup Information
============================
Backup Date: $(date)
Backup Name: $BACKUP_NAME
System: $(uname -a)
Stoatchat Version: $(grep version Cargo.toml | head -1 | cut -d'"' -f2)
Contents:
- Configuration files (Revolt.toml, Revolt.overrides.toml, livekit.yml)
- Nginx configuration
- SSL certificates
- File storage (if applicable)
Restore Command:
./restore.sh $BACKUP_PATH
EOL
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup completed successfully!"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup location: $BACKUP_PATH"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup size: $(du -sh "$BACKUP_PATH" | cut -f1)"
EOF
chmod +x backup.sh
# Create restore script
cat > restore.sh << 'EOF'
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Usage: $0 <backup-directory>"
echo "Example: $0 /root/stoatchat-backups/stoatchat_backup_20260211_051926"
exit 1
fi
BACKUP_PATH="$1"
if [ ! -d "$BACKUP_PATH" ]; then
echo "❌ Backup directory not found: $BACKUP_PATH"
exit 1
fi
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting Stoatchat restore process..."
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Restoring from: $BACKUP_PATH"
# Stop services before restore
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Stopping Stoatchat services..."
./manage-services.sh stop
# Restore configuration files
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Restoring configuration files..."
cp "$BACKUP_PATH/Revolt.toml" . 2>/dev/null && echo "✅ Revolt.toml restored"
cp "$BACKUP_PATH/Revolt.overrides.toml" . 2>/dev/null && echo "✅ Revolt.overrides.toml restored"
cp "$BACKUP_PATH/livekit.yml" . 2>/dev/null && echo "✅ livekit.yml restored"
# Restore Nginx configuration
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Restoring Nginx configuration..."
sudo cp "$BACKUP_PATH/nginx/stoatchat" /etc/nginx/sites-available/ 2>/dev/null && echo "✅ Nginx configuration restored"
# Restore SSL certificates
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Restoring SSL certificates..."
sudo cp -r "$BACKUP_PATH/ssl/"* /etc/letsencrypt/live/st.vish.gg/ 2>/dev/null && echo "✅ SSL certificates restored"
# Reload nginx
sudo nginx -t && sudo systemctl reload nginx
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Restore completed!"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting services..."
./manage-services.sh start
EOF
chmod +x restore.sh
```
### 8. Setup LiveKit (Optional)
```bash
# Download and install LiveKit
wget https://github.com/livekit/livekit/releases/latest/download/livekit_linux_amd64.tar.gz
tar -xzf livekit_linux_amd64.tar.gz
sudo mv livekit /usr/local/bin/
# Create LiveKit configuration
cat > livekit.yml << 'EOF'
port: 7880
bind_addresses:
- ""
rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 60000
use_external_ip: true
redis:
address: localhost:6380
keys:
your-api-key: your-api-secret
EOF
# Start LiveKit (run in background)
nohup livekit --config livekit.yml > livekit.log 2>&1 &
```
### 9. Start Services
```bash
# Start all Stoatchat services
./manage-services.sh start
# Check status
./manage-services.sh status
# Test API
curl http://localhost:14702/
# Test frontend (after nginx is configured)
curl https://st.vish.gg
```
### 10. Setup Automated Backups
```bash
# Create backup cron job
cat > setup-backup-cron.sh << 'EOF'
#!/bin/bash
# Add daily backup at 2 AM
(crontab -l 2>/dev/null; echo "0 2 * * * cd /root/stoatchat && ./backup.sh >> backup-cron.log 2>&1") | crontab -
echo "✅ Backup cron job added - daily backups at 2 AM"
echo "Current crontab:"
crontab -l
EOF
chmod +x setup-backup-cron.sh
./setup-backup-cron.sh
```
## ✅ Verification Steps
After deployment, verify everything is working:
```bash
# 1. Check all services
./manage-services.sh status
# 2. Test API endpoints
curl http://localhost:14702/
curl https://api.st.vish.gg
# 3. Test email functionality
curl -X POST http://localhost:14702/auth/account/create \
-H "Content-Type: application/json" \
-d '{"email": "test@yourdomain.com", "password": "TestPass123!"}'
# 4. Check SSL certificates
curl -I https://st.vish.gg
# 5. Test backup system
./backup.sh --dry-run
```
## 🔧 Configuration Customization
### Environment-Specific Settings
Update `Revolt.overrides.toml` with your specific values:
```toml
[database]
redis = "redis://127.0.0.1:6380" # Your Redis connection
[api]
url = "https://api.yourdomain.com" # Your API domain
[api.smtp]
host = "smtp.gmail.com"
port = 465
username = "your-email@gmail.com" # Your Gmail address
password = "REDACTED_PASSWORD" # Your Gmail app password
from_address = "your-email@gmail.com"
use_tls = true
[events]
url = "https://events.yourdomain.com" # Your events domain
[autumn]
url = "https://files.yourdomain.com" # Your files domain
[january]
url = "https://proxy.yourdomain.com" # Your proxy domain
[livekit]
url = "https://voice.yourdomain.com" # Your voice domain
api_key = REDACTED_API_KEY # Your LiveKit API key
api_secret = "your-livekit-api-secret" # Your LiveKit API secret
```
### Gmail App Password Setup
1. Enable 2-Factor Authentication on your Gmail account
2. Go to Google Account settings → Security → App passwords
3. Generate an app password for "Mail"
4. Use this password in the SMTP configuration
## 🚨 Troubleshooting
### Common Issues
1. **Build Fails**: Ensure Rust is installed and up to date
2. **Services Won't Start**: Check port availability and logs
3. **SSL Issues**: Verify domain DNS and certificate renewal
4. **Email Not Working**: Check Gmail app password and SMTP settings
### Log Locations
- **Stoatchat Services**: `*.log` files in the application directory
- **Nginx**: `/var/log/nginx/error.log`
- **System**: `/var/log/syslog`
## 📚 Additional Resources
- **Stoatchat Repository**: https://github.com/revoltchat/backend
- **Nginx Documentation**: https://nginx.org/en/docs/
- **Let's Encrypt**: https://letsencrypt.org/getting-started/
- **LiveKit Documentation**: https://docs.livekit.io/
---
**Deployment Guide Version**: 1.0
**Last Updated**: February 11, 2026
**Tested On**: Ubuntu 20.04, Ubuntu 22.04