【PR】この記事にはA8.netのアフィリエイト広告を含みます。
先に結論:Docker Compose secretのpathを通常のPOSTGRES_PASSWORDへ入れても、file内容には自動展開されません。XServer VPSでPostgreSQL 17.10を実測すると、実secret値では0/5回失敗し、文字列/run/secrets/db_passwordでは5/5回認証成功しました。POSTGRES_PASSWORD_FILE版は正反対に実secret値で5/5回成功したため、判定は設定方法について解決です。
- Docker secretへpathを書くと中身が環境変数に入る?
- Docker公式ではCompose secretをどう説明している?
- XServer VPSでどんな実験をした?
- 通常のPOSTGRES_PASSWORDへsecret pathを入れるとどうなった?
- POSTGRES_PASSWORD_FILEならどうなった?
- 4条件20回の認証結果は?
- docker compose configとinspectには何が見えた?
- secret fileはcontainer内で本当に読めた?
- _FILE非対応アプリではどうすればよい?
- Compose secretとSwarm secretは同じ?
- 実験中にどんな問題が起きた?
- CPU・RAM・ストレージへの影響は?
- 本番サービスと後片付けは?
- 初心者が迷いそうなポイントは?
- XServer VPSでこの悩みはどこまで解決した?
- よくある質問
- 最新条件の確認先
Docker secretへpathを書くと中身が環境変数に入る?
入りません。Compose secretはcontainer内へfileとしてmountされます。環境変数へ/run/secrets/my_secretと書いた場合、その値はpathを表すただの文字列です。applicationがfileを開かなければsecret内容は使われません。
悩みの起点にしたReddit「Secret assigned to ENV variable in docker-compose has the path as value」では、React/Vite appへVITE_A: /run/secrets/vite_aを設定すると、画面にsecret内容ではなくpathが出たと報告されています。
Docker公式ではCompose secretをどう説明している?
Docker公式のCompose secrets docsでは、secretはLinux containerの/run/secrets/<secret_name>へfileとしてmountされると説明されています。
同docsのMYSQL_PASSWORD_FILEやPOSTGRES_PASSWORD_FILEはDocker共通機能ではなく、一部のDocker Official Imagesが実装している「_FILE convention」です。任意の環境変数名へ_FILEを付ければ動くわけではありません。
XServer VPSでどんな実験をした?
| 項目 | 実測条件 |
|---|---|
| VPS | XServer VPS、4 vCPU、4GB RAM、150GB |
| OS | Ubuntu 26.04 |
| Docker Compose | v5.5.0 |
| DB | postgres:17.10-alpineを2個 |
| secret | 実験ごとに生成した49文字の合成password |
| 認証 | TCP、SCRAM-SHA-256 |
| 試行 | 4条件×5回、計20回 |
| network | Docker internal network、公開portなし |
| 上限 | 各DB 0.5 CPU、256MiB RAM、PID 128 |
本物のpassword、API key、tokenは使っていません。raw合成passwordも結果へ残さず、49文字という長さとSHA-256だけを保存しました。
[PR]
Dockerを安全に試せるVPSなら『XServer VPS』![]()
通常のPOSTGRES_PASSWORDへsecret pathを入れるとどうなった?
wrong版は次の設定です。
services:
db:
image: postgres:17.10-alpine
environment:
POSTGRES_PASSWORD: /run/secrets/db_password
secrets:
- db_password
secrets:
db_password:
file: ./db_password.txt
DBへ実secret値で5回loginすると0/5回で、すべてFATAL: password authentication failedでした。ところがliteral pathの/run/secrets/db_passwordをpasswordとして使うと5/5回成功しました。
secret fileは正しくmountされていましたが、PostgreSQL entrypointは通常のPOSTGRES_PASSWORDを文字列として受け取ります。そのためpath自体がDB passwordとして初期設定されました。
POSTGRES_PASSWORD_FILEならどうなった?
correct版は変数名だけを変えました。
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
実secret値で5/5回認証成功し、literal pathでは0/5回失敗しました。Official PostgreSQL imageのentrypointがPOSTGRES_PASSWORD_FILEを認識し、指定fileの内容を読み取った結果です。
4条件20回の認証結果は?
| DB設定 | login値 | 成功 | 中央値 |
|---|---|---|---|
| 通常変数にpath | 実secret値 | 0/5 | 72.722ms |
| 通常変数にpath | literal path | 5/5 | 88.772ms |
| _FILE変数 | 実secret値 | 5/5 | 66.375ms |
| _FILE変数 | literal path | 0/5 | 86.022ms |
20/20回が期待結果と一致しました。Compose secretのmount成否と、applicationがどの環境変数をどう解釈するかは別問題です。
docker compose configとinspectには何が見えた?
docker compose configとdocker inspectでraw合成secretは0件でした。一方、pathと変数名は確認できました。
- wrong:
POSTGRES_PASSWORD=/run/secrets/db_password - correct:
POSTGRES_PASSWORD_FILE=/run/secrets/db_password - secretのsource名、target path、host source file path
「inspectにsecret値がない」ことと、「applicationが正しいpasswordを使った」ことも別です。raw値が隠れていても、wrong版は意図しないpath文字列をpasswordとして使っていました。
secret fileはcontainer内で本当に読めた?
両DBの/run/secrets/db_passwordを調べると、mode・UID・GID・sizeは444 1000 1000 49でした。fileのSHA-256も生成時の合成secretと一致しています。
つまり、今回の認証失敗は「fileがない」「mountできない」「hashが違う」ためではありません。application側がfile pathを内容へ変換しなかったことが原因です。
_FILE非対応アプリではどうすればよい?
- image公式docsで対象の
_FILE変数を確認する。 - 対応していれば
APP_PASSWORD_FILE=/run/secrets/...を使う。 - 非対応ならapplication codeがsecret fileを直接読む。
- 変更できない場合のみ、entrypoint shimでfileを読みchild processへ渡す。
- 起動後に実際の認証またはAPI requestを行い、path文字列になっていないか検証する。
entrypointで環境変数へ展開すると、child processのenvironmentから見える範囲が増えます。fileを直接読む設計のほうが、値を環境変数へ載せずに済みます。
Compose secretとSwarm secretは同じ?
実装上の性質は同じではありません。今回使ったDocker Composeは、Docker公式docsの説明どおりhost fileをLinux containerへ単一fileとしてbind mountします。
Docker Swarm secretsはmanagerの暗号化Raft logとcontainerのin-memory filesystemを使います。Composeでsecret syntaxを書いただけでhost側source fileまで自動暗号化されるわけではありません。
実験中にどんな問題が起きた?
初回はpg_isreadyだけでDB開始を判定しました。Official imageは初期化用PostgreSQLを一時起動してからfinal serverへ切り替えるため、その途中のrequestが混ざりました。
開始条件を「PostgreSQL init process completeのlog」と「最終passwordによるTCP認証成功」の両方へ変更しました。
2回目は異なるpassword候補が両方通り、password比較として無効でした。最終runでは--auth-host=scram-sha-256を明示し、生成されたpg_hba.confの127.0.0.1、::1、all hostがSCRAM-SHA-256であることも保存しました。
CPU・RAM・ストレージへの影響は?
- wrong PostgreSQL peak RAM:79.52MiB
- _FILE PostgreSQL peak RAM:79.57MiB
- wrong CPU:1.552812秒
- _FILE CPU:1.514781秒
- host MemAvailable:約3273.95MiBから3145.34MiB
- root disk差:53,248 byte増
- 成功run総時間:5.538255秒
DB dataは128MiB tmpfsに置きました。数値は2DBの初期化と20回のauthenticationを含み、大規模DB workloadのbenchmarkではありません。
本番サービスと後片付けは?
公開/health/readyは開始前、実験中、終了後の全3回でHTTP 200でした。database=ok、artifact_storage=okも維持しています。
本番Caddy、FastAPI、PostgreSQLは前後restart 0でした。一時DB 2個、internal network、tmpfsを削除し、dangling volumeは前後0件、公開portも0件です。
初心者が迷いそうなポイントは?
- Compose secretは環境変数ではなくfileとして届く。
- pathを通常変数へ入れてもfile内容には展開されない。
_FILEは一部imageのconventionで、Docker共通の自動機能ではない。- secretがmount済みでも、applicationの読み方が違えば認証失敗する。
pg_isready成功だけではpassword認証成功を証明しない。- authentication testでは
pg_hba.confのmethodも固定する。 - Vite等のclient-side bundleへ入る値を秘密情報として扱わない。
XServer VPSでこの悩みはどこまで解決した?
設定方法について解決です。通常変数へpathを入れたPostgreSQLはpath自体をpasswordとして受け取り、実secret値で0/5回、pathで5/5回成功しました。POSTGRES_PASSWORD_FILE版は実secret値で5/5回成功し、意図どおり動きました。
すべてのimageが_FILEへ対応するわけではありません。また、password rotation、Swarm、Vault、Kubernetes Secretは未検証です。image docsとentrypointを確認し、起動後の実認証まで自動testに含めます。
よくある質問
Q. Docker secretのpathをPASSWORDへ設定すれば中身が入りますか?
A. 入りません。通常はpath文字列がそのまま値になります。applicationがfileを読む必要があります。
Q. 変数名へ_FILEを付ければどのimageでも使えますか?
A. 使えません。imageやapplicationがその変数を実装している場合だけ動きます。
Q. PostgreSQL Official Imageでは何を使いますか?
A. 今回の17.10ではPOSTGRES_PASSWORD_FILE=/run/secrets/db_passwordで実secret値が使われました。
Q. inspectにsecret値がなければ設定成功ですか?
A. いいえ。wrong版もraw値はinspectにありませんでしたが、path自体をpasswordにしていました。実認証で確認します。
Q. Compose secretはhost上でも暗号化されますか?
A. Composeはsource fileをcontainerへmountします。source fileの保存・暗号化・権限管理は別途必要です。
実験日:2026年9月2日。数値は筆者が契約中のXServer VPS 4GB環境における各5回の実測です。Docker Compose、image、entrypoint、認証方式により結果は変わります。

コメント