20
17

More than 3 years have passed since last update.

docker-composeでコンテナの初回起動時に特定の処理を行う方法

Last updated at Posted at 2020-07-24

TL; DR

docker-composeでコンテナの初回起動時に特定の処理を行う方法を簡潔にまとめました。

  1. 初回起動判定付きのシェルスクリプトを作成する
  2. docker inspect コマンドでベースイメージのENTRYPOINTとCMDを調べる
  3. シェルスクリプト → ENTRYPOINT → CMDの順で実行するように設定する

経緯

Dockerfile内でコンテナ初回起動時のみ特定の処理を行うように設定する場合、初回起動判定を仕込んだdocker-entrypoint.shをENTRYPOINTに指定するのが一般的ですが、docker-composeの設定だけでコンテナ初回起動時に処理を挟みたいときにはどうしたら良いのか気になったので試してみました。

※ docker-entrypoint.shについてはこちらの記事の解説が分かりやすいです。
dockerで初回起動時のみ特定の処理を行うヘルパースクリプト(docker-entrypoint.sh)

サンプル

ディレクトリ構成

tree
.
├── db
│   ├── init
│   │   └── 01_create_users.sql
│   └── tmp
│       └── container-init.sh
└── docker-compose.yml

初回起動判定付きのシェルスクリプト

container-init.sh
if [ ! -e '/check' ]; then
    touch /check
    # 初回起動時に実行させたいコマンドをここに書く
    echo "セットアップ"
else
    # 2回目以降
    echo "セットアップ済"
fi

docker inspect

ベースイメージがローカルに無い場合は事前に取得してから docker inspect でENTRYPOINTとCMDを確認します。

$ docker pull mysql:5.7
5.7: Pulling from library/mysql
6ec8c9369e08: Pull complete
177e5de89054: Pull complete
ab6ccb86eb40: Pull complete
e1ee78841235: Pull complete
09cd86ccee56: Pull complete
78bea0594a44: Pull complete
caf5f529ae89: Pull complete
4e54a8bcf566: Pull complete
50c21ba6527b: Pull complete
68e74bb27b39: Pull complete
5f13eadfe747: Pull complete
Digest: sha256:97869b42772dac5b767f4e4692434fbd5e6b86bcb8695d4feafb52b59fe9ae24
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

$ docker inspect mysql:5.7 --format='{{.Config.Entrypoint}}'
[docker-entrypoint.sh]

$ docker inspect mysql:5.7 --format='{{.Config.Cmd}}'
[mysqld]

docker-compose

docker-compose.ymlでentrypointタグで上書きすると、DockerfileのENTRYPOINTとCMDが無視されるので、まとめて指定します。

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: sample
    ports:
      - 3306:3306
    volumes:
      - ./db/tmp:/tmp # container-init.shをコンテナから参照できるようにするため
      - ./db/init:/docker-entrypoint-initdb.d
      - ./db/data:/var/lib/mysql
    container_name: sample-db
    entrypoint: >
      sh -c "
        sh /tmp/container-init.sh &&
        docker-entrypoint.sh mysqld \
          --character-set-server=utf8mb4 \
          --collation-server=utf8mb4_unicode_ci
      "
    # commandタグで指定していたものはentrypointタグでまとめて指定する
    # command: >
    #   --character-set-server=utf8mb4
    #   --collation-server=utf8mb4_unicode_ci

リポジトリ

20
17
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
17