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 を使用してアプリケーションをコンテナ化する

アプリケーションをコンテナにパッケージ化する方法の 1 つに、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 命令は、現在のイメージの上に新しいイメージ レイヤでコマンドを実行し、結果をコミットします。コミットされたイメージは、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 をローカルにコミットする

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

4. ビルド

次に、docker build コマンドを使用して Dockerfile からイメージをビルドします。このコマンドを実行すると、docker デーモンは Dockerfile の手順を使用してイメージをビルドします。詳細については、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 する必要があります。これは自動ビルド パイプラインの一部として行う必要がありますが、テスト環境にはすでにリポジトリが構成されているため、イメージを手動で push できます。

Dockerfile のコミットを 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 した