環境変数を設定したのに認証が動かないとき ── FastAPIで SECRET_KEY が None になる理由
冒頭
- 「アプリは起動しているのに、なぜか認証だけが壊れる」
- 「ローカルでは動くのに、本番(Docker)でだけ死ぬ」
(Signature verification failed / 401 Unauthorized)
これは FastAPI や JWT ライブラリの不具合ではありません。
FastAPI × Docker 構成では、
設定が一箇所でもズレると「壊れているのに静かに動く」状態が簡単に作れます。
よくある症状
-
.envにSECRET_KEYを書いたのにNoneになる - ローカル実行では OK、Docker だけ NG
-
print(SECRET_KEY)して絶望する
JWT を使っている場合、この状態はほぼ確実に
401 / 403 地獄の入口になります。
なぜ厄介か
このとき内部では JWTError が発生しており、
FastAPI はそれを 401 Unauthorized として表に出しています。
- アプリ自体は起動する
- ログも特にエラーを吐かない
- JWT事故と合体すると、原因が分かりにくい
「設定ミスなのに、例外が出ない」
これがこの事故の一番やっかいな点です。
原因パターン
1. --env-file を指定し忘れている
docker run の場合、.env は自動では読み込まれません。
docker run --env-file .env -p 8000:8000 app
これが無いと、
コンテナ内では SECRET_KEY は存在しません。
2. docker run と docker compose の指定方法の違い
-
docker run:--env-fileを明示する必要あり -
docker compose:env_file:や.envの扱いが異なる
同じ .env があるのに挙動が変わる原因になります。
3. settings.py の import 順が早すぎる
SECRET_KEY = os.getenv("SECRET_KEY")
これを module import 時に評価している場合、
-
.envがまだ読み込まれていない - その結果
Noneが取得される - None が正しい値としてキャッシュされる
という事故が起きます。
設定は「存在していない」のではなく、
「早すぎた」だけです。
この構成で確認できること
- 環境変数が正しく読み込まれる状態
-
.envや import 順が壊れたときの再現 - なぜ
Noneが発生するかの切り分け視点
「動かす」ためではなく、
「壊れたときに診断する」ための構成です。
まとめ
- 壊れているのは FastAPI ではない
- 壊れているのは 設定の流れ
- FastAPI は驚くほど正直に動いている
読めば、次に同じ事故が起きても
切り分けで迷わなくなります。
帰り際の一言
他にも FastAPI / Docker / JWT 周りの事故メモを公開しています。
同じような症状があれば、まずこの構成で“正常”を一度作ってみてください。
※同様の認証トラブルの原因切り分けを行っています。記事末尾に相談窓口を記載しています。
🛠️ FastAPI インシデント分析シリーズ
「401 / JWT / Dockerでだけ壊れる」など、原因切り分けが難しいケースをパターン別に公開しています。
🔐 認証・JWTトラブル
/tokenは通るのに /me が401になる理由
[https://zenn.dev/fastapier/articles/0022f125547300]
401 / 403 を取り違えると、原因が見えなくなる
[https://zenn.dev/fastapier/articles/41f9e2e10e7c19]
Depends が静かに壊れて 401 / 403 になる理由
[https://zenn.dev/fastapier/articles/efba40f5bcbbda]
🐳 Docker・本番環境トラブル
ローカルでは動くのに本番だけ落ちる理由
[https://zenn.dev/fastapier/articles/c90e5199e0bafc]
Dockerにしたら logging が出なくなった理由
[https://zenn.dev/fastapier/articles/cd530c54b6e47c]
🏗️ 設計・運用トラブル
main.pyが1000行を超えたときに起きる崩壊の理由
[https://zenn.dev/fastapier/articles/a2a9a5209dedac]
🩺 FastAPI事故 相談窓口(原因特定・構造分析)
FastAPI / JWT / Docker 周りの認証トラブルで、
/token は通るのに /me が 401 になる
本番環境でのみ InvalidSignatureError が発生する
Docker化後にだけ認証が落ちる
など、「原因の層が見えにくい事故」の切り分けと修正方針の整理を行っています。
3時間以上調査しても原因が特定できない場合、
それはコードではなく「構造」に問題がある可能性が高いです。
📩 ご相談方法
GitHubプロフィールに記載のメールアドレスまでご連絡ください。
[https://github.com/hiro-kuroe]
メール本文に、以下3点だけご記載ください(短文でOKです):
① 症状
(例:/me が 401 / 本番だけ署名エラー / Docker化後に認証失敗)
② 環境
(例:ローカルはOK、本番のみNG / Docker使用 / Gunicorn使用 など)
③ 直前に変更した点
(例:SECRET_KEY変更 / .env追加 / 依存パッケージ更新 など)
※まずは分析フェーズ(原因特定と構造整理)から進めます。
修正作業は、原因が明確になった後にご提案します。
Discussion