docker compose run で個別に立ち上げたコンテナを restart で再起動させない方法

どうも、にしむらです。

最近になって開発環境のcomposeコマンドをdocker-composeからdocker composeに変更したのですが、挙動が異なる事があります。

例えば、Railsの開発ではサーバー以外にも個別にスクリプトやコマンドを実行したい場合にrunを使います。

例では Railsサービスをappとしています。

動作確認環境 - Mac OS 11.6.5 - Docker Desktop 4.8.1

docker-compose run --rm app bash
# or
docker compose run --rm app bash

runを使うことで別のコンテナ(プロセス)が立ち上がり個別にコマンドが実行できます。

# ログの表示
docker compose run --rm app tail -f ./logs/develop.log
# Railsコンソール立ち上げ 
docker compose run --rm app bin/rails c 

便利なのですが、サーバーを再起動するために docker compose restart app を実行すると、 docker-compose resatrt app では docker-copmpose up -dコマンドで立ち上げたサーバーコンテナだけが再起動するのですが、 docker compose restart app では run コマンドで立ち上げたコンテナも含めて再起動します。

私はrunでたくさんのプロセスを立ち上げており非常に不便だったのですが、これを回避する方法をようやく見つけました。

コマンド実行用サービスを作成する

新たに個別コマンド実行用サービスをdocker-compose.ymlに定義することでrestart時に巻き添えをくらわないようになりました。

services:
  app: &app
    container_name: my-app
    build:
      context: .
#### 省略
    tty: true
    stdin_open: true

  cmd:
    <<: *app
    container_name: my-cmd
    command: bash
    ports:
      - "3000"

ただ、できればdocker compose up -dした時はサービスcmdを立ち上げたくもないです。

そんな時は、docker-compose.ymlprofilesを指定することで回避できます。proflilesを利用するにはversion: '3.9'にする必要があります。

Compose でのプロファイル利用

version: '3.9'

services:
  app: &app
    container_name: my-app
    build:
      context: .
#### 省略
    tty: true
    stdin_open: true

  cmd:
    <<: *app
    container_name: my-cmd
    command: bash
    ports:
      - "3000"
    profiles:
      - tools

docker-compose.ymlprofilesを記述したサービスは、 コマンドラインオプション--profileで指定しないと使用することは出来ません。

docker compose --profile tools up -d # app, cmdコンテナが起動

なので私はdocker compose up -dで開発環境を起動し、個別にコマンドを実行したい場合に docker compose run --rm cmd [コマンド]を実行します。

ところで、docker compose stopをするとどうなるでしょうか?

なんと、profiles指定したコンテナを含めてすべて停止してくれます、かゆいところに手が届いて素敵だと思いました。

インゲージではエンジニアを募集しています!

ingage.co.jp