1. 概要

このチュートリアルでは、 Spring Bootアプリケーションをドッキングして、分離された環境(別名)で実行する方法に焦点を当てます。 コンテナ

相互に依存し、仮想プライベートネットワークで相互にリンクされているコンテナの構成を作成する方法を学習します。 また、単一のコマンドでそれらを管理する方法についても説明します。

簡単なSpring Bootアプリケーションを作成することから始めましょう。次に、 AlpineLinuxを実行する軽量のベースイメージで実行します。

2. スタンドアロンのSpringBootアプリケーションをDockerize

ドッキングできるアプリケーションの例として、1つのエンドポイントを公開して静的メッセージを返す単純なSpring Bootアプリケーション docker-message-server、を作成します。

@RestController
public class DockerMessageController {
    @GetMapping("/messages")
    public String getMessage() {
        return "Hello from Docker!";
    }
}

正しく構成されたMavenファイルを使用して、実行可能なjarファイルを作成できます。

$> mvn clean package

次に、Spring Bootアプリケーションを起動します。

$> java -jar target/docker-message-server-1.0.0.jar

これで、 localhost:8888/messagesでアクセスできるSpringBootアプリケーションが動作します。

アプリケーションをドッキングするには、最初にDockerfileという名前のファイルを次の内容で作成します。

FROM openjdk:8-jdk-alpine
MAINTAINER baeldung.com
COPY target/docker-message-server-1.0.0.jar message-server-1.0.0.jar
ENTRYPOINT ["java","-jar","/message-server-1.0.0.jar"]

このファイルには、次の情報が含まれています。

  • FROM :イメージのベースとして、前のセクションで作成したJava対応のAlpineLinuxを使用します。
  • MAINTAINER :画像のメンテナー。
  • COPY Dockerにjarファイルをイメージにコピーさせます。
  • ENTRYPOINT :これは、コンテナーの起動時に開始する実行可能ファイルになります。 一部のアプリケーション引数にはENTRYPOINTCMDと組み合わせて使用するため、これらをJSON-Arrayとして定義する必要があります。

Dockerfile からイメージを作成するには、前と同じように‘dockerbuild’を実行する必要があります。

$> docker build --tag=message-server:latest .

最後に、イメージからコンテナを実行できます。

$> docker run -p8887:8888 message-server:latest

これにより、Dockerでアプリケーションが起動し、 localhost:8887 /messagesのホストマシンからアプリケーションにアクセスできます。 ここでは、ホスト(8887)のポートをDocker内のポート( 8888 )にマップするポートマッピングを定義することが重要です。 これは、SpringBootアプリケーションのプロパティで定義したポートです。

注:ポート8887は、コンテナーを起動するマシンでは使用できない場合があります。 この場合、マッピングが機能しない可能性があり、まだ使用可能なポートを選択する必要があります。

コンテナをデタッチモードで実行すると、次のコマンドを使用して、コンテナの詳細を調べ、停止し、削除できます。

$> docker inspect message-server
$> docker stop message-server
$> docker rm message-server

2.1. ベースイメージの変更

別のJavaバージョンを使用するために、ベースイメージを簡単に変更できます。 たとえば、AmazonのCorrettoディストリビューションを使用する場合は、Dockerfileを変更するだけです。

FROM amazoncorretto:11-alpine-jdk
MAINTAINER baeldung.com
COPY target/docker-message-server-1.0.0.jar message-server-1.0.0.jar
ENTRYPOINT ["java","-jar","/message-server-1.0.0.jar"]

さらに、カスタムベースイメージを使用できます。 これを行う方法については、このチュートリアルの後半で説明します。

3. コンポジットでアプリケーションをDockerize

DockerコマンドとDockerfilesは、個々のコンテナーを作成するのに特に適しています。 ただし、分離されたアプリケーションのネットワークで操作する場合、コンテナー管理はすぐに混乱します。

これを解決するために、DockerはDocker Composeという名前のツールを提供します。このツールには、 YAML 形式の独自のビルドファイルが付属しており、複数のコンテナーの管理に適しています。 たとえば、1つのコマンドでサービスの複合を開始または停止したり、複数のサービスのログ出力を1つのpseudo-ttyにマージしたりできます。

3.1. 2番目のSpringBootアプリケーション

異なるDockerコンテナで実行されている2つのアプリケーションの例を作成してみましょう。 それらは互いに通信し、ホストシステムに「単一ユニット」として提示されます。 簡単な例として、2番目のSpring Bootアプリケーションdocker-product-serverを作成します。

@RestController
public class DockerProductController {
    @GetMapping("/products")
    public String getMessage() {
        return "A brand new product";
    }
}

message-server と同じ方法で、アプリケーションをビルドして起動できます。

3.2. Docker作成ファイル

docker-compose.yml という1つのファイルに、両方のサービスの構成を組み合わせることができます。

version: '2'
services:
    message-server:
        container_name: message-server
        build:
            context: docker-message-server
            dockerfile: Dockerfile
        image: message-server:latest
        ports:
            - 18888:8888
        networks:
            - spring-cloud-network
    product-server:
        container_name: product-server
        build:
            context: docker-product-server
            dockerfile: Dockerfile
        image: product-server:latest
        ports:
            - 19999:9999
        networks:
            - spring-cloud-network
networks:
    spring-cloud-network:
        driver: bridge
  • version :使用するフォーマットバージョンを指定します。 これは必須フィールドです。 ここでは新しいバージョンを使用していますが、レガシーフォーマットは「1」です。
  • services :このキーの各オブジェクトは、 service 、別名コンテナーを定義します。 このセクションは必須です。
    • build :指定された場合、docker-composeDockerfileからイメージをビルドできます。
      • context :指定されている場合、Dockerfileが検索されるビルドディレクトリを指定します。
      • dockerfile :指定すると、Dockerfileの代替名が設定されます。
    • image :ビルド機能を使用するときにイメージに付ける名前をDockerに通知します。 それ以外の場合は、ライブラリまたはリモートレジストリでこのイメージを検索しています。
    • networks :これは使用する名前付きネットワークの識別子です。 指定されたname-valueは、networksセクションにリストされている必要があります。
  • ネットワーク:このセクションでは、サービスで利用可能なネットワークを指定します。この例では、 docker-compose タイプ‘bridge’の名前付きnetworkを作成します。 オプションexternaltrueに設定されている場合、指定された名前の既存のオプションが使用されます。

続行する前に、ビルドファイルで構文エラーをチェックします。

$> docker-compose config

次に、イメージを作成し、定義されたコンテナーを作成して、1つのコマンドで開始できます。

$> docker-compose up --build

これにより、message-serverproduct-serverが一度に起動します。

コンテナーを停止するには、コンテナーを Docker から削除し、接続されているネットワークをコンテナーから削除します。 これを行うには、反対のコマンドを使用できます。

$> docker-compose down

docker-compose、の詳細については、記事 Introduction to DockerComposeを参照してください。

3.3. スケーリングサービス

docker-compose の優れた機能は、サービスのスケーリング機能です。 たとえば、 Docker に、 message-server 用に3つのコンテナーを実行し、product-server用に2つのコンテナーを実行するように指示できます。

ただし、これを正しく機能させるには、container_namedocker-compose.ymlから削除して、 Docker が名前を選択し、[衝突を避けるためのX172X]公開ポート構成。

ポートについては、ホスト上のポートの範囲をDocker内の1つの特定のポートにマップするようにDockerに指示できます。

ports:
    - 18800-18888:8888

その後、次のようにサービスをスケーリングできます(変更された yml-file を使用していることに注意してください)。

$> docker-compose --file docker-compose-scale.yml up -d --build --scale message-server=1 product-server=1

このコマンドは、単一のmessage-serverと単一のproduct-serverを起動します。

サービスを拡張するには、次のコマンドを実行できます。

$> docker-compose --file docker-compose-scale.yml up -d --build --scale message-server=3 product-server=2

このコマンドは、2つの追加のメッセージサーバーと1つの追加の製品サーバーを起動します。 実行中のコンテナは停止しません。

4. カスタムベースイメージ

これまでに使用したベースイメージ( openjdk:8-jdk-alpine )には、JDK8がすでにインストールされているAlpineオペレーティングシステムのディストリビューションが含まれていました。 または、独自のベースイメージを作成することもできます(Alpineまたはその他のオペレーティングシステムに基づく)。

これを行うには、ベースイメージとしてAlpineを使用して Dockerfile を使用し、選択したJDKをインストールします。

FROM alpine:edge
MAINTAINER baeldung.com
RUN apk add --no-cache openjdk8
  • FROM :キーワード FROM は、Dockerにタグ付きの特定のイメージをビルドベースとして使用するように指示します。 このイメージがローカルライブラリにない場合は、DockerHubまたはその他の構成済みのリモートレジストリでオンライン検索が実行されます。
  • MAINTAINER MAINTAINER は通常、画像の作成者を識別する電子メールアドレスです。
  • RUN RUN コマンドを使用して、ターゲットシステム内でシェルコマンドラインを実行しています。 ここでは、 Alpine Linuxのパッケージマネージャー、 apk、を使用して、 Java8OpenJDKをインストールしています。

最終的にイメージを作成してローカルライブラリに保存するには、次のコマンドを実行する必要があります。

docker build --tag=alpine-java:base --rm=true .

注意: –tag オプションはイメージに名前を付け、 –rm =trueは正常にビルドされた後に中間イメージを削除します。 このシェルコマンドの最後の文字はドットであり、build-directory引数として機能します。

これで、 openjdk:8-jdk-alpineの代わりに作成されたイメージを使用できます。

5. SpringBoot2.3でのビルドパックのサポート

Spring Boot 2.3は、 buildpacksのサポートを追加しました。 簡単に言うと、独自のDockerfileを作成し、 docker build のようなものを使用してビルドする代わりに、次のコマンドを発行するだけです。

$ mvn spring-boot:build-image

同様に、Gradleでは:

$ ./gradlew bootBuildImage

これを機能させるには、Dockerをインストールして実行する必要があります。

ビルドパックの背後にある主な動機は、HerokuやCloudFoundryなどの有名なクラウドサービスがしばらくの間提供してきたものと同じデプロイメントエクスペリエンスを作成することです。 build-image ゴールを実行するだけで、プラットフォーム自体がアーティファクトの構築とデプロイを処理します。

さらに、Dockerイメージをより効果的に構築する方法を変更するのに役立ちます。 異なるプロジェクトの多くのDockerfileに同じ変更を適用する代わりに、ビルドパックイメージビルダーを変更または調整するだけです。

使いやすさと全体的な開発者エクスペリエンスの向上に加えて、より効率的になる可能性があります。たとえば、buildpacksアプローチは、階層化されたDockerイメージを作成し、Jarファイルの展開バージョンを使用します。

上記のコマンドを実行した後に何が起こるかを見てみましょう。

利用可能なDockerイメージを一覧表示すると、次のようになります。

docker image ls -a

作成したばかりの画像の線が表示されます。

docker-message-server 1.0.0 b535b0cc0079

ここで、イメージの名前とバージョンは、MavenまたはGradle構成ファイルで定義した名前とバージョンと一致します。 ハッシュコードは、画像のハッシュの短いバージョンです。

次に、コンテナを起動するには、次のコマンドを実行します。

docker run -it -p9099:8888 docker-message-server:1.0.0

ビルドしたイメージと同様に、ポートをマップして、Dockerの外部からSpringBootアプリケーションにアクセスできるようにする必要があります。

6. 結論

この記事では、カスタム Docker イメージを構築し、 Spring BootApplicationDockerコンテナーとして実行し、docker-でコンテナーを作成する方法を学びました。 compose

ビルドファイルの詳細については、公式のDockerfileリファレンスおよびdocker-compose.ymlリファレンスを参照してください。

いつものように、この記事のソースコードはGithubにあります。