Python을 이용한 프로젝트를 진행할 때, 각 프로젝트마다 필요한 패키지를 관리하기 위해 **가상 환경(Virtual Environment)**을 사용해본 경험이 있을 것이다.

Info

만약 가상 환경을 만들고 사용하는 방법을 알고 있다면, 이 글을 건너뛰어도 좋다.

Tip

가상 환경과 **환경 변수(Environment Variables)**를 혼동하기 쉽지만, 이 둘은 다른 개념이다. 환경 변수는 시스템에서 프로그램이 사용할 수 있는 변수이고, 가상 환경은 일련의 파일이 포함된 디렉토리이다.

Info

이 글에서는 가상 환경을 생성하고 사용하는 방법과 그 동작 원리에 대해 알아볼 것이다. Python 설치를 포함한 모든 것을 관리해주는 도구를 도입할 준비가 되었다면 uv를 사용해 보는 것도 좋다.

Create a Project

먼저, 프로젝트를 진행할 디렉토리를 생성해보자.

예를 들어, 홈 디렉토리 안에 code라는 디렉토리를 만들고, 그 안에 각 프로젝트를 관리한다고 가정한다.

# home 디렉토리로 이동
cd ~
 
# 모든 프로젝트를 위한 code 디렉토리 생성
mkdir code
 
# code 디렉토리로 이동
cd code
 
# 이 프로젝트를 진행하기 위한 awesome-project 디렉토리 생성
mkdir awesome-project
 
# awesome-project 디렉토리로 이동
cd awesome-project

Create a Virtual Environment

Python 프로젝트를 시작할 때, 프로젝트 내부에 가상 환경을 생성한다.

Tip

매번 생성할 필요 없이 프로젝트마다 단 한 번만 생성하면 된다.

가상 환경을 생성하기 위해 Python의 venv 모듈을 사용한다.

python -m venv .venv

위 명령어를 실행하면 현재 디렉토리에 .venv 라는 디렉토리가 생성되고, 그 안에 가상 환경이 구성된다.

Activate the Virtual Environment

가상 환경을 생성한 후에는 해당 환경을 활성화하여 Python 명령 실행이나 패키지 설치를 가상 환경 내에서 진행한다.

TIP

작업하려는 프로젝트의 터미널 세션을 시작할 때마다 활성화해주면 된다.

source .venv/bin/activate

TIP

새로운 패키지를 설치할 때마다 가상 환경을 재활성화해주는 것이 좋다.

Check the Virtual Environment is Active

가상 환경이 제대로 활성화되었는지 확인해보자.

Tip

반드시 확인할 필요는 없지만, 가상 환경 내에서 의도한 대로 잘 작동하고 있는지 확인해보는 것을 매우 권장한다.

which python
 
# 실행 결과
/home/user/code/awesome-project/.venv/bin/python

만약 결과가 위와 같이 프로젝트 디렉토리 (현재는 awesome-project) 내의 .venv/bin/python 로 표시되면 성공적으로 활성화된 것이다.

Upgrade pip

Tip

uv를 사용하면 pip 대신 uv를 사용해 설치하므로 pip을 업그레이드할 필요가 없다. 😎

(Python에 기본적으로 제공되는) pip을 사용하여 패키지를 설치하는 경우, 최신 버전으로 업그레이드하는 것이 좋다.

패키지 설치와 관련된 대부분의 오류는 pip을 업그레이드하면 해결된다.

Tip

일반적으로 가상 환경을 만든 직후에 한 번만 수행하면 된다.

(위 명령어를 통해) 가상 환경이 활성화되어 있는지 확인 후 다음 명령어를 실행한다:

python -m pip install --upgrade pip

Add .gitignore

Git을 사용한다면, .gitignore 파일을 추가하여 .venv 의 모든 파일을 Git 추적에서 제외해야 한다.

Tip

uv를 사용하여 가상 환경을 생성한 경우, 이미 이 작업이 수행되었으므로 이 단계는 건너뛸 수 있다. 😎

Tip

가상 환경을 생성한 후 단 한 번만 수행하면 된다.

echo '*' > .venv/.gitignore

Install Packages

가상 환경을 활성화한 후, 필요한 패키지를 설치한다.

Tip

프로젝트에 필요한 패키지를 추가하거나 업데이트할 때마다 이 작업을 반복한다.

Install Packages Directly

빠르게 진행해야 하거나 별도의 요구 사항 파일을 사용하지 않는 경우, 패키지를 직접 설치할 수 있다.

Tip

프로그램에 필요한 패키지와 버전을 파일(requirements.txt 또는 [[How to use Poetry|pyproject.toml]])에 넣어두는 것을 (매우) 권장한다.

pip install "fastapi[standard]"
 
# 실행 결과
████████████████████████████████████████ 100%

Install from `requirements.txt“

requirements.txt 파일이 있는 경우, 해당 파일을 통해 패키지를 설치할 수 있다.

pip install -r requirements.txt
 
# 실행 결과
████████████████████████████████████████ 100%

Run Your Program

가상 환경을 활성화한 상태에서 프로그램을 실행하면, 해당 가상 환경의 Python과 패키지가 사용된다.

python main.py
 
# 실행 결과
Hello World

Configure Your Editor

사용하는 에디터에서 프로젝트의 가상 환경을 인식하도록 설정한다. 대부분의 에디터는 자동으로 감지하지만, 확인해보는 것이 좋다.

For example:

Tip

일반적으로 가상 환경을 생성한 후 한 번만 설정해주면 된다.

Deactivate the Virtual Environment

작업을 마쳤다면 가상 환경을 비활성화할 수 있다.

deactivate

이제부터 Python을 실행하면 전역 Python 환경이 사용된다.

Ready to Work

위의 과정을 통해 프로젝트를 진행하기 위한 모든 준비가 완료되었다.

Tip

더 자세한 내용을 알고 싶다면 아래 내용을 계속 읽어보길 권장한다.

Why Virtual Environments

단순히 pip을 사용하여 FastAPI 등 패키지를 설치하면, 해당 패키지들이 전역 Python 환경에 설치된다.

The Problem

전역 환경에 패키지를 설치하면, 여러 프로젝트에서 패키지 버전 충돌 등의 문제가 발생할 수 있다.

예를 들어, philosophers-stone 프로젝트는 harry v1 패키지에 의존한다고 가정하자.

image

그리고 나중에 prisoner-of-azkaban 라는 또 다른 프로젝트를 진행하는데, 이 프로젝트 역시 harry에 의존한다. 하지만, 여기서는 harry v3 이 필요하다.

image

전역 환경에 패키지를 설치하면 두 프로젝트에서 필요한 harry의 버전을 동시에 만족시킬 수 없다. 이로 인해 프로젝트 실행 시 오류가 발생하게 된다.

만약 philosophers-stone 을 실행하고 싶다면 다음과 같이 harry v1을 설치해야 할 것이다:

pip install "harry==1"

위 명령어를 실행하면 전역 파이썬 환경에 harry v1 이 설치된다.

image

하지만, 나중에 prisoner-of-azkaban을 실행하려고 하면, harry v1을 제거하고 harry v3을 설치해야 한다 (혹은 v3을 설치해도 v1은 자동으로 제거된다).

pip install "harry==3"

위 명령어를 실행하면 전역 파이썬 환경에 harry v3이 설치된다.

그 후 나중에 다시 philosophers-stone을 실행하면, 현재 파이썬 환경에서는 harry v3이 설치되어 있기 때문에 실행되지 않을 것이다.

image

Tip

Python 패키지에서는 새로운 버전에서의 변경 사항으로 인해 문제가 발생하지 않도록 노력하는 경우가 많다. 그러나 안전을 위해 새 버전을 의도적으로 설치하고, 모든 것이 제대로 작동하는지 테스트를 실행하는 것이 더 바람직하다.

Where are Packages Installed

Python을 설치하면 여러 파일이 컴퓨터에 설치되고, 패키지는 기본적으로 전역 Python 환경에 설치된다.

# Don't run this now, it's just an example
pip install "fastapi[standard]"
 
████████████████████████████████████████ 100%

그러면 일반적으로 [PyPI]에서 FastAPI 코드가 포함된 압축 파일이 설치된다. 추가로, FastAPI가 의존하는 다른 패키지의 파일 또한 설치된다.

그런 다음 압축 해제한 모든 파일을 컴퓨터의 디렉토리에 넣는다. 기본적으로 다운로드 하고 추출한 파일은 Python 설치와 함께 제공되는 디렉토리, 즉 전역 환경에 설치된다.

What are Virtual Environments

각 프로젝트마다 가상 환경을 생성하여 독립적인 패키지 공간을 갖도록 한다. 이렇게 하면 프로젝트 간 패키지 버전 충돌을 방지할 수 있다.

가상 환경은 전역 환경과 매우 유사한 디렉토리로, 프로젝트의 패키지를 설치할 수 있다. 이런 식으로 각 프로젝트는 자체적인 패키지가 있는 독립적인 가상 환경(.venv 디렉토리)을 갖게 된다.

image

What Does Activating a Virtual Environment Mean

가상 환경을 활성화할 때, 아래 명령어를 실행한다:

source .venv/bin/activate

위 명령어는 PATH 환경 변수를 생성하거나 수정한다.

가상 환경을 활성화하면 해당 경로인 .venv/bin (Linux 및 macOS) 또는 .venv\Scripts (Windows)가 PATH 환경 변수에 추가된다.

즉, 가상 환경을 활성화하기 이전의 PATH가 다음과 같다고 할 때:

/usr/bin:/bin:/usr/sbin:/sbin

시스템은 프로그램을 다음 경로에서 검색한다:

  • /usr/bin
  • /bin
  • /usr/sbin
  • /sbin

이후 가상 환경을 활성화하면, PATH 환경 변수가 다음과 같이 추가된다:

/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin

즉, 시스템이 프로그램을 검색할 때 가장 먼저 다음 경로를 참조한다는 것이다:

/home/user/code/awesome-project/.venv/bin

따라서 터미널에서 python을 입력하면 시스템은 다음 위치에서 Python 프로그램을 찾아서 실행한다.

/home/user/code/awesome-project/.venv/bin/python

중요한 점은 가상 환경의 경로가 PATH 환경 변수의 시작 부분에 추가된다는 것이다. 이로 인해 시스템은 다른 경로의 Python을 찾기 전에 해당 경로를 우선적으로 검색하게 된다다. 따라서 Python을 실행할 때 전역 환경의 Python을 포함한 다른 경로의 Python 대신, 해당 가상 환경의 Python이 실행된다.

Checking a Virtual Environment

가상 환경이 잘 작동하는지 확인하려면 다음 명령어를 실행하면 된다:

which python
 
# 실행 결과
/home/user/code/awesome-project/.venv/bin/python

위와 같이 가상 환경의 Python 경로가 출력되면 정상적으로 활성화된 것이다. Linux와 macOS에서는 which 명령어를, Windows PowerShell에서는 Get-Command 명령어를 사용한다.

이 명령어들은 PATH 환경 변수에 설정된 각 경로를 순서대로 탐색하며, python이라는 프로그램을 발견하면 해당 프로그램의 경로를 출력한다.

가장 중요한 점은 python 명령어를 호출할 때 실제로 실행되는 것이 가상 환경의 Python인지 확인하는 것이다. 따라서 가상 환경이 올바르게 설정되었는지 반드시 확인해야 한다.

Why Deactivate a Virtual Environment

위의 예시처럼, philosophers-stone 프로젝트를 진행하기 위해 해당 가상 환경을 활성화한 후 패키지를 설치하고 작업할 것이다. 그런 다음 다른 프로젝트인 prisoner-of-azkaban 프로젝트를 진행하고 싶을 때는 해당 프로젝트의 경로로 이동한다:

cd ~/code/prisoner-of-azkaban

만약 philosophers-stone의 가상 환경을 비활성화하지 않고 터미널에서 python을 실행하면 당연하게도 philosophers-stone 의 Python을 실행하려고 시도한다.

cd ~/code/prisoner-of-azkaban
 
python main.py
 
# Error importing sirius, it's not installed
Traceback (most recent call last):
	File "main.py", line 1, in
		import sirius

하지만, 이전 가상 환경을 비활성화한 후 prisoner-of-azkaban 가상 환경을 활성화한다면 올바른 가상 환경 변수에 존재하는 Python을 실행한다.

cd ~/code/prisoner-of-azkaban
 
# You don't need to be in the old directory to deactivate, you can do it wherever you are, even after going to the other project
deactivate
 
# Activate the virtual environment in prisoner-of-azkaban/.venv
source .venv/bin/activate
 
# Now when you run python, it will find the package sirius installed in this virtual environment
python main.py
 
# Result
I solemnly swear

Alternatives

가상 환경, 패키지 종속성, 프로젝트 관리를 위해 더 발전된 도구를 사용하고 싶다면 uv를 고려해보자.

Conclusion

이제 Python 가상 환경의 중요성과 사용 방법에 대해 이해했을 것이다. 가상 환경을 활용하여 프로젝트 간 패키지 관리 문제를 해결하고, 더욱 효율적으로 개발을 진행해보자.