Skip to content

Deploy SORAHOST

Rumia Channel edited this page Sep 30, 2026 · 7 revisions

SORAHOST で narou.rs を動かす

SORAHOST (PteWorker の node モード) のコンテナで native 版 narou_rs を常駐させる手順。 Workers は使わない。専用サーバー 1 台で完結し、公開は PteWorker が行う。

設定は 4 か所に分かれる

迷いやすいので先に「どこに何を置くか」を固定する。

置き場 何を置く 誰が読む
GitHub Environment SORAHOST CI が使う値 (endpoint / token / Cloudflare の値 / 公開ホスト名) deploy-sorahost.yml
GitHub Repository variable SORAHOST = T CI の分岐 (T で SORAHOST 配備が有効、Workers CI が停止)
サーバー /home/container/.env アプリの値 (basic 認証 / コネクタ / S3 / 挙動) start.sh が起動時に読む
Cloudflare ダッシュボード コネクタのトークンを取る場所 (置く先ではない) NAROU_CONNECTOR_TOKEN の出どころ

要点: CI に置く値 (GitHub) と、アプリが使う値 (サーバー .env) は別物。 NAROU_* は GitHub ではなく .env に、SORAHOST_* / CLOUDFLARE_* は .env ではなく GitHub に置く。

値の流れ

flowchart LR
  subgraph SRC["値の出どころ"]
    A["PteWorker コンソール<br>エンドポイント / デプロイトークン"]
    B["Cloudflare ダッシュボード<br>API トークン / Account ID<br>コネクタの接続トークン"]
    C["自分で決める値<br>公開ホスト名 / パスワード / S3"]
  end
  subgraph GH["GitHub"]
    D["Environment `SORAHOST`<br>(secrets / vars)"]
    E["Repository variable<br>SORAHOST = T"]
  end
  subgraph CI["CI: deploy-sorahost.yml"]
    F["build → deploy → smoke"]
    G["provision_connector.py<br>コネクタ / ingress / DNS / Access"]
  end
  subgraph SV["SORAHOST サーバー (/home/container)"]
    H[".env<br>start.sh が起動時に読む"]
    I["narou_rs web<br>127.0.0.1:PORT"]
  end
  A -->|"SORAHOST_ENDPOINT / SORAHOST_TOKEN"| D
  B -->|"CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID"| D
  C -->|"SORAHOST_PUBLIC_HOSTNAME 等"| D
  E -->|配備を有効化| F
  D --> F
  D --> G
  G -->|コネクタ・DNS・Access を作成| B
  B -->|"Add a replica のトークン"| H
  C -->|"NAROU_WEB_PASSWORD / NAROU_PUBLIC_HOST / NAROU_CONNECTOR_TOKEN / S3_*"| H
  H --> I
  F -->|バイナリと start.sh を配備| I
Loading

手順 (順に)

Step 0: 前提

  • PteWorker のプロジェクトが作れること (SORAHOST アカウント)
  • 公開ホスト名を自分で決められること (前段にコネクタを使う場合。独自ドメインを Cloudflare DNS で管理する)

Step 1: GitHub の Environment SORAHOST に配備の値を置く

GitHub リポジトリ → Settings → Environments → SORAHOST (無ければ作る) に次を置く:

種類 名前 必須 どこから取るか
secret SORAHOST_ENDPOINT ✅ PteWorker コンソールの「エンドポイント」
secret SORAHOST_TOKEN ✅ PteWorker コンソールの「デプロイトークン」(token rotate で再発行)

Step 2: Repository variable SORAHOST を T にする

GitHub リポジトリ → Settings → Secrets and variables → Actions → Variables に SORAHOST = T を置く。

T にすると deploy-sorahost.yml が走り、Workers 側の CI が止まる。 F / 未設定では何も起きないので、最初に必ず入れる。

Step 3: 配備する

develop へ push するか、Actions → Deploy SORAHOST を手動実行 (workflow_dispatch)。 build → deploy → smoke の順で流れ、公開 URL が返る。

この時点でアプリは起動しているが、basic 認証のパスワードは自動生成されている (コンソールのログに admin / <生成値> と出る)。

Step 4: (前段にコネクタを置く場合) GitHub に Cloudflare の値を足す

Environment SORAHOST に追加:

全部 secret に置く (外部に見える値なので)。var でも読むが secret を推奨。

種類 名前 必須 値
secret CLOUDFLARE_API_TOKEN ✅ Cloudflare の API トークン (下の権限)
secret CLOUDFLARE_ACCOUNT_ID ✅ アカウント ID (識別子だが外に見せたくないので secret)
secret SORAHOST_PUBLIC_HOSTNAME ✅ 公開ホスト名 (例 narou.example.com)
secret SORAHOST_CONNECTOR_NAME 任意 既定 narou-sorahost
secret SORAHOST_SERVICE_PORT 任意 コネクタの向き先 (既定 18080 = PteWorker の PORT)。NAROU_RS_PORT を変えたときだけ合わせる
secret SORAHOST_ACCESS_EMAIL / _DOMAIN / _SESSION Access を使うときだけ メール / ドメイン / セッション期限 既定24h

API トークンの権限 (My Profile → API Tokens → Create Token → Custom token):

  • アカウント全体のポリシーに Edit で追加 (どれでも可、API リファレンスが 3 併記): Cloudflare One Connectors / Cloudflare One Connector: cloudflared / Cloudflare Tunnel
  • さらに ゾーン スコープのポリシーをもう 1 行: 「ゾーン」→ 対象ドメイン → DNS: Edit と Zone: Read
  • Access を使うならアカウント全体に Access: Apps and Policies: Edit
  • Argo Tunnel (Legacy) は旧版なので選ばない

push すると CI (sorahost/ci/provision_connector.py) が冪等に作る: コネクタ → ingress (<公開ホスト名> → 127.0.0.1:<PORT>) → DNS (CNAME) → Access。

Step 5: サーバーの .env にアプリの値を置く

パネルのファイルマネージャ (または SFTP) で /home/container/.env を作る。 形式は KEY=VALUE の行、# はコメント。start.sh が起動時に読む。

# 前段にコネクタを使うとき (Step 4 をやった場合)
NAROU_CONNECTOR_TOKEN=eyJ...          # Cloudflare で確認 (次で取る)
NAROU_PUBLIC_HOST=narou.example.com   # = GitHub の SORAHOST_PUBLIC_HOSTNAME と同じ

# コネクタを使わず素の公開 URL で運用するとき (basic 認証が必須)
NAROU_WEB_USER=admin
NAROU_WEB_PASSWORD=長いランダム文字列

# 挿絵を S3 へ置く場合 (任意)
NAROU_RS_ASSET_BACKEND=s3
S3_ENDPOINT=https://s3.ap-northeast-1.wasabisys.com
S3_BUCKET=your-bucket
S3_REGION=ap-northeast-1
S3_PREFIX=narou/library
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...

Step 6: コネクタのトークンを取る (Step 4 をやった場合)

Cloudflare ダッシュボード → Networks → Tunnels → 該当のコネクタ → Add a replica で eyJ... のトークンを確認し、.env の NAROU_CONNECTOR_TOKEN に貼る。

このトークンは CI では扱わない (公開リポジトリのログに出さないため)。 必ずダッシュボードから手で .env へ移す。

Step 7: 再起動して確認

パネルで restart (または次の配備) → ログを確認:

  • basic 認証を無効にします (コネクタ使用時) または 一時的なパスワードを設定しました
  • 前段のコネクタを起動しました (向き先 127.0.0.1:18080)
  • 起動します (127.0.0.1:18080 / ライブラリ ...)

疎通:

curl -I https://<公開ホスト名>/          # Access のログイン要求 (コネクタ使用時)
curl http://<IP>:<PORT>/                 # 400 (Host 制限。コネクタ使用時)
curl -u admin:<pw> https://<公開 URL>/api/novels/count   # 素の URL 運用時

一致させる値 (関係性の核心)

同じ値を別の場所に置く必要があるもの。ずれると動かない。

一致させる値 GitHub 側 サーバー .env 側
公開ホスト名 SORAHOST_PUBLIC_HOSTNAME NAROU_PUBLIC_HOST
コネクタのトークン (CI は扱わない) NAROU_CONNECTOR_TOKEN ← ダッシュボードで取る
待受ポート SORAHOST_SERVICE_PORT (コネクタの向き先。既定 18080=PteWorker の PORT) NAROU_RS_PORT (変えたときだけ合わせる)

コンテナの中身

/home/container (= ボリューム直下)
  .env                    ← アプリの設定 (ここを編集)
  sorahost.json           配備の定義 (sorahost/sorahost.json)
  start.sh                起動スクリプト (sorahost.json の start が呼ぶ)
  app/                    実行ファイル + webnovel/ (配備で入れ替わる)
  narou-library/          narou のデータ (配備に含めない)
  bin/                    コネクタ (cloudflared)
  .sorahost/releases/...  配備ごとの実行ファイル
  • アプリは PteWorker が渡す PORT にループバックで束縛する (外部へ直接公開しない)
  • メタデータ・本文はライブラリ内の SQLite (.narou/db.sqlite)、挿絵だけ S3 に置く
  • 公開 URL は PteWorker が発行する (sorahost-cli deploy の url、コンソールの url コマンド)

basic 認証とコネクタの関係

  • コネクタ使用時: basic 認証は自動で切る (Access が認証するので二重になるだけ)。 併用したいときだけ NAROU_WEB_PASSWORD を .env に置く。
  • コネクタなし (素の公開 URL): NAROU_WEB_PASSWORD は必須。未設定だと start.sh がランダムなパスワードを作りコンソールに表示する (そのままでは誰も入れないので、 値を決めたいなら .env に置く)。NAROU_ALLOW_NO_PASSWORD=1 で認証なし起動も可。

環境変数リファレンス

サーバー .env に書く値

変数 必須 何のため 設定する値
NAROU_WEB_PASSWORD ✅ 素の公開。コネクタ使用時は任意 basic 認証 長いランダム文字列
NAROU_WEB_USER 任意 basic 認証のユーザ名 例 admin (既定)
NAROU_ALLOW_NO_PASSWORD 任意 1 で認証なし起動を許可 (コネクタなしのときだけ) 1
NAROU_RS_ASSET_BACKEND S3 を使うときだけ 挿絵の保存先 s3 (未設定 = ローカル保存)
S3_ENDPOINT / S3_REGION / S3_BUCKET / S3_PREFIX S3 を使うときだけ S3 接続先 Wasabi: https://s3.<region>.wasabisys.com 等
S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY S3 を使うときだけ S3 資格情報 ストレージのキー
NAROU_RS_LOGIN_KEY 任意 ログイン Cookie の暗号鍵 (base64) openssl rand -base64 24
NAROU_RS_MIRROR_FILES 任意 0 で 小説データ/ を作らない 通常は未設定
NAROU_RS_SECTION_CACHE 任意 0 で変換キャッシュを作らない 通常は未設定
NAROU_RS_KEEP_TXT 任意 0 で変換済みテキストを残さない (ファイルにも DB にも。EPUB は DL ごとに本文から再変換) 通常は未設定 (start.sh が convert.keep-txt=false)
NAROU_RS_LEGACY_YAML 任意 1 で YAML 管理に戻す 通常は未設定
NAROU_RS_EPUB_ENGINE 任意 EPUB エンジン lite / external / auto
NAROU_RS_APP / NAROU_RS_LIBRARY / NAROU_RS_PORT / NAROU_RS_ENV_FILE 任意 配置・ポート・env パス 通常は未設定 (自動)
NAROU_RELAY / SORAHOST_PROXY_KEY リレー同居時だけ 取得リレーの起動・合言葉 1 / 合言葉
NAROU_CONNECTOR_TOKEN コネクタ使用時だけ コネクタの接続トークン Add a replica の値
NAROU_PUBLIC_HOST コネクタ使用時だけ 公開ホスト名 例 narou.example.com
NAROU_CONNECTOR_TOKEN_FILE 任意 トークンをファイルで渡す場合のパス 既定 $VOLUME_DIR/.connector-token

GitHub Environment SORAHOST に置く値

種類 名前 必須 用途
secret SORAHOST_ENDPOINT ✅ PteWorker のエンドポイント
secret SORAHOST_TOKEN ✅ デプロイトークン
secret SORAHOST_SMOKE_URL 任意 配備後の確認先
secret CLOUDFLARE_API_TOKEN コネクタ使用時だけ 権限は Step 4
secret CLOUDFLARE_ACCOUNT_ID コネクタ使用時だけ アカウント ID
secret SORAHOST_PUBLIC_HOSTNAME コネクタ使用時だけ 公開ホスト名
secret SORAHOST_SERVICE_PORT 任意 コネクタの向き先ポート (既定 18080)
secret SORAHOST_CONNECTOR_NAME 任意 既定 narou-sorahost
secret SORAHOST_ACCESS_EMAIL / _DOMAIN / _SESSION Access を使うときだけ 許可範囲・期限 (24h)

Environment SORAHOST に同名の SORAHOST 変数を置かない (Repository variable の判定と混ざる)。

鍵・資格情報の仕様

値 仕様 作り方
NAROU_WEB_PASSWORD 任意の文字列。空だと basic 認証が無効になる 未設定なら start.sh が 24 文字の英数を自動生成
NAROU_RS_LOGIN_KEY base64。復号後 16 バイト以上。32 バイトはそのまま、16〜31 バイトは SHA-256 で伸長 openssl rand -base64 24
SORAHOST_ENDPOINT URL。パス込みでよい PteWorker コンソール
SORAHOST_TOKEN 不透明な文字列。Authorization: Bearer 同 (token rotate で再発行)
SORAHOST_PROXY_KEY 空でない文字列。完全一致 openssl rand -hex 32

既存ライブラリの移行

手元のライブラリ (.narou + 小説データ) を持って行き、挿絵だけを S3 へ逃がす:

narou setting s3.asset-backend=s3
narou illust s3-push        # dry-run
narou illust s3-push -f     # 実際に写す
narou illust s3-verify      # 突き合わせ

容量

実測 (13 作品・画像主体の Pixiv 作品を含む):

保存先 内容 実測
S3 挿絵のバイナリ 36.8 MB
db.sqlite メタデータ + 本文 (brotli) 79 MB
小説データ/ 本文・raw HTML・変換済み・EPUB 148 MB (挿絵を除く)

start.sh は economy=nosave_diff,nosave_raw / convert.no-epub=true / convert.keep-txt=false / convert.section-cache=false / sqlite.mirror-files=false を初回に入れて容量を抑える (詳細と実測値は sorahost/README.md §6)。

メモリ

実測 (narou web 常駐 ~31 MB、narou convert 長編ピーク ~61 MB、2 本同時 ~120 MB)。 384 MB を推奨 (スパイクは うごイラ APNG 組み立てと大きい EPUB)。256 MB でも通常運用は収まる。

更新

develop に push する (CI が配備) か、手元から:

SORAHOST_ENDPOINT=... SORAHOST_TOKEN=... npx sorahost-cli deploy --yes

self-update は使わない。app/webnovel/*.yaml を差し替えたときも配備で反映される。

CI からの自動配備

SORAHOST が T の間、push / 手動実行で build → deploy → smoke が流れる。 Workers 側の CI は止まる。Worker に戻すときは SORAHOST を F か消す。

Worker の取得リレーと同居させる (任意)

既定は別サーバー。同じサーバーで動かすときだけ .env に NAROU_RELAY=1 を足し、 リレー側の起動コマンドを sh start.sh に寄せる (詳細は sorahost/README.md §10)。

使えない機能

browser / folder / send / mail / 外部 AozoraEpub3 / narou_rs_login (ブラウザのある端末で実行→narou login import で取り込む)。

関連

narou.rs

デプロイ

設定

ソース (リポジトリ)

  • sorahost/README.md
  • docs/cloudflare-workers-migration-plan.md
  • COMMANDS.md / AGENTS.md

Clone this wiki locally