以前にDockerfileを書いたとき、yarnをインストールすれば一緒にnodeもインストールされることを活用したが、別の環境では違うnodeのバージョンがインストールされてしまった。
nodeとnpmとyarn周りは永遠に悩まされ、その度に調べてはその場しのぎな気がする。
今回の調査結果をまとめておく
やりたいこと と 背景
作っているアプリケーションはnode14系で動作している。
別の環境で開発しようとしたら、同じDockerfileでビルドしたのだが、node16系がインストールされ、そのバージョン違いによるエラーに悩まされた
どの環境でimageをbuildしても、nodejs14系が使われるようにしたい。
方針
まず、yarnのインストール時に一緒にnodeがインストールされることに依存していると、毎回バージョンが変わりかねないので、可能ならnodeを個別にインストールしたい。
最終的にはDockerfileに落とし込むが、まずは動作を確認したいので、コンテナを立ち上げて逐次実行をためしていく
docker run --rm -it ruby:2.7.4 bash
node のインストール
nodeのバージョンを指定してのダウンロード/インストールで今回活用できたのは nodesourceというレポジトリ。おそらくは公式。
distributions/README.md at master · nodesource/distributions · GitHub
コマンドが 14.x
という書かれ方をしているので、xをほしいバージョンに書き換えるのかと思いきや、そうではないらしい。
minor versionも含めて指定したければもう少し工夫がいりそう。
ともあれ、
curl -fsSL https://deb.nodesource.com/setup_14.x | bash - apt-get install -y nodejs
を実行すると (なお、ここではコンテナ内のroot userなので、sudo は外してある。sudoはインストールされていない)
# node -v v14.19.3
と、14系が入った。
ちなみに、親切なことに
## To install the Yarn package manager, run: curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get update && sudo apt-get install yarn
と、yarnをいれたければこうしてね、を教えてくれてる。
コマンド内容詳細
一度、実行したコマンドを振り返る
curl -fsSL https://deb.nodesource.com/setup_14.x
は、アクセスすればわかるがスクリプトになっている.
curl のオプションはよく見るが、 man curl
の結果から転記すると、
-s
: Silent or quiet mode. Don't show progress meter or error messages.-f
: (HTTP) Fail silently (no output at all) on server errors. This is mostly done to better enable scripts etc to better deal with failed attempts.-S
: When used with -s, --silent, it makes curl show an error message if it fails.-L
: (HTTP) If the server reports that the requested page has moved to a different location (indicated with a Location: header and a 3XX response code), this option will make curl redo the request on the new place
これを | bash -
とパイプしている。
-
は --
と同義で、 以降の引き数は全て、ファイル名や引き数として扱われる。
この場合は、 curl -fsSL
でダウンロードしたファイルの中身がパイプで渡ってくるので、それをそのまま実行するということになる(はず)。
スクリプトの中身は、少々自信はないが、主にやってることは以下で、distributionファイルをダウンロードして、実行しているように見える。
exec_cmd_nobail() { echo "+ $1" bash -c "$1" } # 略 if [ -x /usr/bin/curl ]; then exec_cmd_nobail "curl -sLf -o /dev/null 'https://deb.nodesource.com/${NODEREPO}/dists/${DISTRO}/Release'" RC=$? else exec_cmd_nobail "wget -qO /dev/null -o /dev/null 'https://deb.nodesource.com/${NODEREPO}/dists/${DISTRO}/Release'" RC=$? fi
curl のオプション
* -o
: Write output to
yarn のインストール
こちらはもともとDockerfileに以下のように書いていた
RUN echo 'deb http://ftp.jp.debian.org/debian sid main ' >> /etc/apt/sources.list && \ curl -sS 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 # 略 apt-get install yarn
nodejs インストール時におすすめされていた方法のほうが、安全に見える。
あと、docker build 時に
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
と言われていたのを思い出した。
nodesources が教えてくれた方法にしてみる
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarnkey.gpg >/dev/null echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | tee /etc/apt/sources.list.d/yarn.list
ちょっとつまずいたのは、
RUN echo 'deb http://ftp.jp.debian.org/debian sid main ' >> /etc/apt/sources.list && \
としたうえで apt-get update
すると、node16系 がインストールされてしまうので、先にnode14系までインストールしてしまってから、yarnインストールのためのスクリプトを実行した。
無事にnodejs14系を使ったうえでアプリケーションが動くことを確認した。