💬

Git clone後のdocker初回起動時の/bin/sh: xxx: not foundエラーへの対応

2022/02/11に公開

概要

npmやyarnでパッケージ管理しているプロジェクトで、node_modulesを共有していない場合(通常しないと思いますが)、既存プロジェクトをcloneなどで取得してきた場合、docker初回起動時に、次のようなエラーが出力されます。

  • 前提:docker-compose.yml内でyarn devの起動を指定している
Dockerfile
FROM node:17-alpine
WORKDIR /usr/src/app
docker-compose.yml
version: '3'

services:
  node:
    build: ./
    volumes:
      - ./node:/usr/src/app
    command: sh -c "cd site && yarn dev"
    ports:
      - "3000:3000"
  • Gitからソースコードをcloneしてきて、そのままdocker-composeを実行
docker-compose up -d
  • dockerコンテナが起動しないので、ログを確認
docker-compose logs node
  • 依存パッケージを使用するコマンドが見つからずにエラーとなっている。
yarn run v1.22.17
/bin/sh: next: not found
$ next dev
error Command failed with exit code 127.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

発生理由

これは、npmまたはyarnで、package.jsonに基づいて、依存パッケージを管理をしていて、node_modules内のファイルはGit管理していないため、初回起動時にコマンドが通らずにエラーが発生します。

※そうなると、DockerFile内の指定で、RUN cd site && yarn installのように依存関係にあるパッケージをインストールしたいと考えますが、ビルド実行時点では、docker-compose.yml側でvolumesで指定しているでフォルダは、まだマウントされていないため、フォルダが見つからず、このパターンもエラーになります。

対応策

Gitからcloneしてきた後の初回起動時には、docker-compose up -dする前に、docker-compose runコマンドを実行して、依存パッケージをインストールすることで解消できます。

docker-compose run -w /usr/src/app/site --rm node yarn install
docker-compose up -d

-wオプションにはパッケージをインストールする対象のフォルダ(コンテナ内でのパス)を設定
--rm nodeに続いて、実行させたいインストールコマンドを設定

所感

docker-compose.yml側で初回かどうかを判定・分岐してyarn install等を行うパターンもあるようでしたが、Dockerfiledocker-compose.ymlはなるべく定義型で済ませておきたい(シェル的な処理を書きたくない)のと、初回作業の話のみとなるので、初回導入時にdocker-compose run ・・・を実行する手順としておくことで、特に問題ないかと思います。

Discussion