SpringBoot PR

Spring Bootのアプリをサービス化したら、怒られた話【環境変数が原因だった】

Spring Bootのアプリをサービス化したら、怒られた話【環境変数が原因だった】
記事内に商品プロモーションを含む場合があります

こんにちは!

Webエンジニアになるべく、ポートフォリオ公開に向けて奮闘中のモリヤス(@_moriyas)です。

開発環境で作成したWebアプリを下記の環境で公開しようと色々調べながら進めた結果、かなり詰まってしまったポイントがあったので、今回直面した問題に出会うまでの流れを追いながら説明していきたいと思います!

環境・バージョン

  • AWS(VPC, EC2, RDS)
  • Spring Boot 3.1.1
  • Kotlin 1.8.22
  • OpenJDK 17.0.8.1
  • Apache 2.4.57
  • Amazon Linux 2
  • MySQL 8.0.33

サービス化までやったこと

①Spring Bootで作ったアプリをEC2に、MySQLで作ったDBをRDSにそれぞれ設置

下記の記事や、参考書のやり方で対応し、アプリの起動を確認しました。

EC2 + RDSを構築して、SpringBootとReactを載せてアプリを起動している【前編】

EC2 + RDSを構築して、SpringBootとReactを載せてアプリを起動している【後編】

SpringBoot/React/MySQLの簡単なアプリをAWS EC2にデプロイする

なお、下記の点は記事とは違う方法を取っておりました。

  • WebサーバーにApacheを使用
  • Spring BootのアプリケーションとDBの接続情報をapplication.propertiesに記述する際、セキュリティの観点から環境変数から読み込む形にしていた(.bash_profileに環境変数を設定)←今回の問題のキモになる点でした!!

ここで1つの疑問が…

モリヤス

あれ?でもこのままだと、EC2から抜けたらアプリ終了するくね?

じゃあ、このアプリをずっと動かし続ける方法を探すぞ٩( ᐛ )و

②Spring Bootアプリを動き続けるように設定

「Spring Boot 動かし続ける」とググると、どうやら「サービス化」というらしいぞ!!

ということで改めまして…

「Spring Boot サービス化」とググってみると下記の素敵な記事にヒットしました。

SpringBootをサービス化(デーモン化)して常駐させる

記事通り設定をしてアプリを起動!

sudo systemctl status app_name
をしてステータスを確認すると
Active: active (running)
が出てるので問題なさそう!

ということでSpring Bootで作ったAPI(アプリ)を叩いてみると、つながらないヽ(`Д´#)ノ

モリヤス

あれれ?なぜ??

ささ!ログを見ましょう!!

【AWS】SpringBootアプリのサービス化で作成する「〇〇.service」ファイルの[service:ExecStart = ]の内容について解説

上記記事にログの場所が書いてあった!!

sudo cat /var/log/messages

で見てみると

Sep 14 01:34:33 ip-番号  java: Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure

MySQLとの接続に問題ありそうだな??

ということで、一旦、EC2からRDSへの接続を確認!!

mysqlコマンドで接続すると問題なく接続できた!!

もう少し先ほどのログを見ていくと

Sep 14 01:34:23 ip-番号 java: Caused by: java.net.UnknownHostException: ${ENV_NAME}

こんなメッセージが

${ENV_NAME}!!

環境変数!!

MySQLとの接続情報をapplication.propertiesから環境変数を読み込んで接続するという形をとっているところに問題がありそうだな!

サービス化する前に、起動した時は問題なかったので、MySQLの接続情報に間違えはないはず!

じゃあ調べようということでこちらの記事に出会った。

Linuxでサービス起動したら環境変数が読み込まれなくて困った

一応、ChatGPT君にも聞いたところ下記のような返答が!!

ChatCPT

ユーザーセッションの違い:

~/.bash_profileは、bashのログインシェルが開始されたときにのみ読み込まれるファイルです。一般的には、ユーザーがログインしたときにこれが起こります。
一方で、systemdやApacheを通じて起動されるサービスは、このようなログインシェルを経由しないため、~/.bash_profileは自動的に読み込まれません。

モリヤス

なるほどな気がする!!

.bash_profileに書いた環境変数は読み込まれないのか!

ということで、先ほどの記事に書いてある通り、新しく環境変数を設定する。

sudo vi /etc/sysconfig/env_file(任意のファイル名)

env_file
USER_NAME=username
USER_PASS=userpass
.
.
.

serviceファイルの設定を修正

app.service
[Unit]
Description=application to manage app-name
After=syslog.target

[Service]
User=user-name
ExecStart=/bin/java -jar jar-file-path
Restart=always
SuccessExitStatus=143
EnvironmentFile=/etc/sysconfig/env_file   # ここを追加

[Install]
WantedBy=multi-user.target

サービスを再起動!!

sudo systemctl start app-name

無事に動いた٩( ‘ω’ )و

他の参考記事

[systemd] サービスを削除するときのコマンド

【Spring】AWSデプロイで初心者がぶち当たる疑問に答える