NAS でゼロから作る Transmission
下の動画は、まだ何も設定していない NAS で Bucket & Code Server IDE 1.0.0-55 を実際に動かした記録です。最初の起動画面から始まり、QTS パッケージ Transmission が署名・インストールされてブラウザーで応答し、同じパッケージの arm_64 ビルドをダウンロードするところで終わります。このガイドでは動画を章ごとにたどり、操作する人が何をするか、画面に何が表示されるか、スクリプトが何を確認するかを説明します。
- 準備モジュール、環境、ランタイム
- プロジェクトソースからのパッケージ
- レシピ5 つ、ゲート、サービス
- ビルドアプリ 2 つ、make qpkg
- インストール署名、テストデプロイ、arm_64
画像は、パネルとエディターから取った実行中のコマです。概要のタイルだけはバージョン 1.0.0-62 のものです。NAS のアドレスと名前はすべてのコマでマスクされ、nas.local と NAS と表示されます。
01動画の内容と必要なもの
実行には 25 分 7 秒かかり、動画は 6:26 です。10 秒を超える待ち時間は途中を省き、省いた箇所に実際の待ち時間を表示します。クリックのない状態が 10 秒を超えて続く区間は 4 倍速で再生し、4× と表示します。
スクリプトがブラウザーを操作します。パネルをクリックして進み、完成したプロジェクトの各ファイルをエディターに入力し、次へ進む前にパネルの API で各ステップを確認します。パネル、エディター、ビルド、パッケージは本物です。完成したプロジェクトは、アプリページの 例 タブの エディター用プロジェクト にある例 Transmission (BitTorrent client, own recipes) で、コードを見る でそのファイルを確認できます。
- Bucket & Code Server IDE 1.0.0-55 以降が入った、x86_64 プロセッサーの NAS。arm_64 パッケージは、その NAS 上でクロスビルドします。
- パネルの管理者アカウント。新規インストールでは、最初の起動画面で作成されます。
- NAS のインターネット接続。ビルド環境のルートファイルシステム、ツールチェーン、レシピのソースをダウンロードし、各ダウンロードを sha256 で確認します。
- 署名済みのパッケージを作る場合は、QNAP から自分に発行されたコード署名証明書 (セクション 07)。
02最初のセットアップ
動画 0:00 · 実行 4 秒
新規インストールにはアカウントがないため、パネルを開くと、アカウント administrator の 管理者パスワードを設定 画面だけが表示されます。10 文字以上のパスワードを 2 回入力し、パスワードを設定してサインイン を押します。この画面は、パッケージの起動から 60 分間、ローカルネットワークからのみパスワードを受け付けます。
スクリプトは、パネルが administrator としてサインインしていて、最初の管理者をもう求めないことを確認します。
03モジュール、環境、Go、Python、QDK
動画 0:06 · 実行 59 秒
概要ページは各モジュールをタイルで表示し、新規インストールで動いているのはコアだけです。Git (Forgejo) とエディター (ブラウザー上の VS Code) をスイッチでオンにし、両方のタイルに 実行中 と表示されるまで待ちます。パネルの各アカウントには同名の Forgejo アカウントがあるため、新しいプロジェクトのウィザードでは、リポジトリの所有者として administrator を選べるようになります。
ツールチェーンページの環境の一覧は空で、Ubuntu 24.04 builder を作るボタン この環境を作成 だけがあります。環境 ubuntu2404-builder は 22 秒後にできます。その下のカタログで インストール を押すと、Go 1.27 と Python 3.13 (ランタイム タブ)、QNAP QDK 2.5.0 (QNAP タブ) が加わります。Go はプロジェクトのゲートをビルドし、Python は Web インターフェースのベンダーリストを書くツールを実行し、QDK は QTS パッケージを作ります。
スクリプトは、Git とエディターが実行中であること、ubuntu2404-builder が環境の一覧にあること、go-1.27-x86_64、python-3.13-x86_64、qdk-2.5.0-x86_64 がインストールされていることを確認します。
04新しいプロジェクト
動画 0:52 · 実行 24 秒
プロジェクトページで 新しいプロジェクト を押すと、最初にテンプレートを選ぶよう求められます。ソースからのパッケージ を選び、プロジェクトに Transmission と名前を付けます。この名前がパッケージ名になります。サービスのステップでは Web アプリ を選びます。Web ポートと App Center の「開く」ボタンを備えたバックグラウンドサービスです。ビルドのステップでは環境を選びません。プロジェクトの Makefile の ENV 行が、2 つのアプリに Ubuntu 24.04 builder を指定します。作成後すぐにビルド はオフのままにします。スターターレシピはまだ仮のソースを指しており、最初のビルドは失敗するためです。プロジェクトを作成 を押すと、最初のコミット付きの Forgejo リポジトリができます。
エディターで開く を押すと、プロジェクトがエディターで開きます。フォルダーには recipes/transmission/ (スターターレシピ)、recipes.txt、2 つのアプリ用の Makefile、licenses.txt、qpkg/、scripts/ があります。スクリプトは、プロジェクトのパイプラインにアプリ transmission と transmission-arm64 が並ぶこと、エクスプローラーに recipes が表示されることを確認します。
05レシピ
動画 1:18 · 実行 12 分 12 秒
ライブラリには Transmission とその Web インターフェースのレシピがないため、プロジェクトの recipes/ には独自のレシピが 5 つあります。レシピごとにフォルダーがあり、その中に recipe.json と build.sh があります。5 つは、この 2 つと、libnatpmp、miniupnpc、libdeflate です。後の 3 つはライブラリにもありますが、プロジェクトのアプリでは、ライブラリのものの代わりにプロジェクトのコピーが使われます。curl、OpenSSL、zlib、libevent はライブラリのものを使います。2 つのファイルについては はじめての自作レシピ で説明しています。
スターターレシピ · 14 秒
recipes/transmission/recipe.json には、Transmission 4.1.3 のリリースアーカイブとその sha256、必要なレシピ (curl、OpenSSL、zlib、libevent、libnatpmp、miniupnpc、libdeflate)、静的リンク、チェックが入ります。build.sh は、テスト、翻訳、ドキュメントをオフにして、デーモンと transmission-remote、transmission-create、transmission-edit、transmission-show のために CMake を実行します。
さらに 4 つのレシピ · 1 分 17 秒
コマンドパレットで Bucket: New recipe を実行すると、名前を尋ねられ、スターターから 2 つのファイルが書き出されます。スクリプトはこの方法で libnatpmp 20230423、miniupnpc 2.3.3、libdeflate 1.26、transmission-web 4.1.3 を作り、それぞれにソース、sha256、ビルド手順を書き込みます。Transmission は 3 つのライブラリを静的アーカイブとしてリンクします。Web インターフェースは HTML、CSS、JavaScript で、同じリリースアーカイブの web/ からビルドされます。
ベンダーリスト · 1 分 7 秒
Web インターフェースは esbuild と Sass でビルドされ、recipes/transmission-web/vendor.txt がその npm パッケージを固定します。1 パッケージにつき、sha256、アドレス、配置先の 1 行です。このファイルは、エディターのターミナルで、リリースの package-lock.json から書き出します。ツールは 30 files: 30 checked against the lockfile's sha512 と報告します。完成したファイルは 41 行で、そのうち 11 行はコメントです。
eval "$(bvs use python-3.13-x86_64)" python3 /usr/bin/bucketvs/share/bucketvs/tools/npm-vendor.py package-lock.json CACHE-DIR \ --dev --roots esbuild esbuild-sass-plugin fast-deep-equal \ --platform linux-x64-glibc --platform linux-arm64-glibc --allow-install-scripts \ > recipes/transmission-web/vendor.txt
build.sh にはファイル全体の sha256 が書かれており、ビルドは各パッケージを展開する前にもう一度確認します。npm は実行されず、インストールスクリプトも実行されません。
レシピの一覧、ゲート、スクリプト、ライセンス、アイコン · 6 分 38 秒
recipes.txt は 2 つのアプリがビルドするもの、つまり transmission、transmission-web、cacert を挙げます。cacert は、curl が HTTPS トラッカーを検証する CA バンドルです。それぞれに必要なものは App Builder が追加します。
gate/ には trgate があります。外部モジュールを使わない Go のプログラムです。Transmission の初期設定にはパスワードがなく、RPC の呼び出しは NAS 自身からしか受け付けません。パスワードなしでネットワークに開くと、ポート 9091 に届く誰にでも応答してしまいます。そのためパッケージは、パスワードを選んだあとにだけ transmission-daemon を起動します。trgate は、まずそのポートで設定ページを表示します。パスワードを Transmission が保存するのと同じソルト付きの形式で書き込んでから、同じポートでデーモンを起動します。パッケージはパスワードを生成しないため、ファイルにも QTS のシステムログにもパスワードは書かれません。
scripts/make-qpkg.sh はテンプレートのパッカーで、3 か所が埋められています。KEEP (パッケージが各アプリから取るパス)、own_programs (各アーキテクチャー向けに trgate をビルドする)、own_licences (licenses.txt では入れられないライセンス文書を加える) です。licenses.txt はパッケージに含まれる各レシピのライセンスを挙げ、LICENSE はプロジェクト自身のコードのライセンスです。スクリプトはこの 10 個のファイルを入力します。qpkg/icons/ の 3 つのアイコンは、エクスプローラーでそのフォルダーに Upload... を使って入れます。
サービス · 40 秒
プロジェクトビューの サービスとパッケージ カードには、パッケージの起動・停止スクリプトを書くブロックと qpkg.cfg のキーがあります。Web アプリのプリセットから始めて、スクリプトが仕上げたブロックは 9 つです。ボリューム上のデータフォルダー Transmission、そのフォルダーを所有するグループ arr のアカウント transmission (モード 700)、Web ポート 9091、そのアカウントで動くデーモン trgate (停止の待ち時間 40 秒)、ポート 9091 の待機、ログ行、そしてステータスチェックの running と port_open です。パッケージ タブでは、表示名 Transmission、バージョン 4.1.3、Web ページのパス /transmission/web/、Web ポート 9091、QTS が起動時と停止時に待つ 60 秒を設定します。保存 を押すと各ファイルの diff を含む計画が表示され、コミット でコミットします。
チェック · 30 秒
保存のたびにプロジェクトのレシピが検査され、結果が 問題 ビューに一覧表示されます。スクリプトは No problems have been detected in the workspace を待ち、その後、プロジェクトのレポートには 5 つのレシピが並び、エラーは 0 件です。make lint はターミナルで同じ結果を返します。
コミットとプッシュ · 1 分 42 秒
ソース管理でスクリプトはすべての変更をステージし、Transmission from source としてコミットし、プッシュします。プロジェクトのリモートは HTTPS 経由の Forgejo リポジトリなので、エディターはアカウントの名前とパスワードを尋ねます。これはパネルと Forgejo で共通です。スクリプトは、未コミットのものがなく、リモートより進んだものもなくなるまで待ち、3 つのアイコンを Forgejo から読み戻して、プロジェクトのものとバイト単位で比較します。
06ビルドと make qpkg
動画 5:13 · 実行 10 分 1 秒
プロジェクトビューの ビルド は、プロジェクトの Makefile を実行します。2 つのアプリを Ubuntu 24.04 builder で順に、どちらも静的にビルドします。この NAS の x86_64 プロセッサー向けの transmission と、aarch64 向けの transmission-arm64 (クロスビルド) です。各アプリは 13 個のレシピを依存関係の順にビルドします。ライブラリから cacert、OpenSSL、zlib、nghttp2、zstd、c-ares、curl、libevent、続いてプロジェクトから libnatpmp、miniupnpc、libdeflate、transmission、transmission-web です。これには 8 分 1 秒かかりました。クロスビルドのチェックは qemu-user が登録されている環境でのみ実行され、それ以外ではビルドが未実行として記録します。スクリプトは、両アプリの最新のビルドが完了していて、プロジェクト Transmission を指していることを確認します。
パッケージはエディターのターミナルで、プロジェクトのフォルダー内で作ります (2 分 0 秒)。make qpkg は各アーキテクチャー向けに trgate をビルドするため、Go がパスに必要です:
eval "$(bvs use go-1.27-x86_64)" make qpkg
make qpkg は、各アプリの成功した最新のビルドを QDK でパッケージ化し、Transmission_4.1.3_x86_64.qpkg と Transmission_4.1.3_arm_64.qpkg を build/qpkg/build/ に書き出します。それぞれ約 30 MB です。パッケージには、Transmission の 5 つのプログラム、trgate、Web インターフェース、CA バンドル、ビルドがすべてのパッケージに加える BusyBox、そして NOTICE と各コンポーネントのライセンス文書を含む share/licenses/ が入ります。
07署名
動画にはありません · 実行 3 秒
これはパネルの外で行う唯一のステップです。テストデプロイは署名済みのパッケージだけをインストールし、App Center の署名チェックを決して省略しません。この実行の NAS にはコード署名用のファイルがないため、make qpkg は両方のパッケージを署名なしでビルドしました。スクリプトはパッケージを、QNAP がこのガイドの著者に発行したコード署名証明書を持つコンピューターにコピーし、そこで QDK の qbuild で署名し、署名を確認して、パッケージを build/qpkg/build/ にコピーし戻します。証明書とその秘密鍵が NAS に渡ることはありません。その後、バージョンの一覧で、両方のパッケージが署名済みと表示されます。
署名には自分の証明書を使います。certificate と private_key、チェーン用の ca_certs を、qpkg/qpkg.cfg の隣、または QPKG_CERT_DIR が指すフォルダーに置くと、make qpkg がパッケージに自分で署名します。テンプレートの .gitignore は、これらのファイルを git に入れません。これらがないとパッケージは署名なしになり、テストデプロイは受け付けません。署名なしのパッケージを NAS でどう扱うかは、NAS の所有者が App Center で決めることです。このガイドは、署名なしのパッケージのインストールを勧めません。
08テストデプロイと最初のサインイン
動画 5:53 · 実行 32 秒
プロジェクトのページの テストデプロイ (管理者用) は、App Center がファイルをインストールするのと同じ方法で、x86_64 パッケージを qpkg_cli でこの NAS にインストールします。ジョブは、App Center が確認するまで待ちます。パッケージは、この NAS から削除 または App Center で削除するまでインストールされたままです。ジョブには 18 秒かかりました。
http://<NAS>:9091/ を開くか、App Center の「開く」を押します。ゲートのページ Choose the web interface password が、ユーザー名 (変更しなければ admin) と、8 文字以上のパスワードを 2 回尋ねます。Start Transmission を押します。ページが Transmission の起動中であることを表示し、続いて transmission-daemon がポートを引き継いで、ブラウザーが選んだユーザー名とパスワードを尋ねます。ページがそれらを受け付けるのは、パッケージの起動から 60 分間で、NAS 自身のネットワーク内のコンピューターから、NAS の IP アドレスまたはその名前で開いた場合に限られます。
サインインすると、ブラウザーには転送のない Transmission の Web インターフェースが表示されます。スクリプトは、ページのタイトルが Transmission Web Interface であること、RPC がバージョン 4.1.3 (838877323f) を返すことを確認します。
09arm_64 パッケージ
動画 6:20 · 実行 23 秒
バージョン の一覧の arm_64 の行を右クリックするとメニューが開き、ダウンロード で Transmission_4.1.3_arm_64.qpkg (30,290,058 バイト) を保存します。スクリプトは、ファイルのサイズを一覧のサイズと比較します。
x86_64 の NAS はこのパッケージを実行できないため、スクリプトはエミュレーションで確認します。scripts/qemu-test.sh は、qemu-user が登録された Linux コンピューターでダウンロードしたファイルを展開し、そこで実行します。22 件のチェックはすべて 19 秒で成功します:
- プログラムは静的な AArch64 実行ファイルで、BusyBox と transmission-daemon が動く。
- ゲートが設定ページを返し、パスワードが設定されるまで transmission-daemon は動かず、ページのヘッダーがない POST は拒否される (403)。
- 設定後に RPC が応答し、
session-getがバージョン 4.1.3 を返し、誤ったパスワードは拒否され (401)、Web インターフェースが応答し、出力にもsettings.jsonにもパスワードは含まれない。 - transmission-daemon が Debian の netinst の
.torrentを HTTPS で取得する。これにはパッケージの CA バンドルが必要で、そのあとトレントは削除される。 - ゲートへの TERM で transmission-daemon が終了し、ゲートは 0 で終了する。
この実行では、パッケージを ARM の NAS では動かしていません。
10関連ガイド
- はじめての自作レシピ では、小さなプログラム cmatrix を例に、スターターレシピ、チェック、
make qpkgをたどります。 - 自作レシピによるカスタムアプリ では、ライブラリのレシピに加えてプロジェクトのレシピも使う App Builder アプリを作ります。
- App Center の Transmission は公開済みの例です。その x86_64 パッケージは、同じスクリプトを 1.0.0-55 で以前に実行したときのもので、SHA-256 はそのページにあります。
- Bucket & Code Server IDE の ユーザーガイド は、新しいプロジェクト、プロジェクトビュー、ツールチェーン、App Builder、パッケージのコード署名を説明しています。