deploy.yaml
Rama master · réplica de lectura del repositorio original.
# Phlix Media Server — Deployment Configuration
# SP7: WebSocket worker port binding documentation
#
# This file documents the deployment configuration for exposing the
# WebSocket worker (SyncPlay) to the external network via HAProxy.
#
# Related files:
# - deploy/haproxy.cfg : HAProxy configuration for WS port exposure
# - config/server.php : WS worker settings — timeouts, JWT auth AND the
# 'websocket.host'/'websocket.port' bind keys. Since R14-06 these keys
# DO move the listening socket: src/Server/Runtime/ListenEndpoints.php
# resolves the bind env (PHLIX_WS_HOST/PHLIX_WS_PORT) > config > shipped
# default (websocket://0.0.0.0:8097), and start.php writes the resolved
# pair back into the config pre-fork so the object always describes the
# socket that accepts.
# - start.php : WS worker initialization (~line 636,
# ListenEndpoints::webSocket() — nothing hard-coded; move the bind by
# env/config + restart, never by code edit)
---
# Deployment metadata
deployment:
name: phlix-server
version: "1.0"
last_updated: "2026-10-14"
# WebSocket worker configuration
websocket:
# Port the daemon's WS worker listens on: the RESOLVED bind, default
# 8097 (env PHLIX_WS_HOST/PHLIX_WS_PORT > websocket.host/websocket.port
# in config/server.php > shipped default; resolved by ListenEndpoints,
# R14-06 — the value below mirrors the shipped default).
internal_port: 8097
# External exposure via HAProxy. The shipped haproxy.cfg binds :8443 to
# avoid colliding with the daemon's own :8097 listener (EADDRINUSE);
# firewall the raw daemon port from untrusted networks:
# sudo ufw deny 8097/tcp && sudo ufw allow 8443/tcp
# To keep the client-visible port at 8097 instead, move the daemon's WS
# bind to loopback via env or config — PHLIX_WS_HOST=127.0.0.1 in
# /etc/phlix/env (or websocket.host in config/server.php) — restart the
# daemon, then switch the frontend bind: since R14-06 this needs NO code
# edit. See the PORT PREREQUISITE header in deploy/haproxy.cfg.
exposed_port: 8443
exposed_interface: "0.0.0.0"
# Health check
health_check:
# Port for external health monitoring (separate from WS traffic)
port: 8098
# The WS worker answers a plain HTTP GET with 400 Bad Request — that IS
# the alive signal (it speaks only the WebSocket handshake). 426 appears
# only for a Sec-WebSocket-Version mismatch during a real handshake, so
# no probe can elicit it; HAProxy therefore uses TCP connect checks.
expected_status: 400
path: /
# Connection settings
connection:
# Maximum idle time before WS connection is closed
idle_timeout: 86400 # 24 hours in seconds
# Maximum time for the TCP connect to the backend worker
handshake_timeout: 5000 # milliseconds
# Health check interval
check_interval: 10 # seconds
# Backend (internal WS worker) configuration
backend:
host: "127.0.0.1"
port: 8097
# Health check settings (TCP connect check — never an HTTP status probe)
check_fall: 2 # Mark down after 2 consecutive failures
check_rise: 3 # Mark up after 3 consecutive successes
# HAProxy configuration reference
haproxy:
config_file: "deploy/haproxy.cfg"
user: "haproxy"
group: "haproxy"
max_connections: 4096
# Statistics endpoint (localhost only)
stats:
host: "127.0.0.1"
port: 8404
path: "/stats"
# Frontend configuration (see websocket.exposed_port above for the
# prerequisite before moving this onto :8097)
frontend:
bind: "*:8443"
mode: "http"
# Backend configuration
backend:
server: "127.0.0.1:8097"
mode: "http"
# Port binding summary
ports:
http:
internal: 8096
description: "HTTP/REST API worker (GET /health lives here)"
websocket:
internal: 8097
external: 8443
description: "WebSocket worker for SyncPlay realtime communication"
websocket_health:
port: 8098
description: "Health check frontend for WS worker (400 from a plain GET = alive; TCP checks inside HAProxy)"
# The hub relay is an OUTBOUND-only client connection (src/Hub/RelayConsumer)
# to the hub's relay listener (hub :8802). The server opens NO inbound
# relay listener — there is no 9443 (or any) port to expose here.
relay:
listener: none
direction: "outbound"
description: "Relay tunnel to phlix-hub — outbound client connection only, no server-side port"
# Verification commands
verification:
# Check WS worker liveness through the proxy (400 = worker alive; it only
# speaks the WebSocket handshake)
health_check: |
curl -s -o /dev/null -w '%{http_code}\n' http://<deploy-host>:8443/
# Check WS health frontend (400 = worker alive)
health_endpoint: |
curl -s -o /dev/null -w '%{http_code}\n' http://<deploy-host>:8098/
# HTTP API health (different worker)
http_health: |
curl -s http://<deploy-host>:8096/health
# HAProxy stats
stats: |
curl -s http://localhost:8404/stats
# Dependencies
depends_on:
- "SP6: WebSocket worker implementation (SyncPlayManager, WebSocketServer)"
- "config/server.php: websocket timeouts + JWT handshake auth (SV-4.7)"
- "start.php: WS worker bind resolved by src/Server/Runtime/ListenEndpoints.php (R14-06), default websocket://0.0.0.0:8097 — move via PHLIX_WS_HOST/PHLIX_WS_PORT or websocket.host/port + restart"