Dockerfile で Spring Boot プロジェクトをコンパイル、パッケージ化、デプロイする

1、ドッカーファイル

1.1. Dockerfile とは

        Dockerfile は Docker イメージを自動的に構築する設定ファイルであり、イメージの構築プロセスは指示に従って Dockerfile に定義されます。docker build コマンドラインを使用すると、Docker イメージの自動構築を実現できます。

1.2. Dockerfile の構文分析

        言語や文書の文法を学ぶとき、最も早い学習方法は、他の人がそれをどのように書いているかを見ることです。ここでの「他者」が誰であるかは非常に重要で、臭いチェスバスケットでチェスをすればするほど臭くなります。

        したがって、Dockerfile 構文を学習するには、モデルを見つける必要があります。Dockerhub にアクセスして、オープン ソース ソフトウェアによって公式に提供されているイメージを確認することができます。また、対応する Dockerfile を見つけて、他の人がそれをどのように作成しているかを確認することもできます。上記の nginx:1.20.2 バージョンの Docker イメージ (公式に提供されている) の Dockerfile を取得し、その構文と構築プロセスを 1 行ずつ分析してみましょう。この記事に関連するスクリプトは、github:docker-nginx の公式チャネルから入手できます。

1.3. Dockerfile コマンド

から

        通常、イメージを構築するときは、基本的な Linux オペレーティング システムのリリース イメージが必要であり、これに基づいて独自のイメージを構築します。
        したがって、FROM 命令の機能はベース イメージを指定することであり、ここで nginx が使用するベース Linux イメージは debian:bullseye-slim です。このうち、debian:bullseye は Debian の Linux ディストリビューション オペレーティング システムのバージョンであり、バージョン名は bullseye です。スリムとは、通常、このイメージがリリース バージョンの最小インストール バージョンであることを意味します。構築したイメージは、その後の継続的統合プロセスおよびウェアハウスと Docker サーバー間のネットワークに伝播されるため、イメージの構築を次のように行う必要があります。できるだけ簡単に、結果のサイズを最小限に抑えます。「ベースイメージを選択するときは、サイズに注目する必要があります。Linux の基本機能とプログラムの実行を満たしていれば、イメージは小さいほど優れています。

FROM debian:bullseye-slim

ラベル

        LABEL は、現在のイメージの管理者や連絡先情報など、現在のイメージに説明と説明情報を追加するために使用されます。キーと値のペアを使用してカスタマイズし、1 行で複数を定義できます。

LABEL <key>=<value> <key>=<value> <key>=<value> ...

メンテナ、説明

        メンテナ情報や説明画像の説明情報など、複数行定義することもできます。説明情報が一行で書ききれない場合は「\」で改行することができます。

LABEL maintainer="NGINX Docker Maintainers "
LABEL description="This is a Docker image \
for nginx 1.20.2. "

        Dockerfile の構文には、イメージのメンテナ情報を記述するために使用される MAINTAINER という命令がありますが、現在は使用が推奨されておらず、一律に LABEL が使用されます。

環境

        ENV の機能は環境変数を設定することであり、環境変数を設定すると、その環境変数をシェル スクリプトで使用できるようになります。

        使用方法は ${NGINX_VERSION} です。JAVA を勉強したことのある学生の皆さん、JAVA_HOME 環境変数をどのように設定して使用するかを考えてみてください。ENVも同様です。docker に置いたときに構文が変わっているだけで、構文形式は ENV 環境変数 KEY 環境変数 Value になります。

ENV NGINX_VERSION 1.20.2
ENV NJS_VERSION 0.7.0
ENV PKG_RELEASE 1~bullseye

走る

        RUN命令の役割はLinuxのシェルスクリプトを実行することであり、下図のようにENVで定義した環境変数をシェルスクリプト内で使用することができます。
        nginx イメージの場合、RUN コマンドの機能は、一連のシェル コマンド ライン (スクリプト) を実行して、nginx のインストールを完了することです。したがって、RUN 命令を習得するための鍵は RUN 命令自体ではなく、次の点にあります。

  • nginxを手動でインストールする方法を知っていますか?
  • Linux のシェル スクリプトの構文をご存知ですか?
  • nginxのインストールプロセスをシェルスクリプトとして記述できますか?

        上記 3 つの質問の答えが「はい」の場合は、RUN コマンドを使用してシェル スクリプトを実行し、ソフトウェアのインストールを完了します。これは Dockerfile の記述内容の中核でもあり、Linux シェルについてはこの記事で説明するものではありません。


コピー

        COPY 命令の機能は、ローカル ファイル (イメージ構築が実行されるサーバー) をイメージ ファイルにコピーすることです。

        構文は次のとおりです: COPY <ローカル ファイル パス>:<イメージ ファイル パス>イメージ ファイル パスは、コンテナーの実行時のファイル システムのパスでもあります。

COPY docker-entrypoint.sh /
COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d
COPY 20-envsubst-on-templates.sh /docker-entrypoint.d
COPY 30-tune-worker-processes.sh /docker-entrypoint.d

        ローカル ファイル パスにファイル名のみがある場合は、ファイルと Dockerfile が同じディレクトリにあることを意味します (相対パス構文)。つまり、次のファイルが同じディレクトリにあり、これらのファイルは上で示した nginx 公式 Dockerfile 接続で確認できます。

        注: <ローカル ファイル パス> がディレクトリの場合、ディレクトリではなく、ディレクトリ内のファイルのみがイメージにコピーされます。

作業ディレクトリ

        さらに、WORKDIR ディレクティブを使用して、Dockerfile 内でそれに続く RUN、CMD、ENTRYPOINT、COPY、および ADD 命令のローカル作業ディレクトリを設定できます。

        このように、上記の相対パスは、WORKDIRで指定されたパスからの相対パスになります。「しかし、ビルドを実行する開発者の作業ホストの作業パスと Dockerfile ライターの作業パスの一貫性を確保するのは難しいため、一般的に WORKDIR を使用することはお勧めできません。」

WORKDIR  /root

さらす

Docker コンテナーは、実行時に指定されたネットワーク ポートを公開し、コンテナーのポート マッピングに使用できます。デフォルトのプロトコルは TCP です。形式は次のとおりです。

EXPOSE <端口号>
EXPOSE <端口号>/<协议>

        コンテナー ポートが公開されると、ホスト ポートとのマッピング関係を確立できるため、ホスト ポートにアクセスすることでコンテナー内のサービスにアクセスできるようになります。たとえば、コンテナのポート 80 は TCP と UDP で同時に公開されます。

EXPOSE 80/tcp
EXPOSE 80/udp

停止信号

        このコマンドは、作者は一般的には使用しません。github で docker-nginx の問題を確認したところ、STOPSIGNAL シグナルを追加する目的は、docker の実行後に nginx サービスが正しく終了しないことによって引き起こされるゾンビ プロセスを回避するためであるとのことでした。コンテナが停止している状態です。

STOPSIGNAL SIGQUIT

CMD

        CMD 命令は、Linux コマンドまたはスクリプトを実行するためにも使用されます。これは RUN 命令と一致します。2 つの違いは次のとおりです。

  1. RUN コマンドは、イメージのビルド時、つまりdocker build 時に実行されます。
  2. CMD 命令は、docker run 命令の実行時、つまりコンテナの作成時に実行されます。

        命令の実行周期が異なるからこそ、RUNネーミングで実行される書き込み動作はミラー層に書き込まれます。CMD 命令の実行結果には書き込み操作が含まれており、コンテナ層に書き込まれます。(学習して理解するには、私の以前の記事「ミラー レイヤリングの原理」を参照してください)。
        したがって、CMD 命令と ENTRYPOINT 命令は似ており、どちらもコンテナーの作成時に実行されます。

        注意が必要なのは、「ENTRYPOINT命令をDockerfileに組み込むと、ENTRYPOINTで指定されたスクリプトのパラメータとしてCMD命令が存在することになる」ということです。

以下の形式の構文を参照してください。

CMD には 3 つの形式が含まれています。

  • 1 つ目は、ENTRYPOINT で指定されたスクリプトにパラメータを渡すことです。上記の ENTRYPOINT スクリプトの最後の行にある exec "$@" は、CMD によって渡されたコマンドとパラメータを実行します。nginxサービスの起動を完了します。**この使用法は、公式の Dockerfile (nginx、redis など)** で一般的に使用されます。これは、ENTRYPOINT で指定されたスクリプトで構成の準備作業を行い、最後の行の exec "$@" を通じて CMD を呼び出します。 ENTRYPOINT スクリプト コマンドを使用してコンテナ サービスを開始します。

CMD ["nginx", "-g", "デーモンオフ;"]

  • 2 番目の方法はコマンドまたはシェル スクリプトを実行するもので、パラメーターを渡すことができます。二重引用符に注意してください。構文は最初の形式と同じですが、ENTRYPOINT 指定スクリプトがないため、ENTRYPOINT 指定スクリプトのパラメータとして存在しません。

CMD ["実行可能","param1","param2"]

  • 3 番目のタイプは、 echo "This is a test." | wc -cshell コマンド ラインの実行など、シェル スクリプトを実行するための一般的な構文です。著者は、「Dockerfile ではこのメソッドを使用しないでください。その理由を知る必要はありません。」と述べています。

CMD エコー「これはテストです。」| トイレ -c
 

エントリーポイント

        Dockerfile に複数の ENTRYPOINT が定義されている場合、最後の ENTRYPOINT のみが有効となり、Docker コンテナーが起動されるたびに、ENTRYPOINT で指定されたスクリプトが実行されます。

        nginx:1.20.2 の場合、「/docker-entrypoint.sh」スクリプトは nginx 構成のチェックと nginx サービスの起動手順を定義します。したがって、通常は「ENTRYPOINTで指定されたスクリプトは、通常、イメージ内のコアサービスの起動スクリプトです」。

ENTRYPOINT ["/docker-entrypoint.sh"]

        このスクリプトは最後に nginx サービスの起動を実行しますが、これは CMD コマンドで完了する必要があります。以下の CMD コマンドを参照してください。

1.4. ドッカー操作

詳細については、3-Docker基本操作コマンド・Linux運用・保守・Kanyunを参照してください。


1.画像の生成

# docker build -t springboot-docker 。
# docker build -f ./Dockerfile -t springboot-docker 。
# docker build -f ./Dockerfile -t springboot-docker:0.1 。

[root@ip-100 dockerfile]# docker イメージ
リポジトリ タグ イメージ ID 作成サイズ
springboot-docker 0.1 54dcc83613d7 約 1 分前 682MB
springboot-docker 最新 54dcc83613d7 約 1 分前 682MB


# 注:
# 1. コマンドは Dockerfile が配置されているディレクトリで実行されます;
# 2. 以下の点を忘れないように注意してください。ここでの springboot-docker は、実際に生成されるイメージ名です。

  • --tag -t: イメージの名前とタグ。通常は名前:タグまたは名前の形式です。1 つのビルドで 1 つのイメージに複数のタグを設定できます。
  • -f: 使用する Dockerfile パスを指定します

参考: https://www.runoob.com/docker/docker-build-command.html

2. イメージを実行します

  • -d: コンテナがバックグラウンドで実行されていることを示します
  • --name: コンテナに名前を付けます
  • -p: ポート マッピング。形式はホスト ポート:コンテナ ポートです。上記の意味は、コンテナ内のポート 80 をホストのポート 80 にマップして、外部アクセス サービスを提供することです。

最後のフィールドはイメージ名です

# docker run --name springboot-docker01 -d -p 8080:8080 springboot-docker

[root@ip-100 dockerfile]# docker ps 
コンテナ ID イメージ コマンド作成ステータス ポート名
65bb62a54e55 springboot-docker "java -Djava.securit…" 33 秒前 上り 31 秒 0.0.0.0:8080->8080/tcp, :: :8080->8080/tcp springboot-docker01

ホストブラウザ: http://192.168.192.128:8080/getIpAndPort


3. 起動ログを表示する

docker ログ xxx
docker ログ -f springboot-docker01

2. Dockerfileの多段構築

2.1. Dockerfile の使用例 1

FROM openjdk:8-jdk-alpine as build
WORKDIR /workspace/app

COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src

RUN ./mvnw install -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]

2.2. Dockerfileの使用例2

プロジェクトのルート ディレクトリに Dockerfile を作成します。

# 拉取编译环境
FROM maven:3.6.1 as builder

#拷贝源码到固定的目录,注意前面有个 '.'
COPY . /project

# 切换到源码目录
WORKDIR /project

# 使用maven进行编译
RUN mvn clean package -Dmaven.test.skip=true

# 拉取运行环境,这个镜像打包出的镜像比较小,如需要可换成oracle的jre
FROM fabric8/java-alpine-openjdk8-jre

# 从编译好的镜像中将jar拷贝到运行时容器
COPY --from=builder /project/target/your-jar-name.jar /

# 容器启动时执行的命令,这里可加jvm参数
ENTRYPOINT ["java","-jar","/mqtt-rule-engine.jar"]

# 开放端口,根据自己的配置进行开放
EXPOSE 8080

2.3. Dockerfile の使用例 3

# First stage: complete build environment
FROM maven:3.5.0-jdk-8-alpine AS builder

# add pom.xml and source code
ADD ./pom.xml pom.xml
ADD ./src src/

# package jar
RUN mvn clean package

# Second stage: minimal runtime environment
From openjdk:8-jre-alpine

# copy jar from the first stage
COPY --from=builder target/my-app-1.0-SNAPSHOT.jar my-app-1.0-SNAPSHOT.jar

EXPOSE 8080

CMD ["java", "-jar", "my-app-1.0-SNAPSHOT.jar"]
FROM maven:3.6.3-openjdk-8 AS builder
 #  AS builder 起别名

RUN mkdir /build
# 创建临时文件

ADD src /build/src
#将 src目录复制到临时目录

ADD pom.xml /build
# 将 pom文件复制到临时目录

RUN cd /build && mvn -B -ntp package
# 打包

FROM adoptopenjdk/openjdk8:alpine-jre
# 获取jre

COPY --from=builder /build/target/ems-0.0.1-SNAPSHOT.jar /ems.jar
#从标记点 拷贝jar包 并改名

CMD ["java", "-jar", "/ems.jar"]

# 声明运行方式

 プロジェクトのルートディレクトリで以下のコマンドを実行します。

docker build -t name:tag 。
 

3. プラグインのパッケージ化

3.1. spring-boot-maven-plugin プラグインのパッケージ化

SpringBoot には独自のイメージ パッケージ化ツールが組み込まれているDockerため、spring-boot-starter-parent追加の設定は必要ありません。利点: 書き込みは必要なくDockerFile、セキュリティ、メモリ、パフォーマンス、および Spring が推奨するその他の問題について心配する必要はありません。

3.2. jib-maven-plugin プラグイン

Googleパッケージ化されたプラグイン。利点: ローカルでのインストールDockerや書き込みは必要なくDockerFileJib指定されたウェアハウスに直接プッシュできますDocker

3.3. dockerfle-maven-plugin プラグイン

記述する必要がありDockerFile、ローカルDocker環境が必要ですが、最も便利で、安定しており、自由に制御できます。メリット:安定していてネットワークの制限を受けない、DockerFileは自分で書いているので自由度が高く、自由に変更できるので個人的にはオススメです。

プラグインのパッケージ化の具体的な例については、Java (SpringBoot) プロジェクトを Docker イメージにパッケージ化 (ビルド) するいくつかの方法 - Tencent Cloud 開発者コミュニティ - Tencent Cloud を参照してください。

4、参考:

docker は、Springboot の jar パッケージを自動的にデプロイするために Dockerfile をコンパイルします。 project_dockerfile は、jar package をコンパイルします。xixiyuguang のブログ - CSDN ブログ

2021 年の最新の dockerfile の多段階構築では、Java ソース コードのコンパイル、jar パッケージ、ミラーリングが実装されています - Alibaba Cloud Developer Community

Java (SpringBoot) プロジェクトを Docker イメージにパッケージ化 (ビルド) するいくつかの方法 - Tencent Cloud Developer Community - Tencent Cloud

デプロイメント中に docker_docker コンパイルで Spring Boot プロジェクトをコンパイル、パッケージ化、デプロイする_csdn_meng のブログ - CSDN ブログ

おすすめ

転載: blog.csdn.net/yangyangye/article/details/132622061