fix(backend): pip/uvicorn 을 python3.11 인터프리터에 강제 바인딩

Ubuntu 22.04 의 python3-pip 패키지는 python3.10 용이라, /usr/local/bin/python
만 3.11 로 심볼릭 링크해도 `pip`/`pip3` 명령은 여전히 3.10 의 site-packages
에 의존성을 설치한다. pyproject.toml 이 >=3.11 을 선언했으므로 런타임
인터프리터 불일치 위험.

수정:
- apt 에서 python3-pip 제거. get-pip.py 로 python3.11 전용 pip 를 부트스트랩.
- 모든 pip 호출을 `python -m pip` 로 통일.
- 직후 `RUN python -V && python -m pip -V` sanity check 추가 — 빌드 로그에
  인터프리터 버전이 박혀서 추후 불일치 의심 시 즉시 확인 가능.
- CMD 도 `python -m uvicorn` 으로 변경 — 콘솔 스크립트 shebang 이 아니라
  명시적으로 3.11 인터프리터에서 실행됨을 보장.

검증 (별도 컨테이너에서 nvidia/cuda:12.1.1 베이스로 동일 레이어 실행):
  Python 3.11.0rc1
  pip 26.1.1 from /usr/local/lib/python3.11/dist-packages/pip (python 3.11)
This commit is contained in:
tkrmagid
2026-05-20 23:53:25 +09:00
parent e08f3b0765
commit 9c7c02703a

View File

@@ -10,20 +10,31 @@ ENV DEBIAN_FRONTEND=noninteractive \
PYTHONPATH=/app \ PYTHONPATH=/app \
TZ=Asia/Seoul TZ=Asia/Seoul
# Ubuntu 22.04 의 python3-pip 는 python3.10 을 가리키므로 설치하지 않고,
# python3.11 + get-pip.py 로 3.11 전용 pip 를 부트스트랩한다.
# (Debian/Ubuntu 의 시스템 python 은 ensurepip 가 막혀 있어 get-pip.py 가 가장 깔끔함.)
# 이후 모든 호출은 `python -m pip` 로 통일해 인터프리터/스크립트 불일치를 차단.
RUN apt-get update && apt-get install -y --no-install-recommends \ RUN apt-get update && apt-get install -y --no-install-recommends \
python3.11 python3.11-venv python3-pip \ python3.11 python3.11-venv \
build-essential git curl ca-certificates tzdata \ build-essential git curl ca-certificates tzdata \
libgomp1 \ libgomp1 \
&& ln -sf /usr/bin/python3.11 /usr/local/bin/python \ && ln -sf /usr/bin/python3.11 /usr/local/bin/python \
&& ln -sf /usr/bin/python3.11 /usr/local/bin/python3 \ && ln -sf /usr/bin/python3.11 /usr/local/bin/python3 \
&& curl -sSL https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py \
&& python /tmp/get-pip.py \
&& rm /tmp/get-pip.py \
&& python -m pip install --upgrade pip setuptools wheel \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Sanity check: 이 출력은 빌드 로그에 박혀서 다음에 인터프리터 불일치 의심될 때 즉시 확인 가능.
RUN python -V && python -m pip -V
WORKDIR /app WORKDIR /app
COPY pyproject.toml ./ COPY pyproject.toml ./
# Install PyTorch (CUDA 12.1 wheels) first so the rest of deps don't downgrade it. # Install PyTorch (CUDA 12.1 wheels) first so the rest of deps don't downgrade it.
RUN pip install --extra-index-url https://download.pytorch.org/whl/cu121 \ RUN python -m pip install --extra-index-url https://download.pytorch.org/whl/cu121 \
torch==2.3.1 torchvision==0.18.1 torch==2.3.1 torchvision==0.18.1
# Install runtime deps from pyproject.toml WITHOUT installing the project itself. # Install runtime deps from pyproject.toml WITHOUT installing the project itself.
@@ -34,10 +45,11 @@ RUN pip install --extra-index-url https://download.pytorch.org/whl/cu121 \
RUN python -c "import tomllib; \ RUN python -c "import tomllib; \
deps = tomllib.load(open('pyproject.toml','rb'))['project']['dependencies']; \ deps = tomllib.load(open('pyproject.toml','rb'))['project']['dependencies']; \
open('/tmp/reqs.txt','w').write('\n'.join(deps))" \ open('/tmp/reqs.txt','w').write('\n'.join(deps))" \
&& pip install -r /tmp/reqs.txt && python -m pip install -r /tmp/reqs.txt
COPY app ./app COPY app ./app
EXPOSE 8000 EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] # uvicorn 콘솔 스크립트 대신 `python -m uvicorn` 으로 호출 — 3.11 인터프리터에서 실행됨을 보장.
CMD ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]