🛳️

Docker内のファイル生成とホストへのコピーをコマンド一つでやる

2024/02/09に公開

前提

ローカルとは別の、綺麗な環境で作ったファイルが欲しいことがある。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 --from=gem-stage /foo_work/packed_gems.zip /

コマンド実行

--outputオプションで、barディレクトリに二番目のステージの/以下のファイルを出力している。
BuildKitの有効化のため、DOCKER_BUILDKIT=1の指定が必要な旨がドキュメントに記載されているが、実際はなくても動作していそうだった。

DOCKER_BUILDKIT=1 docker build --output bar .

参考

https://docs.docker.jp/engine/reference/commandline/build.html#id9

Discussion