파이썬 의존성 설치가 분 단위로 늘어지고, venv·pip·poetry·pyenv를 매번 따로 맞춰야 한다면 uv 한 도구로 설치·가상환경·락파일·파이썬 버전까지 묶는 편이 더 단순하다. 러스트로 만든 Astral 도구라 설치 속도가 빠르고, uv pip·프로젝트 모드·워크스페이스까지 같은 CLI에서 이어진다.
아래는 2026년 기준 공식 문서 흐름에 맞춘 설치 경로, pip와의 대응 표, pyproject·uv.lock 프로젝트, 파이썬 버전 관리, Docker·CI 고정, 막히는 케이스다. 뉴스성 인수 이야기보다 “오늘 레포에 어떻게 붙일지”에 맞춰 쓴다. 백엔드 API·데이터 스크립트·모노레포 파이썬 패키지를 다루는 개발자용이다.
uv가 한 번에 맡는 일
uv는 패키지 설치만 하는 도구가 아니다. 공식 문서 기준으로 아래를 한 CLI에 모은다.
패키지 설치·동기화 — 글로벌/가상환경, uv pip install 호환 인터페이스
프로젝트 관리 — pyproject.toml + uv.lock 로 재현 가능한 의존성
파이썬 버전 — 필요한 CPython을 받아서 프로젝트에 고정
도구 실행 — uvx 로 일회성 CLI 도구 실행 (예전 pipx 자리)
워크스페이스 — 여러 파이썬 패키지를 한 루트에서 묶기
JS 쪽 pnpm이 설치 속도와 디스크 공유를 잡았다면, 파이썬 쪽에서는 uv가 비슷한 “기본 설치 경로”로 자리 잡는 중이다. 패키지 매니저 비교 감각은 pnpm vs npm vs Yarn 비교와 나란히 두면 팀 온보딩 설명이 쉬워진다. Astral 도구 생태계(러프·uv) 배경은 Astral 인수와 uv·ruff 글을 참고하면 된다.
하던 일
기존 조합
uv 쪽
패키지 설치
pip / poetry add
uv pip install / uv add
가상환경
python -m venv
uv venv (프로젝트 모드면 자동)
락파일
poetry.lock / requirements.txt 핀
uv.lock + uv sync
파이썬 버전
pyenv / 시스템 파이썬
uv python install
일회성 도구
pipx
uvx ruff 등
표를 “전부 갈아타야 한다”로 읽지 말 것. 레거시 레포는 uv pip 만 얹어도 체감이 난다. 새 서비스부터 프로젝트 모드로 가는 이단 전략이 현실적이다. 온보딩 문서에 설치 도구가 세 줄 이상 적혀 있다면, 그 줄을 줄이는 쪽이 목표다.
속도 벤치마크 숫자는 머신·캐시·미러에 따라 갈린다. 팀 안에서는 “깨끗한 CI 러너에서 requirements 설치 한 번”을 같은 조건으로 재서 비교하는 편이 공정하다. 체감이 안 나면 인덱스 지연·컴파일 확장 패키지 비중이 병목일 수 있다.
설치와 첫 실행 경로
맥·리눅스는 공식 설치 스크립트 또는 홈브류, 윈도우는 PowerShell 설치 스크립트·winget 등이 문서에 정리돼 있다. 설치 후 셸을 다시 열고 버전을 확인한다.
설치 확인 + 빠른 pip 호환 설치
# 설치 후
uv --version
# 기존 습관 유지: 현재/지정 venv에 pip 호환 설치
uv venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
uv pip install requests fastapi
# requirements 고정 파일에서 설치
uv pip install -r requirements.txt
# 재현용 컴파일(선택): 상위 요구사항을 핀 목록으로
uv pip compile requirements.in -o requirements.txt
uv pip 는 명령 이름이 pip를 닮았지만 구현은 별개다. 인덱스 URL, 추가 인덱스, 오프라인 캐시 동작은 공식 문서의 pip 인터페이스 절을 기준으로 확인한다. 사내 PyPI 미러를 쓰는 팀은 UV_INDEX_URL 또는 pyproject.toml 의 인덱스 설정을 먼저 맞춘 뒤 설치 속도를 비교하는 편이 안전하다.
uv 설치 후 venv·pip 호환 명령으로 의존성을 맞추는 흐름 (출처: Astral uv 문서 기준 설명)
프로젝트 모드와 uv.lock
새 레포나 마이그레이션 여유 있는 서비스는 프로젝트 모드가 기본 추천이다. uv init 으로 뼈대를 만들고, 의존성은 uv add / uv remove, 환경 맞추기는 uv sync 한 줄로 끝낸다.
프로젝트 생성·의존성·동기화
# 새 프로젝트
uv init my-api
cd my-api
# 런타임 의존성
uv add fastapi uvicorn[standard] httpx
# 개발 전용 (그룹)
uv add --dev pytest ruff
# 락 기준 환경 맞추기 (CI·동료 PC 동일)
uv sync
# 특정 그룹만
uv sync --group dev
# 스크립트/앱 실행 (환경 활성화 생략 가능)
uv run uvicorn main:app --reload
uv run pytest
uv.lock 은 커밋 대상이다. 동료와 CI가 같은 해석 트리를 쓰게 만든다. pyproject.toml 만 올리고 락을 빼면 “내 PC에선 되는데” 클래식이 다시 열린다.
기존 poetry 레포는 한 번에 삭제하지 말고, 의존성 목록을 옮긴 뒤 uv lock → uv sync 로 검증하고, 파이프라인 성공 후에 poetry 관련 파일을 제거하는 순서가 안전하다. requirements.txt만 있는 레포는 uv add -r requirements.txt 류 마이그레이션 경로를 문서에서 확인한 뒤 적용한다(버전·플래그는 릴리스 노트 기준).
상황
권장 명령
커밋할 파일
로컬 개발 시작
uv sync
pyproject.toml, uv.lock
라이브러리 추가
uv add 패키지
두 파일 모두 변경분
CI 설치
uv sync --frozen
락 변경 없이 실패 유도
프로덕션 이미지
uv sync --no-dev 등
dev 그룹 제외 정책 명시
--frozen 은 “락을 다시 풀지 말고 있는 그대로” 쓰라는 뜻에 가깝다. CI에서 조용히 락이 갱신되는 사고를 막는다.
막히는 케이스:uv sync 는 되는데 python 을 치면 시스템 패키지가 잡힌다 → 셸에 venv가 안 켜진 상태다. uv run … 으로 실행하거나 source .venv/bin/activate 후 which python 이 .venv 를 가리키는지 확인한다.
파이썬 버전을 프로젝트에 고정하기
팀에서 가장 흔한 마찰은 “내 맥은 3.12, CI는 3.11, 서버는 3.10”이다. uv는 필요한 인터프리터를 받아 두고 프로젝트에 묶을 수 있다.
파이썬 설치·프로젝트 핀
# 사용 가능한/설치할 버전 확인
uv python list
uv python install 3.12
# 프로젝트 디렉터리에서 버전 고정 (문서의 pin 흐름)
uv python pin 3.12
# 이후 sync / run 이 해당 버전 기준으로 동작
uv sync
uv run python -V
pyproject.toml 의 requires-python 과 pin이 어긋나면 해석·설치 단계에서 경고나 실패가 난다. 라이브러리를 퍼블리시하는 패키지는 지원 범위를 넓게, 사내 앱은 런타임 한 버전으로 좁히는 편이 운영이 편하다.
데이터 과학 노트북처럼 전역 환경을 쓰던 습관은 프로젝트마다 uv sync 로 바꾸는 쪽이 재현성에 유리하다. “노트북만 빨리”가 목적이면 uvx 로 도구만 돌리고, 공유 결과물은 여전히 락이 있는 레포에서 만드는 이분법이 안전하다.
파이썬 버전 pin과 uv.lock 동기화로 로컬·CI 편차를 줄이는 구조
Docker와 CI에서 재현 가능하게 쓰기
이미지 빌드에서 pip를 그대로 두면 레이어 캐시·해석 시간이 길어지기 쉽다. uv를 빌드 스테이지에 넣고 락 기준으로 설치하면 빌드 로그가 짧아지고, 배포 아티팩트 버전이 흔들리지 않는다.
Dockerfile 스케치 (멀티스테이지 개념)
# syntax=docker/dockerfile:1
FROM python:3.12-slim AS builder
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
WORKDIR /app
COPY pyproject.toml uv.lock ./
# 의존성만 먼저 (소스 복사 전) → 레이어 캐시
RUN uv sync --frozen --no-dev --no-install-project
COPY . .
RUN uv sync --frozen --no-dev
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /app /app
ENV PATH="/app/.venv/bin:$PATH"
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
위는 개념 스케치다. 베이스 이미지 태그, 비루트 유저, 헬스체크, 시크릿 주입은 팀 보안 기준을 따른다. 멀티스테이지로 최종 이미지 두께를 줄이는 일반 원리는 Docker 멀티스테이지 빌드 체크리스트와 같다. 파이썬도 “빌드 도구는 builder, 런타임은 venv bin만” 패턴이 통한다.
깃허브 액션 예시는 대략 다음 순서다. uv 설치 → uv sync --frozen → uv run pytest. 캐시 키에는 uv.lock 해시를 넣는다. 락이 바뀌지 않았는데 매번 전체 해석이 돌면 캐시 경로·환경변수(UV_CACHE_DIR 등)를 점검한다.
막히는 케이스: CI에서 uv sync 가 락을 수정하려 해 실패한다 → 로컬에서 의존성을 바꾼 뒤 락 커밋을 안 한 상태다. PR에 uv.lock 을 포함하고, 파이프라인은 --frozen 을 유지한다.
poetry의 그룹·소스 인덱스·프라이빗 레지스트리 설정은 1:1 자동 변환이 아닐 수 있다. 프라이빗 인덱스 URL, 토큰 환경변수, 플랫폼 마커(windows/macos)가 있는 의존성은 스테이징에서 uv sync 전체 성공을 확인한다.
공급망 측면에서는 “빠른 설치”만큼 “무엇을 설치했는지”가 중요하다. 락파일 커밋, 해시 검증 옵션, 이상 패키지 감사는 Supply Chain 공격 방어 가이드의 pip·컨테이너 절과 같이 본다. 속도만 올리고 출처 정책을 비우면 위험 면적이 커진다.
레포 성격에 따라 pip 호환만 쓸지 프로젝트 모드로 갈지 나누는 기준
매일 쓰는 명령 치트시트
온보딩 문서에 붙여 넣기 좋은 최소 세트다.
목적
명령
환경 맞추기
uv sync
패키지 추가
uv add httpx
개발 도구 추가
uv add --dev ruff pytest
테스트·서버
uv run pytest / uv run uvicorn …
일회성 도구
uvx ruff check .
outdated 점검
uv tree / 문서의 outdated·upgrade 명령
pip 습관 유지
uv pip install -r requirements.txt
린트·포맷을 러프로 통일하면 JS 쪽 바이옴처럼 “도구 하나 + 속도” 조합이 된다. 프론트 린터 통합 감각은 Biome 실전 가이드와 비교해 설명하면 풀스택 팀이 이해하기 쉽다.
자주 막히는 다섯 가지
시스템 파이썬에 직접 설치 — 가능하더라도 프로젝트 venv를 쓰는 쪽이 안전하다. 권한·버전 꼬임을 줄인다.
락 미커밋 — 로컬만 맞고 CI가 다른 트리를 깐다. PR 체크리스트에 uv.lock 을 넣는다.
activate 없이 python만 실행 — uv run 습관이 실수가 적다.
플랫폼 휠 없는 패키지 — 리눅스 CI와 맥 로컬 바이너리 차이는 예전과 같다. 실패 로그의 빌드 의존(gcc, lib 등)을 먼저 본다.
인덱스·프록시 환경변수 누락 — 사내망에서만 실패하면 pip 때와 동일한 네트워크 이슈다. UV_INDEX_URL, 인증 헤더, 인증서 번들을 확인한다.
에러 메시지에 해석 충돌이 찍히면 버전 범위를 넓힌 라이브러리 하나를 의심 후보로 두고, uv tree 로 누가 그 버전을 끌어왔는지 본다. “일단 강제 플래그”보다 범위 조정이 재발을 줄인다.
동료 한 명만 실패하는 경우에는 운영체제 버전, 아키텍처(애플 실리콘 대 인텔), 사내 인증서 가로채기 여부를 먼저 묻는다. 도구 버그로 단정하기 전에 환경 차이를 표로 적어 보면 원인 후보가 빨리 줄어든다. 해결 절차를 이슈 템플릿에 남겨 두면 같은 질문이 반복되지 않는다.
실무 팁: README 설치 절을 uv sync && uv run pytest 두 줄로 끝낼 수 있으면 온보딩 비용이 바로 떨어진다. 예외 패키지(시스템 라이브러리 필요)만 “사전 준비”로 분리해 적는다.