私のSpring Bootアプリでは、Dockerコンテナで実行するプロパティを外部化したいと思っています。最初にデプロイされると、現在my-server/src/main/resources/application.yml
にあるプロパティがロードされ、期待どおりにアプリケーションによって使用されます。すべて正常に動作します。
ただし、私の問題は、これらのプロパティを必要に応じて更新可能にする必要があるため、Dockerコンテナでapplication.yml
ファイルにアクセスする必要があることです。ただし、この時点では、buildDocker
タスクを実行する前にbuild/docker/
ディレクトリに含まれていないため、最初の展開後にコピーしたりアクセスしたりすることはできません。
だから、私はYamlファイルをdocker/
ビルドディレクトリにコピーし、アクセス可能なディレクトリ(/opt/meanwhileinhell/myapp/conf
)にコピーし、spring.config.location
プロパティを使用してDockerfileのJarの設定:
ENTRYPOINT ["Java",\
...
"-jar", "/app.jar",\
"--spring.config.location=classpath:${configDirectory}"]
Dockerコンテナで実行されているコマンドを見ると、これが予想どおりであることがわかります。
/app.jar --spring.config.location=classpath:/opt/meanwhileinhell/myapp/conf]
ただし、このファイルのプロパティを更新してDockerコンテナを再起動すると、変更が反映されません。ファイル許可は次のとおりです。
-rw-r--r-- 1 root root 618 Sep 5 13:59 application.yml
ドキュメント 状態:
カスタム構成の場所が設定されると、デフォルトの場所に加えて使用されます。カスタムの場所は、デフォルトの場所の前に検索されます。
私が間違っていることや誤解していることを理解できないようですが、おそらくもっと重要なのは、このタイプのDockerシナリオの構成を外部化する正しい方法ですか?
DOCKER IMAGE CONFIGURATION
Springが推奨する方法 を見て、Spring Bootを搭載したDockerコンテナを起動すると、次のようになります。
FROM openjdk:8-jdk-Alpine
VOLUME /tmp
ADD target/gs-spring-boot-docker-0.1.0.jar app.jar
ENV Java_OPTS=""
ENTRYPOINT [ "sh", "-c", "Java $Java_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
つまり、イメージはopenjdkを拡張し、コンテナには独自の環境があります。そのようにしている場合は、オーバーライドするものを環境プロパティとして宣言するだけで十分であり、Spring Bootはそれらを取得します- 環境変数が優先されます ymlファイルよりも。
環境変数をdockerコマンドに渡して、目的の構成でコンテナを起動することもできます。 JVMメモリに制限を設定する場合は、以下のリンクを参照してください。
DOCKER構成サンプル
ここでは、Docker Composeを使用して簡単なアプリ環境を起動する方法の例を示します。ご覧の通り、spring.datasource.url
プロパティは環境変数としてここにあるため、application.yml
ファイル。
version: '2'
services:
myapp:
image: mycompany/myapp:1.0.0
container_name: myapp
depends_on:
- mysql
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/myapp?useUnicode=true&characterEncoding=utf8&useSSL=false
ports:
- 8080:8080
mysql:
image: mysql:5.7.19
container_name: mysql
volumes:
- /home/docker/volumes/myapp/mysql/:/var/lib/mysql/
environment:
- MYSQL_USER=root
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE=myapp
command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8
以下も参照してください:
個人的には、あちこちにプロパティファイルを設定しようとする代わりに、Spring Cloud Config Serverを使用します。
tl; drにより、一元化された場所で環境/プロファイルレベルごとにgit(バージョン管理、分岐などを許可)でプロパティを保持し、RESTによって提供されます。 Spring Bootはそれを完全にサポートしています。実際には、環境内で終わる別のプロパティソースにすぎません。
だから私はそれを機能させることができた。クラスパスをDockerFileのディレクトリに渡すのではなく:
"--spring.config.location=classpath:${configDirectory}"]
代わりに、ファイルの完全な場所を渡そうとしました。
"--spring.config.location=file:${configDirectory}/application.yml"]
これは、Dockerコンテナの再起動時に更新されるようになりました。
Xtreme Bikerのバリエーション answer 、今回はSpringブート戦争をドッキングされたTomcatに展開するためのものです…
アプリに公称application.yml
を含めることをお勧めしますが、Docker環境変数を使用して、環境固有のバリエーションを必要とする個々のキーをオーバーライドします。
私がこのアプローチを推奨する理由(Docker環境変数を使用)は次のとおりです。
Spring Bootの Externalized Configuration docs コマンドライン経由で環境を提供する2つの方法を説明します。
SPRING_DATASOURCE_USERNAME=helloworld
)-Dspring.datasource.username=helloworld
)私はJavaオプションを好みます。なぜなら、それらは明示的な意図を表現するからです。 "これは、次のJavaプロセス、およびそのためのonlyJava process "。
最後に、TomcatのCATALINA_OPTS
を、これらのJavaオプション。catalina.sh
からのドキュメントを渡すためのメカニズムとして使用します。
(オプション)Java「start」、「run」、または「debug」コマンドの実行時に使用されるランタイムオプション。Java_OPTSには含めず、Tomcatのみが使用するすべてのオプションをここに含めます。停止プロセス、バージョンコマンドなどによるものではありません。例としては、ヒープサイズ、GCロギング、JMXポートなどがあります。
CATALINA_OPTS
は、setenv.sh
を作成して適切なDocker env宣言を渡すDockerイメージを作成するよりも簡単なルートだからです。
.war
アーティファクトを次のようにビルドします。
./gradlew war
Gradleにより.war
にbuild/libs/api-0.0.1-SNAPSHOT.war
アーティファクトが出力されると予想されます。
そのようなDockerfileを使用します。
FROM Tomcat:8.5.16-jre8-Alpine
EXPOSE 8080
COPY build/libs/api-0.0.1-SNAPSHOT.war /usr/local/Tomcat/webapps/v1.war
CMD ["catalina.sh", "run"]
Dockerイメージを次のようにビルドします。
docker build . --tag=my-api
CATALINA_OPTS
を次のようにコンテナに渡します。
docker run -it \
-p 8080:8080 \
-e CATALINA_OPTS="\
-Dspring.datasource.url='jdbc:mysql://mydatabase.stackoverflow.com:3306' \
-Dspring.datasource.username=myuser \
" \
my-api
そして、docker-composeバリアントは次のようになります。
version: '3.2'
services:
web:
image: my-api
ports:
- "8080:8080"
environment:
- >
CATALINA_OPTS=
-Dspring.datasource.url='jdbc:mysql://mydatabase.stackoverflow.com:3306'
-Dspring.datasource.username=myuser
あなたのアプローチは間違いなく実行可能なソリューションですが、推奨されません。異なる本番環境と開発環境間でイメージを移植できないためです。コンテナは不変であり、すべての環境設定は外部化される必要があります。
スプリングブートの場合、構成を外部化できる非常に強力なプロジェクトがあります。その名前は Spring Cloud Config です。構成サーバーを使用すると、環境固有の構成をgitリポジトリに保存し、それを必要とするアプリケーションに構成を提供できます。基本的には、同じapplication.ymlをgitに保存し、設定サーバーにリポジトリの場所を指定するだけです。
このアプローチに従って、異なる環境用に複数の構成ファイルを定義し、Dockerコンテナーを不変に保つことができます。
私は個人的に2つのオプションを検討します。
環境変数を使用する
app:
image: my-app:latest
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/table
SPRING_APPLICATION_JSON
を使用
app:
image: my-app:latests
ports:
- "8080:8080"
environment:
SPRING_APPLICATION_JSON: '{
"spring.datasource.url": "jdbc:mysql://db:3306/table",
}'