Dockerfile によるコンテナの開発

1. 概要

Docker は、アプリケーションを開発、リリース、実行するためのオープン プラットフォームです。Docker を使用すると、アプリケーションをインフラストラクチャから分離して、インフラストラクチャをマネージド アプリケーションのように扱うことができます。また、コードのリリース、テスト、デプロイを高速化し、コード作成からコード実行までのサイクルを短縮できます。

Docker は、カーネル コンテナ化機能と、アプリケーションの管理およびデプロイをサポートするワークフローとツールを組み合わせることでこれらを実現します。

Docker コンテナは Kubernetes で直接使用できるため、Kubernetes Engine で簡単に実行できます。Docker の基本を学ぶことで、Kubernetes アプリケーションやコンテナ化アプリケーションを開発するスキルが身に付きます。

ラボの内容

このラボでは、次の方法について学びます。

  • サンプル アプリケーションに Dockerfile を作成する
  • イメージをビルドする
  • イメージをコンテナとしてローカルで実行する
  • コンテナの動作を変更する
  • イメージを Artifact Registry に push する

前提条件

これは入門レベルのラボです。Docker とコンテナを使用した経験がほとんどない、あるいはまったくない方を対象としています。Cloud Shell とコマンドラインの知識があれば役立ちますが、必須ではありません。

セルフペース型の環境設定

  1. Google Cloud Console にログインして、プロジェクトを新規作成するか、既存のプロジェクトを再利用します。Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください。

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • プロジェクト名は、このプロジェクトの参加者に表示される名称です。Google API では使用されない文字列で、いつでも更新できます。
  • プロジェクト ID は、すべての Google Cloud プロジェクトにおいて一意でなければならず、不変です(設定後は変更できません)。Cloud Console により一意の文字列が自動生成されます(通常は内容を意識する必要はありません)。ほとんどの Codelab では、プロジェクト ID を参照する必要があります(通常、プロジェクト ID は「PROJECT_ID」の形式です)。好みの文字列でない場合は、別のランダムな ID を生成するか、独自の ID を試用して利用可能であるかどうかを確認することができます。プロジェクトの作成後、ID は「フリーズ」されます。
  • 3 つ目の値として、一部の API が使用するプロジェクト番号があります。これら 3 つの値について詳しくは、こちらのドキュメントをご覧ください。
  1. 次に、Cloud のリソースや API を使用するために、Cloud Console で課金を有効にする必要があります。この Codelab の操作をすべて行って、費用が生じたとしても、少額です。このチュートリアルを終了した後に課金が発生しないようにリソースをシャットダウンするには、Codelab の最後にある「クリーンアップ」の手順を行います。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。

2. サンプル アプリケーション

このラボを円滑に進めるために、サンプル アプリケーションが提供されています。このセクションでは、コンテナ化プロセスに進む前に、ソースコードを取得し、ネイティブ形式でアプリケーションをビルドします。

ソースコード

このラボのソースコードは、GoogleCloudPlatform/container-developer-workshop リポジトリとサンプル アプリケーションのドキュメントから入手できます。

Git を構成

git config --global user.name ${USER}
git config --global user.email ${USER}@qwiklabs.net

サンプル アプリケーションの Cloud Source Repositories のリポジトリのクローンを作成する

gcloud source repos clone sample-app ${HOME}/sample-app &&
cd ${HOME}/sample-app &&
git checkout main

出力

Cloning into '/home/student_03_49720296e995/sample-app'...
remote: Finding sources: 100% (16/16)
remote: Total 16 (delta 0), reused 16 (delta 0)
Receiving objects: 100% (16/16), 47.23 KiB | 681.00 KiB/s, done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.

Project [qwiklabs-gcp-02-4327c4e03d82] repository [sample-app] was cloned to [/home/student_03_49720296e995/sample-app].
Branch 'main' set up to track remote branch 'main' from 'origin'.
Switched to a new branch 'main'

サンプル アプリケーションをビルドする

cd ${HOME}/sample-app
./mvnw compile

出力

[INFO] Scanning for projects...
...
[INFO] Compiling 1 source file to /home/student_03_49720296e995/sample-app/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  10.080 s
[INFO] Finished at: 2022-02-23T17:14:30Z
[INFO] ------------------------------------------------------------------------

サンプル アプリケーションを実行する

cd ${HOME}/sample-app
./mvnw exec:java

出力

[INFO] Scanning for projects...
...
Listening at http://localhost:8080

実行中のアプリケーションをプレビューする

  • Cloud Shell の [ウェブでプレビュー] ボタンをクリックします。
  • ポート 8080 で [プレビュー] をクリックする

次の手順

  • Cloud Shell で Ctrl+C キーを押して、実行中のアプリケーションを停止する

3. Dockerfile

Dockerfile によるアプリケーションのコンテナ化

アプリケーションをコンテナにパッケージ化する方法の一つは、Dockerfile を使用することです。この Dockerfile は、コンテナ イメージのアセンブル方法をデーモンに指示するスクリプトに似ています。詳細については、Dockerfile リファレンス ドキュメントをご覧ください。

サンプル アプリケーション リポジトリに空の Dockerfile を作成します。

touch ${HOME}/sample-app/Dockerfile

任意のエディタで Dockerfile を開きます。

vi ${HOME}/sample-app/Dockerfile

開始イメージを選択する

Dockerfile メソッドを使用してコンテナをビルドするには、コンテナを構築するアプリケーションに関する直接的な知識が必要です。Dockerfile を作成するための最初のステップは、イメージのベースとなるイメージを選択することです。このイメージは、信頼できるソース(通常は会社)によって管理、公開される親イメージまたはベースイメージである必要があります。

FROM 命令は、新しいビルドステージを初期化し、後続のシーケンシャル コマンドのベースイメージを設定します。したがって、FROM 命令は通常、Dockerfile の最初の命令であり、変数をサポートするために後置できるのはオプションの ARG 命令のみです。

構文: FROM <image>[:<tag> | @<digest>] [AS <name>]

画像の形式は <image>:<tag> または <image>@<digest> です。タグまたはダイジェストが指定されていない場合は、デフォルトで :latest タグが使用されます。<image> の形式は、イメージの保存に使用されるレジストリによって異なります。Artifact Registry の場合、<image> の形式は <region>-docker.pkg.dev/<project ID>/<repository name>/<image name>:<image tag> です。

このラボでは、公開 openjdk:11.0-jdk イメージを使用して、Dockerfile に次の行を追加します。

FROM openjdk:11.0-jdk

作業ディレクトリを設定する

WORKDIR 命令は、Dockerfile で後に続くすべての命令の作業ディレクトリを設定します。詳細については、Dockerfile リファレンス ドキュメントの WORKDIR セクションをご覧ください。

構文: WORKDIR <path>

このラボでは、/app ディレクトリを WORKDIR として使用します。Dockerfile の末尾に次の行を追加します。

WORKDIR /app

アプリケーション ファイルをコピーする

COPY 命令は、ディレクトリまたはファイルを <source> の場所から画像ファイル システムの <destination> パスにコピーします。複数の <source> リソースを指定でき、それらはすべてビルド コンテキストに関連しています。ビルド コンテキストについては、ビルドのセクションで詳しく説明します。詳細については、Dockerfile リファレンス ドキュメントの COPY セクションをご覧ください。

構文: COPY <source>... <destination>

このラボでは、リポジトリ内のすべてのファイルをイメージ ファイル システムにコピーし、Dockerfile の末尾に次の行を追加します。

COPY . /app

アプリケーションをコンパイルする

RUN 命令は、現在のイメージの上に新しいイメージレイヤでコマンドを実行し、結果を commit します。結果として commit されたイメージは、Dockerfile の連続したステップに使用されます。詳細については、Dockerfile リファレンス ドキュメントの RUN セクションをご覧ください。

構文: RUN <command>

このラボでは、Maven を使用してアプリケーションを JAR ファイルにコンパイルします。Dockerfile の末尾に次の行を追加します。

RUN ./mvnw compile assembly:single

アプリケーションを開始する

CMD 命令は、実行中のコンテナのデフォルト コマンドを提供します。Dockerfile に含めることができる CMD 命令は 1 つのみです。複数の CMD が指定されている場合は、最後の CMD のみが有効になります。CMD 命令と ENTRYPOINT 命令のどちらを使用しても、より高度な機能を使用できますが、このラボでは説明しません。詳細については、Dockerfile リファレンス ドキュメントの「CMD」セクションをご覧ください。

構文: CMD ["executable","param1","param2"]

このラボでは、コンパイルした JAR ファイルを実行します。Dockerfile の末尾に次の行を追加します。

CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]

最終的な Dockerfile

最終的な Dockerfile は

FROM openjdk:11.0-jdk
WORKDIR /app
COPY . /app
RUN ./mvnw compile assembly:single
CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]

Dockerfile をローカルで commit する

cd ${HOME}/sample-app
git add Dockerfile
git commit -m "Added Dockerfile"

4. ビルド

次に、docker build コマンドを使用して Dockerfile からイメージをビルドします。このコマンドは、Dockerfile の指示に従ってイメージをビルドするよう Docker デーモンに指示します。詳細については、docker build のリファレンス ドキュメントをご覧ください。

イメージをビルドする

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker build --tag sample-app:${IMAGE_TAG} .

出力

Sending build context to Docker daemon  221.2kB
Step 1/4 : FROM openjdk:11.0-jdk
11.0-jdk: Pulling from library/openjdk
0c6b8ff8c37e: Pull complete
412caad352a3: Pull complete
e6d3e61f7a50: Pull complete
461bb1d8c517: Pull complete
e442ee9d8dd9: Pull complete
542c9fe4a7ba: Pull complete
41de18d1833d: Pull complete
Digest: sha256:d72b1b9e94e07278649d91c635e34737ae8f181c191b771bde6816f9bb4bd08a
Status: Downloaded newer image for openjdk:11.0-jdk
---> 2924126f1829
Step 2/4 : WORKDIR /app
---> Running in ea037abb273d
Removing intermediate container ea037abb273d
---> bd9b6d078082
Step 3/4 : COPY . /app
---> b9aec2b5de51
Step 4/4 : RUN ./mvnw compile jar:jar
---> Running in 3f5ff737b7fd
[INFO] Scanning for projects...
...
[INFO] Building jar: /app/target/sample-app-1.0.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  22.952 s
[INFO] Finished at: 2022-02-23T18:09:08Z
[INFO] ------------------------------------------------------------------------
Removing intermediate container 331443caebd3
---> 152f65cc441e
Step 5/5 : CMD ["java", "-jar", "/app/target/sample-app-1.0.0.jar"]
---> Running in 3d595a72231c
Removing intermediate container 3d595a72231c
---> 0e40d7548cab
Successfully built 0e40d7548cab
Successfully tagged sample-app:aaa8895

5. ランニング

コンテナ イメージが正常にビルドされたので、アプリケーションを実行して、docker run コマンドを使用して期待どおりに動作することを確認できます。このコマンドは、テストまたはデバッグのためにコマンド プロンプトのフォアグラウンドでコンテナを起動します。詳細については、docker run のリファレンス ドキュメントをご覧ください。

イメージを使用してコンテナを実行する

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
  --rm \
  -p 8080:8080 \
  sample-app:${IMAGE_TAG}

出力

Listening at http://localhost:8080

コンテナで実行中のアプリケーションをプレビューする

  • Cloud Shell の [ウェブでプレビュー] ボタンをクリックします。
  • ポート 8080 で [プレビュー] をクリックする
  • Cloud Shell で Ctrl+C キーを押してコンテナを停止する

コンテナの動作を変更する

Docker Run の実行では、Dockerfile のデフォルト構成が使用されます。この動作を変更するには、追加の手順とパラメータを追加します。

TRACE ロギングを有効にする

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
  --rm \
  -p 8080:8080 \
  sample-app:${IMAGE_TAG} \
  java -Dorg.slf4j.simpleLogger.defaultLogLevel=trace -jar /app/target/sample-app-1.0.0-jar-with-dependencies.jar

コンテナで実行中のアプリケーションをプレビューする

  • Cloud Shell の [ウェブでプレビュー] ボタンをクリックします。
  • ポート 8080 で [プレビュー] をクリックする
  • [Cloud Shell] タブに切り替えて、追加のロギング
  • Cloud Shell で Ctrl+C キーを押してコンテナを停止する

ポートの変更

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-e PORT=8081 \
-p 8081:8081 \
sample-app:${IMAGE_TAG}

コンテナで実行中のアプリケーションをプレビューする

  • Cloud Shell の [ウェブでプレビュー] ボタンをクリックします。
  • [ポートを変更] をクリックします。
  • 8081 と入力してください
  • [変更してプレビュー] をクリックします。
  • Cloud Shell で Ctrl+C キーを押してコンテナを停止する

6. プッシュ

コンテナ イメージが適切に動作していることを確認し、このコンテナを他の環境や他のユーザーが実行できるようにするには、イメージを共有リポジトリに push する必要があります。これは自動化されたビルド パイプラインの一部として行われるはずですが、テスト環境にはすでにリポジトリが構成されており、イメージを手動で push できます。

Dockerfile commit を sample-app リポジトリに push する

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
git push

イメージに Artifact Registry のタグを付ける

docker tag sample-app:${IMAGE_TAG} \
    us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}

Artifact Registry の認証情報を構成する

gcloud auth configure-docker us-central1-docker.pkg.dev

プロンプトが表示されたら、Do you want to continue (Y/n)? 応答yして Enter を押します

イメージを Artifact Registry に push する

docker push us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}

出力

 The push refers to repository [us-central1-docker.pkg.dev/qwiklabs-gcp-04-b47ced695a3c/apps/sample-app]
  453b97f86449: Pushed
  e86791aa0382: Pushed
  d404c7ee0850: Pushed
  fe4f44af763d: Pushed
  7c072cee6a29: Pushed
  1e5fdc3d671c: Pushed
  613ab28cf833: Pushed
  bed676ceab7a: Pushed
  6398d5cccd2c: Pushed
  0b0f2f2f5279: Pushed
  aaa8895: digest: sha256:459de00f86f159cc63f98687f7c9563fd65a2eb9bcc71c23dda3351baf13607a size: 2424

7. 完了

お疲れさまでした。これでこの Codelab は終了です。

学習した内容

  • サンプル アプリケーションの Dockerfile を作成する
  • イメージを作成しました
  • イメージをコンテナとしてローカルで実行する
  • コンテナの動作を変更しました
  • イメージを Artifact Registry に push した