signage-jetson¶
セットアップスクリプト群¶
本スクリプト群は、Raspberry Pi(Ubuntu)/ NVIDIA Jetson(L4T/Ubuntu) を対象に、端末を サイネージ専用デバイスとして立ち上げるための一連の手順を自動化します。
ネットワーク基盤の統一、アプリ導入と常駐化、AP フォールバック、更新基盤、推論ランタイム、キオスク起動、電源・権限周りまでを 冪等(何度でも再実行可) に整えます。
1) 目的¶
- 即戦力のサイネージ端末化:起動=表示・配信可能な状態(Openbox+Chromium キオスク、Nginx リバースプロキシ、Node サーバ)
- 運用の安定化:systemd-networkd への統一、Wi-Fi 命名・経路メトリック固定、AP 自動化、ログ永続化、UFW 設定
- 保守性の確保:
signage-update.serviceによる更新/復旧、メトリクス送出、パッチマーカーで適用状態を可視化
2) 設計方針¶
- ボード自動判別(Jetson / Pi)+安全スキップ(対象外処理は実行しない)
- 冪等性(差分適用・上書き条件判定・再実行耐性)
- 最小権限(機密は
/etc/signage/secret.env600、sudoers は限定コマンドのみ) - 分割フェーズ:詳細は、下部5)に記載
3) 前提¶
- OS: Ubuntu 系(Jetson L4T/Ubuntu、Ubuntu for Raspberry Pi)
- 必須変数:
DEVICE_ID,BOARD_TYPE,GH_TOKEN,AWS_*(/etc/signage/*.envに配置)
4) 実行ガイド¶
4-1. 初回の配置(releases/initial)¶
sudo mkdir -p /opt/signage-core/signage-jetson/releases
sudo chown -R "$USER:$USER" /opt/signage-core
cd /opt/signage-core/signage-jetson/releases
# signage-jetsonリポのクローン
git clone https://github.com/<your-org-or-user>/signage-jetson.git initial
cd initial
4-2. 一括セットアップの実行(setup_all.sh)¶
setup_all.sh は scripts/setup/ の nnn_*.sh を 番号順に実行します。000 のみ 次の 5 必須引数(DEVICE_ID, BOARD_TYPE, GH_TOKEN, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)と、6つ目の任意引数 [ASSUME_ROLE_ARN] を受け取ります。
(000_*.sh は if [ $# -lt 5 ]; then ... exit 1 で必須引数数を検証。ASSUME_ROLE_ARN は 引数 > 環境変数 > sample > 既定値 の優先度で解決されます)
- 事前検証:5 つの必須引数(下記)を起動直後に検証(未設定で即エラー)
sudo bash setup_all.sh \
<DEVICE_ID> \
<BOARD_TYPE> \
<GH_TOKEN> \
<AWS_ACCESS_KEY_ID> \
<AWS_SECRET_ACCESS_KEY> \
[ASSUME_ROLE_ARN]
# 例(任意引数なし:自動解決)
sudo bash setup_all.sh \
XIG-JON-000 \
jetsonorinnano \
ghp_xxxxxxxxxxxxxxxxxxxxx \
AKIAxxxxxxxxxxxxxxxx \
wJalrXUtnFEMI/K7MDENG/bPxRfiCYxxxxxxxx
# 例(任意引数あり:明示指定)
sudo bash setup_all.sh \
XIG-JON-000 \
jetsonorinnano \
ghp_xxxxxxxxxxxxxxxxxxxxx \
AKIAxxxxxxxxxxxxxxxx \
wJalrXUtnFEMI/K7MDENG/bPxRfiCYxxxxxxxx \
arn:aws:iam::123456789012:role/iot-provisioner-role
注意
- ネットワーク統一/AP 構成の適用中は SSH が切断される可能性があります。可能ならローカルコンソールで実行してください。
- すべて 冪等(再実行可) です。失敗時も同じ手順で再実行できます。
releases/initialの命名は後続スクリプト(例:090_symlink_initial.sh)の前提です。
4-3. 引数の意味¶
| 引数 | 例 | 説明 |
|---|---|---|
DEVICE_ID |
XIG-JON-000 |
端末識別子(監視・ログ・ホスト名整合に使用) |
BOARD_TYPE |
jetsonorinnano/raspberrypi4 |
ボード種別(Jetson / Pi の分岐・最適化) |
GH_TOKEN |
ghp_xxx... |
GitHub PAT(Releases 取得・検証に使用) |
AWS_ACCESS_KEY_ID |
AKIA... |
AWS アクセスキー ID |
AWS_SECRET_ACCESS_KEY |
wJalrXUtnF... |
AWS シークレットアクセスキー(機密) |
ASSUME_ROLE_ARN(任意) |
arn:aws:iam::123456789012:role/iot-provisioner-role |
任意引数。未指定時は 引数 > 環境変数 > signage.env.sample > 既定値 の順で解決し、/etc/signage/signage.env に出力(STEP 000 / 111)。 |
4-4. 依存パッケージ( deps )¶
セットアップスクリプトは deps/ 配下のリストを読み取り、APT / pip の依存を一括導入します。
1 行 1 パッケージ(# 以降はコメント)、共通は pip-common.txt、機種別は Jetson/Raspberry Pi 用に分離。
deps/apt-packages.txt… OS パッケージ(apt-get install対象)deps/pip-common.txt… すべての端末で共通の Python パッケージdeps/pip-jetson.txt… Jetson 専用の Python 追加分(CUDA/NVIDIA 周辺など)deps/pip-raspi.txt… Raspberry Pi 専用の Python 追加分(軽量版やARM最適化など)
5) 各ユニットドキュメントの詳細¶
デバイス識別子・資格情報の配置、Wi-Fi 名称の安定化(wlanINT/wlanUSB)と経路メトリックによる主従切替、journald の永続化、AWS CLI / Fluent Bit の最小構成など、運用前に必要な初期化を 冪等(再実行可)なスクリプト群として提供します。Jetson / Raspberry Pi を自動判別し、不要処理は安全にスキップします。
Node.js の指定バージョン導入(見つからない場合は 20.x へフォールバック)、signage-server / signage-admin-ui を GitHub Releases から取得・SHA256 検証・タイムスタンプ展開(releases/<TIMESTAMP>)・current 切替、(Raspberry Pi 以外での)xignage-edge-detection 導入、xignage-metrics の配置・依存導入・systemd 常駐化、さらに AWS IoT 証明書の安全配置と metrics.env 更新・サービス再起動による反映までを 冪等(再実行可)なスクリプト群として提供します。ボード種別に応じて不要処理は安全にスキップします。
加えて、インターホン機能として STEP 106 で呼び鈴ボタンの常駐サービス(call-button.service)を導入し、STEP 111/112 でイベント送信用の証明書配置と events.env 生成・必要時のサービス再読み込みを行います。
ネットワーク管理を systemd-networkd に統一(競合サービス無効化+eth0 の netplan 適用)、AP モード(hostapd/dnsmasq)の冪等構成、Wi-Fi 接続失敗時の AP 自動起動(oneshot+timer)、ブラウザからの Wi-Fi 設定 GUI 配備、そして 起動最適化(snapd の長期 hold+ソケット起動化/不要サービスのマスク/fstrim タイマー/Raspberry Pi の Bluetooth HCI 無効化)をカバーします。すべて 冪等(再実行可)で、ボード種別や構成に応じて不要処理は安全にスキップします(ネットワーク切替時の一時断に留意)。
update_runner / update_manager / healthcheck の配置と oneshot ユニット signage-update.service による更新実行、Jetson 向け TensorRT/PyCUDA/OpenCV 最小ランタイム導入(Pi は自動スキップ)、コンテンツ格納ディレクトリ整備・linger 有効化・ホスト名設定+mDNS・systemd --user での Node サービス起動、PORT=3001 の drop-in 上書き、Nginx vhost(:3000 → 127.0.0.1:3001//admin 静的配信//socket.io WS//api REST)、および UFW 許可ルールの適用までをカバーします。すべて 冪等(再実行可)で、ボード種別や構成に応じて不要処理は安全にスキップします。
Jetson の extlinux.conf/Raspberry Pi の config.txt・cmdline.txt を調整して起動ログ/スプラッシュを抑制し、tty1 自動ログイン → Openbox + Chromium の キオスク起動(Jetson は Xorg の回転・解像度、Pi は KMS オーバレイ)を設定、GDM を停止します。音声は HDMI を既定 sink に固定。Pi 向けに ブートローダ電源設定(halt で電源断/GPIO wake) と GPIO18 の電源断制御を提供。運用用に sudoers ドロップイン(電源・更新・Wi-Fi リセット)を最小権限で追加し、適用済みパッチ識別の パッチマーカー も生成します。すべて 冪等(再実行可)で、ボード判定により不要処理は安全にスキップします(自動ログインのセキュリティに注意)。
Raspberry Pi ベースイメージ¶
Raspberry Pi 向けの OSベースイメージ(SDカードイメージ) と
対応する signage-jetson タグ・S3 パスの一覧は以下にまとめています。
IO(ボタン/ToF/イベント)¶
物理ボタンのデバウンスとLED制御、ToF の mm 正規化を含む距離読取、AWS IoT への MQTT/TLS 送信、および常駐アプリ(50Hz ループ/スナップショット io_state.json/イベントログ JSONL)の仕様を集約。
実装は BCM 番号を優先(後方互換で BOARD 変数も受理)。
メトリクス送信サービス(metrics)¶
端末の温度/電圧/スロットルなどのメトリクスを 30 秒間隔で AWS IoT Core (MQTTS) へ送信するサービス。
boards/pi.js / boards/jetson.js / boards/generic.js による ボード別取得に対応し、xignage-metrics.service から実行。
- トピック:
xignage/metrics/<device> - 必須環境変数:
IOT_ENDPOINT,IOT_CERT_PATH,IOT_KEY_PATH,IOT_CA_PATH - 任意:
BOARD_TYPE=jetson|pi(自動判定の上書き) - 依存: Node.js v22、
mqtt,yargs
前提となる証明書の用意は ↓
インフラ(AWS IoT 証明書)¶
AWS IoT デバイス単位のプロビジョニング —
create_device_thing.sh+get_iot_creds.sh
開発機で Thing/証明書/ポリシー付与をデバイス単位で行い、/tmp/aws-iot-certs に出力 → 端末側の 112_write_events_iot_env.sh が安全配置します。
ランタイムツール (scripts/bin/) / update.sh¶
サイネージ稼働中に動く実行バイナリの要点をまとめます。詳細は各ページへ。
| 区分 | スクリプト | 概要 | 主な連携/ログ |
|---|---|---|---|
| Wi-Fi/AP | wifi_or_ap |
STA 接続試行 → 失敗で AP へフォールバック。優先 IF の順序付け・疎通/ゲートウェイ検証・/run/ap_hold 管理を実施。 |
wifi-or-ap.service/.timer、$WIFI_OR_AP_LOG |
| Wi-Fi/AP | ap_start |
指定 IF に静的 IP を設定し、dnsmasq と hostapd を起動して AP を立ち上げ。 |
dnsmasq / hostapd、$AP_START_LOG_FILE |
| 更新 | update_manager |
signage-update.service から起動。GUI停止 → ランナー実行 → /tmp/update_done 待機 → 再起動。 |
/var/log/update_manager/…(30日ローテ) |
| 更新 | update_runner |
NTP同期確認 → パッチ適用 → signage-jetson TAR ステージング・切替・世代保持 → 完了シグナル。 |
$UPDATE_RUNNER_LOG(例:/var/log/update_runner/update_runner_*.log) |
| 更新 | update.sh |
アプリ単体更新(signage-server / signage-admin-ui / Jetson では xignage-edge-detection)。staging → current 切替、失敗時即ロールバック。 |
$UPDATE_SCRIPT_LOG、download_with_retry、health(200) |
| 更新 | healthcheck |
必須ファイル存在と Bash/Python 構文をトップレベルで検査。OK で 0。 |
journalctl(各サービスの稼働確認の補助) |
起動時 Wi-Fi/AP → Wi-Fi ブートツール¶
起動後に 既知 Wi-Fi へ接続を試行し、失敗時は AP へ自動フォールバックします。
実行フロー(安定接続のための自動切替)
1) 起動後 30s(以降 5分間隔)で wifi-or-ap.service が実行
2) 既知 SSID へ STA 接続を試行(IF 準備 → wpa_supplicant 起動)
3) ルート/GW/疎通(任意で PING_TARGET)が OK なら 運用続行
4) 失敗時は AP 起動(静的 IP 付与 → dnsmasq/hostapd 起動)
5) /run/ap_hold により 再試行を一定時間抑制(フラップ防止)
更新サブシステム → アップデートツール¶
端末のキオスク動作を止めずに OTA を段階実行し、ヘルスチェックとロールバックで可用性を担保します。
実行フロー(安全な段階更新)
1) GUI停止 & /tmp/UPDATING 設置
2) update_runner 起動(NTP確認 → パッチ適用 → TAR展開)
3) ヘルスチェック OK なら current 切替(NG はロールバック)
4) /tmp/update_done で完了通知 → 再起動
パッチとマイグレーション (patches / migrations)¶
patches / migrations 内のスクリプトは、update_runner 内での更新処理の中で順に実行されます。
各ディレクトリのパスや管理ファイルの場所(例:PATCH_DIR, MIGRATIONS_DIR, PATCH_MARK など)は scripts/lib/config.sh で設定されます。
patches:時系列パッチ(厳格な順次実行 & 途中停止)
- 目的:OS/ランタイム/依存ツールの導入・設定など、一度きり実行すべき更新を順序どおり適用。
- 命名規則:
yyyymmdd_hhmmss_<内容>.sh - 実行順:ファイル名の 日時で昇順 に必ず順に実行。
- 状態管理:成功した最後のファイル名を
PATCH_MARKに記録。次回は 記録より新しいものだけ 実行。 - 失敗時挙動:エラー発生時点で停止(それ以前の適用結果は有効)。以降のパッチは実行しない。
migrations:番号付き移行(番号順に続行 & 成功を .done で記録)
- 目的:アプリのデータ移行・設定生成など、何度でも呼べるが成功は一度でよい処理を番号順に適用。
- 命名規則:
<num/3桁>_<内容>.sh - 実行順:3桁番号の昇順で実行。
- 状態管理:成功したスクリプトと同名で
.doneフラグファイル を 同ディレクトリに生成。.doneが存在するものは スキップ。 - 戻り値の扱い:
0=OK,11=skipは成功扱い・.done作成(skip 時は実装方針に応じて作成しない運用も可)。
それ以外の非 0 は失敗としてログ記録するが、次の番号へ続行。
命名が実行順・再実行制御のすべて
patchesは 日時、migrationsは 3桁番号 がそのまま実行順となります。
命名ブレは予期せぬ順序や 未実行/多重実行 の原因になるため、正規表現に合致するか CI で検査すると安全です。
例:
patches:^\d{8}_\d{6}_[a-z0-9_-]+\.sh$
migrations:^\d{3}_[a-z0-9_-]+\.sh$
共通ライブラリ(config.sh / functions.sh)¶
すべてのセットアップ/ランタイムスクリプトで共有する 既定値と環境変数を一元管理。ボード種別、ディレクトリ、ネットワーク/AP、Nginx、GStreamer、キオスク設定などの基準値を提供します。
スクリプト共通の ヘルパー関数群。log_info/warn/error(ログ)、install_or_link(シンボリックリンク配置・退避)、download_with_retry(リトライ付き取得)などを収録。