[{"data":1,"prerenderedAt":444},["ShallowReactive",2],{"content-/deploy-while-dev-running":3,"all-pages-for-dir":422,"related-/deploy-while-dev-running":423,"og-image-/deploy-while-dev-running":443},{"id":4,"title":5,"body":6,"category":403,"concepts":404,"description":405,"extension":406,"meta":407,"navigation":408,"ogImage":404,"path":409,"project_name":410,"published":411,"publishedAt":412,"seo":413,"stem":414,"tags":415,"todo":404,"unpublished":411,"updatedAt":404,"__hash__":421},"pages/2026-07/2026-07-31/deploy-while-dev-running.md","dev サーバーを止めずにデプロイできるよう、Nuxt のビルド出力先と Content DB を分けた",{"type":7,"value":8,"toc":392},"minimark",[9,13,17,28,31,34,38,49,70,73,76,83,86,90,93,104,107,117,123,132,138,143,146,149,156,171,174,177,180,183,187,193,196,203,206,209,217,224,227,230,236,246,249,259,262,273,284,287,290,305,315,318,322,325,332,335,342,348,359,373,376],[10,11,5],"h1",{"id":12},"dev-サーバーを止めずにデプロイできるようnuxt-のビルド出力先と-content-db-を分けた",[14,15,16],"p",{},"ビルドとデプロイに何分かかっているかを測ろうと、所要時間計測スクリプトを叩いた。",[18,19,24],"pre",{"className":20,"code":22,"language":23},[21],"language-text","=== Nuxt Build & Deploy Phase Timer ===\n","text",[25,26,22],"code",{"__ignoreMap":27},"",[14,29,30],{},"ヘッダーだけ出て、そこで止まった。\nポート3000で dev サーバーが動いている、というのが理由だった。",[14,32,33],{},"前は動いていたはずだ。\nlocalhost を立ち上げっぱなしのままデプロイして、それで困った覚えがない。",[35,36,37],"h2",{"id":37},"デプロイを止めていたガード",[14,39,40,41,44,45,48],{},"止めていたのは ",[25,42,43],{},"assert-no-dev-server.mjs"," で、ポート3000を検査して ",[25,46,47],{},"pnpm generate"," を中断する。\n入ったのは 2026-07-30 の 14:21、つまり前日だった。",[14,50,51,52,55,56,58,59,55,62,65,66,69],{},"理由はコミットメッセージにそのまま書いてあった。\n",[25,53,54],{},"pnpm dev"," と ",[25,57,47],{}," は、既定で ",[25,60,61],{},".nuxt",[25,63,64],{},".data/content/contents.sqlite"," を共有する。\n同時に走ると prerender 中の content query が 500 を返し、",[25,67,68],{},"prerender.failOnError: false"," がそれを握り潰す。\n結果として、記事が抜け落ちた dist が「ビルド成功」として出来上がる。",[14,71,72],{},"7/30 はこれで記事189本が消えていた。",[14,74,75],{},"厄介なのは、失敗が失敗として現れない点だ。\nビルドは成功で終わる。",[14,77,78,79,82],{},"自分の記憶では「本番に出てから気づいた」ことになっていたが、記録を読ませたら違った。\ndist から記事が抜けた段階で、postgenerate の ",[25,80,81],{},"verify-blog-payload"," が止めていた。\n本番までは行っていない。",[14,84,85],{},"そしてこの日の午前、そのガードにもう一度引っかかっている。\n10:52 に dev サーバーを止めてデプロイを流したのに、10:53:19 に新しい node がポート3000を掴んでいた。\n自分では止めたつもりでも、1分後には別の node が同じポートを握っている。",[35,87,89],{"id":88},"ビルド出力先と-content-db-の分離","ビルド出力先と Content DB の分離",[14,91,92],{},"ガードの発想は「dev を止めてから generate しろ」である。\n筋は通っているが、別セッションが dev を立て直すたびにデプロイできなくなる。\n立てた覚えのない dev サーバーのせいで、こちらのデプロイが止まる。",[14,94,95,96,99,100,103],{},"そこで方針を変えて、競合そのものを消すことにした。\n調べさせたら、",[25,97,98],{},"@nuxt/content"," に ",[25,101,102],{},"_localDatabase"," という内部オプションがあった。\nSQLite の置き場を差し替えられる。\ngenerate 側だけ、そこで別ファイルに逃がす。",[14,105,106],{},"dev 側の設定は動かさない。\n止めさせないための分離なので、そこを触っては意味がない。",[14,108,109,110,113,114,116],{},"実装に入る直前で、共有していたのが ",[25,111,112],{},".data"," だけではないと分かった。\n",[25,115,61],{}," も共有していて、しかも計測スクリプトの227行目がそれを無条件で消していた。\ndev が使っているビルドディレクトリを、デプロイのたびに消していたことになる。",[14,118,119,122],{},[25,120,121],{},"buildDir"," も分ける必要がある。\n数行で済む話ではなくなった。",[14,124,125,128,129,131],{},[25,126,127],{},"nuxt.config.ts"," は環境変数で切り替えるだけにして、既定値は従来どおり残した。\n渡すのは ",[25,130,47],{}," にだけである。",[18,133,136],{"className":134,"code":135,"language":23},[21],"NUXT_BUILD_DIR=.nuxt-build\nNUXT_CONTENT_LOCAL_DB=.data/content-build/contents.sqlite\n",[25,137,135],{"__ignoreMap":27},[14,139,140,142],{},[25,141,127],{}," を触る以上、ビルド中に混ぜるわけにはいかない。\n先にデプロイを済ませ、それから分離を入れる順序にした。\nデプロイは約20分かかり、14:12 に完了した。",[35,144,145],{"id":145},"ポートチェックに代わる分離ガード",[14,147,148],{},"ポートを見るガードは要らなくなる。\nただし外すだけだと、分離が壊れたときに何も止めなくなる。",[14,150,151,152,155],{},"代わりに ",[25,153,154],{},"assert-build-dirs-separated.mjs"," を新設して、毎回3点を検査させた。",[157,158,159,163,168],"ul",{},[160,161,162],"li",{},"環境変数が渡っているか",[160,164,165,167],{},[25,166,127],{}," がそれを読んでいるか",[160,169,170],{},"値が dev 側と別物か",[14,172,173],{},"判定できなければ止める fail-closed にした。",[14,175,176],{},"新しいガードで怖いのは「入れたのに素通りしていた」ことなので、壊れた状態を作って本当に止まるかを試させた。\n両方のケースで止まった。",[14,178,179],{},"途中、検証用に作ったディレクトリを消そうとして、再帰削除ガードに変数展開を拒否された。\n消すのはやめて、別の新しいディレクトリで検証を続けた。",[14,181,182],{},"判定ロジックは純粋関数に切り出させ、テストを4件足した。\n既存と合わせて9件が通った。",[35,184,186],{"id":185},"dev-を動かしたままの-generate-検証","dev を動かしたままの generate 検証",[14,188,189,190,192],{},"設定が揃ったので、dev を起動したまま ",[25,191,47],{}," を回す。\nこれが本番相当の検証になる。",[14,194,195],{},"一度目は prerender の途中、tags ページのあたりで止まった。\n自分では何も止めていない。",[14,197,198,199,202],{},"exit code は 3221225794、つまり ",[25,200,201],{},"0xC0000142","（STATUS_DLL_INIT_FAILED）だった。\nWindows がプロセスを起動できなくなったときのコードで、典型的な原因はメモリかハンドルの枯渇である。",[14,204,205],{},"空きメモリは 3.9GB。\nnode が 9.6GB 以上を持っていた。\ngenerate は 8GB を要求するので、そもそも届かない。",[14,207,208],{},"内訳を出させると、二つの塊が並んだ。",[157,210,211,214],{},[160,212,213],{},"dev サーバー3つ（4.9GB）",[160,215,216],{},"chrome-devtools MCP 4つ（4.8GB）",[14,218,219,220,223],{},"合わせて 9.7GB。\nMCP の起動時刻は 06:37、06:39、09:32、10:16 と古い。\nどれもこのセッションからは接続できず、ハングしていたものだった。\n",[25,221,222],{},"list_pages"," が応答しなかったのも、これが原因だった可能性がある。",[14,225,226],{},"掃除させたら空きが 3.1GB から 6.7GB になった。\n3000で動いている別セッションの dev は残す。\nそれが DB を掴んでいない状態で完走しても、検証にならない。",[14,228,229],{},"再実行の途中でまた 1.9GB まで落ちたので、使っている 3003 だけ残して他を落とさせた。\n1.9GB から 5.5GB に戻った。",[14,231,232,233,235],{},"このあたりで、走っているのがデプロイなのか分からなくなって聞いた。\n答えは「デプロイではない」だった。\n",[25,234,47],{}," はビルドと postgenerate の検証7本までで、Cloudflare へのアップロードは含まない。\nローカルで完結する。",[14,237,238,239,241,242,245],{},"二度目は完走した。\n検証7本すべて通過。\n7/30 に落ちた ",[25,240,81],{},"（250/250 リンク）と ",[25,243,244],{},"verify-tag-related-output","（欠落0件）が、dev を動かしたまま両方パスした。",[35,247,248],{"id":248},"走りっぱなしのプロセスをどう検知するか",[14,250,251,252,255,256,258],{},"メモリを食い潰していたのは、閉じ忘れたセッションの残骸である。\n",[25,253,254],{},"/clear"," は打っている。\nただし ",[25,257,254],{}," が消すのはコンテキストだけで、そのセッションが立てた dev サーバーや MCP サーバーは残る。\nセッションを並べて使っていると、どれがどれの残骸かが分からない。",[14,260,261],{},"そこで、ステータスラインに走っている数を出せないか頼んだ。",[14,263,264,265,268,269,272],{},"計測から入らせた。\nステータスラインは頻繁に呼ばれるので、重い処理を足すと体感を壊す。\n",[25,266,267],{},"netstat"," は 54ms、",[25,270,271],{},"tasklist"," は 665ms。\n後者は使えない。",[14,274,275,276,279,280,283],{},"ところが netstat の結果が空で返ってくる。\n原因は文字コードだった。\nWindows の netstat は cp932 で出力するのに、デコードで出た例外を握り潰していた。\n直しても、今度は dev サーバーだけ出てこない。\n",[25,277,278],{},"-p TCP"," が IPv4 に限定していて、dev は ",[25,281,282],{},"[::1]","（IPv6 ループバック）でリッスンしていた。",[14,285,286],{},"そこまで直して 3001 と 3003 を 95ms で拾えるようになり、ステータスラインの4行目に数が出た。",[14,288,289],{},"出たものを見て、狙いから外れているのに気づいた。\n表示されるのはマシン全体の数であって、セッションごとではない。\nどのセッションのプロセスかが分からなければ、「そこで止めてくれ」と伝えられない。",[14,291,292,293,296,297,300,301,304],{},"セッション固有の判定ができないか試させた。\n",[25,294,295],{},"psutil"," 7.0.0 が入っていて、祖先チェーンから ",[25,298,299],{},"claude.exe","（PID 37432）まで辿れた。\n原理的にはできる。\nただし 205ms かかり、",[25,302,303],{},"children(recursive=True)"," は 242ms。\n一括取得に変えると、かえって遅くなった。\nステータスラインが毎回払うコストではない。",[14,306,307,308,311,312,314],{},"結局、ステータスラインは数を出すだけにして、",[25,309,310],{},"/procs"," コマンドを別に作らせた。\n一覧にはリポジトリ名まで出るので、止めていいものを見て選べる。\nステータスラインには ",[25,313,310],{}," への案内を足した。",[14,316,317],{},"異常に増えたことに気づければ、この用途は足りる。",[35,319,321],{"id":320},"止めた-mcp-のその後","止めた MCP のその後",[14,323,324],{},"しばらくして一覧を見たら、さっき落としたはずの MCP がまた走っていた。\n3つ止めさせた。",[14,326,327,328,331],{},"MCP を止めた側のセッションは、そのままでは使えない。\n",[25,329,330],{},"/mcp"," から reconnect が要る。\n繋ぎ直せば当然また立ち上がるので、止めて終わりにはならない。",[35,333,334],{"id":334},"更新で効かなくなっていた権限設定",[14,336,337,338,341],{},"別セッションで ",[25,339,340],{},"claude"," を起動したら、見慣れない警告が出た。",[18,343,346],{"className":344,"code":345,"language":23},[21],"Permission allow rule (.claude\\settings.local.json): Write(.claude/**) is not\nmatched by file permission checks — only Edit(path) rules are.\nUse Edit(.claude/**) instead\n",[25,347,345],{"__ignoreMap":27},[14,349,350,351,354,355,358],{},"事故か設定崩れかと思って調べさせたが、どちらでもなかった。\n7ヶ月前から置いてある1行を、Claude Code 2.1.210 が新しく警告するようになっただけだった。\nファイル権限のチェックにマッチするのは ",[25,352,353],{},"Edit(path)"," のルールで、",[25,356,357],{},"Write(...)"," 形式は元から効いていない。",[14,360,361,362,364,365,368,369,372],{},"効かないものを残す理由はないので、削除させた。\nJSON として壊れていないこと、",[25,363,357],{}," 形式のルールが0件になったことまで確認済みである。\n",[25,366,367],{},"Edit(.claude/**)"," は残してあるので、",[25,370,371],{},".claude"," 配下の編集許可はこれまでどおり効く。",[35,374,375],{"id":375},"残ったもの",[157,377,378,381,384,387],{},[160,379,380],{},"「dev を止めろ」というガードは、止められない事情（別セッションが立てた dev）を想定していなかった。禁止で守るより、競合そのものを消すほうが運用に耐える",[160,382,383],{},"新しいガードは、壊した状態を作って止まるところを見るまで信用しない",[160,385,386],{},"分離ガードが見ているのは generate の開始時だけで、走り出したあとに dev が立ち上がる分には無防備なまま",[160,388,389,391],{},[25,390,254],{}," はプロセスを片付けない。セッションを増やした日は、残骸がメモリを持っていく",{"title":27,"searchDepth":393,"depth":393,"links":394},2,[395,396,397,398,399,400,401,402],{"id":37,"depth":393,"text":37},{"id":88,"depth":393,"text":89},{"id":145,"depth":393,"text":145},{"id":185,"depth":393,"text":186},{"id":248,"depth":393,"text":248},{"id":320,"depth":393,"text":321},{"id":334,"depth":393,"text":334},{"id":375,"depth":393,"text":375},"dev",null,"所要時間計測スクリプトがガードで止まったのをきっかけに、pnpm dev と pnpm generate が共有していた .nuxt と Content の SQLite を分離した。ついでに走りっぱなしのプロセスを一覧する /procs も作った。","md",{},true,"/deploy-while-dev-running","mdx-playground",false,"2026-07-31T00:00:00.000Z",{"title":5,"description":405},"2026-07/2026-07-31/deploy-while-dev-running",[416,417,418,419,420],"Nuxt","デプロイ","SQLite","Claude Code","開発環境","C3rOqGiwBrtyggJiks0pXdE5rRnX0uTRG6iWcv6_o1s",[],[424,428,431,435,439],{"title":425,"path":426,"publishedAt":427},"herdr Windowsベータ導入とFeliCa勤怠構想、Claude Code警告の退治まで — 開発ツールと環境整備の一日","/herdr-felica-and-env-fixes","2026-07-15T00:00:00.000Z",{"title":429,"path":430,"publishedAt":412},"2026年7月31日の開発日記 - 消えたファイルの原因を物証で特定した日","/2026-07-31-diary",{"title":432,"path":433,"publishedAt":434},"開発環境のバックアップを仕上げ、復旧手順をスキル化してGitHubで版管理する","/claude-env-backup-and-restore-skill","2026-07-30T00:00:00.000Z",{"title":436,"path":437,"publishedAt":438},"苦手な語だけを解き直すページを作った日 - 正解1回で消える穴と、自動再生設定のD1同期漏れ","/weak-words-page-and-d1-settings-sync","2026-07-27T00:00:00.000Z",{"title":440,"path":441,"publishedAt":442},"覚えのないデプロイの犯人は自分の別セッションだった — Claude Codeマルチセッション運用の落とし穴","/claude-code-multi-session-deploy-mystery","2026-07-25T00:00:00.000Z","https://log.eurekapu.com/og/blog/deploy-while-dev-running.png?v=2026-07-31T00%3A00%3A00.000Z&title=dev%20%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%92%E6%AD%A2%E3%82%81%E3%81%9A%E3%81%AB%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%80%81Nuxt%20%E3%81%AE%E3%83%93%E3%83%AB%E3%83%89%E5%87%BA%E5%8A%9B%E5%85%88%E3%81%A8%20Content%20DB%20%E3%82%92%E5%88%86%E3%81%91%E3%81%9F&author=Kei%20Komatsu&sig=6cfaa8d70e146948",1785552631720]