🛳️
Docker内のファイル生成とホストへのコピーをコマンド一つでやる
前提
ローカルとは別の、綺麗な環境で作ったファイルが欲しいことがある。Dockerを使う場合、ホストのディレクトリをバインドマウントしたり、コンテナを立ち上げてからdocker cp
したりすることが多い。
実はいちいちコンテナを起動しておかなくても、--output
オプションを使うとコマンド一発でできるのだが、この情報に辿り着くまで時間がかかったのでメモしておく。
手順
例えばDocker環境内でインストールしたgemを手元に持ってくる場合は、下記のようになる。
Gemfileの作成
# frozen_string_literal: true
source "https://rubygems.org"
gem "rails"
Dockerfileの作成
最初のステージで成果物を生成し、二番目のステージでそれを自身のルートへコピーしている。二番目のステージはFROM scratch
で、余計なファイルを含まない環境になっている。
FROM ruby:3.2.0 AS gem-stage
WORKDIR /foo_work
COPY Gemfile /foo_work
RUN apt update && apt install -y zip
RUN gem update bundler
RUN bundle config set --local path 'vendor/bundle'
RUN bundle install
RUN zip -r packed_gems.zip ./vendor/bundle
FROM scratch
COPY /foo_work/packed_gems.zip /
コマンド実行
--output
オプションで、barディレクトリに二番目のステージの/以下のファイルを出力している。
BuildKitの有効化のため、DOCKER_BUILDKIT=1
の指定が必要な旨がドキュメントに記載されているが、実際はなくても動作していそうだった。
DOCKER_BUILDKIT=1 docker build --output bar .
参考
Discussion