Files
360_player/docker-compose.yml
T
JianMiauandClaude Opus 5 fa220b00eb 新增 nginx 容器終結 TLS,讓播放器可用 HTTPS 連線
摘要:
比照 badminton-scoreboard 的做法,加一個 nginx 容器負責 SSL,
反向代理到原本的 Node 應用;Node 端維持純 HTTP,不碰憑證。

根本原因:
播放器原本只提供 HTTP。專案內原先想直接 symlink www/certificate 進來,
但那份憑證是 2026-04-16 從 DSM 複製出來的靜態副本,已於 2026-07-01 過期,
且 DSM 續期後不會自動更新副本。共用目錄 /volume1/docker/certs 才是
其他專案在用、且持續被續期的來源(目前效期至 2026-09-04)。

影響:
- 外網連線全程明文
- 若沿用 www/certificate,瀏覽器會直接因憑證過期而擋下連線

修法:
- 新增 docker/nginx/(Dockerfile + entrypoint.sh):啟動時把 cert.pem 與
  chain.pem 正規化並串成 fullchain,依環境變數產生 nginx 設定,
  再用 inotifywait 監看憑證目錄,續期後自動 reload,不需重啟容器
- docker-compose.yml 拆成 360-player(app)與 360-player-web(nginx)兩個服務,
  憑證以唯讀掛載 ${SSL_CERT_DIR:-/volume1/docker/certs}
- 保留 app 的 HTTP 埠:憑證綁網域,區網用 IP 連 HTTPS 必定跳警告,
  維持 區網走 http / 外網走 https 兩條路
- .env.example 補上 SSL_* 與 HTTPS_PORT 設定項

針對本專案調整(與 badminton-scoreboard 不同之處):
- proxy_buffering off + proxy_max_temp_file_size 0:影片走 HTTP Range 串流,
  開著緩衝 nginx 會把整段回應先寫成暫存檔,數 GB 來源會塞爆容器磁碟
- proxy_read_timeout/send_timeout 24h:/api/events 是 SSE,轉檔動輒數小時,
  預設 60 秒會被切斷導致進度停止更新
- 移除 websocket 的 Upgrade 標頭:本專案用 SSE,沒有 websocket

驗證:
以 entrypoint 相同的 awk 邏輯在本機組出 fullchain,openssl 解析得到完整三層
憑證鏈(jianmiau.tk → Let's Encrypt YR2 → ISRG Root YR),且 cert 與 privkey
的 modulus 相符。docker compose config 展開後的路徑與埠號皆正確。
註:無 docker daemon 權限,未實際 build 與啟動容器。

順帶修正 README:videoDir 範例改為 NAS 路徑、VAAPI 一節更新為已實機驗證。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 11:07:29 +08:00

53 lines
1.9 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
services:
360-player:
container_name: 360-player
build:
context: .
dockerfile: Dockerfile
image: 360-player:latest
restart: unless-stopped
ports:
# 區網用 IP 直連的 HTTP(憑證是網域名,IP 連一定會跳警告,所以留一條明文)。
# 想只走 HTTPS 的話把這兩行刪掉,改用下面的 expose 就好。
- "${PORT:-8360}:8360"
expose:
- "8360"
volumes:
# 影片資料夾(NAS 上的實際路徑)→ 容器內 /videos,唯讀
- "${VIDEO_DIR:-/volume1/photo/Badminton}:/videos:ro"
# 轉檔輸出 + probe 快取 → 容器內 /cache(需要可寫)
- "${CACHE_DIR:-./cache}:/cache"
environment:
TZ: ${TZ:-Asia/Taipei}
# CPU 轉檔時 libx264 的 presetNAS CPU 弱可改 superfast / ultrafast(檔案會稍大)
X264_PRESET: ${X264_PRESET:-veryfast}
# 本機為 Intel J4025UHD 600),已啟用 VAAPI 硬體轉檔;
# 換到沒有 /dev/dri 的機器時要把下面兩行註解掉,否則容器起不來。
devices:
- /dev/dri:/dev/dri
360-player-web:
container_name: 360-player-web
build:
context: .
dockerfile: docker/nginx/Dockerfile
image: 360-player-web:latest
restart: unless-stopped
depends_on:
- 360-player
ports:
- "${HTTPS_PORT:-8443}:8443"
environment:
TZ: ${TZ:-Asia/Taipei}
NGINX_PORT: 8443
NGINX_SERVER_NAME: ${NGINX_SERVER_NAME:-_}
SSL_CERT_DIR: /etc/nginx/certs
SSL_CERT_FILE_NAME: ${SSL_CERT_FILE_NAME:-cert.pem}
SSL_CHAIN_FILE_NAME: ${SSL_CHAIN_FILE_NAME:-chain.pem}
SSL_KEY_FILE_NAME: ${SSL_KEY_FILE_NAME:-privkey.pem}
UPSTREAM_HOST: 360-player
UPSTREAM_PORT: 8360
volumes:
# 憑證來源與 badminton-scoreboard 共用;DSM 續期後 entrypoint 會自動 reload
- "${SSL_CERT_DIR:-/volume1/docker/certs}:/etc/nginx/certs:ro"