Python venvの使い方:作成・有効化からrequirements.txtと本番運用まで
EdwardMoon
Python venvの中心となる機能は、プロジェクトごとにパッケージのインストール先を分離することです。venvはPython標準ライブラリの機能です。システムPythonへ直接パッケージを入れると、OSのツールや他のアプリケーションとバージョンが競合する場合がありますが、仮想環境なら各プロジェクトに必要なバージョンを独立して管理できます。
この記事ではLinux、macOS、Windowsでの作成と確認から、requirements.txt、閉域環境のwheelhouse、systemd、安全な削除、トラブル対応まで説明します。コピーする前にPythonのバージョンとプロジェクトパスを実環境へ合わせてください。

クイックスタート
プロジェクト内に.venvを作り、そのPythonでpipを実行するのが基本です。pipだけを呼ぶよりpython -m pipを使う方が、選択中のインタープリターとpipの対応を明確にできます。
mkdir -p ~/projects/sample-app
cd ~/projects/sample-app
python3 --version
python3 -m venv .venv
source .venv/bin/activate
python -m pip --version
python -m pip install --upgrade pip
python -m pip install requests
python -c "import requests; print(requests.__version__)"
deactivate
仮想環境ディレクトリはソースコードではありません。.venv/をGitへコミットせず、依存関係ファイルからいつでも再作成できるように管理します。
venvとは何か、何を分離するのか
Pythonの完全な複製ではなく、独立した実行環境
作成先にはpyvenv.cfg、実行ファイル用ディレクトリ、独立したsite-packagesが作られます。プラットフォームと作成オプションにより、Python実行ファイルはコピーまたはシンボリックリンクになります。venvはコンテナのようにOSを隔離する技術ではなく、作成に使ったベースPythonとOSライブラリへ依存します。
python3 -m venv .venv
find .venv -maxdepth 2 -type f -o -type l | sort | head -30
cat .venv/pyvenv.cfg
仮想環境で実行しているか正確に確認する
有効化スクリプトは、環境の実行ファイルディレクトリをPATHの先頭へ追加します。ただし有効化は必須ではないため、VIRTUAL_ENVだけで判定すると見落とす場合があります。Python内部でsys.prefixとsys.base_prefixを比較する方が確実です。
python - <<'PY'
import sys
print("executable :", sys.executable)
print("prefix :", sys.prefix)
print("base_prefix :", sys.base_prefix)
print("inside venv :", sys.prefix != sys.base_prefix)
PY
作成前の確認
使用するPythonの実際の場所とバージョン、venvモジュール、pipのブートストラップ可否を確認します。複数Pythonがある場合は、python3.11のように対象を明示して作成してください。
command -v python3
python3 --version
python3 -m venv --help >/dev/null
python3 -m ensurepip --version
一部のLinuxではvenvやpipが別パッケージです。名称は配布元とPythonバージョンで異なるため、リポジトリで確認してから導入します。システムPythonでsudo pip installを使うことは避ける方が安全です。
# Debian/Ubuntu系の一般的な例
sudo apt update
sudo apt install python3-venv python3-pip
# RHEL/Rocky系では先に提供パッケージを確認
sudo dnf list --available 'python3*' | grep -E 'pip|virtualenv'
OS・シェル別の作成と有効化
| 環境 | 作成 | 有効化 |
|---|---|---|
| Linux/macOS bash・zsh | python3 -m venv .venv | source .venv/bin/activate |
| Linux/macOS fish | python3 -m venv .venv | source .venv/bin/activate.fish |
| Windows cmd | py -m venv .venv | .venv\Scripts\activate.bat |
| Windows PowerShell | py -m venv .venv | .venv\Scripts\Activate.ps1 |
有効化後はパスとバージョンを確認します。プロンプトの(.venv)は補助表示にすぎません。実インタープリターのパスも確認することで、別環境へインストールする誤りを減らせます。
command -v python
python --version
python -m pip --version
python -c "import sys; print(sys.executable)"
有効化せずに実行する
venvを使うためにsourceは必須ではありません。cron、systemd、CIでは有効化スクリプトへ依存せず、環境内Pythonの絶対パスを直接実行する方が動作を予測しやすく、ログ分析も容易です。
# Linux/macOS
/opt/sample-app/.venv/bin/python /opt/sample-app/app.py
/opt/sample-app/.venv/bin/python -m pip list
# Windows PowerShell
.\.venv\Scripts\python.exe .\app.py
パッケージとrequirements.txtを管理する
現在のPythonからpipを呼ぶ
python -m pip install --upgrade pip
python -m pip install 'requests>=2.32,<3'
python -m pip list
python -m pip check
pip checkは、インストール済みパッケージが宣言する依存関係の互換性を検査します。導入後にアプリケーションのテストと一緒に実行すると、不足や競合を早く発見できます。
環境のスナップショットを作成・再現する
pip freezeは直接・間接の依存パッケージの現在のバージョンを出力し、本番環境の記録に役立ちます。ただしOS、CPU、Pythonが変わると同じファイルで導入できない場合があるため、実行条件も記録してください。
python -m pip freeze > requirements.txt
python -m pip check
# 新しい環境で再現
python3 -m venv .venv-new
.venv-new/bin/python -m pip install --upgrade pip
.venv-new/bin/python -m pip install -r requirements.txt
.venv-new/bin/python -m pip check
プロジェクトへ含めるファイル
# .gitignore
.venv/
__pycache__/
*.py[cod]
.env
# バージョンとインストール状態を記録
python --version
python -m pip --version
python -m pip freeze
閉域・オフライン環境で運用する
ダウンロードするオンラインサーバーは、対象と同じOS、CPUアーキテクチャ、Pythonのメジャー・マイナーバージョンにそろえることが重要です。wheelはプラットフォームやPython ABIに依存する場合があり、別のPCで取得したものをコピーするだけでは失敗することがあります。
オンラインサーバーでwheelhouseを準備する
python3 -m venv bundle-venv
bundle-venv/bin/python -m pip install --upgrade pip
# wheelだけを許可すると、オフラインサーバーでソースビルドが必要なパッケージを事前に検出できる。
bundle-venv/bin/python -m pip download --only-binary=:all: --dest wheelhouse -r requirements.txt
sha256sum wheelhouse/* > SHA256SUMS
tar -czf python-wheelhouse.tar.gz wheelhouse requirements.txt SHA256SUMS
sha256sum python-wheelhouse.tar.gz > python-wheelhouse.tar.gz.sha256
オフラインサーバーで検証してから導入する
sha256sum -c python-wheelhouse.tar.gz.sha256
tar -xzf python-wheelhouse.tar.gz
sha256sum -c SHA256SUMS
python3 -m venv .venv
.venv/bin/python -m pip install --no-index --find-links=wheelhouse -r requirements.txt
.venv/bin/python -m pip check
--only-binary=:all:で失敗するパッケージには、互換wheelがありません。その場合はオンラインのビルドサーバーで必要なコンパイラーと開発ヘッダーを使ってwheelを作成し、同一条件の試験サーバーに新しい環境を作ってインストールと実行を確認します。
systemdサービスから利用する
systemdは対話シェルではないため、source .venv/bin/activateは不要です。ExecStartへPythonの絶対パスを指定し、秘密情報はソースコードと分離した権限制限付きファイルで管理します。
# /etc/systemd/system/sample-app.service
[Unit]
Description=Sample Python application
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=sampleapp
Group=sampleapp
WorkingDirectory=/opt/sample-app
EnvironmentFile=/etc/sample-app/sample-app.env
ExecStart=/opt/sample-app/.venv/bin/python /opt/sample-app/app.py
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
sudo systemd-analyze verify /etc/systemd/system/sample-app.service
sudo systemctl daemon-reload
sudo systemctl enable --now sample-app.service
sudo systemctl status sample-app.service --no-pager
sudo journalctl -u sample-app.service -n 100 --no-pager
移動せず再作成すべき理由
インストールされたスクリプトのshebangには、環境のPythonへの絶対パスが記録される場合があります。別の場所やサーバーへコピーすると壊れる可能性があるため、venv自体を配布成果物として扱いません。新しい場所で環境を作り、依存関係ファイルやwheelhouseから再インストールするのが公式の推奨方法です。
# 既存環境の実行条件と依存関係を記録
.venv/bin/python --version
.venv/bin/python -m pip freeze > requirements.txt
# 新しい場所で再作成
python3 -m venv /opt/sample-app/.venv
/opt/sample-app/.venv/bin/python -m pip install -r requirements.txt
/opt/sample-app/.venv/bin/python -m pip check
安全に削除する
削除はディレクトリを取り除く操作ですが、変数の誤りや空のパスによって別データを消すおそれがあります。絶対パスとpyvenv.cfgを確認し、稼働中のサービスが使っていないか調べてください。
# このブロックはサブシェルで実行するため、取り消しても現在のログインシェルは終了しません。
(
set -eu
VENV="$(realpath -e -- .venv)"
test -d "$VENV" && test -f "$VENV/pyvenv.cfg" || {
echo '가상환경 디렉터리가 아니므로 중단합니다.' >&2
exit 1
}
case "$VENV" in /|"$HOME"|/opt|/usr|/var)
echo '삭제할 수 없는 상위 경로입니다.' >&2; exit 1 ;;
esac
printf 'delete target: %s\n' "$VENV"
grep -R --fixed-strings "$VENV" /etc/systemd/system /etc/cron* 2>/dev/null || true
# 上記結果と稼働中のサービス・cronを確認してから回答します。
read -r -p '이 경로만 삭제하려면 DELETE 입력: ' answer
if [ "$answer" != DELETE ]; then
echo '취소했습니다.'
exit 0
fi
rm -rf -- "$VENV"
)
本番環境の交換時は旧ディレクトリをすぐ削除せず、新環境を別パスに作成・試験してからサービスを切り替えます。問題があれば旧パスへ戻せます。
よくある問題と対処
| 症状 | 最初の確認 | 対処方針 |
|---|---|---|
No module named venv | OSのvenvパッケージ | 現在のPythonに合うvenvをOSリポジトリから導入 |
| 導入したのにimportできない | sys.executableとpython -m pip --version | 同じインタープリターのpipで再導入 |
| PowerShellで有効化できない | 実行ポリシーと組織の方針 | 独自に緩和せず、Pythonの絶対パスで実行するか管理者の指示に従う |
| コピーした環境が動かない | shebangの絶対パス | 新しい場所で環境を再作成し、依存関係を再導入 |
| オフラインwheelを導入できない | OS・CPU・Python ABIタグ | 対象と同一条件でwheelhouseを再作成 |
| pipの依存関係が競合 | python -m pip check | バージョン制約を整理し、新しい環境で検証 |
python -c "import sys; print(sys.executable); print(sys.version)"
python -m pip --version
python -m pip list
python -m pip check
python -m site
venv・virtualenv・pipx・condaの選択基準
- venv:標準ライブラリだけでプロジェクト別環境を手動管理する場合に適する。
- virtualenv:豊富な作成オプションや幅広いPython互換機能が必要な場合に検討する。
- pipx:BlackやAnsible Lintなど、どこからでも実行するPython CLIをアプリケーション別環境へ導入する場合に適する。
- conda:Pythonパッケージとネイティブライブラリを一緒に管理する科学・データ分野で主に使う。
一般的なサーバー・開発環境の依存関係分離なら、まず標準のPython venvを使い、CLI配布やネイティブ依存など明確な要件がある場合に他のツールを選ぶと単純です。
実務チェックリスト
- 対象Pythonの実行ファイルとバージョンを確認してから作成する。
python -m pipで導入し、pip checkで検証する。.venv/をバージョン管理から除外し、requirementsまたはlockファイルを保管する。- 本番サービスは有効化スクリプトではなくPythonの絶対パスを使う。
- コピー・移動せず、対象の場所で再作成する。
- 閉域用バンドルは同じOS・CPU・Python条件で作り、SHA-256を検証する。
- 削除前に実パス、
pyvenv.cfg、サービスとcronからの参照を確認する。
関連ガイド
公式資料
まとめ
venvの要点は有効化コマンド自体ではなく、使うインタープリターとパッケージパスを分離し、再現可能に管理することです。開発中は.venvを有効化し、運用自動化では絶対パスを指定します。依存関係ファイル、実行条件、完全性検証、交換手順を併せて管理すれば、サーバーや閉域環境でも安定して運用できます。