docker compose runで使い捨てコンテナを起動する方法|exec・upとの使い分けとテスト・マイグレーション実行のCompose設計

運営:リナックスマスター.JP(代表 宮崎智広)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Docker > docker compose runで使い捨てコンテナを起動する方法|exec・upとの使い分けとテスト・マイグレーション実行のCompose設計
「マイグレーションだけ実行したいのに、docker compose up で全サービスが起動してしまう」
テスト実行時にデータベースコンテナだけ動かしたい、シェルスクリプトの挙動を確かめたい。そういった「コマンドを1回実行して終わり」の作業は、開発やCI パイプラインで頻繁に発生します。

その用途に設計されているのが docker compose run です。

この記事では、docker compose run の基本的な使い方から、docker compose exec・up との違い、データベースマイグレーションとテスト実行への応用まで解説します。Ubuntu 24.04 LTS および Docker Compose v2 系(compose-plugin)を想定環境として説明します。

この記事のポイント

・docker compose run はコンテナを1回起動してコマンドを実行・終了する命令
・--rm フラグを付けると実行後にコンテナが自動削除される
・exec は「起動済みのコンテナ」への接続で、run とは用途が異なる
・マイグレーション実行・テスト実行のCI設計に活用できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

docker compose run が解決する問題

docker compose up は、定義されたサービスを継続的に起動・維持するための命令です。Webサーバー・データベース・キャッシュサーバーを一括で起動するには便利ですが、「データベースのマイグレーションを走らせたい」「テストを1回実行したい」という用途には向いていません。

サービスを継続稼働させずに「コマンドを1回実行する」ための命令が docker compose run です。

主な用途は次のとおりです。

・データベースのマイグレーション(例: flask db migrate、php artisan migrate)
・テストスイートの実行(例: pytest、phpunit)
・データのシードや初期化スクリプト
・使い捨ての調査用コンテナ(bash起動)

docker compose run は、compose ファイルで定義されたサービスの設定(イメージ・ボリューム・環境変数・ネットワーク)を引き継ぎながら、指定したコマンドを実行します。これにより、開発環境と同じ設定でコマンドを走らせられます。

docker compose run の基本的な書き方

1. サービスを指定してコマンドを1回実行する

docker compose run の基本構文は次のとおりです。

docker compose run SERVICE COMMAND [ARGS...]

以下のように web サービスと db サービスが docker-compose.yml に定義されているとします。

# docker-compose.yml services: web: image: python:3.12-slim volumes: - .:/app working_dir: /app depends_on: - db db: image: postgres:16 environment: POSTGRES_DB: myapp POSTGRES_USER: myuser POSTGRES_PASSWORD: secret

この構成で web サービス上の Python スクリプトを1回実行するには、次のように書きます。

docker compose run web python manage.py migrate

コマンドが終了すると、web コンテナは停止します。ただし --rm を付けないかぎりコンテナは残り続けるため、繰り返し実行すると停止済みのコンテナが溜まっていきます。

2. --rm フラグで使い捨てコンテナにする

実行のたびに停止コンテナが溜まるのを防ぐには、--rm フラグを付けます。

docker compose run --rm web python manage.py migrate

--rm を付けると、コマンド終了と同時にコンテナが自動削除されます。開発やCI では常に付けておくのが一般的です。

3. エントリポイントと環境変数を上書きする

docker compose run は、起動時にコンテナのエントリポイントとコマンドを上書きできます。

bash でコンテナ内を調査するには次のように書きます。

docker compose run --rm --entrypoint /bin/bash web

環境変数を一時的に変更するには -e オプションを使います。

docker compose run --rm -e APP_ENV=test web python manage.py test

また、--no-deps を付けると depends_on で指定した依存サービスを起動せずに実行できます。db への接続が不要な単体テストに便利です。

docker compose run --rm --no-deps web python -m pytest tests/unit/

docker compose exec・up との使い分け

1. exec は起動済みコンテナへの接続

docker compose exec は、すでに起動しているコンテナ内でコマンドを実行します。

docker compose exec web bash

run との最大の違いは「新しいコンテナを作るかどうか」です。

・run: 新しいコンテナを起動してコマンドを実行する
・exec: 起動済みのコンテナ内でコマンドを実行する(コンテナを新規作成しない)

docker compose up でサービスが稼働中のときに調査・設定の確認をしたい場合は exec を使います。逆に、サービスが起動していない状態でコマンドを実行したい場合は run を使います。exec を使おうとしてサービスが起動していないとエラーになるため、ここを混同するとトラブルの原因になります。

2. up --no-deps で単一サービスを起動する

docker compose up --no-deps SERVICE は、指定したサービスだけを起動して維持します。

docker compose up --no-deps -d web

run とは異なり、このコマンドではサービスが継続稼働します。バックグラウンド起動(-d)と組み合わせて、特定のサービスだけを開発モードで動作させたい場合に使います。

3つの命令の使い分けを整理すると次のようになります。

・コマンドを1回実行して終わる → docker compose run --rm
・起動中コンテナに接続して調査する → docker compose exec
・サービスを継続稼働させる(依存なし)→ docker compose up --no-deps

Dockerコンテナの設計パターンについて体系的に学びたい場合は、Dockerセミナー(linuxmaster.jp)のカリキュラムも参考になります。

実践:マイグレーションとテスト実行のCompose設計

1. データベースマイグレーションを docker compose run で自動化する

データベースコンテナが起動している状態で、マイグレーションコマンドを実行するパターンです。

healthcheck を使うと、db が準備完了になるまで待ってから web を起動できます。

# docker-compose.yml services: db: image: postgres:16 environment: POSTGRES_DB: myapp POSTGRES_USER: myuser POSTGRES_PASSWORD: secret healthcheck: test: ["CMD-SHELL", "pg_isready -U myuser"] interval: 5s retries: 5 web: build: . depends_on: db: condition: service_healthy environment: DATABASE_URL: postgresql://myuser:secret@db:5432/myapp volumes: - .:/app working_dir: /app

この構成でマイグレーションを実行するには次のように書きます。

docker compose run --rm web python manage.py migrate

docker compose run は depends_on の条件も引き継ぐため、db が healthy になるまで待ってから web コンテナを起動し、マイグレーションを実行します。

Dockerfile のエントリポイントにマイグレーションを組み込む設計もありますが、マイグレーション失敗時にアプリが起動できなくなる問題が発生しやすいです。run で分離しておくほうが、失敗の原因が明確になります。
出力例(環境により異なります):

Operations to perform: Apply all migrations: auth, contenttypes, myapp, sessions Running migrations: Applying myapp.0001_initial... OK Applying myapp.0002_add_user... OK

2. テストスイートの実行とCI連携

テスト用のサービスを Compose ファイルに定義して run で呼び出す設計がCI では一般的です。

# docker-compose.yml services: db: image: postgres:16 environment: POSTGRES_DB: testdb POSTGRES_USER: testuser POSTGRES_PASSWORD: testpass test: build: . depends_on: - db environment: DATABASE_URL: postgresql://testuser:testpass@db:5432/testdb APP_ENV: test volumes: - .:/app working_dir: /app

GitHub Actions など CI パイプラインでの呼び出し例です。

# .github/workflows/test.yml 抜粋 - name: テストを実行する run: docker compose run --rm test pytest tests/ - name: コンテナを片付ける run: docker compose down -v

docker compose down -v を最後に実行すると、named volume も含めて片付けます。テストのたびにクリーンな状態で始められるため、テスト環境の汚染を防げます。

終了コードの扱いにも注意が必要です。docker compose run は実行したコマンドの終了コードをそのまま返します。pytest がテスト失敗で終了コード 1 を返せば、CI パイプラインは失敗として扱います。これにより、テスト失敗時に自動でデプロイを止める設計が自然に実現できます。

よくある問題と対処法

問題1: 実行後に停止コンテナが溜まっている

原因: --rm を付けずに run を繰り返した場合、停止したコンテナが残り続けます。

対処: --rm を常に付けるか、docker compose rm で停止コンテナをまとめて削除します。

# 停止済みコンテナをまとめて削除する docker compose rm -f

問題2: --no-deps を付けたときに接続エラーになる

原因: --no-deps を付けると depends_on に指定したサービスは起動しません。db が必要なコマンドで --no-deps を使うと、接続先がないためエラーになります。

対処: db が必要な場合は --no-deps を外します。db だけを先に起動しておく方法もあります。

# db だけを先に起動する docker compose up -d db # その後 web サービスでマイグレーションを実行する docker compose run --rm web python manage.py migrate

問題3: ポートにアクセスできない

原因: docker compose run はデフォルトでポートをホストに公開しません。compose ファイルの ports 設定は run 時には自動適用されません。

対処: -p オプションでポートを明示的に指定します。

docker compose run --rm -p 8080:8080 web python manage.py runserver 0.0.0.0:8080

まとめ

docker compose run の主なオプションをまとめます。
やりたいこと コマンド
コマンドを1回実行する docker compose run SERVICE COMMAND
実行後にコンテナを自動削除する docker compose run --rm SERVICE COMMAND
依存サービスを起動せずに実行する docker compose run --rm --no-deps SERVICE COMMAND
エントリポイントを上書きしてbashを起動する docker compose run --rm --entrypoint /bin/bash SERVICE
環境変数を一時的に変更して実行する docker compose run --rm -e VAR=value SERVICE COMMAND
ポートを指定して実行する docker compose run --rm -p HOST:CONTAINER SERVICE COMMAND
起動済みコンテナにコマンドを実行する docker compose exec SERVICE COMMAND
docker compose run は「1回コマンドを実行して終わる」という用途に特化した命令です。--rm を常に付けて使い捨てコンテナにすること、依存サービスの扱いを --no-deps で制御することが、Compose 設計の基本です。

マイグレーション・テスト実行・初期化スクリプトをすべて run で統一しておくと、CI パイプラインの組み立てがシンプルになります。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、
Dockerコンテナの設計から本番運用まで、体系的に学べるセミナーを開催しています。
詳細・日程は >> https://docker.linuxmaster.jp/ からご確認ください。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

運営

リナックスマスター.JP(代表 宮崎智広)

株式会社イーネットマーキュリーが運営するLinux教育サイトです。代表の宮崎智広は現役のLinuxサーバー管理者として20年以上の実務経験を持ち、累計3,100名以上のエンジニアを指導してきました。実践型のLinuxセミナーや無料マニュアルの配布を通じてLinux人材の育成に取り組んでいます。