nologyance.net

日々のアウトプット

systemdでdaemonを動かすときの環境変数

なるほど環境変数ね、完全に理解した

Proxyの記事を書いたときにはそう思ってました。 http://nologyance.net/2019/02/08/post-617

落とし穴

そういうときには大抵見落としがあるわけで。

環境変数全然わかってませんでした。出直してきます。

背景

SpringFramework

SpringBootにはapplication.propaties(yml)という素敵なコンフィグの仕組みがあります。 簡潔にいうとDBの接続情報をはじめ、色々な設定情報を設定ファイルに外だしできるというもの。 これを使うと、開発環境と本番環境の接続情報を書き換えたり、 アプリケーション実行時に動的に値を読み込む仕組みが構築できます。

上書きの方法

アプリケーション実行時には設定ファイルはjarの中に梱包されているため、 直接書き換えることはできません。 Spring側で上書きの仕組みをいくつか用意してくれています。

環境変数での上書き

その中の一つに環境変数への設定があります。 例えばこんな感じのapplication.ymlが梱包されているとすると

app:
  test:
    db:
      user:username
      password:passwd

環境変数に APP_TEST_DB_USER=overrideuser APP_TEST_DB_PASSWORD=overridepass のようにプロパティ名を大文字のスネークケースを設定することで Springがアプリの起動時に読み込んでくれます。

systemdへの登録

このアプリをデーモンプロセスとして起動する場合、systemdのユニットファイルを利用します。 こちらの記事がわかりやすかったです。 http://enakai00.hatenablog.com/entry/20130917/1379374797

上記の記事には記載されていませんが、プロセスを実行するユーザを指定することもできます。 デフォルトはrootで実行されるのかな?(未検証)

プロパティが上書きされない

ユニットファイルに起動ユーザを指定して、~/.bashrcに環境変数をセットして再読み込み、 いざ、起動!

当然のように反映されません。(いつもの)

調査のため、プロセスを起動するユーザにログインしてprintenvコマンドを使って 環境変数を覗いてみるとちゃんとセットされています。

ということはsystemdでのデーモン起動時には~/.bashrcが読まれていないということ。

解決策

systemdプロセスの場合は、ユニットファイルで環境変数が記載されたファイルを指定してあげる必要があるみたいです。 EnvironmentFileというオプションで設定ファイルの場所を指定します。 この場合、変数展開を利用するために一工夫必要なため注意。

https://qiita.com/kobanyan/items/f8e8a3bd5406e1d290fb