Python venv 사용법의 핵심은 프로젝트별 Python 패키지 설치 공간을 분리하는 데 있다. venv는 Python 표준 라이브러리 기능이다. 시스템 Python에 패키지를 직접 설치하면 운영체제 도구나 다른 애플리케이션과 버전이 충돌할 수 있지만, 가상환경을 사용하면 각 프로젝트가 필요한 버전을 독립적으로 관리할 수 있다.
이 글은 Linux·macOS·Windows에서 가상환경을 생성하고 확인하는 기본 절차부터 requirements.txt, 폐쇄망 wheelhouse, systemd 서비스, 안전한 삭제와 문제 해결까지 실무 관점에서 설명한다. 명령은 복사하기 전에 Python 버전과 프로젝트 경로를 실제 환경에 맞게 바꾼다.

Python venv 빠른 시작
프로젝트 디렉터리 안에 .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에 커밋하지 말고, 의존성 파일을 사용해 언제든 다시 만들 수 있게 관리하는 것이 핵심이다.Python venv란 무엇이며 어떻게 격리하는가
완전히 복제된 Python이 아니라 별도의 실행 컨텍스트
가상환경을 만들면 대상 디렉터리에 pyvenv.cfg, 실행 파일 디렉터리, 독립적인 site-packages가 생성된다. 플랫폼과 생성 옵션에 따라 Python 실행 파일은 복사본 또는 심볼릭 링크일 수 있다. 따라서 venv는 컨테이너처럼 OS를 격리하는 기술이 아니며, 생성에 사용한 기본 Python과 운영체제 라이브러리에 의존한다.
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 생성 전 확인 사항
먼저 사용할 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'
운영체제와 셸별 생성·활성화 명령
| 환경 | 생성 | 활성화 |
|---|---|---|
| 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)"
Python venv 활성화 없이 실행하는 방법
Python 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
Python venv 패키지 설치와 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
폐쇄망·오프라인 환경에서 Python venv 운영
폐쇄망에서는 인터넷 연결 서버가 대상 서버와 같은 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
(cd wheelhouse && 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 서비스에서 Python venv 사용
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
Python venv를 이동하지 말고 다시 생성해야 하는 이유
가상환경에 설치된 스크립트의 shebang에는 환경 인터프리터의 절대 경로가 기록될 수 있다. 디렉터리를 다른 위치나 서버로 복사하면 이 경로가 깨질 수 있으므로 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
Python venv 안전하게 삭제하기
가상환경 삭제는 디렉터리 제거이지만, 변수 오타나 빈 경로가 있으면 다른 데이터를 지울 수 있다. 삭제 전에 절대 경로와 pyvenv.cfg를 확인하고, 실행 중인 서비스가 해당 환경을 사용하지 않는지 점검한다.
VENV="$(realpath -- .venv)"
printf 'delete target: %s
' "$VENV"
test -n "$VENV"
test "$VENV" != "/"
test -f "$VENV/pyvenv.cfg"
# systemd나 cron이 이 경로를 사용하지 않는지 먼저 확인한다.
grep -R --fixed-strings "$VENV" /etc/systemd/system /etc/cron* 2>/dev/null || true
read -r -p "위 가상환경만 삭제하려면 DELETE 입력: " answer
test "$answer" = "DELETE"
rm -rf -- "$VENV"
자주 발생하는 문제와 해결 방법
| 증상 | 우선 확인 | 해결 방향 |
|---|---|---|
No module named venv |
배포판의 venv 패키지 | OS 저장소에서 현재 Python 버전에 맞는 venv 패키지 설치 |
| 설치했는데 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: Python 표준 라이브러리만으로 프로젝트별 환경을 수동 관리할 때 적합하다.
- 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 참조 여부를 확인한다.
관련 가이드
공식 참고 문서
정리
Python venv의 핵심은 활성화 명령 자체가 아니라, 프로젝트가 사용할 인터프리터와 패키지 경로를 분리하고 그 환경을 재현 가능하게 관리하는 데 있다. 개발 중에는 .venv를 활성화해 편리하게 사용하고, 운영 자동화에서는 절대 경로를 지정한다. 의존성 파일, 실행 조건, 무결성 검증과 교체 절차를 함께 관리하면 서버와 폐쇄망에서도 안정적으로 운영할 수 있다.