メインコンテンツまでスキップ

Linux(ヘッドレス版)

Linux 版の配布状況

Linux 版は現在ベータ版を配布しています。今すぐ導入する場合は、Debian / Ubuntu 向けのベータ版の手順を使ってください。

このページのインストール用スクリプトと systemd での導入は、Linux 正式版の公開後に使えます。

ヘッドレス版は、自分の画面を持たない Linux 向けの版です。設定と受信の確認は、すべてブラウザーから行います。ブラウザーで開くこの画面を、以下では web console と呼びます。

アンテナのそばに置いたままにする小型の機械に向いています。

対応する環境​

項目条件
機種x86_64 と arm64(Raspberry Pi 4、Raspberry Pi 5 など)
OSglibc 2.35 以降の Linux(Debian 12、Raspberry Pi OS bookworm、Ubuntu 22.04 以降)
サービスの管理systemd
SDR導入にあるものと同じです

Debian / Ubuntu に入れる​

Debian 12 以降、Ubuntu 22.04 以降、または Raspberry Pi OS bookworm の機械で、次のコマンドを実行します。まず、ダウンロードと検証に使うパッケージを入れます。

sudo apt update
sudo apt install -y ca-certificates curl jq minisign

続けて、ヘッドレス版を入れます。

curl -fsSL https://jrd.linux.moe/install-headless.sh | sudo sh

実行には curl と、jq か python3 のどちらかが要ります。どちらも無いときは、sudo apt install jq で jq を入れてからやり直してください。

このコマンドは次のように動きます。

  • この機械の機種(x86_64 か arm64 か)に合う最新版を取り、SHA-256 を照合してから /opt/jrd-receiver に置きます。
  • minisign が入っていれば、アプリの更新と同じ公開鍵で署名も検証します。
  • 専用のユーザー jrd を作ります。
  • systemd にサービス jrd-receiver として登録し、起動します。機械を再起動したあとも自動で起動します。
  • SDR を使うための USB の設定を置きます。

設定と記録は /var/lib/jrd-receiver に置かれます。

終わると、開く URL が表示されます。ブラウザーでの開き方はブラウザーで開くにあります。

待ち受けるホスト​

既定では 127.0.0.1:35262 で待ち受けます。インストール時に --host を指定すると、IP アドレスやホスト名を変えられます。カンマ区切りで複数指定することもできます。

curl -fsSL https://jrd.linux.moe/install-headless.sh | sudo sh -s -- --host 0.0.0.0
curl -fsSL https://jrd.linux.moe/install-headless.sh | sudo sh -s -- --host 127.0.0.1,receiver.local --port 35262
  • 0.0.0.0 はすべての IPv4 インターフェース、:: はすべての IPv6 インターフェースで待ち受けます。
  • ホスト名は、その機械自身のアドレスに名前解決できるものを指定します。起動時に解決し、その名前でのブラウザーアクセスも許可します。
  • 0.0.0.0,127.0.0.1 のように待ち受けが重なる場合は、同じアドレス族のワイルドカードにまとめます。
  • すべての待ち受け先を確保できない場合は起動せず、原因をログに出します。

指定内容は再起動後も使われ、インストールコマンドを再実行するときに引数を省けば引き継がれます。ループバックへ戻すには --host 127.0.0.1 を明示します。ブラウザーを開く際は、待ち受け先の IP アドレスかホスト名を使ってください。

LAN へ待ち受けを広げると、到達できる端末からすべての操作を行えます。組み込みのパスワード認証はないため、信頼できるネットワーク内で使ってください。リバースプロキシの名前だけを許可したい場合は、待ち受けを増やさずに --allow-hostを使います。

USB の設定​

導入のコマンドは、USB の設定として次の 2 つのファイルを置きます。

ファイル役割
/etc/udev/rules.d/60-jrd-receiver.rulesSDR を plugdev グループから読み書きできるようにします。サービスはこのグループの権限で SDR を開きます
/etc/modprobe.d/jrd-receiver-blacklist.confRTL-SDR をテレビ受信用のドライバ(dvb_usb_rtl28xxu)がつかまないようにします。このドライバがつかんでいると、JR-D Receiver から開けません

設定を反映するために、次の操作が要ることがあります。

  • SDR を挿したまま導入した場合は、いったん抜いて挿し直します。
  • ドライバの無効化は、機械を再起動するか、次のコマンドを実行すると反映されます。
sudo rmmod dvb_usb_rtl28xxu

Linux で SDR を使うための設定の詳しい解説は、次の文書にあります。

ブラウザーで開く​

ヘッドレス版は、既定では 127.0.0.1:35262 だけで待ち受けます。そのため、ほかの機械のブラウザーからは、そのままでは届きません。別の端末から開くには、次のどちらかの方法を使います。

SSH のポート転送​

手元の端末で次のコマンドを実行します。

ssh -L 35262:127.0.0.1:35262 <機械>

接続したまま、手元のブラウザーで http://127.0.0.1:35262 を開きます。

Tailscale​

ヘッドレス版を入れた機械で次のコマンドを実行します。

tailscale serve --bg 35262

同じ tailnet に入っている端末のブラウザーで、https://<機械>.<tailnet>.ts.net を開きます。

届く範囲の管理​

JR-D Receiver には、パスワードなどの保護の機能がありません。web console を開けた人は、すべての操作ができます。どの端末から届くようにするかは、利用者が管理してください。詳しくはブラウザーからの確認と操作にあります。

最初の設定​

web console を開いたら、次の順に設定します。

  1. ライセンスを認証します。ヘッドレス版を入れた機械が、端末 1 台として数えられます。
  2. 最初の設定のとおりに、無線機とプリセットを選びます。

フォルダとファイルを選ぶダイアログは、web console では出ません。代わりに、ヘッドレス版を入れた機械の上のパスを入力します。記録の出力先の既定は /var/lib/jrd-receiver/output です。/home と /root の下は、サービスから見えないので指定できません。別のディスクに記録するときは、/mnt や /srv の下に置き、ユーザー jrd が書き込めるようにします。

動作の確認とログ​

サービスが動いているかどうかは、次のコマンドで確かめます。

systemctl status jrd-receiver

ログは systemd の journal に入ります。次のコマンドで、流れてくるログを見られます。

journalctl -u jrd-receiver -f

更新​

更新は、web console の設定画面にある「アップデート」の欄で行います。

  1. 「更新を確認」を押します。新しい版があれば、その版と変更点が表示されます。無ければ「最新の版です」と表示されます。
  2. 「更新して再起動」を押し、確認に答えます。

更新のあいだ、受信は止まります。新しい版を取り、署名を検証してから入れ替え、サービスが新しい版で起動し直します。起動し直すと、web console の画面も自動で読み込み直されます。

ボタンを押すまで、更新の確認も、更新も行いません。

導入のコマンドをもう一度実行しても、最新版に入れ替わります。

curl -fsSL https://jrd.linux.moe/install-headless.sh | sudo sh

アンインストール​

先に、web console の「ライセンス」欄で認証を解除します。解除しておくと、同じライセンスを別の機械で認証できます。

そのあと、次のコマンドを実行します。

curl -fsSL https://jrd.linux.moe/install-headless.sh | sudo sh -s -- --uninstall

このコマンドは、サービス、/opt/jrd-receiver、USB の設定の 2 つのファイルを消します。systemctl edit で足した起動の引数(--allow-host など)も消します。設定と記録(/var/lib/jrd-receiver)と、ユーザー jrd は残ります。

Debian 系以外で手で入れる​

導入のコマンドを使わずに入れるときは、次のものを自分で置きます。

  • バイナリ:配布物を展開すると、jrd-receiverd が 1 つ入っています。配布物の URL は https://jrd.linux.moe/<版>/jrd-receiverd_<版>_linux_<x86_64|aarch64>.tar.gz の形です。
  • systemd のユニットと USB の設定:全文が導入のスクリプト(https://jrd.linux.moe/install-headless.sh)の中にあります。それを写して、USB の設定の表にある場所と /etc/systemd/system/jrd-receiver.service に置きます。
  • 実行するユーザー:ユニットは、ユーザー jrd が plugdev グループの権限で動かす前提で書いてあります。

jrd-receiverd の引数は次のとおりです。

引数内容既定
--listen <アドレス:ポート>単一の IP アドレスとポートを指定する従来の形式です。--host、--port とは併用できません127.0.0.1:35262
--host <ホスト[,ホスト...]>IP アドレスとホスト名をカンマ区切りで指定します。名前解決後に待ち受け、指定したホスト名でのアクセスも許可します127.0.0.1
--port <ポート>--host に共通のポートです35262
--state-dir <パス>設定、ライセンス、自分用のプリセットを置くフォルダです。自分用の対応表は、この下の data/ に置きます(CSV の置き場所)。バイナリに入っている標準のプリセットとデータ表も、起動のたびにこの下の bundled へ書き出します/var/lib/jrd-receiver
--presets-dir <パス>標準のプリセットを、バイナリに入っているものの代わりに、このフォルダから読みます。開発用で、ふつうは指定しませんバイナリに入っているもの
--data-dir <パス>データ表を、バイナリに入っているものの代わりに、このフォルダから読みます。開発用で、ふつうは指定しませんバイナリに入っているもの
--allow-host <名前>web console を開ける名前を足します。何度でも指定できます。使いどころはほかの名前で開くにありますなし
--no-self-updateweb console からの更新を無効にします。「アップデート」の欄は、今の版と、更新の手順の案内だけになります有効

対応表の CSV は、<state-dir>/bundled/data/(同梱)と <state-dir>/data/(自分用)の 2 か所から読み込みます。同梱の側は起動のたびにバイナリから書き出し直すので、編集しないでください。同じ名前の CSV が両方にあるときは、自分用のファイルだけを読みます。CSV に誤りがあると、その CSV の場所(フルパス)と理由をログに出して終了します。書式は対応表 CSVにあります。

Docker で動かす​

Docker のイメージは配っていません。次の Dockerfile を使って、自分でビルドします。

# JR-D Receiver のヘッドレス版を動かすイメージ。配布はしていないので、自分でビルドする。
# docker build -t jrd-receiver packaging/docker
FROM debian:bookworm-slim

ARG JRD_BASE_URL=https://jrd.linux.moe
# 配布物の署名を確かめる minisign の公開鍵(アプリの更新と同じ鍵)
ARG JRD_MINISIGN_PUBKEY=RWRPiQluUsoXOdkDT11Jz1c6EnargPsjU7nL/nPTuItImKkBQNxSKvBp

RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl jq minisign \
&& rm -rf /var/lib/apt/lists/*

# 公開のバイナリを取り、latest.json の SHA-256 と、minisign の署名を確かめてから置く
RUN set -eu; \
case "$(uname -m)" in \
x86_64) platform=headless-linux-x86_64 ;; \
aarch64) platform=headless-linux-aarch64 ;; \
*) echo "対応していない機種です: $(uname -m)" >&2; exit 1 ;; \
esac; \
curl -fsSL "$JRD_BASE_URL/latest.json" -o /tmp/latest.json; \
missing() { echo "配布先($JRD_BASE_URL)の案内に、$platform の配布物がありません。ヘッドレス版がまだ公開されていないか、この機種向けの配布がありません" >&2; exit 1; }; \
url=$(jq -er ".platforms[\"$platform\"].url" /tmp/latest.json) || missing; \
sha256=$(jq -er ".platforms[\"$platform\"].sha256" /tmp/latest.json) || missing; \
signature=$(jq -er ".platforms[\"$platform\"].signature" /tmp/latest.json) || missing; \
curl -fsSL "$url" -o /tmp/jrd.tar.gz; \
echo "$sha256 /tmp/jrd.tar.gz" | sha256sum -c -; \
printf "%s" "$signature" | base64 -d > /tmp/jrd.tar.gz.sig; \
minisign -Vq -P "$JRD_MINISIGN_PUBKEY" -m /tmp/jrd.tar.gz -x /tmp/jrd.tar.gz.sig; \
mkdir -p /opt/jrd-receiver; \
tar -xzf /tmp/jrd.tar.gz -C /opt/jrd-receiver jrd-receiverd; \
rm /tmp/latest.json /tmp/jrd.tar.gz /tmp/jrd.tar.gz.sig

VOLUME /var/lib/jrd-receiver
EXPOSE 35262

# コンテナの中では全アドレスで待ち受け、外への公開は docker run の -p 127.0.0.1:35262:35262 で絞る。
# 更新はイメージの作り直しで行うので、自己更新は切る。
ENTRYPOINT ["/opt/jrd-receiver/jrd-receiverd", "--listen", "0.0.0.0:35262", "--state-dir", "/var/lib/jrd-receiver", "--no-self-update"]

この内容を Dockerfile という名前で保存し、同じフォルダで次のコマンドを実行します。

docker build -t jrd-receiver .

起動は次のコマンドで行います。

docker run -d --name jrd-receiver --restart unless-stopped \
--device /dev/bus/usb \
-v /etc/machine-id:/etc/machine-id:ro \
-v jrd-data:/var/lib/jrd-receiver \
-p 127.0.0.1:35262:35262 \
jrd-receiver
指定意味
--device /dev/bus/usbSDR をコンテナに渡します
-v /etc/machine-id:/etc/machine-id:roライセンスが端末を見分けるのに使います。渡さないと、コンテナを作り直すたびに別の端末として数えられ、台数の上限に達します
-v jrd-data:/var/lib/jrd-receiver設定、ライセンス、記録を、コンテナを作り直しても残します
-p 127.0.0.1:35262:35262ホストの 127.0.0.1 にだけ出します。-p 35262:35262 と書くと、LAN の全体から届くようになります

テレビ受信用のドライバの無効化は、ホストに置きます。ホストに次のファイルを作り、USB の設定と同じ方法で反映します。コンテナは root で動くので、udev の規則は要りません。

/etc/modprobe.d/jrd-receiver-blacklist.conf
blacklist dvb_usb_rtl28xxu

SDR の挿し直しと更新の手順も、導入のコマンドで入れた場合と違います。

  • SDR の挿し直し:SDR を挿し直したら、docker restart jrd-receiver でコンテナを再起動します。--device /dev/bus/usb が渡すのは、起動した時点のデバイスの並びだからです。
  • 更新:web console に更新のボタンは出ません。docker build --no-cache -t jrd-receiver . でイメージを作り直し、コンテナを作り直します。