Composeサービスは、起動時ランチャーが別のプロジェクトディレクトリ、envファイル、または優先順位の異なる値の取得元を解決すると、再起動後に異なる環境変数を使用することがあります。
手動コマンドは意図したフォルダーで、あるシェル環境を使って実行される一方、systemd、NASのスケジューラー、またはPortainerは、再起動後に同じComposeファイルを別のコンテキストから起動することがあります。また、サービスが、編集後のファイルを再読み込みするのではなく、作成時に環境変数が固定された既存のコンテナを再起動している可能性もあります。一度に複数のファイルを編集する前に、手動起動経路と起動時経路で、レンダリングされたComposeモデルと実行中プロセスの環境変数を比較してください。
実行中の環境と意図したファイルを比較する
コンテナID、作成日時、イメージ、Composeラベル、プロジェクト名、そしてメインプロセス内で実際に確認できる値を記録します。共有ログに秘密情報を出力せず、意図したenvファイルと比較してください。
Linuxのプロセス環境には実行時に渡された値が公開されます。これは、現在のコンテナが実際には使用していない可能性のあるenvファイルを読むよりも強力な根拠になります。
コンテナに古い値が含まれており、再起動時のデプロイより前に作成されている場合、サービスはコンテナを再起動しただけかもしれません。コンテナが新しい場合は、優先順位とパスの解決を確認してください。
Composeの環境変数の優先順位を正しい順序で適用する
影響のない変数を1つ選び、CLIフラグ、シェルの値、environment:、env_file:、デフォルトまたは明示的な.env、イメージのENVなど、すべての取得元を一覧にします。
Dockerは正式な環境変数の優先順位を定義しています。そのため、正しいenvファイルであっても、起動サービスやスタック管理ツールによって注入された、より優先度の高い値に置き換えられることがあります。
重複するファイル名だけを検索しないでください。レンダリングされたComposeモデル、ユニットファイル、管理ツールの設定、シェル環境、イメージのデフォルト値を対象に、変数名そのものを検索します。
プロジェクトディレクトリと相対envパスを確認する
手動コマンドの作業ディレクトリと、起動ランチャーの作業ディレクトリ、Composeファイルの引数、プロジェクトディレクトリ、相対env_file参照を比較してください。
Compose仕様は、サービスと設定の解決に使用されるアプリケーションモデルを定義しています。そのため、選択されたプロジェクト定義とそのパスは、実行中のコンテナから再発見されるプロパティではなく、デプロイ時の入力情報です。
デプロイツールが対応している場合は、起動に不可欠なenvファイルに絶対パスを使用してください。または、明示的なプロジェクトディレクトリと作業ディレクトリを設定し、手動起動と自動起動で同じファイルが解決されるようにします。
systemdの作業ディレクトリと環境ファイルを確認する
有効なユニット、すべてのドロップイン、WorkingDirectory=、Environment=、EnvironmentFile=、ExecStart=を確認します。起動時に読み込まれるユニットと、手動で使用したコマンドを比較してください。
systemdの実行設定は、サービスの作業ディレクトリと環境ファイルを定義します。これらは、対話型ログインシェルの現在のディレクトリやエクスポート済み変数を自動的に引き継ぎません。
ユニットまたはドロップインを変更した後は、systemdマネージャーを再読み込みし、有効なユニットを再度確認してください。テンプレートや未使用のファイルを編集しても、実際に起動するサービスは変わりません。
スタック管理ツールの変数と保存済みデプロイ状態を確認する
PortainerまたはNASのUIがスタックを管理している場合は、保存済みの変数、アップロードされたenvファイル、Gitのデプロイパス、Webhookによる更新動作、表示されるComposeモデルを比較してください。
Portainerは.envとstack.envの動作を区別しています。そのため、管理ツールに入力した値が、ホスト上で直接編集したファイルの値と異なる場合があります。
信頼できる情報源を1つに決めてください。GitやWebエディターで管理するスタックを、再起動のたびに別のローカルコピーから手動で起動してはいけません。
単に再起動するのではなく、コンテナを再作成する
コンテナの作成日時とenvファイルの編集日時を比較します。意図したCompose設定をレンダリングしたうえで、影響を受けるサービスだけを制御された形で再作成してください。
Red Hatのsystemdに関するガイダンスでは、再起動する前にサービスが実際に使用するファイルと上書き設定を確認することを推奨しています。これにより、古いユニットやラッパーが古い値でコンテナを再作成するのを防げます。
コンテナを再起動しても、Composeから環境変数が再構築されることはありません。永続データを保護し、レンダリングされたモデルが意図したボリュームとシークレットを指していることを確認してから、コンテナを再作成してください。
手動起動、再起動、再デプロイで同じモデルを生成する
Composeファイル、プロジェクト名、プロジェクトディレクトリ、envファイルのパス、スタックの所有者、起動依存関係を固定します。マスキング済みのレンダリング設定と、機密情報を含まない環境変数のフィンガープリントを保存してください。
ZimaSpaceのDockerバックアップの対象範囲に関する記事では、関連するルールとして、環境ファイルとデプロイ定義を永続状態とともに保存する必要があると説明しています。
手動での再作成、ホストの再起動、スケジュール更新、スタック管理ツールからの再デプロイのすべてで、同じマスキング済み環境変数フィンガープリントを持つサービスが作成されるようになれば、問題は解決しています。
よくある質問
.envとenv_fileの違いは何ですか?
プロジェクトの.envファイルは通常、Composeへの展開用の値を提供します。一方、サービスのenv_fileはコンテナに渡す変数を提供します。両者の相互作用と優先順位は、完全なComposeモデルによって決まります。
コンテナを再起動すると、変更したenvファイルが再読み込みされますか?
いいえ。環境変数の値はコンテナ作成時に設定されます。通常は、修正したCompose設定からサービスを再作成する必要があります。
なぜ再起動後だけ問題が発生するのですか?
再起動経路では、手動起動とは異なるsystemdユニット、スケジューラー、管理ツールに保存された変数、別の作業ディレクトリ、または古いComposeコピーが使用されている可能性があります。
サポートとヒント
もっと読む

Dockerボリュームの復元でファイルの内容は再現されるのに、拡張属性が失われるのはなぜですか?
xattr のインベントリ、tar と Rsync のオプション、名前空間、保存先のサポート状況、権限、ラベル、アプリメタデータ、テストを網羅したボリューム復元の診断。

Composeファイルを変更した後も、実行中のコンテナが古いメモリ制限を維持するのはなぜですか?
ライブcgroup、再起動と再作成の違い、Composeのフィールド、ハードリミットとソフトリミット、親スコープ、スワップ、ランタイムヒープを網羅したメモリ制限の診断。

リバースプロキシを再起動すると、1つのセルフホストアプリですべてのセッションが無効になるのはなぜですか?
再起動の範囲、Cookieの所有権、シークレットのローテーション、キャッシュを利用したセッション、スティッキールーティング、認証ゲートウェイ、復旧を網羅したセッション喪失の診断。

