🌊

Docker/PodmanでのChromium拡張nos2xのビルド

2024/12/06に公開

これは「Nostr」のアドベントカレンダー12/6用に書いた記事です。

https://adventar.org/calendars/10004

前日の12/5はhassaku tachibana (atasinti)さんの絵で振り返るNostr2024年、次の12/7は薄味のキャルピスさんのNostrで過ごした2024年(総評) - 仮称となっています。

絵で振り返るNostr2024年
https://yakihonne.com/article/naddr1qvzqqqr4gupzpc9ge0t4a0lya7a63fjl749mgdv9ssz0dhqt5jnytz3y6lmy9525qq24j6r809ghw5pefejxskn0v4cyc4ndw3nh5fld4ag

以下は私のNostrタイムラインです。

https://nostter.app/ohac@www.sighash.info

Chromeウェブストア

Chromium系のウェブブラウザを使う場合、Chromeウェブストアから拡張機能をインストールすることが多いと思います。例えばNostrで使用されることが多いnos2xは以下からインストールできるようになっています。

https://chromewebstore.google.com/detail/nos2x/kpgefcfmnafjgpblomihpgmejjdanjjp

ただ、このような暗号鍵を扱う拡張機能の場合、nos2xをビルドした人(たぶんfiatjafさん)やウェブストアを信用(Trust)しなくてはなりません。(私もそうやって使ってきましたし、今も使ってはいますが)

ということで今回は拡張機能であるnos2xを自分でビルドしようという記事となります。
(nostr-keyxの記事を考えていましたが、書く量が増えそうなので今回はやめときます。)

nos2x

nos2xのソースコードはgithubに公開されています。

https://github.com/fiatjaf/nos2x

README.md を読むと以下のようにせよと書かれていました。

git clone https://github.com/fiatjaf/nos2x
cd nos2x
yarn
./build.js prod

実はここの手順が以前間違っており、以下の修正をプルリクエストした経緯があります。

https://github.com/fiatjaf/nos2x/commit/49a1ec1325152ffe5bd98e0807321b5940cc4a70

以前はyarn run buildだったようで手順が変わったようですが、ドキュメントが放置されてしまっていたようです。

おかげでコントリビューターに潜り込むことができましたよ。

あとで気付いたのですが justfile というファイルが置いてあって、justコマンドが使えるならjustを実行するだけでビルドできるようですね。

Docker/PodmanコンテナでNixを体験

ではビルドしてみましょう。しかし、開発環境が入っていないならそのままではビルドできませんね。

ホストOSにあれこれ入れたくないとか、手順の再現性が低いとかになりがちなので今回はコンテナ内でビルドしたいと思います。コンテナについては説明は省きます。Linux上で動く仮想環境ですね。

なおコンテナ以外の方法としてはホストOSのaptやらasdfなどのランタイム管理ツールなどもあります。

まずはDockerかPodmanが動く状態にしてください。例として私の今の環境はUbuntuなのでaptでインストールできます。(サブPCにNixOSもありますが今回はUbuntuの例にしておきます。)

$ podman
Command 'podman' not found, but can be installed with:
sudo apt install podman
$ sudo apt install podman

インストールができたらNixをコンテナで実行してみます。

$ podman run -it --rm docker.io/nixos/nix:2.25.3
...
bash-5.2# nix-env --version
nix-env (Nix) 2.25.3

これでベースコンテナの準備は整いました。

ビルドしていく

まずはソースコードを取ってきます。

bash-5.2# cd
bash-5.2# git clone https://github.com/fiatjaf/nos2x.git
Cloning into 'nos2x'...

gitは標準で使えました。

justを実行してみましょう。

bash-5.2# cd nos2x
bash-5.2# ls
README.md	 build.js   icon.png  package.json
babel.config.js  extension  justfile
bash-5.2# just
bash: just: command not found

まあそらないですわな。nix-shellでjustが使えるshellに入ります。

bash-5.2# nix-shell -p just
...
[nix-shell:~/nos2x]# just -V    
just 1.28.0

では実行。

[nix-shell:~/nos2x]# just
./build.js prod
/usr/bin/env: 'node': No such file or directory

nodeが必要なようです。パッケージ名はnodejsのようなのでこれも使えるようにします。

[nix-shell:~/nos2x]# nix-shell -p nodejs
...
[nix-shell:~/nos2x]# node --version
v20.15.1

nix-shellはこのように入れ子で実行していくことができます。

[nix-shell:~/nos2x]# just
./build.js prod
...
Error: Cannot find module 'esbuild'

esbuildというモジュールがないと言われます。うーんなにそれ〜。
よく分からんけど同様にnix-shellで入るか試してみます。

[nix-shell:~/nos2x]# nix-shell -p esbuild
...
[nix-shell:~/nos2x]# esbuild --version
0.20.2

ハイレタハイレタ...

しかし、justを実行してもエラーが出ます。モジュールで入れないといけないっぽい。
だんだん記事がカジュアルな文章になってきたのは試しながら書いているからです。

そういえばREADMEの最初にyarnと書いてあったのでこれを入れてみます。

[nix-shell:~/nos2x]# nix-shell -p yarn
...
[nix-shell:~/nos2x]# yarn -v
1.22.22

yarnを実行。

[nix-shell:~/nos2x]# yarn
...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 25.59s.

なんかいけたっぽい。

[nix-shell:~/nos2x]# just
./build.js prod
build success.

なんかいけたっぽい2

extensionディレクトリに成果物ができたっぽいのであとはこれをChromiumなどに開発者モードにして読み込めば使えるのではないかと思います。

パッケージ化

justfileにpackageを作るためのルールが書いていたので、せっかくなので実行してみます。

[nix-shell:~/nos2x]# just package
./build.js prod
build success.
cd extension; zip -r archive *; cd ..; mv extension/archive.zip ./nos2x.zip
sh: line 1: zip: command not found
mv: cannot stat 'extension/archive.zip': No such file or directory
error: Recipe `package` failed on line 8 with exit code 1

zipコマンドがないようです。

[nix-shell:~/nos2x]# nix-shell -p zip
...
[nix-shell:~/nos2x]# just package
...
[nix-shell:~/nos2x]# ls -l nos2x.zip
-rw-r--r-- 1 root root 819291 Dec  6 00:51 nos2x.zip

なんかできたっぽいです。

必要なパッケージをまとめる

入れ子でnix-shellを実行してきましたが、必要なコマンドは把握できたのでこれらをまとめます。

[nix-shell:~/nos2x]# (CTRL-Dを押す)
exit
(何回か押すとプロンプトがbashに戻る)
bash-5.2# 

これでnix-shell内で使えていたコマンドは使えない状態に戻りました。

bash-5.2# nix-shell -p just nodejs yarn zip

[nix-shell:~/nos2x]# 

ビルド環境に色々とファイルが入ってしまっているので別ディレクトリにcloneしてそこでビルドできるか試してみます。

[nix-shell:~/nos2x]# cd

[nix-shell:~]# git clone nos2x nos2x2
Cloning into 'nos2x2'...
done.

[nix-shell:~]# cd nos2x2
[nix-shell:~/nos2x2]# yarn
...
[nix-shell:~/nos2x2]# just package
...
[nix-shell:~/nos2x2]# ls -l nos2x.zip
-rw-r--r-- 1 root root 819291 Dec  6 01:00 nos2x.zip

できました。

Dockerfile化

このままでは手作業がだいぶあるのでDockerfileにして手順を減らしたいと思います。
まずはホストOSに戻るまでCTRL-Dを押します。

[nix-shell:~/nos2x2]# 
exit
bash-5.2# 
exit
$ 

Dockerfileを作成。

$ vi Dockerfile
...編集...
$ cat Dockerfile # こんな感じに
FROM docker.io/nixos/nix:2.25.3
RUN nix-channel --update && nix-collect-garbage
RUN nix-env -i just nodejs yarn zip
RUN cd /root && git clone https://github.com/fiatjaf/nos2x.git
WORKDIR /root/nos2x
RUN yarn
RUN just package

コンテナのビルド。

$ podman build -t nos2x .
...
Successfully tagged localhost/nos2x:latest
...

実行。

$ podman run -it --rm -v $PWD:/host nos2x cp nos2x.zip /host/
$ ls nos2x.zip
nos2x.zip

無事、nos2x.zipがホストOSにコピーされました。

感想など

nos2xをビルドするというだけの内容でしたが、書いてみると結構なボリュームになってしまいました。結論としては7行程度のDockerfileとコマンドを2回実行するという手順になりましたのでだいぶ簡単になったかと思います。

あとソースコードに変なマルウェアが入っていないかどうかとか、コミットに信頼できそうな人のPGP署名があるかどうかなど色々とチェックした方がよいと思いますが、まあ面倒ですよね。Don't Verify. Trust.

ここまで読んでいただき、ありがとうございました。今後ともNostrをよろしくね。

Discussion