uvでvenvを利用しない方法について for dev-container

お久しぶりのTechブログとなります。

はい、復活ブログの第2弾です。
どうも、もりりんです。

再開しようと思ってはいたものの…作業も忙しいしと、放置期間が長すぎましたね。
これからは(も)、頑張って更新していきます。(尻すぼみにならないように…)

今回は、Pythonでよく使われているPythonパッケージ管理ツールのuvについてです。
dev-containerを久しぶりに使ったのですが、uv経由でパッケージをインストールすると仮想環境のvenvを作りますが、そもそも開発用にdev-containerに隔離しているのだからvenv作らなくていいでしょ?と、いろんな記事を見てチャレンジしました。

まぁいつも通りブログの情報だと結局うまくいかず、AIに問い合わせつつドキュメントやissueをみて試行錯誤することになりました。

同じように悩んでいる人もいるかと思い、先達に習って簡単にブログ化しておきましょう。

では、スタートです。

このブログは人力で書いており、誤字脱字・表現のアドバイスにのみAIを利用しています。

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 syncでは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が早いのか、自分との戦いです。(意味不明)

さて、今回もお読みいただきありがとうございました。
こういった小ネタブログも増やしていきますので、お待ちください。

お知らせ

生成AIを活用したお悩み相談チャットサービス「Chit (チット)」を10月リリース予定です。

AIキャラクターを最大3人まで選択でき、昔ながらの井戸端会議っぽい雑談、マンツーマンでの悩み相談といった、使い方自由に色々なキャラクターと「会話」ができるAIチャットサービスです。

また、プライバシーに配慮し、会話履歴を含めたデータの2次利用(AIの学習、広告等)は一切いたしません。安心してご利用いただけます。