uvでvenvを利用しない方法について for dev-container
お久しぶりのTechブログとなります。
はい、復活ブログの第2弾です。
どうも、もりりんです。

再開しようと思ってはいたものの…作業も忙しいしと、放置期間が長すぎましたね。
これからは(も)、頑張って更新していきます。(尻すぼみにならないように…)
今回は、Pythonでよく使われているPythonパッケージ管理ツールのuvについてです。
dev-containerを久しぶりに使ったのですが、uv経由でパッケージをインストールすると仮想環境のvenvを作りますが、そもそも開発用にdev-containerに隔離しているのだからvenv作らなくていいでしょ?と、いろんな記事を見てチャレンジしました。
まぁいつも通りブログの情報だと結局うまくいかず、AIに問い合わせつつドキュメントやissueをみて試行錯誤することになりました。
同じように悩んでいる人もいるかと思い、先達に習って簡単にブログ化しておきましょう。
では、スタートです。
venvを作りたくないよー
もう個人の嗜好です。
こんなところにこだわるなら、実装進めようzeというのも分かります。
でも、作りたくなかったのでこだわりました。
dev-containerとは?、uvとは?については、紹介ブログが山ほど、わんさかあるのでそちらを確認してください。
今回の「uvでvenvを作らずに」パッケージインストールする方法のみ記載します。みんなも短い方がいいよね?
やっぱり辿り着くまでの過程も簡単に載せています。
Let’s チャレンジ
前提条件です。
# Python 3.12.11
# uv 0.8.15
よくブログで紹介されている実装です。
まずは、Dockerfileに以下を追加します。
# Dockerfile
# UVにvenvではなく、システムのPythonを利用するように仕向ける制御
ENV UV_SYSTEM_PYTHON=1 \
UV_PROJECT_ENVIRONMENT=/usr/local/
続いて、インストールコマンドです。
uv sync --frozen
# もしくは
uv sync --frozen --system
みなさんはできましたか?
私は、venvが作成されました。
ちなみにuv 0.8.15では、「–system」のオプションは存在しませんよ?
一体どこからきたのか…もしくは過去はあったのか?
syncのhelpは以下でした。(コードブロックが保存できなかったので、画像ですいません。)

うん、systemオプションはありませんね。
frozenオプションは、uv.lockに展開されたバージョンを変更せずにインストールするためのものなので関係なし。
となると、uv sync自体がダメなのでは?
ということで、ドキュメントで仕様を確認しましょう。
このドキュメントでは、venvを無効化する内容は記載されていませんね。
# Google翻訳
リポジトリ内のファイル.venvに追加することで、イメージビルドに含まれないようにするのがベストプラクティスです。
プロジェクトの仮想環境はローカルプラットフォームに依存するため、イメージ内で最初から作成する必要があります。
.dockerignore
とも書かれてます。
ついでに「UV_PROJECT_ENVIRONMENT」に関する記載も見つかりました。
「VIRTUAL_ENV」でどうにかなりそうな匂いもするが、今回はスキップします。

もう少し検索を進めると、pipインターフェースの使用で「–system」オプションを発見します。
コンテナはすでに分離されているため、システムのPython環境はこのコンテキストを安全に使用できます。
--systemフラグを使用してシステム環境にインストールできます。
# Dockerfile
RUN uv pip install --system ruff
お、uv pip installコマンドだと、「–system」オプションがあるのですね。
確かめてみましょう。

おーーー、確かにありますね。
だとすると、ブログではsyncとpip installを取り違えているのでしょうか?
しかし、ブログ執筆前に検証しているでしょうし、分かりませんね。
一応、GitHubのイシューも確認しましょう。
「Sync with system Python?」というタイトルで投稿されています。
スレッド内で2024/8/10に運営メンバーから以下のように回答されています。
Na this isn't supported yet.
そして、関連イシューがもう1つあります。
2つの記事をかる〜く目を通しましたが、Closeされておらず議論はまだ続いていますね。
.venvを残しておいても影響は小さいでしょ勢が強い気はしますが…
まぁ、今はいいでしょう。
であれば、素直に「uv pip install –system」を使いましょうか。
Claude(SaaS)に参考リンクを全て渡して提案してもらいました。
# uv.lockを強制的に再生成(必要であれば)
uv lock
# uv.lockから依存関係リストをrequirement.txt形式で抽出し、依存関係をシステム環境にインストール
uv export --no-hashes | uv pip install --system -r -
# プロジェクト自体をシステム環境にインストール
uv pip install --system -e .'
# devcontainer.jsonのpostCreateCommandに設定する場合
bash -c 'uv lock && uv export --no-hashes | uv pip install --system -r - && uv pip install --system -e .'
# 必要に応じて、sudoを付与すること
はい、これで僕の要求通りにdev-container環境構築を構築でき、動作確認が取れました。
ありがとう、Claude。またPro契約再開するからね。
正直なところ、.venvはプロジェクトルートにできるので実行コンテナと分離されていて問題ないはずです。
ただ、そもそもdev- container(Docker)で分離した開発環境を用意しているんだから、破壊されてもcontainerを作り直せば済むだけだよね?と考えています。
もちろん何かあれば自己責任ですし(そもそもcontainerなので影響はほぼなし)、その分の勉強になるから良いのです。(AI時代も勉強大事)
おわりに
次の記事で出ますが、Kiroを利用したSpec開発の環境構築で詰まりに詰まった内容です。
これの内容だけでも需要があるかと思うので、別枠で先行公開です。
いやー、AIに頼り切りだと調査能力や本当にAIの回答が正しいのかチェックする能力が試されます。
エージェントの検索機能だと、GitHubのissueスレッド内ラリーとかの表示上省略されているページとか検索できないし、結局はそこを含めて人が担当する部分ですね。
ここはAIの進歩にお任せしましょう。
この記事を執筆している9/16のAM1では、Claude4.5が今週リリースされると噂されていますが、どうでしょうか?
この記事の公開が早いのか、Claudeが早いのか、自分との戦いです。(意味不明)
さて、今回もお読みいただきありがとうございました。
こういった小ネタブログも増やしていきますので、お待ちください。