Closed f-lab-stephen closed 1 year ago
각 로컬 동작 확인은 스크린샷을 올리는 것으로 AC 달성 확인하겠습니다!
docker file 작성하기에 앞서 requirements.txt에 설치된 패키지들을 저장하기 위해 poetry export -f requirements.txt > requirements.txt 명령어를 사용했습니다.
다만 poetry run pip freeze > requirements.txt로 작성해야 하는지 위 명령어를 사용하는지에 대해 헷갈리네요.
asgiref==3.6.0 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac \ --hash=sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506 django==3.2.18 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:08208dfe892eb64fff073ca743b3b952311104f939e7f6dae954fe72dcc533ba \ --hash=sha256:4d492d9024c7b3dfababf49f94511ab6a58e2c9c3c7207786f1ba4eb77750706 djangorestframework==3.14.0 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8 \ --hash=sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08 install==1.3.5 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:0d3fadf4aa62c95efe8d34757c8507eb46177f86c016c21c6551eafc6a53d5a9 \ --hash=sha256:e67c8a0be5ccf8cb4ffa17d090f3a61b6e820e6a7e21cd1d2c0f7bc59b18e647 pip==23.1 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:408539897ee535dbfb83a153f7bc4d620f990d8bd44a52a986efc0b4d330d34a \ --hash=sha256:64b1d4528e491aa835ec6ece0c1ac40ce6ab6d886e60740f6519db44b2e9634d pytz==2022.7.1 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0 \ --hash=sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a sqlparse==0.4.3 ; python_version >= "3.11" and python_version < "4.0" \ --hash=sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34 \ --hash=sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268
requirements.txt 확인하니 이런식으로 생겼네요 pip freeze와는 다른거 같습니다.
도커파일을 작성할때 RUN 뒤에 poetry export -f requirements.txt > requirements.txt가 필요할까요?
poetry 기반의 패키지 관리시 도커파일에 requirements.txt를 카피하는 대신 다른 방법으로 하는거 같은데 좀 더 알아봐야 겠네요.
관련된 내용 찾다보니 The python stage is used just to provide a common basis for the poetry and runtime stages. The poetry stage installs Poetry, and uses it to install the Python application and its dependencies in a virtual environment. The runtime stage builds the final Docker Image by copying and configuring the virtual environment from the poetry stage.
이런식으로 multi-stage building을 통해 이미지 사이즈를 줄이기도 하네요. 마지막 스테이지는 compose에 들어가는 걸까요?
오 poetry
를 쓰는 이유는 pip
를 직접 안 쓰기 위해서입니다 ㅠㅠ 검색 키워드를 poetry install, docker, image, gunicorn 등으로 해서 찾아 보세요
강력한 힌트 하나만 드리자면 Dockerfile 안에
RUN poetry install --no-dev
커맨드가 한 번은 들어가야 할 거예요. 저희 팀의 컴포넌트 중에서는 여기서 --no-root
옵션을 붙이거나 다른 옵션을 더 붙이기도 합니다.
이미지 사이즈를 줄이기 위한 방법으로 책에서도 소개된 multi-stage build를 이용해 볼 수 있습니다. 첫 번째 스테이지에서 poetry install 후 빌드하고, 마지막 스테이지에서 첫 번째 스테이지의 결과를 복사한 후 gunicorn을 실행하는 식으로요.
pip을 안쓰고 poetry install을 쓰기 위해서는 먼저 poetry 설치에 대한 부분이 도커파일에 들어가야 할꺼 같습니다.
[internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 455B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/python:3.11.2 3.3s => CANCELED [base 1/2] FROM docker.io/library/python:3.11.2@sha256:5329e75033c4446dc92d702cf8ebbeb63e549d9b83076a776f6753e10817fc3c 0.0s => => resolve docker.io/library/python:3.11.2@sha256:5329e75033c4446dc92d702cf8ebbeb63e549d9b83076a776f6753e10817fc3c 0.0s => => sha256:74707af2d4ec537fd45394f8f6a9d93b1cd6b939f2dc942c2c09cdfa1e636102 7.92kB / 7.92kB 0.0s => => sha256:5329e75033c4446dc92d702cf8ebbeb63e549d9b83076a776f6753e10817fc3c 2.14kB / 2.14kB 0.0s => => sha256:9c5aa3f126bd652d22fcb5fbaea0446609747aa71454fd01a07810b6172e4b78 2.22kB / 2.22kB 0.0s => [internal] load build context 0.0s => => transferring context: 15.26kB 0.0s => CACHED [base 2/2] WORKDIR /realtor 0.0s => ERROR [poetry 1/3] COPY pyproject.toml poetry.lock README.md ./
흐음... poetry lock & toml 파일 카피가 안되네요. 도커파일을 realtor안에 만들어서 realtor안에서 build 했는데 저 파일들이 realtor밖에 있어서 그런걸까요?
FROM python:3.11.2 as base
ENV PYTHONUNBUFFERED=1
WORKDIR /realtor
FROM base as poetry
ENV PIP_DEFAULT_TIMEOUT=100 \ PIP_DISABLE_PIP_VERSION_CHECK=1 \ PIP_NO_CACHE_DIR=1 \ POETRY_VERSION=1.4.1
COPY pyproject.toml poetry.lock README.md ./ COPY realtor ./realtor
RUN poetry install --no-dev CMD ["poetry", "run", "python", "realtor/manage.py", "runserver"]
이런식으로 작성했는데 pip env는 따로 설정을 안했던거 같아서 다른 사람들이 공통적으로 쓰는거 그대로 사용했습니다.
copy전에 poetry를 설치해야할꺼 같아서 RUN curl -sSL https://install.python-poetry.org | python3 -를 먼저 추가해줬는데 같은 에러가 나네요. pip를 통해 설치해야할꺼 같아서 찾아보고 있습니다.
Dockerfile 안에 pip
는 한 글자도 들어가서는 안 됩니다! 일단 Dockerfile을 repo root directory로 옮기고, WORKDIR
를 바꾸지 않고 COPY
를 하세요. 거기서 poetry install
을 해야 할 거고요.
아마 그 과정에서 poetry
가 커맨드가 안 먹을 가능성도 있습니다. 그건 또 해결 방법을 찾아보세요 (hint: PATH)
참고할 만한 링크
위 링크를 많이 참고하되, 현재 상태에서 필요 없는 부분도 있을 것이므로 필요한 부분만 찾아서 이것저것 실험해 보세요.
아마 우리한테 필요한 딱 적정량은 Dockerfile 기준 50줄보다 약간 적게, 커맨드 개수는 20개 내외면 되겠습니다.
FROM python:3.11.2 as base
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
POETRY_HOME="/opt/poetry" \
POETRY_VIRTUALENVS_IN_PROJECT=true \
POETRY_NO_INTERACTION=1 \
PYSETUP_PATH="/opt/pysetup" \
VENV_PATH="/opt/pysetup/.venv"
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"
FROM base as builder RUN apt-get update \ && apt-get install --no-install-recommends -y \ curl \ build-essential
ENV POETRY_VERSION=1.4.1 RUN curl -sSL https://install.python-poetry.org | python -
WORKDIR $PYSETUP_PATH COPY ./poetry.lock ./pyproject.toml ./ RUN poetry install --no-dev
FROM base as production ENV PATH="/opt/pysetup/.venv/bin:$PATH" WORKDIR /realtor
COPY --from=builder $VENV_PATH $VENV_PATH COPY ./gunicorn_conf.py /gunicorn_conf.py
COPY ./docker-entrypoint.sh /docker-entrypoint.sh RUN chmod +x /docker-entrypoint.sh
COPY ./realtor /realtor
ENTRYPOINT /docker-entrypoint.sh $0 $@ CMD [ "gunicorn", "--worker-class uvicorn.workers.UvicornWorker", "--config /gunicorn_conf.py", "main:realtor"]
참고하면서 이런식으로 만들었는데 도커파일 빌드는 성공했는데 git commit 하니깐 black....................................................................Failed
error: cannot format gunicorn_conf.py: Cannot parse: 4:5: FROM python:3.11.2 AS base 가 뜨네요... isort만 통과했습니다
black exclude에 해당 .py파일만 올려놓으려고 하는데 괜찮을까요
네 제외하셔도 됩니다!
목표
아래와 같은 컨테이너를 생성할 수 있도록 Dockerfile과 docker-compose.yaml 파일을 생성한다.
AC