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

第23章:docker compose runで“一回だけ実行”を武器にする🗡️🧴

この章は「migrate / seed / test / lint みたいな“単発コマンド”を、全部コンテナ経由に統一して、作業手順を短くする」回です😎✨ 結果として、「READMEが長くならない」「人によって手順がブレない」「ローカルが汚れない」が一気に進みます🚀


1) runって結局なに?🤔➡️“使い捨て作業部屋”です🏠🧹

docker compose run は、サービス設定(volumes/env/networkなど)を借りて、別コンテナを新規に作り、コマンドを1回だけ実行してくれるコマンドです。(Docker Documentation)

ポイントは2つ👇(ここ超大事!)

  1. run で渡したコマンドは、サービスに書いてある command:上書きします🧠(Docker Documentation)
  2. runports を自動では公開しません(ポート衝突防止)🚫🔌(Docker Documentation) 公開したいときだけ --service-ports-p を付けます✅(Docker Documentation)

2) run / exec / up の使い分け🍱

迷ったらこの3行でOKです🙆‍♂️

  • up:いつもの“常駐チーム”(API/DB/Redis/Worker)を起動🏃‍♂️🏃‍♀️
  • exec起動中のコンテナの中でコマンドを叩く🛠️(TTYがデフォで付く)(Docker Documentation)
  • run新しい単発コンテナを作って、コマンドを1回だけ実行🎯(Docker Documentation)

exec は「すでに走ってる箱に入って作業」👷 run は「作業用の使い捨て箱を作って終わったら捨てる」🧴🗑️ …って覚えると一生忘れません😆


3) “事故率が下がる”run の黄金テンプレ🥇✨

基本はこれだけでOK👇

docker compose run --rm <service> <command...>

--rm を付けると、終わったらコンテナを自動削除してくれます🧹(単発のゴミが溜まりにくい)(Docker Documentation)

さらによく使う追加オプション👇

  • --no-deps:依存サービス(DBなど)を 起動しない🛑(lint/test に便利)(Docker Documentation)
  • --service-ports:そのサービスの ports を 公開して実行🔌(GUI系/Studio系に便利)(Docker Documentation)
  • -e KEY=VAL / --env-from-file:単発実行だけ env を足す🔑(Docker Documentation)
  • -T:TTYを切る(CIやスクリプトで詰まりにくい)🤖(Docker Documentation)

4) “単発コマンド”の定番レシピ集🍳✨(migrate/seed/test/lint)

ここからは、サービス名を例として api / db で書きます📌 (あなたのComposeのサービス名に合わせて読み替えればOK👌)


4.1 Lint(DBいらない)🧼✨

docker compose run --rm --no-deps api npm run lint

狙い:DBを起こさない=速い🏎️💨 --no-deps は “DBいらない作業” で超効きます。(Docker Documentation)


4.2 TypeCheck(DBいらない)🧠✅

docker compose run --rm --no-deps api npm run typecheck

4.3 Test(DBいらない/いる で分ける)🧪🔥

DB不要テスト(ユニット中心):

docker compose run --rm --no-deps api npm test

DB必要テスト(統合/E2Eなど):

docker compose run --rm api npm run test:integration

run は必要に応じて関連サービスを起動することがあるので、「DB要る/要らない」を明示して事故を減らすのがコツです🧯(Docker Documentation)


4.4 DBマイグレーション(だいたいDB要る)🐘📦

docker compose run --rm api npm run migrate

ここが気持ちいいポイント👇

  • 「どのPCでも同じコマンド」になる🧬
  • ローカルにツールを入れなくていい🙌
  • READMEが「この1行でOK」になりがち📘✨

4.5 Seed(初期データ投入)🌱✨

docker compose run --rm api npm run seed

4.6 DBに“中から”入る(psqlなど)🧑‍🚀🔍

公式ドキュメントにもある定番の形です👇(db サービスで psql を起動)(Docker Documentation)

docker compose run --rm db psql -h db -U <user>

コツ:-h dbdb は “サービス名” です📛 コンテナ同士はサービス名で繋がる、あの世界観ですね🕸️📡


5) “ポートが必要な単発コマンド”は --service-ports 🎛️🔌

run は ports を公開しない仕様なので、GUI/Studio系を単発で立ち上げるときはこうします👇(Docker Documentation)

docker compose run --rm --service-ports api npm run studio

もし ports を手動で指定したいなら -p でもOK👇(Docker Documentation)

docker compose run --rm -p 5555:5555 api npm run studio

6) “文章の手順”を減らす小ワザ:コマンドの別名を作る🪄📝

「毎回 docker compose run ... を打つのめんどい!」ってなったら、別名で短縮しちゃいましょう😆

例:package.json(ルート)に“ショートカット”を作る発想👇 (これ自体はホストで動くけど、実処理はコンテナに寄せられるので目的は達成できます🙆‍♂️)

{
"scripts": {
"dc:lint": "docker compose run --rm --no-deps api npm run lint",
"dc:test": "docker compose run --rm --no-deps api npm test",
"dc:migrate": "docker compose run --rm api npm run migrate",
"dc:seed": "docker compose run --rm api npm run seed"
}
}

これで👇みたいに短くなります✨

npm run dc:migrate

7) よくある詰まりポイント🧯(ここだけ読めば助かるやつ)

A) 「なんかポートに繋がらない」😵

run は ports を公開しません🚫🔌 👉 --service-ports を付けるか、-p を付けましょう。(Docker Documentation)

B) 「DBが起きてなくて失敗する」🐘💥

--no-deps を付けたまま migrate してる、があるあるです😂 👉 DB要る作業では --no-deps を外す!

C) 「スクリプト/CIで止まる(TTYまわり)」🤖🧱

exec はデフォでTTYを割り当てる設計です。スクリプト用途では --interactive=false などを使う場面があります。(Docker Documentation) run 側でも -T(TTY無効)を使うと詰まりにくいことがあります。(Docker Documentation)


8) 演習(3分で“武器化”⚔️)🎮✨

  1. Lintを単発で回す

    • docker compose run --rm --no-deps api npm run lint
  2. マイグレーションを単発で回す

    • docker compose run --rm api npm run migrate
  3. 「ポートが必要な単発」を想定して --service-ports で起動してみる

    • docker compose run --rm --service-ports api <何かポートを使うコマンド>

できたら勝ちです🏆🎉


9) AIに頼むときの“良い聞き方”🤖🗣️(サクッと)

Copilot/Codex系に聞くなら、こういう“条件付き”が強いです💪✨

  • docker compose run で migrate/seed/test/lint を統一したい。api サービスで動く npm scripts を提案して。DBが要る/要らないで --no-deps を使い分けたい」
  • run は ports を公開しないので、Studio系だけ --service-ports にしたい。安全な例を出して」

まとめ🎁✨

次の第24章(ログ運用)に行くと、「単発実行した結果をログで追う」が自然につながって、デバッグ速度が上がります🕵️‍♂️💨