1P by GN⁺ 11시간전 | ★ favorite | 댓글 1개
  • uv로 전환 시 Python 디펜던시 설치 속도가 pip 대비 약 10배 빨라지고, 별도의 venv 없이 비루트(non-root) 사용자로도 실행 가능함
  • pyproject.toml 기반으로 상위 의존성만 명시하면 uv가 자동으로 lock 파일을 관리하며, 의존성 트리와 정확한 버전 관리가 pip freeze보다 우수함
  • Dockerfile에서는 uv 및 uvx 바이너리 복사, pyproject.toml/uv.lock 파일 사용, 환경 변수 설정 등 단계별 변경이 필요
  • uv sync/add/remove, uv:outdated와 같은 명령어로 쉽게 의존성 추가·삭제·업데이트 및 패키지 최신 버전 확인 등 다양한 관리가 가능
  • 규칙적으로 lock 파일 관리 및 의존성 업데이트가 가능해져 협업 및 배포 환경에서 일관성 확보에 장점

10배 빨라진 의존성 설치, venv 미사용, 비루트 환경 구성

  • uv는 기존 pip 대비 Python 프로젝트의 의존성 설치 속도를 크게 개선하는 툴임
  • uv 도입으로 Flask/Django 등 다양한 프로젝트에서 기존 pip 대비 약 10배 빠른 설치 속도를 경험할 수 있음
  • 별도의 가상환경(venv) 없이도 컨테이너 내에서 비루트 사용자로 안전하게 실행할 수 있음

pyproject.toml vs requirements.txt

  • 기존의 requirements.txt 대신 pyproject.toml 파일에 상위 의존성만 명시하면 uv가 자동으로 uv.lock 파일을 생성함
    • pyproject.toml에 [project] dependencies 항목 추가
    • 기존 requirements.txt 삭제
  • uv의 lock 파일은 pip freeze 결과와 유사하지만 정확한 의존성 트리와 버전 정보를 갖추고 있음

Dockerfile 구성 변경

  • uv 및 uvx 바이너리를 컨테이너에 복사해 사용(정적 컴파일된 Rust 바이너리 사용)
  • 기존 requirements*.txt 대신 pyproject.toml, uv.lock* 파일 복사
  • 환경 변수 추가:
    • UV_COMPILE_BYTECODE=1: 빌드 단계에서 바이트코드로 미리 컴파일
    • UV_PROJECT_ENVIRONMENT="/home/python/.local": 별도의 venv를 생성하지 않고 특정 경로에 패키지 설치
  • 의존성 설치 명령어도 기존 pip3-install 대신 uv-install로 변경
    • 예: RUN chmod 0755 bin/* && bin/uv-install

의존성 추가, 삭제, 업데이트 등 관리

  • 별도의 run 스크립트로 컨테이너 내 uv 명령어를 실행할 수 있음
    • ./run deps:install: 이미지 빌드 후 lock 파일을 호스트로 내보내면서 설치
    • ./run deps:install --no-build: 빌드 없이 lock 파일만 갱신
    • ./run uv add mypackage --no-sync: pyproject.toml 및 lock 파일만 갱신, 실제 설치는 별도 실행
    • ./run uv remove mypackage --no-sync: 패키지 제거
    • ./run uv:outdated: 현재 의존성의 최신 버전 확인

영상 및 실습 가이드 제공

  • uv 도입, pyproject.toml 작성, Dockerfile 변경, lock/sync 명령, 의존성 추가/삭제, 최신 버전 확인 등 실제 데모 및 git diff 예시 제공
  • Flask, Django 두 프로젝트의 마이그레이션 diff도 참고 가능
Hacker News 의견
  • uv는 pyenv, virtualenv, pip을 직접 대체하는 워크플로우를 지원한다는 점을 주목할 필요 있음. lockfile이나 pyproject.toml로 강제되는 방식이 아님. uv python pin <version> 명령어로 현재 디렉토리에 .python-version 파일 생성, uv virtualenv로 pyenv처럼 해당 버전의 파이썬을 다운로드 후 .venv 가상환경 생성, uv pip install -r requirements.txt로 requirements.txt의 패키지 설치, uv run <command>로 .env 파일의 환경변수 포함해 명령 실행 가능. 단, 환경변수 우선순위 문제 주의 (관련 이슈)

    • uv의 유연성은 정말 감탄스러운 수준임. pip으로 10분 걸릴 작업을 uv로 20~30초만에 처리하는 경험
    • uv 사용 계기는 바로 이 부분임. 엄청 편리함. 다만 uv pip이 느린 경우가 있어 원인을 모르겠는 상황, 혹시 회사의 네트워크 환경 문제인 것 같음
    • python 버전 정보가 pyproject.toml에도 저장되는 것으로 아는데, .python-version 파일이 꼭 필요한가라는 궁금증
  • # 항상 최신 lock file을 보장하는 스크립트
    if ! test -f uv.lock || ! uv lock --check 2>/dev/null; then
      uv lock
    fi
    

    이런 방식은 lock file의 존재 의미를 무색하게 만듦. 파일이 없거나 무효할 경우, lock file에 심각한 문제가 발생한 상태라 관련 프로젝트에 익숙한 사람이 직접 대응하는 게 바람직함. 그렇지 않다면 lock file을 둘 이유가 없음. CI에서 lock file을 자동으로 교체해 혼동 발생 가능성 있음

    • (작성자 답변) lock file이 무효한 경우, 조용히 넘어가서 새 파일을 만드는 게 아님. uv lock에서 친절한 메시지로 실패 처리, 쉘 스크립트의 errexit로 바로 중단됨. uv lock --check 에러 리다이렉트는 같은 에러가 두 번 출력되는 것 방지 목적. lock 파일을 일부러 잘못 만들고 스크립트 실행 시, 구체적 에러 메시지와 함께 빌드가 멈춤. 스크립트는 if-else로 바꿔 더 명확하게 고침. lock 파일이 없으면 새로 생성하는 게 맞는 흐름임. 이때 생성해서 커밋하면 됨
    • uv sync --locked 옵션에서 이 부분 커버됨. lock file이 없거나 오래되면 명확히 실패시킴. 항상 --locked 옵션과 함께 빌드하는 걸 제안
    • 파이썬 세계에서는 lock file을 버전 관리에 잘 안 올리고, 설치 과정의 "이상한 단계"로 다루는 경우가 많음
    • 이 방식엔 심각한 버그가 있음. --frozen 플래그를 쓰면 lock file이 갱신 안 되는 것이 맞는데, 실제로는 반대로 동작. lock file이 없거나 맞지 않으면 사람이 개입해야 한다는 점 동의
    • 그래도 lock file이 없으면 첫 실행이거나, 어차피 git upstream을 통해 덮어쓰이게 됨. 깨진 경우는 누군가 설치에 실수한 것이고, 새로 만드는 방법이 사실상 유일하게 합리적이라고 생각. 드문 예외지만 간단한 처리로서 충분함
  • 파이썬 툴이 파이썬 외의 언어로 개발되는 건 완전 반대 입장임. C가 이미 있어서 CPython이 표준화되어 있는데 굳이 새로운 언어(예: Rust)가 필요하지 않음. Pendulum 패키지가 3.13 지원을 7개월 넘게 지연했는데 Rust 네이티브 때문에 해당 문제를 고칠 줄 아는 사람이 부족해서라고 봄. 만약 C였다면 직접 고쳤을 것. (관련 이슈) 이상적으로는, Rust와 같은 외부 언어로 빠른 datetime을 만들고 싶다면 FFI로 여러 언어에서 쓸 수 있는 형식으로 만드는 게 맞음. Rust 기반은 아직 썩 마음에 들지 않고, 리눅스 커뮤니티가 꺼리는 것도 이해하게 됨

    • 이 관점 존중하지만, uv 같은 툴을 Rust로 만드는 건 좋은 아이디어라고 생각. 파이썬 관리 도구를 파이썬으로 만들면 "닭이 먼저냐 달걀이 먼저냐" 상황이 생김. 파이썬 도구를 쓰려면 파이썬 자체가 먼저 설치되어 있어야 하고, 어떤 파이썬 버전이 쓰이는지, 도구가 사용하는 라이브러리와 실제 앱 간의 충돌 가능성, 환경 변수 관리, 디버깅 모두 복잡해짐. 반면 Rust 등으로 빌드된 바이너리 도구는 그냥 받아서 쓰면, 이런 걸 신경쓸 필요 없이 즉시 동작. 사용자는 툴이 어떤 언어로 만들어졌는지 크게 신경 안 써도 됨
    • 파이썬을 좋아하지만, uv의 간편함과 속도는 비교 불가. EOL된 서버에서 최신 파이썬 필요할 때, 작은 스크립트에 종속성만 빠르게 설치하고 싶을 때 모두 uv가 베스트임. 동의하는 부분도 있는데, 예전에는 pure python으로만 짜다가, 점차 C extension을 쓰고, 한계 느끼면 아예 거의 모두 C로 쓰고 싶어지더라. C가 어려워서 최근엔 Rust로 리팩토링하는 중. 외부 코드가 내부보다 많아지면 그냥 전부 다른 언어로 바꾸는 게 나음
    • 파이썬만으로 도구를 만들어야 한다는 생각이 강하다면, 느린 Pylint 기다릴 때 본인은 산책하고 있겠음
    • 다양한 언어 지원은 사용자에게 별 부담 아님. 도구는 빠르고 문제를 잘 해결하면 충분. 실제로 속도가 훨씬 빠름. 관리도구는 개발자가, 사용 대상을 위한 도구임
    • 나는 어떤 언어로 만들어졌든 기능만 잘하면 됨. 파이썬 사용자가 도구에 기여할 수 있다는 점은 있지만, 도구가 목적을 잘 수행하면 언어는 상관 없음. 오히려 환경 문제에 봉착했을 때, 파이썬으로 만든 도구는 그 문제까지 영향을 받아 버릴 수도 있음
  • pip 대신 uv를 쓸 땐 조심해야 함. 기본으로는 pyc 파일을 생성하지 않으니 서비스 시작이 느려질 수도 있음 (참고)

  • uv를 flask 컨테이너에 써보면, 빌드 타임 차이가 지루할 만큼 클 뿐만 아니라, 설치 과정이 매우 예측 가능해짐. pip으로 종속성 버전이 바뀌는 당혹스러움이 없음. pyproject.toml 쓰고, uv lock 하면 끝. docker에서는 pyproject.toml, uv.lock 파일만 복사(HOT COPY)하고 uv sync --frozen --no-install-project 실행하면 앱 코드는 건너뛰고 설치 레이어는 캐싱 가능. 패키지 하나만 바뀌어도 전체 레이어 재빌드를 할 때의 고통을 알면 이 기능이 왜 중요한지 느낌. 환경변수 UV_PROJECT_ENVIRONMENT=/home/python/.local 사용시 venv 없이 베이스 이미지를 pre-warm 하면 빌드 공유 및 인프라 비용 절감. UV_COMPILE_BYTECODE=1 옵션으로 빌드 시 .pyc 파일 생성. mutable environment 소멸 및 reproducibility 강제, 이제 빌드가 안 되면 lockfile 책임으로 원인 명확해짐

  • 2025년이 되어도 파이썬 패키징과 의존성 관리는 여전히 혼란스러운 상태

    • uv를 모두가 쓰지 않아서 계속 혼란스러운 거라 생각함
    • 언어 설계 초기부터 이런 부분을 제대로 세팅하는 게 중요하다는 교훈임. v2.0 이후로 미루지 말 것, metadata를 실행 스크립트에 넣기 전에 여러번 고민할 것, 어떤 언어에는 맞지만 파이썬에는 좋지 않은 방식일 수 있음
    • 나는 의존성 문제를 한 번도 겪어본 적 없음. requirements.txt와 venv만 써도 충분
    • 의존성 관리가 여전히 엉망, 이제는 Rust까지 추가됨
  • uv, pip, conda 등 파이썬 패키지 관리자의 보안성 비교가 궁금함. 속도도 좋지만, 패키지 매니저의 보안이 훨씬 더 중요하다고 생각

    • uv가 pip보다 더 안전한 편임. 임의 코드 실행 없이 dependency를 분석, 기본적으로 패키지 해시 검증, 타이포스쿼팅 등 여러 위험성을 회피. 속도와 재현성도 뛰어남 (기술 소개, 호환성 문서)
    • 하지만 본질적으로 모든 패키지 관리자는 검증되지 않은 타사 코드를 다운로드 및 실행하게 됨. uv와 pip의 구현상 보안 차이보다, 애초에 외부 코드에 대한 정책을 마련하지 않은 점이 더 중요한 위험 요인임
  • PyPI에 패키지를 올리는 입장이라서, 개인적으로는 빠른 속도 때문에 uv를 쓰고 싶지만, pip과 완벽히 동일하게 동작한다는 보장이 없다면 쉽사리 바꿀 수 없음. 사용자가 "pip install xxx"로 오류를 겪으면, 나도 동일 환경에서 재현·디버깅해야 하니까

    • pip과 100% 동일 방식은 아님. 큰 차이는 호환성 문서에서 다루고 있음. 일부는 표준대로 바뀌는 과정의 차이, 일부는 uv 고유의 디자인 선택임
  • UV는 실행만 하면 괜찮은 결과를 주는, 최근 파이썬 패키징에 가장 긍정적인 변화 중 하나라는 생각

  • 생산 환경 컨테이너 구축에 uv를 사용하는 훌륭한 가이드 문서도 소개함 (가이드 보기)