はじめに
この記事では、プログラミング初学者の僕が
1つのアプリを本リリースするまでに開発中に躓いたところや苦戦したところを
自分なりに整理してまとめ、理解を深めることを目的としています。
今回は、
Dockerfile.devでNode.jsとYarnをインストールしようとした時に起きたエラー
についてです。
背景
アプリの開発に必要なソフトウェアを用意するため、
Dockerfile.devを作成しました。
ベースイメージにはruby:3.4.10を使っています。
最初はNode.jsとYarnの配布元をAPTに登録し、apt-getでインストールしようとしていました。
APTは、Debianなどでソフトウェアを管理・インストールするための仕組みです。
当初のDockerfile.dev
# ベースイメージの指定
FROM ruby:3.4.10
# ...(省略)...
# 必要なパッケージのインストール
RUN apt-get update -qq \
# 必要なパッケージをインストール
&& apt-get install -y ca-certificates curl gnupg \
# キーリングディレクトリを作成
&& mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& NODE_MAJOR=26 \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
&& wget --quiet -O - /tmp/pubkey.gpg https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs yarn vim
# ...(省略)...
当初のコードには、Yarnの配布元を登録するために、次の処理が含まれていました。
wget --quiet -O - /tmp/pubkey.gpg https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
ところが、Dockerイメージのビルドに失敗し、エラーの末尾に次のように表示されました。
did not complete successfully: exit code: 127
exit code: 127は、実行しようとしたコマンドが見つからない時に出る終了コードです。
ただ、この1行だけだと、どのコマンドが見つからなかったのか特定できません。
なので直前のエラー表示も確認してみたところ、
apt-key add -が見つからないということが分かりました。
apt-keyとは
apt-keyは、APTが配布元の署名を確認するために使う鍵を管理するコマンドです。
僕は最初、apt-keyを使ってパッケージをインストールしているのだと思っていました。
しかし、実際にインストールするのはapt-getです。
apt-keyは、その前段階にある鍵の登録に使われていました。
今回つまずいた原因
ruby:3.4.10の標準イメージは、Debian 13をベースにしています。
Debian 13ではapt-keyが削除されているので、
apt-key add -を含む手順はそのままでは動きません。
また、apt-key addによる鍵の登録は非推奨となっています。
この方法で追加した鍵は、特定の配布元だけではなく、
APT全体の信頼済み鍵として扱われてしまうため、セキュリティ上のリスクが高まるからという理由みたいです。
その代わり現在はSigned-Byを使って、
「この配布元の署名を確認するときは、この鍵を使う」と指定する方法が推奨されるようになりました。
つまり今回は、
apt-keyが使えない環境だったことと、そもそも古い鍵の登録方法を使っていたことに気付きました。
(なぜかNode.js側は最初から新しい書き方でインストールしてましたが。。w)
解決方法
僕はYarnの配布元をAPTに登録する処理をやめ、
Node.jsをインストールした後にnpmを使ってYarnをインストールする方法に変更しました。
RUN apt-get update -qq \
&& apt-get install -y ca-certificates curl \
&& curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \
&& apt-get install -y build-essential libpq-dev nodejs vim libvips libvips-tools imagemagick \
&& npm install --global yarn
このコードでは、次の順番で処理しています。
-
curlなど、準備に必要なパッケージをインストール。 -
curlでNodeSourceの設定スクリプトを取得し、bashで実行。
このスクリプトが、Node.jsの配布元(NodeSourceリポジトリ)と署名確認用の鍵を設定する。 -
apt-getでNode.jsなどをインストール。 - npmを使ってYarnをインストール。
NodeSourceの設定スクリプトはapt-keyを使わず、Signed-Byオプションで鍵を指定しています。
Yarnはnpm経由でインストールするため、Yarnの配布元をAPTに追加する必要もなくなりました。
なお、変更前のコードではNode.js 26系を指定していましたが、
変更後のsetup_lts.xはLTS版を設定しています。
変更前後でNode.jsのバージョンが同じになるとは限らないため、
アプリで使うNode.jsのバージョンを確認する必要があります。
ちなみに、今回はNodeSourceの設定スクリプトの中で勝手に実行していましたが、
apt-keyを使わなくなった今、推奨されている方法はざっくりと次のような手順を踏むのかなと思います。
忘れないように学んだコマンド・パッケージ
bash -
シェルスクリプトを実行するコマンド。
apt-get
パッケージを管理・インストールするコマンド。
ca-certificates
証明書の検証に必要なパッケージ。
curl
ダウンロードに必要なパッケージ。
gpg --dearmor
ASCII形式の鍵をバイナリ形式に変換する。
まとめ
僕の環境では、
apt-keyを使う処理をやめ、Yarnをnpm経由でインストールすることで
Dockerイメージをビルドできました。
環境構築では、エラーが出ても何から調べれば良いか分からず、
手が止まってしまうことがあります。
今回調べたことが、同じように困っている方の助けになれば幸いです。
