"Distroless"Docker 이미지로 FastAPI 애플리케이션 패키징

Distroless Docker Images은 더 얇은 용기를 만드는 데 도움을 주기 위해 Google에서 제안한 프로젝트입니다. 프로젝트 설명에는 "운영 체제를 제외한 언어 중심 도커 이미지"라고 명시되어 있습니다. 재미있을 것 같죠?

애플리케이션에 필요하지 않을 수 있는 많은 OS 패키지 및 라이브러리가 있는 우분투, 알파인, 데비안과 같은 일반적인 기본 이미지와 비교할 때 Distroless 이미지에는 애플리케이션을 실행하는 데 필요한 것만 있습니다.

RedHat이 이 문서article에서 설명한 것처럼 Distroless 컨테이너가 항상 가장 안전한 솔루션은 아니라는 점은 주목할 가치가 있습니다.

표준 라이브러리가 일부 상위 수준 OS 기능에 의존하기 때문에 Python 애플리케이션을 패키징하는 것은 어렵지만 가능합니다.

Python distroless 컨테이너는 gcr.io/distroless/python3 이미지에 pip도 없고 easy_install도 없기 때문에 다단계 빌드 프로세스가 필요합니다.

"Distroless"Docker 이미지를 사용하여 FastAPI api를 패키징해 보겠습니다.

다음은 샘플 API 서버입니다.

import fastapi, uvicorn
from starlette.requests import Request
import prometheus_client
import os

api = fastapi.FastAPI()

REQUESTS = prometheus_client.Counter(
    'requests', 'Application Request Count',
    ['endpoint']
)

@api.get('/ping')
def index(request: Request):
    REQUESTS.labels(endpoint='/ping').inc()
    return "pong"

@api.get('/metrics')
def metrics():
    return fastapi.responses.PlainTextResponse(
        prometheus_client.generate_latest()
    )

if __name__ == "__main__":
    print("Starting webserver...")
    uvicorn.run(
        api, 
        host="0.0.0.0",
        port=int(os.getenv("PORT", 8080)),
        debug=os.getenv("DEBUG", False),
        log_level=os.getenv('LOG_LEVEL', "info"),
        proxy_headers=True
    )


Pipenv를 패키지 관리자로 사용하겠습니다. 다음은 Pipfile입니다.

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
fastapi = "==0.77.1"
uvicorn = "==0.17.6"
prometheus-client = "==0.14.1"
Jinja2 = "==3.1.2"

[dev-packages]

[requires]
python_version = "3.10"


그래서 Distroless Python 이미지로 FastAPI 애플리케이션을 패키징할 수 있는 다음 Dockerfile(주석 포함)로 끝났습니다.

첫 단계:

FROM python:3.10-slim AS base

# Setup env

## Avoid to write .pyc files on the import of source modules
ENV PYTHONDONTWRITEBYTECODE 1

# Enable fault handler
ENV PYTHONFAULTHANDLER 1


두 번째 단계:

# Dependencies
FROM base AS python-deps

### Install pipenv and compilation dependencies
RUN pip install pipenv \
    && apt-get update \
    && apt-get install -y --no-install-recommends gcc

### Install python dependencies in /.venv
COPY Pipfile .
COPY Pipfile.lock .

# Allows to install the pipenv packages into the project instead of home user
# --deploy
RUN PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy


세 번째 단계:

# Runtime
FROM gcr.io/distroless/python3

WORKDIR /app

# Copy the python packages because the distroless base image does 
COPY --from=python-deps /.venv/lib/python3.10/site-packages /app/site-packages

# Set the Python path where the interpreter will look for the packages
ENV PYTHONPATH /app/site-packages
COPY . .

EXPOSE 8080
ENTRYPOINT ["python", "app.py"]


결과 이미지는 약 25Mb였습니다.



my github repository에서 모든 코드를 찾을 수 있습니다.

Python 응용 프로그램에 "Distroless"를 사용하거나 사용하지 않는 포인트가 있으면 언제든지 의견을 남겨주세요.

좋은 웹페이지 즐겨찾기