3.7 KiB
3.7 KiB
Production Deployment Guide
This guide describes a production-style deployment for Linear Void using Docker Compose, Gitea registry images, and Cloudflare fronting.
Target Topology
- Host: Linux server with Docker Engine
- Reverse proxy: nginx container (linearvoid-nginx)
- Core services: playout, chat, redis, postgres
- Observability: prometheus, grafana
- CDN/edge: Cloudflare
Prerequisites
- Docker Engine + Docker Compose plugin
- Network access to git.allucanget.biz
- A valid .env file with production values
- DNS configured for linearvoid.tv (and media.linearvoid.tv if split media domain is used)
Environment File
Use .env with at least:
- CI_REGISTRY_URL
- CI_REGISTRY_NAMESPACE
- CHAT_PORT
- NGINX_PORT
- DATABASE_URL (if overridden)
- REDIS_URL (if overridden)
- ADMIN_USERNAME
- ADMIN_PASSWORD
- VITE_PUBLIC_APP_URL
- VITE_PUBLIC_WS_URL
- VITE_PUBLIC_HLS_URL
- Cloudflare/R2 variables when media sync is enabled
See .env.example and SETUP.md for full variable reference.
Pull-and-Run Deployment
From repository root:
docker login git.allucanget.biz
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d --remove-orphans
First-Time or Recovery Provisioning
- Ensure host paths exist:
mkdir -p data/chat data/playlist data/media data/hls
- Confirm volumes and networks:
docker volume ls
docker network ls
- Start stack:
docker compose -f docker-compose.prod.yml up -d
Health Verification
After startup, check service status:
docker compose -f docker-compose.prod.yml ps
Endpoint checks:
- App: http://{host}:8080/
- Nginx health: http://{host}:8080/health
- Chat health: http://{host}:3000/health
- Playout health: http://{host}:8081/health
- Prometheus: http://{host}:9090
- Grafana: http://{host}:3001
Domain checks:
Zero/Low-Downtime Update Pattern
- Pull newest images.
- Recreate changed services only:
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d nginx chat playout
- Re-run health checks.
Rollback
If new images are unhealthy:
- Pin previous tags in docker-compose.prod.yml.
- Pull pinned tags.
- Restart impacted services.
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d nginx chat playout
Operational Tasks
View logs
docker compose -f docker-compose.prod.yml logs -f nginx chat playout
Restart one service
docker compose -f docker-compose.prod.yml restart chat
Stop stack
docker compose -f docker-compose.prod.yml down
Keep volumes (recommended) vs remove volumes (destructive)
# keep data
docker compose -f docker-compose.prod.yml down
# destructive (remove data)
docker compose -f docker-compose.prod.yml down -v
Nginx and Proxy Considerations
- If an external proxy (for example Nginx Proxy Manager) fronts the stack, align request body limits with internal nginx.
- For resumable admin uploads, ensure client_max_body_size supports chunk requests in both proxy layers.
Security Baseline
- Use strong ADMIN_PASSWORD and rotate regularly.
- Keep Docker host access restricted.
- Prefer HTTPS/WSS through Cloudflare.
- Restrict exposed ports if only proxy access is needed.
Common Deployment Pitfalls
- Missing frontend build artifacts in local-only compose workflows.
- Wrong registry credentials or missing login.
- Misaligned domain env vars (app/ws/hls) causing mixed-origin errors.
- Proxy-layer body size limits returning 413 on upload.
- Health checks failing before service warmup is complete.