BuildKit

build時の命令実行形式の変更

  • BuildKitを無効:Dockerfileの命令を上から逐次的に実行
  • BuildKitを有効:依存関係を解析し、依存しないステップを並列実行可能

build時のセキュアな秘密情報の受け渡し

--mount=type=secret--mount=type=sshが導入されて、build時にシークレット情報をセキュアに渡すこと可能になった。
(今まではbuild時にシークレット情報を渡した場合に、imageにシークレット情報が埋め込まれてしまう場合があった)

build時にGitHubからCloneするために秘密鍵を渡す例

FROM alpine

RUN apk update && \
    apk add git openssh-client

# ssh-keyscan で known_hosts を登録(StrictHostKeyChecking no に倒さずホスト認証を行う)
RUN mkdir -p -m 0700 /root/.ssh && ssh-keyscan github.com >> /root/.ssh/known_hosts
RUN --mount=type=secret,id=ssh,dst=/root/.ssh/id_ed25519 GIT_SSH_COMMAND='ssh -i /root/.ssh/id_ed25519' git clone 

秘密鍵は以下の方法で作成した。
パスフレーズを設定すると--mount=type=secretではエラーになるので、パスフレーズなしで作成。

ssh-keygen -t ed25519 -C "your_email@example.com"

ref. https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent

$ docker build -t github:latest --secret id=ssh,src=$HOME/.ssh/id_ed25519 .

秘密鍵は、imageに残らない。

--progressオプションを指定すれば詳細を表示しながらbuildされる。

$ docker build  --no-cache --progress=plain -t github:latest --secret id=ssh,src=$HOME/.ssh/id_ed25519 .

Docker内でDockerを動かす(DooD)

Dockerコンテナ内でDockerデーモンを使用する手法として Docker Outside of Docker (DooD) がある。 ホストのDockerデーモンをコンテナ内から使用するためにdockerソケットをマウントしてコンテナを起動する。

$ docker run -itd -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/var --name skynet your-org/ci-docker-pack

※ ローカルのdockerソケット

$ ll /var/run/docker.sock
lrwxr-xr-x  1 root  daemon    38B  4 11 08:55 /var/run/docker.sock -> /Users/<username>/.docker/run/docker.sock

サンプルのdocker compose.ymlで実行

docker compose.yml ```yml services: nginx: image: nginx:latest ports: - 8080:80 volumes: - ./src:/usr/share/nginx/html - ./nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php-fpm php-fpm: image: my-php-fpm build: context: . dockerfile: ./php-fpm/Dockerfile volumes: - ./src:/var/www/html ```
$ docker exec -it skynet /bin/bash
bash-5.1# cd /var
bash-5.1# docker compose build
[+] Building 10.7s (5/5) FINISHED
...

DOCKER_BUILDKIT=1を明示的に有効化してもエラーは発生しない。

env DOCKER_BUILDKIT=1 docker compose build
[+] Building 1.8s (5/5) FINISHED
...

対応策

CircleCIなどのCI環境でDockerコマンドを実行する場合、ホストのソケットを直接共有するのではなく setup_remote_docker や Dedicated runner を使用することが推奨される。