メインコンテンツまでスキップ

第13章:Windowsでハマりがちな点(改行/パス/権限)🪤😵

(Todo APIを育てるシリーズ🌱📦)

この章は「ハマりどころを先に踏んで、最短で回避できるようになる」章だよ😆✨ やることはシンプルで、“事故を再現→原因がわかる→直せる” を3本立てで体験します💪🐳


この章のゴール🎯✨

  • 🧻 CRLF/LF(改行) でシェルやツールがコケる理由を理解して、直せる
  • 🗺️ パス(Windows/WSL/コンテナ) の“どれをどこで使うか”で迷わなくなる
  • 🔒 権限(Permission denied) を見た瞬間に「まず何を疑うか」が決まる

0) まず知っておくと事故が減る“超重要ルール”🧠⚡

  • Docker Desktopは更新がかなり速い(隔週リリースへ)ので、挙動が変わることがあるよ🔁🆙 (Docker)

  • WindowsとLinux(WSL/コンテナ)で“ファイルの扱い”が違うのが根っこです🌳

    • Docker公式も「WSL2のLinux側にプロジェクトを置く」方向を強く推してるよ📌 (Docker)
    • 共有(マウント)しすぎると重くなったり、DBやキャッシュはボリュームの方が速い…などの注意も公式にあるよ🐢➡️🐇 (Docker Documentation)

ここから先は「ありがち事故」をわざと起こして、サクッと直していこう😆🧯


1) 改行(CRLF/LF)で起きる事故🧻💥

1-1. 事故を再現してみよう(1分)⏱️😈

Todo APIに、起動前に叩くスクリプトがある想定にするよ(実務でよくある)🧩

## scripts/healthcheck.sh(わざとCRLFになりがちなやつ)
#!/usr/bin/env sh
echo "ok"

コンテナ内で実行(例)👇

sh scripts/healthcheck.sh

典型的な症状👇

  • ^M が見える / bad interpreter
  • exec user process caused: no such file or directory

こういうの、ほぼ CRLF(Windows改行) が混ざって Linux で壊れてるパターンです🪤 (Windows=CRLF / Linux=LF の差が原因になりやすい)(Endjin)


1-2. 直し方(最短)🧼✨

VS Codeでそのファイルを開いて、右下の CRLFLF に変える👉保存💾 さらに「新規ファイルの既定改行」も LF にしておくと事故が激減するよ⚡ (VS Code設定で eol\n にする手順)(Stack Overflow)


1-3. 予防の“鉄板セット”🛡️📌

A) .gitattributes で「リポジトリはLF」を固定🧷

(チームでも個人でも強い💪)

## だいたいこれでOK(必要なら拡張子で細かく)
* text=auto eol=lf

Git側の改行自動変換(core.autocrlf)は環境が混ざると差分地獄になりやすいので、方針を決めて固定が安全だよ🧠 (Zenn)

B) “謎の大量差分”が出たらコレを疑う🌀

WSL側では差分ゼロなのに、GUIクライアント(例:GitHub Desktop)で大量変更…は改行変換が原因のことがあるよ😵‍💫 (GitHub)


🤖 AI活用プロンプト(改行編)

  • 「このエラー文、CRLF/LFが原因の可能性ある?判断ポイント3つと確認コマンド出して」
  • 「このリポジトリ(Node/TS)に最適な .gitattributes と .editorconfig を提案して」

2) パス(Windows/WSL/コンテナ)で起きる事故🗺️💥

2-1. 事故の典型:どの“世界”のパスか混ざる😵

Dockerを叩く場所によって、通るパスが違うよ🧩

  • Windows側の例C:\Users\you\project
  • WSL側の例/home/you/project/mnt/c/Users/you/project
  • コンテナ側の例/app

混ざると、-v「見つからない」「空ディレクトリがマウントされる」 みたいな事故が起きる😇 スペース入りパスで解釈が崩れる話も報告があるよ🪤 (GitHub)


2-2. 直し方(現場で効くルール)✅

ルール①:Dockerコマンドは“同じ世界”から叩く🌍

  • WSLのターミナルから叩くなら、WSLのパスで統一(Linuxの感覚でOK)🐧
  • Windowsのターミナルから叩くなら、Windowsのパスで統一🪟

ルール②:相対パスを使う(最強)📌

プロジェクト直下で👇

docker run --rm -v .:/app -w /app node:20 bash -lc "ls -la"

相対パスは“世界のズレ”を減らせて超強い💪✨

ルール③:外付け/別ドライブはハマりやすい😵

別ドライブの bind mount がうまくいかない報告もあるので、怪しい時はまずここを疑う🪤 (GitHub)


🤖 AI活用プロンプト(パス編)

  • 「この docker run / compose のエラー、パスの解釈ミスっぽい?直す手順を3つ」
  • 「Windows+WSL2で、事故りにくいディレクトリ配置ルールを提案して」

3) 権限(Permission denied)で起きる事故🔒💥

3-1. 事故を再現(“書けない”を作る)😈

bind mount した場所に、コンテナから書き込もうとして…👇

  • Permission denied
  • EACCES
  • ファイルが root 所有っぽく見える

このへんは “Windowsのファイルシステム(NTFS)” と “Linuxの権限(uid/gid)” が噛み合ってないのが原因になりがち🧩 特に /mnt/c/... 側は、Linuxの chmod/chown が期待通り効かないケースがあるよ🪤 (Stack Overflow)


3-2. 直し方(よく効く順)🧯✨

A) “書き込みが多い場所”はボリュームに逃がす📦

Docker公式も「DBやキャッシュなど“コード以外”はボリュームの方が速い&安全」寄りの考え方を案内してるよ🚀 (Docker Documentation)

例:node_modulesdist、DBデータ、npmキャッシュなど

B) コンテナの実行ユーザーを合わせる👤🔧

WSL側で id が取れるなら、こういう“合わせ技”が効くことが多い💪

docker run --rm -it \
--user "$(id -u):$(id -g)" \
-v .:/app -w /app \
node:20 bash

(composeなら user: で固定もできるよ🧩)

C) そもそもプロジェクトをWSL側に置く📁🐧

Docker公式の推し方針:WSL2のLinux側にプロジェクトを置く(ファイル周りの不具合や性能問題を避けやすい)📌 (Docker)


🤖 AI活用プロンプト(権限編)

  • 「EACCES/Permission denied が出た。原因候補トップ5と確認コマンド順に出して」
  • 「compose.ymlで“書き込み先はvolume、コードだけbind”にする設計に直して」

4) 症状から逆引きチートシート📋⚡

  • 🧻 ^M / bad interpreter → 改行がCRLFっぽい → VS CodeでLF化 / .gitattributes
  • 🗺️ マウントしたのに空 → パスの“世界”がズレた → 相対パスで -v .:/app / 同じ場所から実行
  • 🔒 EACCES / Permission denied → bind先がWindows側 or uid/gidズレ → volumeに逃がす / --user

5) ミニ課題(10分)⏱️🏋️‍♂️

  1. scripts/healthcheck.sh を作って、わざとCRLFで壊す😈
  2. VS Codeで LF に直して、動くのを確認
  3. -v .:/app の相対パスでコンテナ起動して、/app にファイルが見えるのを確認👀
  4. --user "$(id -u):$(id -g)" あり/なしで、ファイル作成時の違いを観察🔍

次に繋がる一言🔜✨

この章で「Windows特有の事故」を踏めたので、次の 第14章:bind mount と volume の使い分け がめちゃ気持ちよく理解できるはず😆⚖️ (特に “node_modules” と “DBデータ” が主役になるよ📦🛡️)