🐳

compose.yamlのdepends_onは起動順であって、ビルド順ではない

に公開

TL;DR

compose.yamlには、depends_on句があるが、あれを使ってマルチステージビルドを制御することはできない。なぜなら、depends_onは起動順を制御するためのプロパティだから。

背景

複数のDockerfileの依存関係を管理する手法として、docker composeが使えるのではないかと思って、調べてみるとdepends_onっていうよさげな管理情報がつけられることが判明。でも、それを使っても、docker compose buildがうまくいかなくて悩んだ末の結果。

複数ファイルのdocker buildはオレオレスクリプトでやるしかないのか?

$ ls
A.Dockerfile  compose.yaml  depend_on_A.Dockerfile
$ docker compose build depend_on_a_builder 
Compose can now delegate builds to bake for better performance.
 To do so, set COMPOSE_BAKE=true.
[+] Building 1.3s (2/2) FINISHED                                                                                                                                                        docker:default
 => [depend_on_a_builder internal] load build definition from depend_on_A.Dockerfile                                                                                                              0.0s
 => => transferring dockerfile: 150B                                                                                                                                                              0.0s
 => WARN: InvalidDefaultArgInFrom: Default value for ARG ${IMAGE_A} results in empty or invalid base image name (line 2)                                                                          0.0s
 => ERROR [depend_on_a_builder internal] load metadata for docker.io/library/image_a:latest                                                                                                       1.3s
------
 > [depend_on_a_builder internal] load metadata for docker.io/library/image_a:latest:
------
failed to solve: image_a: failed to resolve source metadata for docker.io/library/image_a:latest: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
compose.yaml
services:
  a_builder:
    build:
      context: .
      dockerfile: A.Dockerfile
      target: export-stage
    image: image_a
  depend_on_a_builder:
    build:
      context: .
      dockerfile: depend_on_A.Dockerfile
      target: export-stage
      args:
        - IMAGE_A=image_a
    depends_on:
      - a_builder

A.Dockerfile
FROM ubuntu20.04:latest AS base

RUN touch /A.result

FROM scratch AS export-stage
COPY --from=base /A.result /
depend_on_A.Dockerfile
ARG IMAGE_A
FROM ${IMAGE_A} AS image_a

FROM scratch AS export-stage
COPY --from=image_a /A.result /

Discussion