- Docker and Docker Compose installed
- Domain name with DNS pointing to your server
- SSL certificates (recommended: Let's Encrypt with Traefik or similar)
- Reverse proxy setup (Nginx, Traefik, Cloudflare, etc.)
Copy the example environment file and configure it for your domain:
cp .env.example .envEdit .env with your production values:
# Your production domain configuration
PUBLIC_URL=https://yourdomain.com
FRONTEND_DOMAIN=yourdomain.com
BACKEND_DOMAIN=api.yourdomain.com
# API URLs (used by frontend at build time)
VITE_API_URL=https://api.yourdomain.com/api
VITE_WS_URL=wss://api.yourdomain.com
# CORS Configuration
CORS_ORIGIN=https://yourdomain.com
# Generate a secure webhook token
WEBHOOK_TOKEN=$(openssl rand -base64 32)
# Enable proxy trust
TRUST_PROXY=true# Production deployment
docker-compose -f docker-compose.prod.yml up -d
# Check logs
docker-compose -f docker-compose.prod.yml logs -fThe production Docker Compose includes Traefik labels. Ensure your Traefik configuration includes:
# traefik.yml
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: your-email@domain.com
storage: /etc/traefik/acme.json
httpChallenge:
entryPoint: webExample Nginx configuration:
# Frontend
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8080;
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;
}
}
# Backend API
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:3001;
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;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}If using Cloudflare:
- Set SSL/TLS mode to "Full (strict)"
- Enable WebSocket support in Network settings
- Configure your origin server to use HTTPS
| Variable | Required | Default | Description |
|---|---|---|---|
PUBLIC_URL |
Yes | - | Public URL of your frontend |
FRONTEND_DOMAIN |
Yes | - | Domain for frontend service |
BACKEND_DOMAIN |
Yes | - | Domain for backend API |
VITE_API_URL |
Yes | - | Full API URL (build-time) |
VITE_WS_URL |
Yes | - | WebSocket URL (build-time) |
CORS_ORIGIN |
Yes | - | Allowed CORS origins |
WEBHOOK_TOKEN |
Recommended | - | Secure webhook token |
WEBHOOK_PATH |
No | /api/webhook/doorbell |
Custom webhook path |
TRUST_PROXY |
No | true |
Enable proxy trust |
FRONTEND_PORT |
No | 8080 |
Frontend container port |
BACKEND_PORT |
No | 3001 |
Backend container port |
Generate a strong webhook token:
# Generate secure token
openssl rand -base64 32
# Or use uuidgen
uuidgen- Database is stored in Docker volumes
- Regular backups recommended
- Consider encryption at rest for sensitive data
- Use HTTPS/WSS in production
- Configure firewall to only allow necessary ports
- Use strong SSL/TLS configuration
- Backend:
https://api.yourdomain.com/api/health - Frontend:
https://yourdomain.com/(should return 200)
# View all logs
docker-compose -f docker-compose.prod.yml logs -f
# View specific service logs
docker-compose -f docker-compose.prod.yml logs -f backend
docker-compose -f docker-compose.prod.yml logs -f frontendThe application exposes basic health metrics at /api/health:
{
"status": "healthy",
"timestamp": "2025-06-30T12:00:00.000Z",
"uptime": 3600,
"environment": "production"
}- Check proxy WebSocket configuration
- Verify WSS protocol for HTTPS sites
- Check firewall settings
- Verify
CORS_ORIGINmatches your frontend domain - Check proxy headers are being forwarded
- Ensure
TRUST_PROXY=trueis set
- Check environment variables are set during build
- Verify API URLs are accessible during build
- Check Docker build logs
Enable debug logging:
# Add to .env
NODE_ENV=development
# Restart services
docker-compose -f docker-compose.prod.yml restart# Backup database
docker-compose -f docker-compose.prod.yml exec backend cp /app/data/doorbell.db /app/data/backup-$(date +%Y%m%d).db
# Copy backup to host
docker cp $(docker-compose -f docker-compose.prod.yml ps -q backend):/app/data/backup-$(date +%Y%m%d).db ./# Backup all data
docker run --rm -v doorbell_doorbell-data:/data -v $(pwd):/backup alpine tar czf /backup/doorbell-data-$(date +%Y%m%d).tar.gz -C /data .
docker run --rm -v doorbell_doorbell-uploads:/data -v $(pwd):/backup alpine tar czf /backup/doorbell-uploads-$(date +%Y%m%d).tar.gz -C /data .# Pull latest images
docker-compose -f docker-compose.prod.yml pull
# Restart with new images
docker-compose -f docker-compose.prod.yml up -dThe application handles database migrations automatically on startup. No manual intervention required.