Overview
Docker Compose simplifies the deployment and management of Homarr, especially when using external databases or Redis. This guide provides production-ready configurations for various scenarios.
Docker Compose is recommended for production deployments as it provides better container orchestration, easier updates, and cleaner configuration management.
Prerequisites
Docker 20.10+ installed
Docker Compose 2.0+ installed (or Docker with Compose plugin)
Basic understanding of YAML syntax
Basic Setup
Minimal Configuration
Create a docker-compose.yml file:
version : '3.8'
services :
homarr :
image : ghcr.io/homarr-labs/homarr:latest
container_name : homarr
restart : unless-stopped
ports :
- '7575:7575'
volumes :
- ./homarr/data:/appdata
environment :
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
- LOG_LEVEL=info
- DB_DRIVER=better-sqlite3
- DB_URL=/appdata/db/db.sqlite
Create a .env file in the same directory:
# Generate with: openssl rand -hex 32
SECRET_ENCRYPTION_KEY = 0000000000000000000000000000000000000000000000000000000000000000
Replace the SECRET_ENCRYPTION_KEY with a real 64-character hex string. Never commit this to version control.
Start Homarr
# Start in detached mode
docker compose up -d
# View logs
docker compose logs -f
# Stop services
docker compose down
Production Configurations
Homarr with MySQL
version : '3.8'
services :
homarr :
image : ghcr.io/homarr-labs/homarr:latest
container_name : homarr
restart : unless-stopped
ports :
- '7575:7575'
volumes :
- ./homarr/data:/appdata
environment :
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
- LOG_LEVEL=info
- DB_DRIVER=mysql2
- DB_HOST=mysql
- DB_PORT=3306
- DB_USER=homarr
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=homarrdb
depends_on :
mysql :
condition : service_healthy
mysql :
image : mysql:8.0
container_name : homarr-mysql
restart : unless-stopped
environment :
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=homarrdb
- MYSQL_USER=homarr
- MYSQL_PASSWORD=${DB_PASSWORD}
volumes :
- ./mysql/data:/var/lib/mysql
healthcheck :
test : [ 'CMD' , 'mysqladmin' , 'ping' , '-h' , 'localhost' ]
interval : 10s
timeout : 5s
retries : 5
Homarr with PostgreSQL
version : '3.8'
services :
homarr :
image : ghcr.io/homarr-labs/homarr:latest
container_name : homarr
restart : unless-stopped
ports :
- '7575:7575'
volumes :
- ./homarr/data:/appdata
environment :
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
- LOG_LEVEL=info
- DB_DRIVER=node-postgres
- DB_URL=postgres://homarr:${DB_PASSWORD}@postgres:5432/homarrdb
depends_on :
postgres :
condition : service_healthy
postgres :
image : postgres:16-alpine
container_name : homarr-postgres
restart : unless-stopped
shm_size : 128mb
environment :
- POSTGRES_USER=homarr
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=homarrdb
- PGDATA=/var/lib/postgresql/data/pgdata
volumes :
- ./postgres/data:/var/lib/postgresql/data
healthcheck :
test : [ 'CMD-SHELL' , 'pg_isready -U homarr -d homarrdb' ]
interval : 10s
timeout : 5s
retries : 5
Full Stack with External Redis
version : '3.8'
services :
homarr :
image : ghcr.io/homarr-labs/homarr:latest
container_name : homarr
restart : unless-stopped
ports :
- '7575:7575'
volumes :
- ./homarr/data:/appdata
environment :
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
- LOG_LEVEL=info
- DB_DRIVER=node-postgres
- DB_URL=postgres://homarr:${DB_PASSWORD}@postgres:5432/homarrdb
- REDIS_IS_EXTERNAL=true
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on :
postgres :
condition : service_healthy
redis :
condition : service_healthy
postgres :
image : postgres:16-alpine
container_name : homarr-postgres
restart : unless-stopped
shm_size : 128mb
environment :
- POSTGRES_USER=homarr
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=homarrdb
- PGDATA=/var/lib/postgresql/data/pgdata
volumes :
- ./postgres/data:/var/lib/postgresql/data
healthcheck :
test : [ 'CMD-SHELL' , 'pg_isready -U homarr -d homarrdb' ]
interval : 10s
timeout : 5s
retries : 5
redis :
image : redis:7-alpine
container_name : homarr-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
High Availability Configuration
For production environments with multiple Homarr instances:
version : '3.8'
services :
homarr-1 :
image : ghcr.io/homarr-labs/homarr:latest
container_name : homarr-1
restart : unless-stopped
ports :
- '7575:7575'
volumes :
- ./homarr/data:/appdata
environment :
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
- LOG_LEVEL=info
- DB_DRIVER=node-postgres
- DB_URL=postgres://homarr:${DB_PASSWORD}@postgres:5432/homarrdb
- REDIS_IS_EXTERNAL=true
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on :
postgres :
condition : service_healthy
redis :
condition : service_healthy
homarr-2 :
image : ghcr.io/homarr-labs/homarr:latest
container_name : homarr-2
restart : unless-stopped
ports :
- '7576:7575'
volumes :
- ./homarr/data:/appdata
environment :
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
- LOG_LEVEL=info
- DB_DRIVER=node-postgres
- DB_URL=postgres://homarr:${DB_PASSWORD}@postgres:5432/homarrdb
- REDIS_IS_EXTERNAL=true
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on :
postgres :
condition : service_healthy
redis :
condition : service_healthy
postgres :
image : postgres:16-alpine
container_name : homarr-postgres
restart : unless-stopped
shm_size : 128mb
environment :
- POSTGRES_USER=homarr
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=homarrdb
- PGDATA=/var/lib/postgresql/data/pgdata
volumes :
- ./postgres/data:/var/lib/postgresql/data
healthcheck :
test : [ 'CMD-SHELL' , 'pg_isready -U homarr -d homarrdb' ]
interval : 10s
timeout : 5s
retries : 5
redis :
image : redis:7-alpine
container_name : homarr-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
load-balancer :
image : nginx:alpine
container_name : homarr-lb
restart : unless-stopped
ports :
- '80:80'
volumes :
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on :
- homarr-1
- homarr-2
Environment Variables Reference
All environment variables from the Docker installation guide apply. Here are Docker Compose-specific considerations:
Using .env Files
Create a .env file for sensitive values:
# Encryption
SECRET_ENCRYPTION_KEY = your-64-char-hex-string
# Database
DB_PASSWORD = secure_password
MYSQL_ROOT_PASSWORD = root_password
# Logging
LOG_LEVEL = info
# User Permissions
PUID = 1000
PGID = 1000
Add .env to your .gitignore to prevent committing secrets to version control.
Authentication Configuration
For OIDC or LDAP, add to your .env:
# OIDC
AUTH_PROVIDERS = oidc
AUTH_OIDC_CLIENT_ID = your-client-id
AUTH_OIDC_CLIENT_SECRET = your-client-secret
AUTH_OIDC_ISSUER = https://auth.example.com
AUTH_OIDC_CLIENT_NAME = My SSO
# LDAP
AUTH_PROVIDERS = ldap
AUTH_LDAP_URI = ldap://ldap.example.com:389
AUTH_LDAP_BASE = dc = example, dc = com
AUTH_LDAP_BIND_DN = cn = admin, dc = example, dc = com
AUTH_LDAP_BIND_PASSWORD = adminpassword
Management Commands
Starting Services
Start in Background
Start with Logs
Rebuild and Start
Viewing Logs
All Services
Specific Service
Last 100 Lines
Stopping Services
Stop (Preserve Containers)
Stop and Remove
Stop, Remove, and Delete Volumes
Updating Services
Backup your data
tar -czf backup- $( date +%Y%m%d ) .tar.gz ./homarr ./mysql ./postgres ./redis
Scaling Services
Run multiple Homarr instances:
docker compose up -d --scale homarr= 3
Scaling requires external database and Redis. Don’t scale with SQLite.
Reverse Proxy Integration
Traefik Labels
Add Traefik labels to your Homarr service:
services :
homarr :
image : ghcr.io/homarr-labs/homarr:latest
labels :
- "traefik.enable=true"
- "traefik.http.routers.homarr.rule=Host(`homarr.example.com`)"
- "traefik.http.routers.homarr.entrypoints=websecure"
- "traefik.http.routers.homarr.tls=true"
- "traefik.http.routers.homarr.tls.certresolver=letsencrypt"
- "traefik.http.services.homarr.loadbalancer.server.port=7575"
Nginx Proxy Manager
Create a proxy host in NPM:
Domain: homarr.example.com
Forward Hostname: homarr (container name)
Forward Port: 7575
WebSocket Support: Enabled
SSL: Use Let’s Encrypt
Caddy
Add to your Caddyfile:
homarr.example.com {
reverse_proxy homarr:7575
}
Backup and Restore
Automated Backup Script
Create backup.sh:
#!/bin/bash
BACKUP_DIR = "./backups"
DATE = $( date +%Y%m%d-%H%M%S )
mkdir -p " $BACKUP_DIR "
# Stop services
docker compose stop
# Backup data
tar -czf " $BACKUP_DIR /homarr-backup- $DATE .tar.gz" \
./homarr ./mysql ./postgres ./redis ./.env
# Start services
docker compose up -d
# Keep only last 7 backups
ls -t " $BACKUP_DIR "/homarr-backup- * .tar.gz | tail -n +8 | xargs -r rm
echo "Backup completed: homarr-backup- $DATE .tar.gz"
Make it executable and run:
chmod +x backup.sh
./backup.sh
Restore from Backup
# Stop services
docker compose down
# Restore data
tar -xzf backups/homarr-backup-YYYYMMDD-HHMMSS.tar.gz
# Start services
docker compose up -d
Troubleshooting
Service Won’t Start
Check service status:
View detailed logs:
docker compose logs homarr
Database Connection Failed
Verify database is running:
docker compose ps postgres
Check database logs:
docker compose logs postgres
Test connection from Homarr container:
docker compose exec homarr ping postgres
Port Already in Use
Change the port mapping in docker-compose.yml:
ports :
- '8080:7575' # Use port 8080 instead
Permission Denied Errors
Fix ownership of data directories:
sudo chown -R 1000:1000 ./homarr ./mysql ./postgres ./redis
Or set PUID/PGID in docker-compose.yml:
environment :
- PUID=1000
- PGID=1000
Best Practices
Use external databases for production (MySQL or PostgreSQL)
Always use .env files for secrets, never hardcode in docker-compose.yml
Enable healthchecks for all services
Use named volumes for databases in production
Implement regular backups with automated scripts
Monitor resource usage with docker stats
Keep images updated by running docker compose pull regularly
Use specific version tags instead of latest for stability
Document your setup including all environment variables
Test restore procedures to ensure backups work
Next Steps
Kubernetes Deployment Deploy Homarr on Kubernetes for scalability
Configuration Guide Advanced configuration and tuning
Integrations Connect your self-hosted services
Backup & Restore Backup your Homarr installation