# Copia come .env sul server: cp .env.production.example .env # Genera secret: openssl rand -hex 32 POSTGRES_PASSWORD=CHANGE_ME_STRONG_PASSWORD SECRET_KEY_BASE=CHANGE_ME_openssl_rand_hex_64 JWT_SECRET=CHANGE_ME_openssl_rand_hex_32 MEDIAMTX_WEBHOOK_SECRET=CHANGE_ME_openssl_rand_hex_32 # RTMP pubblico per telefoni (IP WAN o DDNS + porta 1935) MEDIAMTX_RTMP_URL=rtmp://www.matchlivetv.it:1935 # Dominio pubblico (Nginx Proxy Manager → Rails :3000) APP_PUBLIC_URL=https://www.matchlivetv.it HLS_PUBLIC_URL=https://www.matchlivetv.it/hls CORS_ORIGINS=https://www.matchlivetv.it,https://matchlivetv.it ALLOWED_HOSTS=www.matchlivetv.it,matchlivetv.it,192.168.1.146,localhost YOUTUBE_REDIRECT_URI=https://www.matchlivetv.it/api/v1/youtube/callback # YouTube OAuth — vedi docs/YOUTUBE_SETUP.md YOUTUBE_CLIENT_ID= YOUTUBE_CLIENT_SECRET= YOUTUBE_PLATFORM_REFRESH_TOKEN= # Stripe LIVE (Dashboard in modalità Live — non riusare price_ di Test) # Match Live TV → Premium Light | Match Live TV PRO → Premium Full STRIPE_SECRET_KEY=sk_live_... STRIPE_WEBHOOK_SECRET=whsec_... # webhook https://www.matchlivetv.it/webhooks/stripe (modalità Live) STRIPE_PREMIUM_LIGHT_MONTHLY_PRICE_ID= STRIPE_PREMIUM_LIGHT_YEARLY_PRICE_ID= STRIPE_PREMIUM_FULL_MONTHLY_PRICE_ID= STRIPE_PREMIUM_FULL_YEARLY_PRICE_ID= STRIPE_PREMIUM_LIGHT_PRICE_ID= STRIPE_PREMIUM_FULL_PRICE_ID= RAILS_LOG_LEVEL=info # Titolare trattamento (GDPR) — obbligatorio in produzione PRIVACY_CONTROLLER_NAME=Emiliano Frascaro PRIVACY_CONTROLLER_ADDRESS=Via Guido De Ruggiero, 89 - 20142 - Milano (MI) PRIVACY_CONTACT_EMAIL=privacy@matchlive.it PRIVACY_CONTROLLER_VAT= # Email transazionali (reset password, inviti) MAILER_FROM=Match Live TV # Aruba: smtps.aruba.it porta 465 con SSL (non STARTTLS su 587) SMTP_ADDRESS=smtps.aruba.it SMTP_PORT=465 SMTP_USERNAME=noreply@matchlivetv.it SMTP_PASSWORD= SMTP_AUTH=plain SMTP_SSL=true SMTP_STARTTLS=false PASSWORD_RESET_EXPIRY_HOURS=2 # Disco video dedicato (recordings MediaMTX + dati Garage + log + Active Storage). Montare es. 800GB su /media/videos MATCHLIVETV_VIDEOS_ROOT=/media/videos/matchlivetv # Log cron e YouTube relay ffmpeg (default: ${MATCHLIVETV_VIDEOS_ROOT}/log) # MATCHLIVETV_LOG_DIR=/media/videos/matchlivetv/log # Replay storage — Garage (obbligatorio in produzione per Premium replay) # Dopo il primo deploy: bash scripts/setup_garage_production.sh (crea garage.prod.toml + chiavi) REPLAY_STORAGE_ENDPOINT=http://garage:3900 REPLAY_STORAGE_BUCKET=matchlivetv-replays REPLAY_STORAGE_REGION=garage REPLAY_STORAGE_ACCESS_KEY_ID= REPLAY_STORAGE_SECRET_ACCESS_KEY= REPLAY_STORAGE_FORCE_PATH_STYLE=true # Streaming replay: Rails fa auth, edge serve /media/ → Garage (non passa da Puma) REPLAY_MEDIA_PUBLIC_BASE_URL=https://www.matchlivetv.it/media REPLAY_MEDIA_REDIRECT=true # Puma: 5 thread (no secondo worker senza più RAM) RAILS_MAX_THREADS=5 # Ops monitoring — notifiche push (ntfy self-hosted) e health check # 1) Avvia servizio: docker compose up -d ntfy # 2) NPM: proxy HTTPS → http://192.168.1.146:8090 (es. ntfy.matchlivetv.it, WebSockets ON) # 3) App ntfy sul telefono: server custom = NTFY_PUBLIC_URL, iscriviti a OPS_NTFY_TOPIC NTFY_PUBLIC_URL=https://ntfy.matchlivetv.it # Topic segreto: stesso nome in app ntfy (subscribe) e in OPS_NTFY_URL OPS_NTFY_URL=http://ntfy:80/matchlivetv-ops-YOUR_SECRET_SUFFIX OPS_NTFY_TOKEN= OPS_ALERT_EMAIL= OPS_NOTIFY_SEVERITIES=critical,warning OPS_NOTIFY_COOLDOWN_MINUTES=30 OPS_HEALTH_INTERVAL_SECS=180 OPS_HEALTH_TOKEN= OPS_DISK_WARN_PERCENT=80 OPS_DISK_CRIT_PERCENT=90 OPS_RECORDINGS_WARN_GB=20 OPS_RECORDINGS_CRIT_GB=50 OPS_SIDEKIQ_STALE_SECS=300 OPS_LOG_SUBSCRIBER=false # Sentry (opzionale — error tracking produzione) SENTRY_DSN= SENTRY_TRACES_SAMPLE_RATE=0.1