Files
linearvoid/DEPLOYMENT.md
T
zwitschi c10d98f3b4
CI / test (push) Successful in 3m51s
CI / docker (push) Successful in 6m16s
CI / release (push) Skipped
Refactor code structure for improved readability and maintainability
2026-08-04 21:19:49 +02:00

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

  1. Ensure host paths exist:
mkdir -p data/chat data/playlist data/media data/hls
  1. Confirm volumes and networks:
docker volume ls
docker network ls
  1. 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

  1. Pull newest images.
  2. Recreate changed services only:
docker compose -f docker-compose.prod.yml pull

docker compose -f docker-compose.prod.yml up -d nginx chat playout
  1. Re-run health checks.

Rollback

If new images are unhealthy:

  1. Pin previous tags in docker-compose.prod.yml.
  2. Pull pinned tags.
  3. 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 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.