For

2022.12.30

docker composeでVolume Trickを使ってnode_modulesをホストから切り離しつつコミット時にhuskyでlint-stagedを実行する

概要

docker-compose.yml でnode_modules用のvolumesを定義してホストの通常のリソースを開発環境のnode_modulesと切り離したいことがあると思います。
その場合、Dev Containers(旧Remote-Container)から出るとhuskyで eslint --fixprettier --write などのnode_modulesに依存する処理が実行できなくなります。
これらを両立する方法です。

docker-compose.yml

今回サンプルとして使用する docker-compose.yml は以下です。

yml_____docker-compose.yml_____version: "3"

services:
  frontend:
    image: node:16.19.0
    volumes:
      - ./frontend:/app
      - node_modules:/app/node_modules
    command: sleep infinity
    ports:
      - 5173:5173

volumes:
	  node_modules:


.husky/pre-commit

続いて、コンテナ内でlint-stagedを実行するサンプルです。

bash_____pre-commit_____#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

docker compose up -d
docker compose exec -T frontend npx lint-staged
# yarnを使用している場合は yarn lint-staged


こうすることでVSCodeのDev Containersを利用していない状態でコミットしたとき、コンテナが立ち上がっていなければ立ち上げてから docker compose exec でコンテナ内のリソースで実行できます。
-T はttyについてのオプションで、ttyについては「 DockerのTTYって何? 」がわかりやすかったです。

おまけ

docker compose コマンドが docker-compose コマンドと等しいコマンドとしていずれ置き換えられるようにという方針で進んでいるという認識のもと、普段は docker compose コマンドを利用しているのですが、docker-compose exec に関しての ドキュメント を見ると以下の記述があります。

このコマンドは docker exec と同じです。


シンプルに知りませんでした。今後はこっちを使おうと思います。
使ってみたところ docker compose exec でないとdocker-compose.ymlのservice名でコンテナを指定できなかったのでやっぱり docker compose exec を使うことにしました。