第23章:docker compose runで“一回だけ実行”を武器にする🗡️🧴
この章は「migrate / seed / test / lint みたいな“単発コマンド”を、全部コンテナ経由に統一して、作業手順を短くする」回です😎✨ 結果として、「READMEが長くならない」「人によって手順がブレない」「ローカルが汚れない」が一気に進みます🚀
1) runって結局なに?🤔➡️“使い捨て作業部屋”です🏠🧹
docker compose run は、サービス設定(volumes/env/networkなど)を借りて、別コンテナを新規に作り、コマンドを1回だけ実行してくれるコマンドです。(Docker Documentation)
ポイントは2つ👇(ここ超大事!)
runで渡したコマンドは、サービスに書いてあるcommand:を 上書きします🧠(Docker Documentation)runは ports を自動では公開しません(ポート衝突防止)🚫🔌(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 dbのdbは “サービス名” です📛 コンテナ同士はサービス名で繋がる、あの世界観ですね🕸️📡
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分で“武器化”⚔️)🎮✨
-
Lintを単発で回す
docker compose run --rm --no-deps api npm run lint
-
マイグレーションを単発で回す
docker compose run --rm api npm run migrate
-
「ポートが必要な単発」を想定して
--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にしたい。安全な例を出して」
まとめ🎁✨
docker compose runは 単発実行の標準化に効く🗡️(Docker Documentation)--rmを付けると運用がキレイ🧹(Docker Documentation)- DBいらない作業は
--no-depsで爆速🏎️(Docker Documentation) - ports が要る単発は
--service-ports/-p🔌(Docker Documentation)
次の第24章(ログ運用)に行くと、「単発実行した結果をログで追う」が自然につながって、デバッグ速度が上がります🕵️♂️💨