こんにちは!
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君にも聞いたところ下記のような返答が!!
ユーザーセッションの違い:
~/.bash_profileは、bashのログインシェルが開始されたときにのみ読み込まれるファイルです。一般的には、ユーザーがログインしたときにこれが起こります。
一方で、systemdやApacheを通じて起動されるサービスは、このようなログインシェルを経由しないため、~/.bash_profileは自動的に読み込まれません。
なるほどな気がする!!
.bash_profileに書いた環境変数は読み込まれないのか!
ということで、先ほどの記事に書いてある通り、新しく環境変数を設定する。
sudo vi /etc/sysconfig/env_file(任意のファイル名)
USER_NAME=username
USER_PASS=userpass
.
.
.
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
無事に動いた٩( ‘ω’ )و
他の参考記事
【Spring】AWSデプロイで初心者がぶち当たる疑問に答える