基本を整理
Dockerfileとは、dockerイメージを作成するためのテキストファイル。つまり「Dockerイメージの設計図」
Dockerfileの書き方としては、「FROM」,「RUN」,「CMD」などを記述し、作成します。
作成したものから読み解いていく
Webアプリのために(chatGPT)が作成したdockerファイルを見ていく。
# ベースイメージを指定
FROM maven:3.8.3-openjdk-17-slim AS build
# 作業ディレクトリを指定
WORKDIR /app
# Maven Wrapperのセットアップ
COPY .mvn .mvn
# Mavenプロジェクトをビルド
COPY pom.xml .
RUN mvn -B dependency:go-offline
# アプリケーションのビルド
COPY src src
RUN mvn -B package -DskipTests
# 本番用の軽量なJREベースイメージを使用
FROM openjdk:17-jdk-slim
# アプリケーションのJARファイルをコピー
COPY --from=build /app/target/*.jar /app/app.jar
# アプリケーションの実行
CMD ["java", "-jar", "/app/app.jar"]
ひとつずつ見ていく
# ベースイメージを指定
FROM maven:3.8.3-openjdk-17-slim AS build
Dockerfileの中で一番最初に記述されるべき命令
Dockerイメージのベースとなるイメージを指定
# 作業ディレクトリを指定
WORKDIR /app
コマンドを実行する作業ディレクトリを指定
後続の命令が実行される作業ディレクトリを指定。ここでは、/appディレクトリが作業ディレクトリとして使用
# Maven Wrapperのセットアップ
COPY .mvn .mvn
ホスト(ローカル)のファイルやディレクトリをDockerイメージにコピー。
具体的な使い方としては、ソースコードや設定ファイルはローカルで作成して、COPYを使ってDockerイメージにコピーして使用する。
つまり、ここではホストの「.mvn」をdockerイメージ内の「/app/.mv」にコピーしている。
# Mavenプロジェクトをビルド
COPY pom.xml .
RUN mvn -B dependency:go-offline
Dockerイメージ内で、シェルコマンド実行をする
ここでは、pomファイルのコピーをして、依存関係の解決をする。アプリビルドの準備的な立ち位置。必須ではないが、ビルドプロセスを高速化させるため、実行することが一般的。
# アプリケーションのビルド
COPY src src
RUN mvn -B package -DskipTests
ソースコードをDockerイメージにコピーし、アプリをビルド
後続で使用するjarファイルがtarget配下に生成される
# 本番用の軽量なJREベースイメージを使用
FROM openjdk:17-jdk-slim
またFROMがある(詳しくはおまけに記載)
新しいベースイメージを指定
ここでは、Javaアプリケーションを実行するために使用する軽量なJREイメージを指定
# アプリケーションのJARファイルをコピー
COPY --from=build /app/target/*.jar /app/app.jar
ビルドステージ(buildステージ)から生成されたJavaアプリケーションのJARファイルをコピーする。
「--from=build」と記述しないと、直近でFROM指定したイメージから取得してきてしまう(ない)
# アプリケーションの実行
CMD ["java", "-jar", "/app/app.jar"]
dockerコンテナが実行されるときに、実行されるデフォルトのコマンドを指定
ここでは 「java -jar /app/app.jar」を実行するように記載している
参考
おまけ_ステージについてChatGPTに聞いてみた
ステージ(stages)とは、Dockerfile内で複数の環境を定義し、それぞれの環境で異なる作業を行う方法です。マルチステージビルドは、1つのDockerfile内で複数の段階(ステージ)を持つことができ、各段階で異なる作業が行われます。
典型的なマルチステージビルドの流れは次のようになります:
最初のステージ(buildステージ): このステージでは、ビルド用の環境が設定されます。通常、ビルドツールやコンパイラが含まれるイメージが使用されます。このステージでは、プロジェクトの依存関係を解決し、アプリケーションのビルドが行われます。
2番目以降のステージ(実行ステージなど): これらのステージでは、ビルドされたアプリケーションが実行されるための環境が設定されます。通常、実行に必要な最小限のコンポーネントのみが含まれるイメージが使用されます。このステージでは、ビルドステージからビルドされた成果物がコピーされ、アプリケーションが実行されます。
マルチステージビルドの利点は、Dockerイメージのサイズを最小限に抑えることができることです。ビルドツールやコンパイラなどの開発用のツールは、実行時に必要ないため、最終的なイメージに含める必要がありません。このように、マルチステージビルドを使用することで、最終的なDockerイメージのサイズが小さくなり、セキュリティとパフォーマンスが向上します。
つまり、ビルドと実行の環境を分けて最終的なイメージは必要最低限にするといいよね