Docker Deployment
This guide covers deploying SlimRMM using Docker and Docker Compose.
Prerequisites
- Docker 24.0 or higher
- Docker Compose 2.20 or higher
- A domain name (optional but recommended)
- SSL certificate (Let's Encrypt recommended)
1. Install Docker
Ubuntu/Debian
bash
# Update packages
sudo apt update
sudo apt install -y curl
# Install Docker
curl -fsSL https://get.docker.com | sudo sh
# Add user to docker group
sudo usermod -aG docker $USER
# Install Docker Compose
sudo apt install -y docker-compose-plugin
# Verify installation
docker --version
docker compose versionRHEL/CentOS
bash
# Install Docker
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Start Docker
sudo systemctl enable --now docker
# Add user to docker group
sudo usermod -aG docker $USER2. Create Project Directory
bash
mkdir -p /opt/slimrmm
cd /opt/slimrmm3. Create Docker Compose File
Create docker-compose.yml:
yaml
version: '3.8'
services:
postgres:
image: postgres:16-alpine
container_name: slimrmm-db
restart: unless-stopped
environment:
POSTGRES_USER: rmm
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: rmm
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U rmm"]
interval: 10s
timeout: 5s
retries: 5
networks:
- slimrmm
redis:
image: redis:7-alpine
container_name: slimrmm-redis
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- slimrmm
backend:
image: ghcr.io/slimrmm/backend:latest
container_name: slimrmm-backend
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
- DATABASE_URL=postgresql+asyncpg://rmm:${DB_PASSWORD}@postgres:5432/rmm
- REDIS_URL=redis://redis:6379/0
- SECRET_KEY=${SECRET_KEY}
- AGENT_INSTALL_KEY=${AGENT_INSTALL_KEY}
- FRONTEND_URL=${FRONTEND_URL}
- DEBUG=false
volumes:
- ./certs:/app/certs
- ./logs:/app/logs
ports:
- "8000:8000"
networks:
- slimrmm
frontend:
image: ghcr.io/slimrmm/frontend:latest
container_name: slimrmm-frontend
restart: unless-stopped
depends_on:
- backend
environment:
- VITE_API_URL=${BACKEND_URL}
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
networks:
- slimrmm
volumes:
postgres_data:
redis_data:
networks:
slimrmm:
driver: bridge4. Create Environment File
Create .env:
bash
# Database
DB_PASSWORD=your_secure_database_password
# Security Keys (generate with: python3 -c "import secrets; print(secrets.token_urlsafe(32))")
SECRET_KEY=your_generated_secret_key
AGENT_INSTALL_KEY=your_generated_agent_key
# URLs
FRONTEND_URL=https://rmm.example.com
BACKEND_URL=https://rmm.example.com/apiGenerate secure keys:
bash
# Generate SECRET_KEY
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
# Generate AGENT_INSTALL_KEY
python3 -c "import secrets; print(secrets.token_hex(16))"5. Configure Nginx
Create nginx.conf:
nginx
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
upstream backend {
server backend:8000;
}
server {
listen 80;
server_name rmm.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name rmm.example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# API and WebSocket
location /api/ {
proxy_pass http://backend/api/;
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;
proxy_read_timeout 86400;
}
# Health check
location /health {
proxy_pass http://backend/health;
}
# Frontend
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
}
}6. SSL Certificate
Let's Encrypt (Recommended)
bash
# Install certbot
sudo apt install -y certbot
# Get certificate
sudo certbot certonly --standalone -d rmm.example.com
# Copy certificates
sudo mkdir -p ssl
sudo cp /etc/letsencrypt/live/rmm.example.com/fullchain.pem ssl/
sudo cp /etc/letsencrypt/live/rmm.example.com/privkey.pem ssl/
sudo chmod 644 ssl/*.pemAuto-renewal
bash
# Add to crontab
echo "0 0 * * * certbot renew --quiet && docker compose restart frontend" | sudo crontab -7. Start Services
bash
# Pull images
docker compose pull
# Start services
docker compose up -d
# Check status
docker compose ps
# View logs
docker compose logs -f8. Initialize Database
bash
# Run migrations
docker compose exec backend alembic upgrade head9. Create Admin User
bash
docker compose exec backend python -c "
from app.core.database import get_db_sync
from app.services.auth_service import AuthService
db = next(get_db_sync())
auth_service = AuthService()
user = auth_service.create_user(
db,
username='admin',
email='admin@example.com',
password='YourSecurePassword123!',
is_admin=True
)
print(f'Admin user created: {user.username}')
"10. Verify Installation
- Open
https://rmm.example.comin your browser - Log in with admin credentials
- Check health endpoint:
https://rmm.example.com/health
Updating
bash
# Pull latest images
docker compose pull
# Restart services
docker compose up -d
# Run any new migrations
docker compose exec backend alembic upgrade headBackup
bash
# Backup database
docker compose exec postgres pg_dump -U rmm rmm > backup_$(date +%Y%m%d).sql
# Backup volumes
docker run --rm -v slimrmm_postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/postgres_data.tar.gz /dataTroubleshooting
View Logs
bash
# All services
docker compose logs -f
# Specific service
docker compose logs -f backendRestart Services
bash
docker compose restartReset Database
bash
# Warning: This deletes all data!
docker compose down -v
docker compose up -d