0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VS Code Dev Containers で “Docker コンテキスト地獄”** にハマり — package.json が見えない、コンテナが即死する… を全部解決するまでの全記録 > Node18 × Puppeteer × Remote-Containers の罠と、その抜け出し方を > ログとともに完全再現・総括しました。

Posted at

TL;DR

Before (詰み) After (解決)
context.devcontainer 直下 → ビルド時に package.json が見えない context: ..プロジェクトルート を丸ごと渡す
volumes: ./:/usr/src/appコードが実体化しない volumes: ../:/usr/src/app に合わせてマウント
スクリプト完了でコンテナ終了 → VS Code が接続できない tail -f /dev/null を最後に添えて常駐
依存解決をすべて RUN npm install で実行 → build キャッシュが無効 COPY package*.jsonnpm iCOPY . の三段構えで高速化

1. 環境

項目 バージョン
OS Windows 11 + WSL2(Ubuntu)
Docker Desktop 4.42.1 (engine 28.2.2)
VS Code 1.102.1 + Dev Containers 0.422.1
Node 18
Puppeteer ^22
Dev Container 構成 .devcontainer/{dockerfile, docker-compose.yml, devcontainer.json}

2. 事象とエラーログ

2-1. MODULE_NOT_FOUND: puppeteer/install.js

Error: Cannot find module '/usr/app/node_modules/puppeteer/install.js'
...
Node.js v18.20.8

2-2. npm ERR! enoent Could not read package.json

npm ERR! enoent Could not read package.json: ENOENT: no such file or directory, open '/usr/src/app/package.json'

2-3. Dev Container が起動後すぐ停止

Error response from daemon: container ... is not running
VS Code: "An error occurred setting up the container."

3. 原因を掘る 🔍

症状 真因
puppeteer の post-install が失敗 Dockerfile が .devcontainer 内だけをビルドnode_modules 生成前に install.js を叩こうとして空振り
package.json が見つからない context を誤指定 (.) したため ルートがビルドに含まれず
コンテナが即死 command に指定した Node スクリプトが完了 → PID 1 が終了 → コンテナ停止

4. 施した4つの修正

4-1. docker-compose.yml を全面修正

services:
  scraper:
    # ▶︎ ビルド対象はプロジェクト全体
    build:
      context: ..                       # ← 変更!
      dockerfile: .devcontainer/dockerfile
    tty: true
    ports:
      - "80:80"
    # ▶︎ マウントも親ディレクトリへ合わせる
    volumes:
      - ../:/usr/src/app
    # ▶︎ スクリプト完了後もプロセスを残す
    command: >
      bash -c "npm install &&
      node scripts/scrape_comenu.js || echo 'script ended'; tail -f /dev/null"

4-2. Dockerfile をベストプラクティス寄りに

FROM node:18

# ① Chrome とフォント類を最小インストール
RUN apt-get update \
  && apt-get install -y wget gnupg --no-install-recommends \
  && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub \
     | gpg --dearmor -o /usr/share/keyrings/googlechrome-linux-keyring.gpg \
  && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/googlechrome-linux-keyring.gpg] \
     http://dl.google.com/linux/chrome/deb/ stable main" \
     > /etc/apt/sources.list.d/google.list \
  && apt-get update \
  && apt-get install -y google-chrome-stable fonts-ipafont-gothic --no-install-recommends \
  && rm -rf /var/lib/apt/lists/*

# ② 依存解決をキャッシュ効く順に
WORKDIR /usr/src/app
COPY ../package*.json ./               # ← まず package.json だけ
RUN npm ci --unsafe-perm

# ③ 残りのコードを最後にコピー
COPY .. .

CMD ["node","scripts/scrape_comenu.js"]

4-3. devcontainer.json

{
  "name": "MealMax Scraper Dev",
  "dockerComposeFile": ["docker-compose.yml"],
  "service": "scraper",
  "workspaceFolder": "/usr/src/app",
  "settings": {
    "terminal.integrated.shell.linux": "/bin/bash"
  },
  "extensions": [
    "dbaeumer.vscode-eslint",
    "eamodio.gitlens"
  ],
  "skipFeatureAutoInstall": true
}

5. 動作確認 ✅

# devcontainer CLI が生成した compose プロジェクト
$ docker compose -p scraper_devcontainer ps

NAME                               STATUS           PORTS
scraper_devcontainer-scraper-1     Up About a minute 0.0.0.0:80->80/tcp

VS Code からもコンテナに入り、node scripts/scrape_comenu.js が正常に動作することを確認。


6. Ultra-Thinking💡: もう二度とハマらないための5箇条

  1. context に渡すディレクトリ = コンテナに必要な最小ソースの集合
    docker-compose config で実際のパス解決を 必ず チェック。
  2. COPY 手順はキャッシュを意識して二段構え
    1️⃣ COPY package*.jsonnpm ci
    2️⃣ COPY .(コード変更時だけ再ビルド)
  3. Dev Containers では volume と context を “同じ階層” に合わせると楽
    → ホスト側で変更して即反映、ビルド時も同じパス基準。
  4. コンテナを落とさないワンライナー
    cmd || true; tail -f /dev/null … 開発時の定番テク。
  5. エラーは 上から順に 直す
    MODULE_NOT_FOUND は大抵「コピー漏れ」or「mount ミス」。焦って npm を疑わない。

7. まとめ 📝

  • “コンテキストとマウントのズレ” が原因で、

    • package.json 不在 → ビルド失敗
    • スクリプト終了 → コンテナ停止
      に連鎖していた。
  • contextvolumes をプロジェクトルートに合わせ、Dockerfile を段階的コピーに直しただけで すべて解決

  • Dev Containers は「設定フォルダ(.devcontainer)とアプリ本体を切り分ける」のが王道。

これであなたも “Docker コンテキスト地獄” とはお別れ!
Happy Container Hacking🐳✨


参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?