本番配置の結果を反映(配置用ユーザーでの clone、動作確認結果、新着 100 件の調査)
This commit is contained in:
+17
-13
@@ -3,7 +3,7 @@ title: tver の現状
|
|||||||
tags:
|
tags:
|
||||||
- homelab
|
- homelab
|
||||||
- tver
|
- tver
|
||||||
status: 本番配置を準備中
|
status: 本番稼働中
|
||||||
---
|
---
|
||||||
|
|
||||||
# tver の現状
|
# tver の現状
|
||||||
@@ -14,7 +14,7 @@ status: 本番配置を準備中
|
|||||||
## 今の状態
|
## 今の状態
|
||||||
|
|
||||||
- Go の HTTP サーバー、TVer API クライアント、ドラマ・バラエティの新着表示、テスト、web・worker コンテナの定義がある
|
- Go の HTTP サーバー、TVer API クライアント、ドラマ・バラエティの新着表示、テスト、web・worker コンテナの定義がある
|
||||||
- web・worker・登録番組の定期確認まで実装済み。本番配置に向けて、NAS用PostgreSQL定義と配置手順を整備している
|
- **本番稼働中。** dockageのweb・worker、NASのPostgreSQL 17、NFS動画保存を構成し、実動画の取得・再生・Range配信まで確認済み
|
||||||
- リポジトリ: `https://gitea.kazu634.com/kazu634/tver.git`
|
- リポジトリ: `https://gitea.kazu634.com/kazu634/tver.git`
|
||||||
|
|
||||||
## 目的
|
## 目的
|
||||||
@@ -31,9 +31,10 @@ TVer(`https://tver.jp/`)で公開中の動画情報を取得し、選んだ
|
|||||||
| 自動ダウンロード | **作る**(番組を登録し、新しい回を自動でダウンロードする) |
|
| 自動ダウンロード | **作る**(番組を登録し、新しい回を自動でダウンロードする) |
|
||||||
| 再生 | **アプリの中で再生する** |
|
| 再生 | **アプリの中で再生する** |
|
||||||
| ダウンロード | yt-dlp を使う |
|
| ダウンロード | yt-dlp を使う |
|
||||||
| デプロイ | 公開リポジトリをdockage VMの`/opt/stacks/tver`へcloneし、Dockgeでbuild・起動する。更新は`git pull --ff-only`後に再ビルドする |
|
| デプロイ | 読み取り専用のGiteaユーザー`tver-deploy`でdockage VMの`/opt/stacks/tver`へcloneし、`docker compose up -d --build`で起動する。Dockgeにも同じスタックが表示される。更新は`git pull --ff-only`後に再ビルドする |
|
||||||
|
| 配置用のGit認証 | `tver-deploy`を`tver`の読み取り共同作業者とし、repository読み取りトークンをdockageの権限`600`の専用credentialファイルに保存する。トークンの実値はGitや文書へ残さない |
|
||||||
| 開発言語 | **Go**(`web`・`worker` とも)。yt-dlp は外部コマンドとして呼び、進捗・結果は yt-dlp の出力から読み取る |
|
| 開発言語 | **Go**(`web`・`worker` とも)。yt-dlp は外部コマンドとして呼び、進捗・結果は yt-dlp の出力から読み取る |
|
||||||
| DB | **NAS上のtver専用Postgres 17コンテナ**(Giteaと同じ方式)。ユーザー・DB名は`tver`、公開ポートは`15434`。ポートが空いているかは未確認 [要確認] |
|
| DB | **NAS上のtver専用Postgres 17コンテナ**(Giteaと同じ方式)。ユーザー・DB名は`tver`、公開ポートは`15434`。dockageからの到達を確認済み |
|
||||||
| DB ドライバ | `github.com/jackc/pgx/v5` の `pgxpool` |
|
| DB ドライバ | `github.com/jackc/pgx/v5` の `pgxpool` |
|
||||||
| DB テスト | `github.com/fergusstrange/embedded-postgres` v1.34.0 の Postgres 17 を起動する。Apple Silicon では Rosetta 2 が必要 |
|
| DB テスト | `github.com/fergusstrange/embedded-postgres` v1.34.0 の Postgres 17 を起動する。Apple Silicon では Rosetta 2 が必要 |
|
||||||
| 定期実行 | **`worker` 内のスケジューラ** |
|
| 定期実行 | **`worker` 内のスケジューラ** |
|
||||||
@@ -104,6 +105,7 @@ TVer(`https://tver.jp/`)で公開中の動画情報を取得し、選んだ
|
|||||||
- `compose.yaml` は web と worker を定義する。web は dockage VM の LAN アドレス `192.168.10.155:8080` で公開し、待ち受けは `WEB_ADDR` で変更できる。両方へ `DATABASE_URL` と同じ動画ボリュームを渡し、worker の並行数は `WORKER_CONCURRENCY`(既定1、最大2)で指定する
|
- `compose.yaml` は web と worker を定義する。web は dockage VM の LAN アドレス `192.168.10.155:8080` で公開し、待ち受けは `WEB_ADDR` で変更できる。両方へ `DATABASE_URL` と同じ動画ボリュームを渡し、worker の並行数は `WORKER_CONCURRENCY`(既定1、最大2)で指定する
|
||||||
- NAS用の`deploy/nas/tver-db/compose.yaml`は`postgres:17`を`15434:5432`で公開し、`/volume1/docker/tver-db/pgdata`へ保存する。パスワードは同ディレクトリのGit管理外`.env`から注入する
|
- NAS用の`deploy/nas/tver-db/compose.yaml`は`postgres:17`を`15434:5432`で公開し、`/volume1/docker/tver-db/pgdata`へ保存する。パスワードは同ディレクトリのGit管理外`.env`から注入する
|
||||||
- 本番配置と更新の手順は[[docs/deploy|tver 本番配置手順]]にまとめる。dockageでは`/volume1/video`を`/mnt/nas-tver`へNFSマウントし、その配下の`tver`だけをコンテナ内の`/videos`へ渡す
|
- 本番配置と更新の手順は[[docs/deploy|tver 本番配置手順]]にまとめる。dockageでは`/volume1/video`を`/mnt/nas-tver`へNFSマウントし、その配下の`tver`だけをコンテナ内の`/videos`へ渡す
|
||||||
|
- Giteaは匿名閲覧とSSHを無効にしているため、dockageのclone・pullは読み取り専用`tver-deploy`のrepository読み取りトークンを使う。Gitのcredential helperはGiteaのHTTPS URLに限定する
|
||||||
- DB は NAS 上に tver 専用 Postgres 17 コンテナを置く。`internal/store` の埋め込み SQL を `schema_migrations` で管理し、`pg_advisory_lock` で複数プロセスからの同時適用を直列化する。web は起動時に `pgxpool` で接続してマイグレーションを適用する
|
- DB は NAS 上に tver 専用 Postgres 17 コンテナを置く。`internal/store` の埋め込み SQL を `schema_migrations` で管理し、`pg_advisory_lock` で複数プロセスからの同時適用を直列化する。web は起動時に `pgxpool` で接続してマイグレーションを適用する
|
||||||
- `download_jobs` は `episode_id` を一意にして二重登録を防ぎ、ジョブの状態・段階別進捗・結果を持つ。`subscriptions` はシリーズ単位の登録と最終確認日時を持つ。worker からの操作と画面用の一覧取得を `internal/store` にまとめる
|
- `download_jobs` は `episode_id` を一意にして二重登録を防ぎ、ジョブの状態・段階別進捗・結果を持つ。`subscriptions` はシリーズ単位の登録と最終確認日時を持つ。worker からの操作と画面用の一覧取得を `internal/store` にまとめる
|
||||||
- worker は `yt-dlp[default]` と ffmpeg を外部コマンドとして使い、映像・音声・結合・移動の段階別進捗を1秒間隔に間引いて保存する。独立した heartbeat を5秒ごとに更新し、正確な全体パーセントは保存しない。`after_move:filepath` で実パスを取り、ffprobe で H.264 と AAC の MP4 を確認して成功とする。失敗は取り消し、DRM、地域制限、ネットワーク、配信不可、抽出失敗、出力不正、その他の順に扱い、自動再試行しない
|
- worker は `yt-dlp[default]` と ffmpeg を外部コマンドとして使い、映像・音声・結合・移動の段階別進捗を1秒間隔に間引いて保存する。独立した heartbeat を5秒ごとに更新し、正確な全体パーセントは保存しない。`after_move:filepath` で実パスを取り、ffprobe で H.264 と AAC の MP4 を確認して成功とする。失敗は取り消し、DRM、地域制限、ネットワーク、配信不可、抽出失敗、出力不正、その他の順に扱い、自動再試行しない
|
||||||
@@ -117,8 +119,9 @@ TVer(`https://tver.jp/`)で公開中の動画情報を取得し、選んだ
|
|||||||
| TVer `platform-api.tver.jp` | 新着一覧(`/service/api/v1/callNewerDetail/{drama\|variety}`)・番組のエピソード一覧 | **非公開 API**。セッションは `/v2/api/platform_users/browser/create` で発行する(yt-dlp と同じ方式) |
|
| TVer `platform-api.tver.jp` | 新着一覧(`/service/api/v1/callNewerDetail/{drama\|variety}`)・番組のエピソード一覧 | **非公開 API**。セッションは `/v2/api/platform_users/browser/create` で発行する(yt-dlp と同じ方式) |
|
||||||
| TVer `service-api.tver.jp` | 番組の season 一覧(`/api/v1/callSeriesSeasons/{series_id}`) | **非公開 API**。[yt-dlp の TVer extractor](https://github.com/yt-dlp/yt-dlp/blob/master/yt_dlp/extractor/tver.py) と同じ取得方式 |
|
| TVer `service-api.tver.jp` | 番組の season 一覧(`/api/v1/callSeriesSeasons/{series_id}`) | **非公開 API**。[yt-dlp の TVer extractor](https://github.com/yt-dlp/yt-dlp/blob/master/yt_dlp/extractor/tver.py) と同じ取得方式 |
|
||||||
| yt-dlp | ダウンロード | TVer extractor を使う |
|
| yt-dlp | ダウンロード | TVer extractor を使う |
|
||||||
|
| Gitea `gitea.kazu634.com` | 配置元 | 匿名cloneとSSHは使えない。`tver-deploy`のHTTPSトークンでclone・pullする |
|
||||||
| NAS ds923p(NFS) | 動画の保存先 | `/volume1/video`をdockageの`/mnt/nas-tver`へNFSv3でマウントし、アプリは`tver`サブフォルダを使う。DSMのNFS権限は`192.168.10.155`のみ |
|
| NAS ds923p(NFS) | 動画の保存先 | `/volume1/video`をdockageの`/mnt/nas-tver`へNFSv3でマウントし、アプリは`tver`サブフォルダを使う。DSMのNFS権限は`192.168.10.155`のみ |
|
||||||
| NAS ds923p(Postgres 17) | DB | tver専用コンテナを`15434:5432`で公開し、DSMファイアウォールで`192.168.10.155`のみ許可する。`15434`の空きは未確認 [要確認] |
|
| NAS ds923p(Postgres 17) | DB | tver専用コンテナを`15434:5432`で公開し、DSMファイアウォールで`192.168.10.155`のみ許可する。dockageから接続確認済み |
|
||||||
|
|
||||||
## 確認済みの事実
|
## 確認済みの事実
|
||||||
|
|
||||||
@@ -131,20 +134,21 @@ TVer(`https://tver.jp/`)で公開中の動画情報を取得し、選んだ
|
|||||||
- SIGTERM で止めると `.part` と `.ytdl` が残り、再実行で 437,066 バイトから 438,090 バイトへ続きから取得できた [実機] 2026-10-03 確認
|
- SIGTERM で止めると `.part` と `.ytdl` が残り、再実行で 437,066 バイトから 438,090 バイトへ続きから取得できた [実機] 2026-10-03 確認
|
||||||
- 到達不能のプロキシ経由の通信失敗と存在しないエピソードは、ともに yt-dlp の終了コード 1 だった。stderr の文言で分類が必要。DRM・地域制限の失敗文言と終了コードは実測していない(yt-dlp の extractor ソースのみ確認) [実機] 2026-10-03 確認
|
- 到達不能のプロキシ経由の通信失敗と存在しないエピソードは、ともに yt-dlp の終了コード 1 だった。stderr の文言で分類が必要。DRM・地域制限の失敗文言と終了コードは実測していない(yt-dlp の extractor ソースのみ確認) [実機] 2026-10-03 確認
|
||||||
- yt-dlp の TVer extractor は日本のみ(`_GEO_COUNTRIES = ['JP']`)。DRM 付きの作品は取得できない [公式] https://github.com/yt-dlp/yt-dlp/blob/master/yt_dlp/extractor/tver.py (取得日: 2026-10-03)
|
- yt-dlp の TVer extractor は日本のみ(`_GEO_COUNTRIES = ['JP']`)。DRM 付きの作品は取得できない [公式] https://github.com/yt-dlp/yt-dlp/blob/master/yt_dlp/extractor/tver.py (取得日: 2026-10-03)
|
||||||
- dockage VM に NAS のマウントは無い。ルートの空きは約 20GB [実機] 2026-10-03 確認
|
|
||||||
- DSMのNFS権限を接続元`192.168.10.155`、読み書き、全ユーザーをadminへ割り当て、`sys`、非同期オンにすると、dockageからNFSv3で`/volume1/video`をマウントできた。設定直後の1回目は`access denied`、直後の2回目は成功したため、権限の反映待ちと考えられる [実機] 2026-10-04 確認
|
- DSMのNFS権限を接続元`192.168.10.155`、読み書き、全ユーザーをadminへ割り当て、`sys`、非同期オンにすると、dockageからNFSv3で`/volume1/video`をマウントできた。設定直後の1回目は`access denied`、直後の2回目は成功したため、権限の反映待ちと考えられる [実機] 2026-10-04 確認
|
||||||
- DSMのadminアカウントが無効でも、UID `65532`のコンテナから`tver`サブフォルダの作成・書き込み・読み込み・rename・削除に成功した。NAS上の所有者はUID `1024`・GID `100`。`/mnt/nas-tver/tver`は作成済み [実機] 2026-10-04 確認
|
- DSMのadminアカウントが無効でも、UID `65532`のコンテナから`tver`サブフォルダの作成・書き込み・読み込み・rename・削除に成功した。NAS上の所有者はUID `1024`・GID `100`。`/mnt/nas-tver/tver`は作成済み [実機] 2026-10-04 確認
|
||||||
- NFSマウントのファイル名上限は`namlen=255` [実機] 2026-10-04 確認
|
- NFSマウントのファイル名上限は`namlen=255` [実機] 2026-10-04 確認
|
||||||
|
- Giteaは`REQUIRE_SIGNIN_VIEW = true`・`DISABLE_SSH = true`で、匿名HTTPSの`info/refs`はHTTP `401`だった。読み取り専用ユーザー`tver-deploy`とrepository読み取りトークンで`/opt/stacks/tver`へのcloneに成功した [実機] 2026-10-04 確認
|
||||||
|
- dockageで`docker compose up -d --build`を実行してweb・workerを起動でき、Dockgeにも`tver`スタックとして表示された。DSMファイアウォール設定後、dockageからNASのTCP `15434`へ到達できた [実機] 2026-10-04 確認
|
||||||
|
- 本番の`/healthz`はHTTP `200`、新着バラエティは98件だった。4分の本編`ep5hcgopp2`は登録から20秒以内に完了し、92,340,468バイトの1080p H.264/AAC MP4をNASへ保存した。所有者はUID `1024`・GID `100`、`.incoming`は空で、`/library`とHTTP Range `206`も確認した [実機] 2026-10-04 確認
|
||||||
|
- NASは番組フォルダ内に所有者UID `0`の`@eaDir`を作る。ライブラリ一覧はDBから作るため、アプリへの影響はない [実機] 2026-10-04 確認
|
||||||
|
- `callNewerDetail/drama`は毎回100件を返し、応答に続きや総件数を示す項目はなかった。`result.contents`は`type=newer`で、`content`は`id`・`version`・`title`のみ。`page=2`・`offset=100`・`limit=200`を付けても先頭・末尾IDが同じ100件となり、パラメータは無視された。100件を超えて取得する手段は見つからなかったが、非公開APIのため不可能とは断定しない。新着一覧は直近100件までとなる一方、登録番組の自動確認は番組ごとの`callSeriesSeasons`→`callSeasonEpisodes`を使うため、新着から外れた回も取りこぼさない [実機] 2026-10-04 確認
|
||||||
|
|
||||||
## 課題
|
## 課題
|
||||||
|
|
||||||
- 新着 API が 100 件で打ち切りか、続きを取得できるか [要確認]
|
- **DBバックアップは未着手。** コンテナ内の`pg_dump`→gzip→NAS `/volume1/backups/tver/`、既定14日保持の日次処理を用意する
|
||||||
- 新着のうち DRM 付きの作品の割合 [要確認]
|
- ファイル名の各入力要素はUTF-8で60バイトに制限しているが、NFSマウントは`namlen=255`のため広げる余地がある。読みやすさとフルパス長も含めて上限を決める
|
||||||
- 非公開 API と yt-dlp の TVer 対応は、TVer 側の変更で予告なく壊れうる。壊れたことを検知する手段が要る
|
- 動画ファイルのパス検査と操作をGoの`os.Root`へ移し、`VIDEO_DIR`外へのアクセス防止をディレクトリ境界で扱えるか検討する
|
||||||
- Container ManagerとDSMで、DB公開ポート`15434`が未使用か確認する [要確認]
|
- DRM・地域制限の実例探しはTVerへの大量アクセスになるため行わず、運用中に観測する。workerは失敗時の`error_message`をDBへ保存し、既知の文言に一致しない失敗は`unknown`にする。実例が出た時点で分類を見直す
|
||||||
- ファイル名の各入力要素をUTF-8で60バイトに制限している。NFSマウントの`namlen=255`を判断材料に、この上限を維持するかは今後検討する
|
|
||||||
- 稼働後に、コンテナ内の`pg_dump`→gzip→NAS `/volume1/backups/tver/`、既定14日保持のバックアップを用意する
|
|
||||||
- DRM・地域制限の yt-dlp 失敗時の文言と終了コードは未実測 [要確認]
|
|
||||||
|
|
||||||
## 確かめ方
|
## 確かめ方
|
||||||
|
|
||||||
|
|||||||
+51
-17
@@ -26,9 +26,7 @@ tags:
|
|||||||
| PostgreSQL 公開ポート | `15434` |
|
| PostgreSQL 公開ポート | `15434` |
|
||||||
| PostgreSQL ユーザー / DB | `tver` / `tver` |
|
| PostgreSQL ユーザー / DB | `tver` / `tver` |
|
||||||
| アプリ配置先 | `/opt/stacks/tver` |
|
| アプリ配置先 | `/opt/stacks/tver` |
|
||||||
|
| Gitea配置用ユーザー | `tver-deploy`(リポジトリ読み取りのみ) |
|
||||||
> [!warning] 起動前の未確認事項
|
|
||||||
> - [要確認] Container Manager と DSM で、TCP `15434` が他のコンテナやサービスに使われていないこと。
|
|
||||||
|
|
||||||
## 1. NASを準備する
|
## 1. NASを準備する
|
||||||
|
|
||||||
@@ -75,7 +73,7 @@ tags:
|
|||||||
### 1.3 Container ManagerでPostgreSQLを起動する
|
### 1.3 Container ManagerでPostgreSQLを起動する
|
||||||
|
|
||||||
1. Container Managerの「プロジェクト」で、`/volume1/docker/tver-db/compose.yaml`を使う`tver-db`プロジェクトを作成する。
|
1. Container Managerの「プロジェクト」で、`/volume1/docker/tver-db/compose.yaml`を使う`tver-db`プロジェクトを作成する。
|
||||||
2. 起動前に、他のプロジェクトとポート一覧を確認し、`15434`が空いていることを確認する。[要確認]
|
2. 起動前に、他のプロジェクトとポート一覧を確認し、`15434`が空いていることを確認する。
|
||||||
3. プロジェクトをビルド・起動する。
|
3. プロジェクトをビルド・起動する。
|
||||||
4. `tver-postgres`が`healthy`になることを確認する。
|
4. `tver-postgres`が`healthy`になることを確認する。
|
||||||
5. コンテナログに`database system is ready to accept connections`があることを確認する。
|
5. コンテナログに`database system is ready to accept connections`があることを確認する。
|
||||||
@@ -86,6 +84,8 @@ tags:
|
|||||||
|
|
||||||
TCP `15434`について、送信元`192.168.10.155`だけを許可するルールを追加する。他の送信元を許可する広いルールより前に配置し、LAN内の別ホストからDBへ接続できない構成にする。
|
TCP `15434`について、送信元`192.168.10.155`だけを許可するルールを追加する。他の送信元を許可する広いルールより前に配置し、LAN内の別ホストからDBへ接続できない構成にする。
|
||||||
|
|
||||||
|
DSMファイアウォールを設定した状態で、dockageからNASのTCP `15434`へ到達できることを確認済みである。[実機] 2026-10-04 確認
|
||||||
|
|
||||||
## 2. dockageを準備する
|
## 2. dockageを準備する
|
||||||
|
|
||||||
### 2.1 NFSクライアントとマウント先を用意する
|
### 2.1 NFSクライアントとマウント先を用意する
|
||||||
@@ -127,42 +127,70 @@ docker rmi busybox:stable
|
|||||||
|
|
||||||
`/mnt/nas-tver/tver`は作成済みで、上記のDockerコンテナによる操作は実機確認済みである。[実機] 2026-10-04 確認。別環境へ作り直す場合も、書き込み確認が成功するまでworkerを起動しない。
|
`/mnt/nas-tver/tver`は作成済みで、上記のDockerコンテナによる操作は実機確認済みである。[実機] 2026-10-04 確認。別環境へ作り直す場合も、書き込み確認が成功するまでworkerを起動しない。
|
||||||
|
|
||||||
### 2.3 リポジトリと環境変数を用意する
|
### 2.3 Giteaに配置用ユーザーを用意する
|
||||||
|
|
||||||
公開リポジトリを標準のスタックディレクトリへcloneする。
|
Giteaは`REQUIRE_SIGNIN_VIEW = true`かつ`DISABLE_SSH = true`で動作している。匿名HTTPSの`info/refs`は`401`となり、SSHも使えないため、配置専用の読み取り資格情報を使う。[実機] 2026-10-04 確認
|
||||||
|
|
||||||
|
1. Giteaの管理画面で、配置専用ユーザー`tver-deploy`を作成する。
|
||||||
|
2. `kazu634/tver`リポジトリの「設定」→「共同作業者」で`tver-deploy`を追加し、権限を「読み取り」にする。
|
||||||
|
3. `tver-deploy`でGiteaへログインし、ユーザー設定の「アプリケーション」からrepository読み取り権限だけを持つトークンを作成する。
|
||||||
|
4. トークンは作成時に安全な場所へ控え、この文書、シェル履歴、Git管理下のファイルへ実値を書かない。
|
||||||
|
|
||||||
|
### 2.4 dockageにclone用トークンを保存する
|
||||||
|
|
||||||
|
Dockerホストの管理ユーザー`kazu634`で次を実行する。トークンは非表示で読み取り、権限`600`の専用credentialファイルへ保存する。credential helperはGiteaのHTTPS URLにだけ設定する。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/stacks
|
install -d -m 700 ~/.config/git
|
||||||
git clone https://gitea.kazu634.com/kazu634/tver.git tver
|
read -rs -p 'Gitea token: ' TOKEN; echo
|
||||||
|
umask 077
|
||||||
|
printf 'https://tver-deploy:%s@gitea.kazu634.com\n' "$TOKEN" > ~/.config/git/credentials-tver
|
||||||
|
unset TOKEN
|
||||||
|
git config --global credential.https://gitea.kazu634.com.helper 'store --file ~/.config/git/credentials-tver'
|
||||||
|
git clone https://tver-deploy@gitea.kazu634.com/kazu634/tver.git /opt/stacks/tver
|
||||||
cd /opt/stacks/tver
|
cd /opt/stacks/tver
|
||||||
```
|
```
|
||||||
|
|
||||||
`.env.example`をGit管理外の`.env`へコピーし、実環境の値を設定する。
|
この手順で認証付きcloneに成功した。[実機] 2026-10-04 確認。トークンを失効・更新した場合は、同じ手順で`credentials-tver`を作り直す。
|
||||||
|
|
||||||
|
### 2.5 アプリの環境変数を用意する
|
||||||
|
|
||||||
|
`.env.example`をGit管理外の`.env`へコピーし、`DATABASE_URL`へパスワード用の伏字を入れる。ファイルを`600`にしてから、パスワードを非表示で読み取り、伏字だけを置換する。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
cd /opt/stacks/tver
|
||||||
umask 077
|
umask 077
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
|
sed -i 's|^DATABASE_URL=.*|DATABASE_URL=postgres://tver:__SET_PASSWORD__@192.168.10.201:15434/tver?sslmode=disable|' .env
|
||||||
chmod 600 .env
|
chmod 600 .env
|
||||||
|
read -rs -p 'PostgreSQL password: ' DB_PASSWORD; echo
|
||||||
|
sed -i "s|__SET_PASSWORD__|${DB_PASSWORD}|" .env
|
||||||
|
unset DB_PASSWORD
|
||||||
|
if grep -q '__SET_PASSWORD__' .env; then echo 'DATABASE_URLのパスワードが未設定です' >&2; exit 1; fi
|
||||||
```
|
```
|
||||||
|
|
||||||
`.env`には次の形式で設定する。`<PostgreSQLのパスワード>`はNAS側の`.env`と同じ実値へ置き換える。
|
完成した`.env`は次の項目を持つ。`DATABASE_URL`の実値は表示したり、文書へ転記したりしない。
|
||||||
|
|
||||||
```dotenv
|
```dotenv
|
||||||
DATABASE_URL=postgres://tver:<PostgreSQLのパスワード>@192.168.10.201:15434/tver?sslmode=disable
|
DATABASE_URL=<設定済み・表示しない>
|
||||||
VIDEO_HOST_DIR=/mnt/nas-tver/tver
|
VIDEO_HOST_DIR=/mnt/nas-tver/tver
|
||||||
VIDEO_DIR=/videos
|
VIDEO_DIR=/videos
|
||||||
WORKER_CONCURRENCY=1
|
WORKER_CONCURRENCY=1
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!warning] パスワードの文字種
|
> [!warning] パスワードの文字種
|
||||||
> 上のURLへ埋め込む値に予約文字がある場合はURLエンコードが必要になる。NAS準備時に16進文字列で生成すれば、この追加処理を避けられる。
|
> この手順で使うPostgreSQLパスワードには、URLや`sed`の区切りに影響する`@`・`:`・`/`・`?`・`#`・`%`・`|`を含めない。NAS準備時に16進文字列で生成すれば、この制約を満たせる。
|
||||||
|
|
||||||
### 2.4 Dockgeで起動する
|
### 2.6 起動する
|
||||||
|
|
||||||
1. Dockgeでスタックディレクトリ `/opt/stacks/tver` の`compose.yaml`を`tver`スタックとして開く。
|
`/opt/stacks/tver`でwebとworkerをビルドして起動する。
|
||||||
2. webとworkerの両方が`build`対象であり、`.env`が読み込まれることを確認する。
|
|
||||||
3. 「Deploy」でビルドと起動を行う。
|
```bash
|
||||||
4. Dockge上でweb・workerがともにrunningになり、再起動を繰り返していないことを確認する。
|
cd /opt/stacks/tver
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
この方法で起動すると、Dockgeの画面にも`tver`スタックとして表示された。[実機] 2026-10-04 確認。Dockge上でweb・workerがともにrunningになり、再起動を繰り返していないことを確認する。
|
||||||
|
|
||||||
コマンドでも状態とログを確認できる。
|
コマンドでも状態とログを確認できる。
|
||||||
|
|
||||||
@@ -186,6 +214,12 @@ docker compose logs --tail=100 web worker
|
|||||||
5. NASの`/volume1/video/tver`に規則どおりのMP4が作成されたことを確認する。
|
5. NASの`/volume1/video/tver`に規則どおりのMP4が作成されたことを確認する。
|
||||||
6. `tver-postgres`のログとweb・workerのログに、接続失敗やマイグレーション失敗がないことを確認する。
|
6. `tver-postgres`のログとweb・workerのログに、接続失敗やマイグレーション失敗がないことを確認する。
|
||||||
|
|
||||||
|
> [!success] 本番の動作確認結果
|
||||||
|
> `/healthz`はHTTP `200`、新着バラエティは98件を表示した。4分の本編`ep5hcgopp2`を登録すると20秒以内に完了し、NASの`video/tver/<番組名>/`へ92,340,468バイトの1080p H.264/AAC MP4が保存された。所有者はUID `1024`・GID `100`、`.incoming`は空だった。`/library`の表示・再生とHTTP Range `206`も確認した。[実機] 2026-10-04 確認
|
||||||
|
|
||||||
|
> [!note] Synologyの`@eaDir`
|
||||||
|
> NASが番組フォルダ内に所有者UID `0`の`@eaDir`を作る。アプリのライブラリ一覧はファイルシステムの走査ではなくDBから作るため、表示や再生には影響しない。[実機] 2026-10-04 確認
|
||||||
|
|
||||||
## 4. 更新する
|
## 4. 更新する
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
Reference in New Issue
Block a user