Docker 25.0 でヘルスチェックに start-interval オプションが追加された

Docker にはヘルスチェック機能があるが、25.0start-interval オプションが追加された。

The options that can appear before CMD are:

  • --interval=DURATION (default: 30s)
  • --timeout=DURATION (default: 30s)
  • --start-period=DURATION (default: 0s)
  • --start-interval=DURATION (default: 5s)
  • --retries=N (default: 3)

...

start interval is the time between health checks during the start period. This option requires Docker Engine version 25.0 or later.

HEALTHCHECK - Dockerfile reference | Docker Docs

いままでは、以下のように interval 間隔でヘルスチェックがされていた。 このとき start-period を指定していると、コンテナ開始から指定した時間が経過するまでは失敗しても無視されるという動作をする。

 |<------- start-period(10s) --------->|
 |<- interval(5s) ->|<- interval(5s) ->|<- interval(5s) ->|<- interval(5s) ->|
 |
 +------------------+------------------+------------------+------------------+
 ^                  ^                  ^                                           
 |                  |                  |                                            
失敗               失敗               成功                                            

start-interval を指定すると、start-period の時のヘルスチェック間隔を設定できる。使い道としては、Docker Compose で depends_onservice_healthy を指定する時に起動が完了するまで待ち、立ち上がったら素早くhealthy状態に移行できるように高頻度でヘルスチェックしつつ、通常のヘルスチェックを頻繁にしなくするということができる。

なお、start-period 期間内でヘルスチェックを通ると指定した時間が経過していなくても、通常のヘルスチェックに移行する。

- SI: start-interval

 |<-------- start-period(3s) ---------->|
 |<- SI(1s) ->|<- SI(1s) ->|<- SI(1s) ->|<---------------- interval(10s) ---------------->|
 |
 +------------+------------+------------+-------------------------------------------------+
 ^            ^            ^            ^                                           
 |            |            |            |                                            
失敗         失敗         失敗         成功                                            

Docker Compose では compose.yaml で以下のように指定できる。

compose.yaml:

services:
  app:
    ...
    depends_on:
      db:
        condition: service_healthy
  db:
    image: mysql:8
    volumes:
      - type: volume
        source: mysql_data
        target: /var/lib/mysql
    ports:
      - target: 3306
        published: 3306
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
      start_period: 10s
      start_interval: 1s
      interval: 600s
      timeout: 30s
      retries: 0
volumes:
  mysql_data: