C++ アプリケーションに対してのマルチステージビルドの生成
前提条件
- git クライアント を持っていること。 本節における例では、コマンドラインベースの Git クライアントを用いることにします。 クライアントはどのようなものでも利用可能です。
概要
この節では C++ アプリケーション用のマルチステージ Docker ビルドの生成について説明しています。 マルチステージビルドは、ビルド過程でのさまざまなステージにおいて、さまざまなベースイメージを使用できるようにする Docker 機能です。 これにより最終イメージのサイズを最適化し、ビルド時の依存関係を実行時の依存関係から分離できます。
C++ などのようなコンパイル言語における標準的な方法として、コードをコンパイルするためのビルドステージと、コンパイル済みバイナリを実行するためのランタイムステージの 2 つを用意します。 こうするのは、実行時にはビルド時の依存パッケージが必要ないからです。
サンプルアプリケーションの入手
端末に Hello, World! を出力する単純な C++ アプリケーションを用いていきます。
これ行うために、本ガイドで利用するサンプルリポジトリをクローンします。
$ git clone https://github.com/dockersamples/c-plus-plus-docker.gitここに示す例は、リポジトリ内の hello ディレクトリ配下にあります。
そのディレクトリに入って、ファイルを見てみます。
$ cd c-plus-plus-docker/hello
$ ls以下のようなファイルが表示されます。
Dockerfile hello.cppDockerfile の確認
IDE またはテキストエディターを使って Dockerfile を開きます。
Dockerfile には Docker イメージをビルドする命令が含まれています。
# ステージ 1: ビルドステージ
FROM ubuntu:latest AS build
# C++ コードコンパイルのための build-essential インストール
RUN apt-get update && apt-get install -y build-essential
# ワーキングディレクトリの設定
WORKDIR /app
# コンテナーへのソースコードコピー
COPY hello.cpp .
# C++ コードをスタティックコンパイルし、ランタイムライブラリへの依存をなくす
RUN g++ -o hello hello.cpp -static
# ステージ 2: ランタイムステージ
FROM scratch
# ビルドステージからのスタティックバイナリのコピー
COPY --from=build /app/hello /hello
# バイナリを実行するコマンド
CMD ["/hello"]Dockerfile にはステージが 2 つあります。
- ビルドステージ: このステージはイメージとして
ubuntu:latestを利用し、C++ コードをコンパイルしてスタティックバイナリを生成します。 - ランタイムステージ: このステージは
scratchイメージを利用しますが、これは空のイメージです。 ビルドステージからスタティックバイナリをコピーしてそれを実行します。
Docker イメージのビルド
Docker イメージをビルドするため、hello ディレクトリに入って以下のコマンドを実行します。
$ docker build -t hello .-t フラグはこのイメージに対して hello という名前をつけるものです。
Docker コンテナーの実行
Docker コンテナーを起動するため、以下のコマンドを実行します。
$ docker run hello端末に Hello, World! が出力されます。
まとめ
本節では C++ アプリケーション向けにマルチステージビルドの生成方法について学びました。 マルチステージビルドは最終イメージのサイズを最適化し、ランタイムの依存パッケージからビルド時の依存パッケージを切り離します。 本例における最終イメージにはスタティックイメージしか含まれず、ビルド時の依存パッケージは含まれていません。
イメージとして空のイメージをベースとしたため、普通にあるような OS ツールが含まれていません。
したがってコンテナー内では、たとえば ls といった単純なコマンドすら実行することはできません。
$ docker run hello lsこうしてイメージを軽量にそしてセキュアに作り出します。