uv runで.envが読み込まれないときの対処|env-fileと既存環境変数の優先順

uv runにenv-fileを指定し、probe.pyで2つのダミー環境変数だけを確認する説明図

答え:uv runでdotenvを使うときは、ファイルを置くだけでなく、--env-file .envまたはUV_ENV_FILEで読むファイルを明示します。同じ名前の変数が複数の場所にある場合は、既存のプロセス環境が最優先です。複数の--env-fileを指定した場合は、後に指定したファイルが前のファイルを上書きします。

優先度が高い順に並べると、既存環境 → 後に指定したdotenv → 先に指定したdotenvです。この記事では秘密を含まないITTRIP_DEMO_MODEとITTRIP_DEMO_REGIONだけを表示し、環境変数全体や実際のAPIキーは出力しません。例はuv 0.13.0、Python 3.13.7で7項目を確認した内容です。

目次

base.envとlocal.envを作る

コマンドを実行する作業ディレクトリに、テキストエディタで次の2ファイルを作ります。値は挙動確認用の安全なダミーです。

base.env

ITTRIP_DEMO_MODE=base
ITTRIP_DEMO_REGION=test

local.env

ITTRIP_DEMO_MODE=local

local.envではMODEだけを変更し、REGIONは定義しません。2ファイルを重ねたとき、MODEだけが後のファイルで置き換わり、REGIONは前のファイルから残ることを確認できます。

probe.pyで対象の2変数だけを見る

同じディレクトリにprobe.pyを作ります。os.environ全体を表示せず、調べたい変数だけをos.getenv()で読みます。秘密値が混ざる端末でも、無関係な環境変数を画面やログへ出さないためです。

import os

print("ITTRIP_DEMO_MODE =", os.getenv("ITTRIP_DEMO_MODE"))
print("ITTRIP_DEMO_REGION =", os.getenv("ITTRIP_DEMO_REGION"))

ファイル指定の有無で結果を比べる

まず、シェル側に同名変数がなく、UV_ENV_FILEも設定されていない状態で、ファイルを指定せずに実行します。

uv run -- python probe.py
ITTRIP_DEMO_MODE = None
ITTRIP_DEMO_REGION = None

次にbase.envを明示します。

uv run --env-file base.env -- python probe.py
ITTRIP_DEMO_MODE = base
ITTRIP_DEMO_REGION = test

.envという名前のファイルが作業ディレクトリにあっても、uvが自動で読むことを期待するのではなく、--env-file .envのように指定するのが確実です。「ファイルはあるのにNoneになる」ときは、まず実行コマンドに指定があるかを確認します。

7項目の期待結果

条件MODEREGION
ファイル指定なしNoneNone
base.envbasetest
base.envの後にlocal.envlocaltest
既存環境のMODEがshellshelltest
UV_ENV_FILE=base.envbasetest
--no-env-fileNoneNone
UV_NO_ENV_FILE=1NoneNone

ここでのNoneは、対象の変数が別の場所でも設定されていない前提です。端末やIDEに同名変数が残っていれば、その既存値が表示されます。

既存の環境変数がdotenvより優先される

base.envにはMODEがbaseとありますが、uvを起動する環境にMODEをshellとして設定すると、結果はshellです。REGIONは既存環境にないため、ファイルのtestが使われます。

PowerShell

$env:ITTRIP_DEMO_MODE = "shell"
uv run --env-file base.env -- python probe.py
Remove-Item Env:ITTRIP_DEMO_MODE

POSIX系シェル

export ITTRIP_DEMO_MODE=shell
uv run --env-file base.env -- python probe.py
unset ITTRIP_DEMO_MODE
ITTRIP_DEMO_MODE = shell
ITTRIP_DEMO_REGION = test

最後の解除コマンドまで実行し、検証用の値を後の作業へ残さないようにします。

複数ファイルでは後の指定が前を上書きする

--env-fileは複数回指定できます。次の例では、先に共通値のbase.env、後に差分のlocal.envを読みます。

uv run --env-file base.env --env-file local.env -- python probe.py
ITTRIP_DEMO_MODE = local
ITTRIP_DEMO_REGION = test

MODEは両方のファイルにあるため後のlocalになり、REGIONはlocal.envにないためbase.envのtestが残ります。ただし、既存環境に同名変数があれば、ファイル同士の順番よりも既存環境が上です。

優先度が高い順に、既存環境、後に指定したdotenv、先に指定したdotenvを並べた説明図
同名変数は上位の値が使われ、後のファイルにない変数は前のファイルから引き継がれます。 · 図を拡大

UV_ENV_FILEでファイルを渡す

ファイル指定はUV_ENV_FILEでも渡せます。実行後は、検証用の設定を解除します。

PowerShell

$env:UV_ENV_FILE = "base.env"
uv run -- python probe.py
Remove-Item Env:UV_ENV_FILE

POSIX系シェル

export UV_ENV_FILE=base.env
uv run -- python probe.py
unset UV_ENV_FILE

この例の期待結果はMODEがbase、REGIONがtestです。コマンドを見ただけでは使用ファイルが分からないため、トラブル調査ではUV_ENV_FILEが外側のシェルや実行環境に残っていないかも確認します。

--no-env-fileとUV_NO_ENV_FILEで読込を止める

--no-env-fileはdotenvの読込を無効にします。明示したファイルを一時的に無効化した結果を確認する例です。

uv run --env-file base.env --no-env-file -- python probe.py
ITTRIP_DEMO_MODE = None
ITTRIP_DEMO_REGION = None

環境変数で無効化する場合はUV_NO_ENV_FILE=1を使います。

PowerShell

$env:UV_ENV_FILE = "base.env"
$env:UV_NO_ENV_FILE = "1"
uv run -- python probe.py
Remove-Item Env:UV_NO_ENV_FILE
Remove-Item Env:UV_ENV_FILE

POSIX系シェル

export UV_ENV_FILE=base.env
export UV_NO_ENV_FILE=1
uv run -- python probe.py
unset UV_NO_ENV_FILE UV_ENV_FILE

この確認でも、シェルにMODEやREGIONそのものが既に設定されていれば、その既存値は残ります。無効になるのはdotenvファイルからの読込です。

相対パスは実行時のcwdを確認する

base.envのような相対パスの基点は、実行時のカレントワーキングディレクトリ(cwd)です。現在地は次のコマンドで確認できます。

PowerShell

Get-Location

POSIX系シェル

pwd

別の場所から起動している可能性があるなら、まず絶対パスで試すと、ファイル内容の問題かパスの問題かを切り分けやすくなります。

--directoryや--projectを組み合わせた場合の差は、この単純な例から断定しません。複雑な起動方法では、実際のcwdと渡したパスを個別に確認してください。

アプリ側のload_dotenvとは別レイヤー

ここまで説明したのは、uvがコマンドを起動する前にdotenvを環境へ渡す仕組みです。Pythonアプリの中でload_dotenv()などを呼ぶ処理は、起動後にアプリ自身が行う別の読込です。両方を同時に使うと、どちらの層が値を入れたのか分かりにくくなります。

uv側だけを検証するときは、今回のprobe.pyのようにos.getenv()だけを使います。また、uvのコマンドライン・環境変数・設定ファイルという「uv設定の選択順」と、読み込んだdotenv内の「変数値の勝敗」は別の話として整理してください。

FAQ

.envという名前なら自動で読まれますか?

uvによる自動読込を前提にせず、--env-file .envまたはUV_ENV_FILEで明示します。

local.envを先に指定すれば優先されますか?

いいえ。後に指定したファイルが前を上書きします。共通値のbase.envを先、差分のlocal.envを後にします。

原因調査で環境変数を全部表示してよいですか?

避けてください。実APIキーやトークンが混ざる可能性があります。対象名だけを選び、可能ならダミー値で再現します。

公式出典

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次