Full Configuration Example
Usage Principles
Section titled “Usage Principles”The full template is for discovering field names, confirming hierarchy, and preparing your own configuration file. Do not copy every default into production unless you intentionally own that value. Production configs should usually pin secrets, database, Redis, domains, reverse proxy settings, storage paths, and enabled feature settings.
Recommended workflow:
- Start from the minimal production skeleton below.
- Copy individual sections from the full template only when you enable the matching feature.
- Run
synctv config validate. - Run
synctv config show --output yamlto inspect the final effective configuration after defaults, config files, environment variables, and CLI overrides are merged. Secrets are redacted.
Configuration Templates
Section titled “Configuration Templates”Use _file keys for secrets whenever possible.
server: host: "0.0.0.0" port: 8080 enable_reflection: false cors_allowed_origins: - "https://app.example.com" trusted_proxies: - "10.0.0.0/8"
data_dir: "/var/lib/synctv"
database: url_file: "/run/secrets/database_url" max_connections: 20 min_connections: 5
redis: url_file: "/run/secrets/redis_url" key_prefix: "synctv:"
jwt: secret_file: "/run/secrets/jwt_secret"
security: credential_encryption_key_file: "/run/secrets/credential_encryption_key" opaque_server_setup_secret_file: "/run/secrets/opaque_server_setup_secret"
management: enabled: true transport: "unix" enable_reflection: false
bootstrap: create_root_user: true root_username: "root" root_email: "admin@example.com" root_password_file: "/run/secrets/bootstrap_root_password"
logging: level: "info" format: "json"
metrics: enabled: true host: "0.0.0.0" port: 9090 auth: mode: "bearer_token" bearer_token_file: "/run/secrets/metrics_bearer_token"This skeleton does not enable clustering, WebAuthn, OAuth2, SMTP, media provider instances, file-backed HLS storage, or file-backed proxy slice cache. Add those only when the corresponding feature is required.
This template covers all static configuration fields in the current version. Provider fields only configure local built-in provider adapters in this process; remote provider instances are persisted through the management API/CLI. See Media Providers for details.
The template lists both inline secret fields and *_file fields to show the hierarchy. Do not copy both styles blindly into production; prefer *_file or environment injection, and make sure referenced files exist.
server: host: "0.0.0.0" port: 8080 enable_reflection: false trusted_proxies: - "10.0.0.0/8" - "192.168.0.0/16" cors_allowed_origins: - "https://app.example.com" cluster_secret: "" cluster_secret_file: "/run/secrets/cluster_secret" advertise_host: "synctv-0.synctv-headless.default.svc.cluster.local" shutdown_drain_timeout_seconds: 30 grpc_max_message_size_bytes: 16777216
time: timezone: "Asia/Shanghai"
public_ids: sqids: alphabet: null min_length: 12
security: credential_encryption_key: "" credential_encryption_key_file: "/run/secrets/credential_encryption_key" opaque_server_setup_secret: "" opaque_server_setup_secret_file: "/run/secrets/opaque_server_setup_secret"
data_dir: "/var/lib/synctv"
metrics: enabled: true host: "0.0.0.0" port: 9090 tls: enabled: false cert_path: "" key_path: "" auth: mode: "bearer_token" bearer_token: "" bearer_token_file: "/run/secrets/metrics_bearer_token" basic_username: "" basic_password: "" kubernetes: audience: "" authentication_cache_ttl_seconds: 60 authorization_cache_ttl_seconds: 60
management: enabled: true transport: "unix" port: 50052 unix_socket_path: "run/synctv.sock" auth_token: "" enable_reflection: false
database: url: "" url_file: "/run/secrets/database_url" host: "" port: 0 username: "" password: "" name: "" max_connections: 20 min_connections: 5 connect_timeout_seconds: 10 idle_timeout_seconds: 600 max_lifetime_seconds: 1800
redis: url: "" url_file: "/run/secrets/redis_url" host: "" port: 0 username: "" password: "" database: 0 connect_timeout_seconds: 5 key_prefix: "synctv:" deployment_mode: "standalone" sentinel_master_name: null sentinel_addresses: []
jwt: secret: "" secret_file: "/run/secrets/jwt_secret" access_token_duration_hours: 1 refresh_token_duration_days: 30 guest_token_duration_hours: 4 clock_skew_leeway_secs: 60
logging: level: "info" format: "json" filter: null backtrace: false file_path: null
livestream: rtmp_port: 1935 public_rtmp_host: "stream.example.com" gop_cache_size: 2 stream_timeout_seconds: 300 cleanup_check_interval_seconds: 60 pull_max_retries: 10 pull_initial_backoff_ms: 1000 pull_max_backoff_ms: 30000 max_flv_tag_size_bytes: 10485760 gop_cache_max_memory_mb: 100 hls_memory_max_mb: 0 hls_storage_backend: "memory" hls_shared_storage: false hls_storage_path: "" hls_oss: endpoint: "" access_key_id: "" access_key_id_file: "/run/secrets/hls_oss_access_key_id" secret_access_key: "" secret_access_key_file: "/run/secrets/hls_oss_secret_access_key" bucket: "" region: null base_path: "hls/" flv_max_connection_duration_seconds: 86400 flv_write_timeout_seconds: 30
webauthn: enabled: true rp_id: "example.com" rp_origin: "https://app.example.com" rp_name: "SyncTV" allowed_origins: - "https://admin.example.com" allow_subdomains: false allow_any_port: false timeout_seconds: 300
email: smtp_host: "smtp.example.com" smtp_port: 587 smtp_username: "synctv@example.com" smtp_password: "" smtp_password_file: "/run/secrets/smtp_password" from_email: "synctv@example.com" from_name: "SyncTV" use_tls: true
media_providers: alist: request_timeout_seconds: 30 connect_timeout_seconds: 10 emby: request_timeout_seconds: 30 connect_timeout_seconds: 10 bilibili: request_timeout_seconds: 30 connect_timeout_seconds: 10
webrtc: mode: "peer_to_peer" enable_builtin_stun: true stun_port: 3478 stun_host: "0.0.0.0" stun_external_addr: "" filter_private_ice_candidates: true
connection_limits: max_per_user: 5 max_per_room: 200 max_total: 10000 idle_timeout_seconds: 300 max_duration_seconds: 86400 ws_message_rate_limit_per_second: 50
bootstrap: create_root_user: true root_username: "root" root_email: "admin@example.com" root_password: "" root_password_file: "/run/secrets/bootstrap_root_password"
cluster: enabled: false critical_channel_capacity: 1000 publish_channel_capacity: 10000 discovery_mode: "redis" leader_election_mode: "redis" peers: [] catchup_window_secs: 300 stream_max_length: 10000
password_complexity: min_length: 8 require_uppercase: true require_lowercase: true require_digit: true require_special: false max_repeated_chars: 3
buffer_sizes: websocket_outbound: 256 audit_buffer: 10000
cache: l1_capacity: 500 l1_ttl_seconds: 300 l2_ttl_seconds: 300 username_cache_capacity: 1000 username_cache_ttl_seconds: 3600 permission_cache_capacity: 1000 permission_cache_ttl_seconds: 300 proxy_slice_cache_enabled: true proxy_slice_file_backend_enabled: false proxy_slice_file_cache_dir: ""
messaging_rate_limits: chat_per_second: 10 danmaku_per_second: 3 window_seconds: 1
http_rate_limits: auth_max_requests: 5 auth_window_seconds: 60 write_max_requests: 30 write_window_seconds: 60 read_max_requests: 100 read_window_seconds: 60 media_max_requests: 20 media_window_seconds: 60 admin_max_requests: 30 admin_window_seconds: 60 streaming_max_requests: 200 streaming_window_seconds: 60 websocket_max_requests: 10 websocket_window_seconds: 60
grpc_rate_limits: auth_max_requests: 5 auth_window_seconds: 60 email_max_requests: 5 email_window_seconds: 60 media_max_requests: 20 media_window_seconds: 60 write_max_requests: 30 write_window_seconds: 60 admin_max_requests: 30 admin_window_seconds: 60 read_max_requests: 100 read_window_seconds: 60URL Form and Split Form
Section titled “URL Form and Split Form”database and redis both support full URLs and split fields. Prefer url_file in production because it minimizes credential exposure.
Database URL form:
database: url_file: "/run/secrets/database_url"Database split form:
database: host: "postgres.example.com" port: 5432 username: "synctv" password_file: "/run/secrets/database_password" name: "synctv"Redis URL form:
redis: url_file: "/run/secrets/redis_url"Redis Sentinel form:
Sentinel cannot be combined with cluster.enabled=true. For clustered deployments, use a stable single Redis endpoint, managed Redis, or a platform that guarantees stable connection semantics.
redis: deployment_mode: "sentinel" sentinel_master_name: "mymaster" sentinel_addresses: - "redis://sentinel-0.redis:26379" - "redis://sentinel-1.redis:26379" - "redis://sentinel-2.redis:26379"Render the Complete Effective Config
Section titled “Render the Complete Effective Config”synctv config show --output yamlWith an explicit config file:
synctv --config /etc/synctv/synctv.yaml config show --output yamlTOML output:
synctv --config /etc/synctv/synctv.yaml config show --output tomlValidate Before Deployment
Section titled “Validate Before Deployment”synctv --config /etc/synctv/synctv.yaml config validateValidation checks required secrets, cluster Redis requirements, TCP management authentication, CORS origins, gRPC message size, WebAuthn origins, and path resolution.
Related Pages
Section titled “Related Pages”- Configuration Index: all fields, types, defaults, and detail pages.
- Environment Variables: supported
SYNCTV_*variables. - How Configuration Works: precedence, search paths, secret files, and
data_dirpath resolution.