◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Claude Code
⟐ Claude Code/2026-05-13初級

Claude Code の Bash ツールで `npm run dev` や `docker run` が止まる — 長時間実行プロセスの正しい扱い方

Claude Code で npm run dev や docker run を実行すると Bash ツールがハングする問題の原因と解決策。バックグラウンド実行・タイムアウト設定・プロセス管理の実践的な手順を解説します。

claude-code132troubleshooting61bash5npmdockerlong-running-processfix11

claude-code-long-running-process-hang-fix と検索してこのページに辿り着いた方は、おそらく Claude Code に「開発サーバーを起動して動作確認して」と頼んだら、画面がくるくる回ったまま何も返ってこなくなった経験をされているかと思います。

私自身、2014年から個人でアプリを開発してきて、Claude Code をワークフローに組み込み始めた当初にこの問題で何度か時間を溶かしました。npm run dev を Bash ツールで実行させた瞬間、セッションが完全にフリーズするあの感覚は、最初は何が起きているのかまったく分かりませんでした。

なぜ Claude Code の Bash ツールは長時間プロセスでフリーズするのか

Claude Code の Bash ツールは、コマンドの完了を待ってから結果を返す設計になっています。ls、git status、npm install のような「実行して終わる」コマンドには問題ありません。

しかし npm run dev や docker run、python -m http.server のようなフォアグラウンドで動き続けるプロセスを渡すと、Bash ツールはプロセスが終了するまでレスポンスを待ち続けます。開発サーバーは手動で止めない限り終了しませんから、事実上セッションは永遠に応答待ちになります。

これはバグではなく仕様です。「コマンドを実行して結果を受け取る」という設計原則に従った動作ですが、Web 開発では常駐プロセスを扱う場面が多いため、知らないとはまりやすい落とし穴になっています。

症状の確認 — どのコマンドでハングが起きるか

ハングが起きやすいコマンドのパターンです。

フロントエンド / Node.js 系:

  • npm run dev、yarn dev、pnpm dev
  • next dev、vite、webpack serve
  • npm start(Express サーバー等)

バックエンド・インフラ系:

  • docker run、docker compose up(-d なし)
  • python manage.py runserver
  • rails server、php artisan serve

ウォッチモード系:

  • jest --watch、vitest watch
  • tsc --watch
  • nodemon server.js

逆に、一度実行して終わるコマンド(npm run build、docker build、jest --runInBand)はそのまま使えます。

解決策1 — バックグラウンド実行(& + リダイレクト)

最もシンプルな解決策は、コマンドをバックグラウンドで実行させることです。

# 開発サーバーをバックグラウンドで起動し、ログをファイルに保存
npm run dev > /tmp/dev-server.log 2>&1 &
echo "PID: $!"
 
# 数秒待ってからログを確認
sleep 3 && cat /tmp/dev-server.log

& をコマンド末尾に付けると、プロセスをバックグラウンドに送りつつ Bash ツールはすぐに PID を返して終了します。$! で直前に起動したプロセスの PID を取得しておくと、後で停止させるときに便利です。

Claude Code にこのパターンを伝えるプロンプトの例です。

開発サーバーを起動して、3000番ポートで動いているか確認してください。
サーバーはバックグラウンドで起動し、ログは /tmp/dev-server.log に保存してください。
起動確認は curl http://localhost:3000 で行ってください。

解決策2 — timeout コマンドで強制終了タイミングを指定する

「起動して特定のエラーが出ないか確認したい」という場面では、timeout コマンドが役立ちます。

# 10秒間だけ起動してログを取る
timeout 10 npm run dev > /tmp/dev-server.log 2>&1 || true
 
# ログを確認
grep -E "(error|Error|started|listening|ready)" /tmp/dev-server.log

timeout 10 を付けると、10秒後にプロセスが自動停止します。起動直後のエラーチェックや、ポート待ち受けの確認程度なら十分です。

解決策3 — curl や wait-on で起動完了を確認する

開発サーバーを起動してから「ページが表示されるか確認して」という用途には、次のパターンが実用的です。

# バックグラウンドで起動
npm run dev > /tmp/dev-server.log 2>&1 &
DEV_PID=$!
 
# ポートが開くまで最大30秒待つ
for i in $(seq 1 30); do
  if curl -s http://localhost:3000 > /dev/null 2>&1; then
    echo "✅ 起動確認: http://localhost:3000 で応答あり"
    break
  fi
  sleep 1
done
 
# サーバーを停止
kill $DEV_PID 2>/dev/null

npx wait-on を使うとより簡潔になります。

npm run dev > /tmp/dev-server.log 2>&1 &
DEV_PID=$!
npx wait-on http://localhost:3000 --timeout 30000 && echo "✅ Server ready"
kill $DEV_PID 2>/dev/null

解決策4 — Docker は必ず -d フラグを付ける

Docker コンテナの起動は -d(デタッチ)フラグが必須です。

# ❌ これは止まる
docker run -p 3000:3000 myapp
 
# ✅ これは動く
docker run -d -p 3000:3000 --name myapp myapp
docker logs myapp

docker compose up の場合も同様です。

# ✅ バックグラウンド起動
docker compose up -d
 
# コンテナの状態確認
docker compose ps
docker compose logs --tail=20

Claude Code への指示例です。

docker compose up -d で起動して、すべてのサービスが healthy になっているか確認してください。
確認後に docker compose ps の結果を教えてください。

CLAUDE.md にプロセス管理の規則を書いておく

このパターンを毎回プロンプトで説明するのは手間なので、プロジェクトの CLAUDE.md に一度書いておくと楽です。

## プロセス管理ルール
 
- 開発サーバーの起動は必ずバックグラウンド実行すること
  - 例: `npm run dev > /tmp/dev.log 2>&1 &`
- docker compose は必ず `-d` フラグを付ける
- 起動確認は curl または wait-on で行う
- プロセスの停止は `kill <PID>` または `docker compose down`
- テストはウォッチモードではなく `--runInBand` または通常実行を使う

Claude Code の CLAUDE.md 設定ガイドでも、このような実行環境の制約をプロジェクトに記述する方法を解説しています。

フリーズしてしまったセッションの回復方法

すでにセッションがフリーズした状態の場合は、以下の手順で回復できます。

1. Claude Code の停止ボタンを押す(ターミナルの場合は Ctrl+C)

進行中のリクエストを中断します。

2. 残ったプロセスを手動で停止する

# ポート3000を使っているプロセスを確認
lsof -ti:3000 | xargs kill 2>/dev/null
 
# または名前で探す
pkill -f "npm run dev"
pkill -f "vite"

3. ポートが解放されたか確認する

lsof -i:3000
# 何も表示されなければポートは空き

ウォッチモードのテストが止まる問題

jest --watch や vitest watch も同様にハングします。CI 相当の動作をさせる場合は、ウォッチフラグを外してください。

# ❌ ウォッチモードは止まる
jest --watch
 
# ✅ 一回実行して終了
jest --runInBand
npx vitest run
 
# カバレッジ付き
jest --coverage

「テストが全部通るか確認して」と Claude Code に頼む際は、ウォッチモードを使わない旨を明示すると確実です。

よくある間違いパターン

実際の開発で遭遇しやすい、プロンプトの書き方とその改善例です。

❌ フリーズするプロンプト例:

開発サーバーを起動して、ページが崩れていないか確認してください

Claude Code がそのまま npm run dev を実行してフリーズします。

✅ フリーズしないプロンプト例:

開発サーバーをバックグラウンドで起動(npm run dev > /tmp/dev.log 2>&1 &)して、
起動後に curl http://localhost:3000 でレスポンスを確認してください。
確認が終わったらサーバーを停止してください。

明示的にバックグラウンド実行の指示を入れることで、Claude Code は適切なコマンド設計をしてくれます。

この問題で詰まっている方の参考になれば幸いです。Claude Code の Bash ツールは「コマンドを実行して終わる」設計だということを意識しておくと、他のハング問題(python input() を含むスクリプト、対話型 CLI ツール等)にも同じ考え方で対処できます。

関連するトラブルシューティングとして、Claude Code の Bash ツール実行エラー全般の解決ガイドも参考になります。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⟐ Claude Code2026-05-10
Claude Code の Read が大きなファイルを最後まで読まないとき — PARTIAL view の受け取り方と offset / limit の設計
Read が大きなファイルを途中までしか返さないとき、Claude Code は PARTIAL view の通知を出しています。通知の受け取り方と、行数ではなくバイト予算で offset / limit を決める方法を、実測値とともにお伝えします。
⟐ Claude Code2026-05-02
Claude Code の Edit ツールで「old_string is not unique」エラーを止める実践的な書き換え戦略
Claude Code の Edit ツールで「old_string is not unique」が頻発するのは、編集ターゲットの一意性をプロンプト側で保証していないことが根本原因です。再発を防ぐ書き換え戦略を解説します。
⟐ Claude Code2026-05-24
Claude Code で連続する Edit が連鎖的に失敗するときの直し方 — old_string が消える・重複する問題
Claude Code が同じファイルへ Edit を連続で投げると、2件目以降が突然『not found』や『not unique』で落ちることがあります。原因は順序依存とコンテキスト二重化で、Read 再実行と分割パッチで救えます。