← Back to Blog

[Python] requirements.txt

computer science > programming

2026-07-066 min read

#computer-science #programming #python #pip #requirements #virtual-environment #ubuntu #macos #docker

requirements.txt란?

requirements.txt는 Python project에서 필요한 package 목록을 적어두는 파일이다. Ubuntu server, Ubuntu desktop, macOS에서 Python project를 배포하거나 실행할 때 가장 흔하게 사용하는 의존성 관리 방식 중 하나이다.

예를 들어 project에서 requests, numpy, pandas를 사용한다면 다음처럼 작성할 수 있다.

requests
numpy
pandas

다른 사람이 이 project를 실행하려면 같은 package를 설치해야 한다. 이때 package를 하나씩 직접 설치하는 대신 requirements.txt를 사용하면 한 번에 설치할 수 있다.

python3 -m pip install -r requirements.txt

requirements.txt는 다음 문제를 해결한다.

이 project를 실행하려면 어떤 Python package가 필요한가?
어떤 version의 package를 설치해야 하는가?
다른 환경에서도 같은 의존성을 재현할 수 있는가?

기본 사용 흐름

Ubuntu 기준의 일반적인 흐름은 다음과 같다.

sudo apt update
sudo apt install python3 python3-pip python3-venv

python3 -m venv .venv
source .venv/bin/activate
python -m pip install requests numpy pandas
python -m pip freeze > requirements.txt

macOS에서는 먼저 Python 3가 설치되어 있는지 확인한다.

python3 --version
python3 -m pip --version

Python 3가 없다면 Homebrew로 설치할 수 있다.

brew install python

그다음 흐름은 Ubuntu와 거의 같다.

python3 -m venv .venv
source .venv/bin/activate
python -m pip install requests numpy pandas
python -m pip freeze > requirements.txt

이후 다른 Ubuntu 또는 macOS 환경에서는 다음 명령어로 같은 package를 설치한다.

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

보통 repository에는 source code와 함께 requirements.txt를 commit한다. 하지만 .venv directory는 commit하지 않는다.

commit: requirements.txt
ignore: .venv/

requirements.txt 작성법

가장 단순한 형태는 package 이름만 쓰는 것이다.

requests
numpy
pandas

이렇게 쓰면 설치 시점에 pip가 설치 가능한 최신 version을 선택한다. 간단한 실험 code에서는 충분할 수 있지만, 실제 project에서는 version을 명시하는 것이 더 안정적이다.


version 고정

특정 version을 정확히 고정하려면 ==를 사용한다.

requests==2.32.3
numpy==2.1.3
pandas==2.2.3

이 방식은 재현성이 좋다. 다른 컴퓨터나 서버에서도 같은 version을 설치하기 때문이다.

다만 너무 오래 고정해두면 보안 patch나 bug fix를 놓칠 수 있다. 그래서 주기적으로 package version을 점검하고 업데이트해야 한다.


version 범위 지정

항상 정확한 version만 써야 하는 것은 아니다. 필요에 따라 version 범위를 지정할 수 있다.

문법의미
package==1.2.3정확히 1.2.3 설치
package>=1.2.01.2.0 이상 설치
package<=2.0.02.0.0 이하 설치
package>=1.2.0,<2.0.01.2.0 이상, 2.0.0 미만 설치
package~=1.2.0호환 가능한 release 범위 설치

예를 들어 다음은 requests2.31.0 이상, 3.0.0 미만으로 설치한다.

requests>=2.31.0,<3.0.0

library를 만드는 경우에는 너무 강하게 version을 고정하면 사용자가 다른 package와 함께 쓰기 어려울 수 있다. 반대로 application을 배포하는 경우에는 재현성을 위해 더 강하게 고정하는 경우가 많다.


pip freeze

현재 environment에 설치된 package 목록은 pip freeze로 확인할 수 있다.

python -m pip freeze

출력 예시는 다음과 같다.

certifi==2024.8.30
charset-normalizer==3.4.0
idna==3.10
numpy==2.1.3
pandas==2.2.3
python-dateutil==2.9.0.post0
pytz==2024.2
requests==2.32.3
six==1.16.0
tzdata==2024.2
urllib3==2.2.3

이 결과를 파일로 저장하면 requirements.txt가 된다.

python -m pip freeze > requirements.txt

주의할 점은 pip freeze가 직접 설치한 package뿐 아니라 의존성으로 함께 설치된 package까지 모두 출력한다는 것이다.

예를 들어 requests만 설치해도 certifi, charset-normalizer, idna, urllib3 같은 package가 함께 기록될 수 있다. 이 목록은 실행 환경을 정확히 재현하는 데는 좋지만, 사람이 읽기에는 다소 길어질 수 있다.


직접 관리하는 requirements.txt

작은 project에서는 직접 필요한 package만 적어두는 방식도 많이 사용한다.

requests>=2.31.0,<3.0.0
numpy>=2.0.0,<3.0.0
pandas>=2.2.0,<3.0.0

이 방식은 project가 실제로 직접 사용하는 package를 파악하기 쉽다. 하지만 하위 의존성 version까지 완전히 고정하지는 않으므로, 시간이 지나면 설치 결과가 달라질 수 있다.

정리하면 다음과 같다.

방식장점단점
pip freeze 결과 저장환경 재현성이 좋음파일이 길고 직접 의존성이 잘 보이지 않음
필요한 package만 직접 작성읽기 쉽고 관리가 단순함하위 의존성까지 완전히 고정되지는 않음

application 배포나 실험 재현이 중요하면 pip freeze 기반이 유리하다. 학습용 예제나 작은 script는 직접 관리해도 충분한 경우가 많다.


file 이름과 위치

관례적으로 project root에 requirements.txt를 둔다.

my_project/
  main.py
  requirements.txt

설치할 때는 project root에서 다음 명령어를 실행한다.

python -m pip install -r requirements.txt

파일 이름을 다르게 만들 수도 있다. 예를 들어 개발용 의존성을 분리할 수 있다.

requirements.txt
requirements-dev.txt

requirements.txt에는 실행에 필요한 package를 적고, requirements-dev.txt에는 test, lint, formatting 도구를 적는다.

# requirements-dev.txt
pytest
ruff
black

설치할 때는 파일 이름을 지정한다.

python -m pip install -r requirements-dev.txt

comment 사용

requirements.txt에서는 #으로 comment를 작성할 수 있다.

# HTTP client
requests>=2.31.0,<3.0.0

# data analysis
numpy>=2.0.0,<3.0.0
pandas>=2.2.0,<3.0.0

package가 많아지면 용도별로 comment를 달아두는 것이 좋다. 나중에 어떤 package가 왜 필요한지 파악하기 쉬워진다.


가상환경과 함께 사용하기

requirements.txt는 가상환경과 함께 사용할 때 가장 자연스럽다.

Ubuntu에서 venv module이 없다면 먼저 설치한다.

sudo apt update
sudo apt install python3-venv

macOS에서는 보통 Python 3 설치에 venv가 포함되어 있다. 설치 여부는 다음처럼 확인한다.

python3 -m venv --help

그다음 project마다 가상환경을 만든다.

python3 -m venv .venv

Ubuntu와 macOS shell에서는 다음처럼 활성화한다.

source .venv/bin/activate

활성화되면 prompt 앞에 (.venv)가 붙는다.

(.venv) user@ubuntu:~/my_project$

macOS에서는 prompt가 다음처럼 보일 수 있다.

(.venv) user@macbook my_project %

그다음 package를 설치한다.

python -m pip install -r requirements.txt

가상환경을 사용하면 project별로 package version을 분리할 수 있다. 전역 Python 환경에 package를 계속 설치하면 project마다 필요한 version이 충돌할 수 있다.


requirements.txt 업데이트

새 package를 추가했다면 requirements.txt도 함께 업데이트해야 한다.

예를 들어 fastapi를 설치했다고 하자.

python -m pip install fastapi

현재 환경 전체를 고정하려면 다시 freeze한다.

python -m pip freeze > requirements.txt

직접 관리하는 방식이라면 파일에 한 줄을 추가한다.

fastapi>=0.115.0,<1.0.0

중요한 점은 code에서 새 package를 사용하기 시작했다면 의존성 파일도 같이 변경해야 한다는 것이다. 그렇지 않으면 다른 사람이 project를 실행할 때 ModuleNotFoundError가 발생할 수 있다.


설치 확인

의존성이 제대로 설치되었는지 확인하려면 새로운 가상환경에서 다시 설치해보는 것이 가장 확실하다.

python3 -m venv .venv-test
source .venv-test/bin/activate
python -m pip install -r requirements.txt
python main.py

test가 있는 project라면 test까지 실행한다.

pytest

이 과정은 배포 전 확인에도 유용하다. 내 컴퓨터에서는 이미 설치되어 있어서 동작하지만, 새 환경에서는 빠진 package 때문에 실패하는 경우가 많기 때문이다.


자주 발생하는 문제

ModuleNotFoundError

다음 error는 필요한 package가 설치되지 않았을 때 발생한다.

ModuleNotFoundError: No module named 'requests'

먼저 가상환경이 활성화되어 있는지 확인한다.

which python
which pip
python --version
python -m pip --version

가상환경이 활성화되어 있다면 보통 .venv 경로가 출력된다.

/home/user/my_project/.venv/bin/python
/home/user/my_project/.venv/bin/pip

그다음 requirements.txt를 다시 설치한다.

python -m pip install -r requirements.txt

pip와 python이 다른 환경을 가리키는 경우

Ubuntu와 macOS에서는 system Python, user Python, virtual environment Python이 섞일 수 있다. 환경이 꼬였을 때는 pip 대신 python -m pip 형태를 쓰면 더 명확하다.

python -m pip install -r requirements.txt
python -m pip freeze

이 방식은 현재 실행 중인 python에 연결된 pip를 사용한다.

externally-managed-environment error

Ubuntu 23.04 이후 환경, 최신 Debian 계열, 일부 macOS Python 환경에서는 전역 환경에 pip install을 실행할 때 다음과 비슷한 error가 날 수 있다.

error: externally-managed-environment

이 error는 system Python 환경을 pip로 직접 변경하지 말라는 의미이다. 해결 방법은 전역 설치 대신 가상환경을 사용하는 것이다.

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

대부분의 project에서는 이 방식이 가장 안전하다.

Ubuntu apt와 macOS Homebrew

Ubuntu의 apt, macOS의 Homebrew, Python의 pip는 역할이 다르다.

도구용도
aptUbuntu system package 설치
brewmacOS system package 또는 개발 도구 설치
pipPython package 설치

예를 들어 Python 실행 환경과 venv module은 apt로 설치한다.

sudo apt install python3 python3-pip python3-venv

macOS에서 Python 자체가 필요하면 Homebrew로 설치할 수 있다.

brew install python

반면 project에서 사용하는 Python library는 가상환경 안에서 pip로 설치한다.

python -m pip install requests

platform별 package 문제

일부 package는 운영체제나 Python version에 따라 설치 가능 여부가 다를 수 있다. 이 경우 marker를 사용할 수 있다.

uvloop; sys_platform == "linux"

이 줄은 Linux 환경에서만 uvloop를 설치한다.


Docker에서 사용하기

Docker image를 Ubuntu 기준으로 만들 수도 있다. 이 경우에도 requirements.txt를 image 안으로 복사한 뒤 package를 설치한다.

예를 들어 project 구조가 다음과 같다고 하자.

my_project/
  main.py
  requirements.txt
  Dockerfile

Ubuntu base image를 사용하는 Dockerfile 예시는 다음과 같다.

FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        python3 \
        python3-pip \
        python3-venv \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY requirements.txt .

RUN python3 -m venv /opt/venv \
    && /opt/venv/bin/python -m pip install --upgrade pip \
    && /opt/venv/bin/python -m pip install -r requirements.txt

ENV PATH="/opt/venv/bin:$PATH"

COPY . .

CMD ["python", "main.py"]

Ubuntu container에서도 system Python에 직접 pip install을 하기보다 가상환경을 만들어 설치하는 편이 좋다. 최신 Ubuntu/Debian 계열에서는 system Python이 externally managed 환경으로 취급될 수 있기 때문이다.

image를 build한다.

docker build -t my-python-app .

container를 실행한다.

docker run --rm my-python-app

일부 package는 compile에 필요한 system dependency가 필요할 수 있다. 예를 들어 C extension을 build해야 한다면 build-essential이나 관련 개발 package를 추가로 설치해야 할 수 있다.

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        python3 \
        python3-pip \
        python3-venv \
        build-essential \
    && rm -rf /var/lib/apt/lists/*

Docker에서는 requirements.txt를 먼저 복사하고 설치한 뒤 source code를 복사하는 순서가 유리하다. 의존성이 바뀌지 않으면 Docker layer cache를 재사용할 수 있기 때문이다.


requirements.txt와 pyproject.toml

최근 Python project에서는 pyproject.toml을 사용하는 경우도 많다. pyproject.toml은 package metadata, build 설정, dependency 설정을 함께 담을 수 있다.

하지만 requirements.txt는 여전히 단순하고 널리 쓰인다. 특히 script, 작은 application, Docker image, server 배포 환경에서는 다음 형태가 자주 사용된다.

COPY requirements.txt .
RUN python -m pip install -r requirements.txt

requirements.txt는 복잡한 project 관리 도구를 쓰지 않아도 의존성을 전달할 수 있는 가장 기본적인 파일이다.


정리

requirements.txt는 Python project의 의존성을 기록하는 파일이다.

핵심 명령어는 다음 두 가지이다.

python -m pip freeze > requirements.txt
python -m pip install -r requirements.txt

실제 project에서는 다음 원칙을 지키면 좋다.

project root에 requirements.txt를 둔다.
.venv는 commit하지 않는다.
Ubuntu에서는 python3-venv를 설치한 뒤 가상환경을 만든다.
macOS에서는 python3가 있는지 확인하고 없으면 Homebrew 등으로 설치한다.
Docker는 Ubuntu base image에서도 venv를 만들어 설치한다.
새 package를 추가하면 requirements.txt도 업데이트한다.
재현성이 중요하면 version을 고정한다.
환경이 헷갈리면 python -m pip를 사용한다.

작은 project에서는 필요한 package만 직접 적어도 충분하다. 배포나 실험 재현이 중요하다면 pip freeze로 version을 고정하고, 새 환경에서 설치가 되는지 확인하는 것이 좋다.