Есть более одного способа кожи кошки, но этот рисунок заставляет мое сердце трепетать.
Контейнеризировать приложение Python
Asgi.py в нашем приложении каталог
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def hello():
return "World"
Dockerfile.
FROM python:3.7-buster as base
ENV SHELL=/bin/bash \
USER=python \
UID=10001
# Create a user for the app to be owned by
RUN set -eux; adduser \
--disabled-password \
--gecos "" \
--home "/var/lib/python3" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
"${USER}"
# Manually create the users home directory
RUN mkdir -p "/var/lib/python3" && chown -R "${USER}" /var/lib/python3
FROM base as build
# Install the app requirements in its own layer.
# Isolating the "build" stage from the application stage removes
# some of the unwanted cruft that comes with install
# python dependencies
USER ${USER}
RUN python -m pip install \
--user \
'uvicorn[standard]' \
'fastapi' \
'wheel'
FROM base
COPY --from=build --chown=${USER} /var/lib/python3/.local /var/lib/python3/.local
ENV PATH=$PATH:/var/lib/python3/.local/bin
USER root
ENTRYPOINT ["docker-entrypoint.sh"]
COPY docker-entrypoint.sh /usr/bin/docker-entrypoint.sh
# Create a designated location for the app as the python user
USER ${USER}
WORKDIR /usr/lib/python
COPY ./app ./app
CMD ["app.asgi:app"]
Входная точка
#!/bin/bash -e
# If the CMD has not changed process it as a pure Python implementation
if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ]; then
set -- uvicorn "$@" --host 0.0.0.0 --http h11 --loop asyncio
fi
echo
echo "Running $@"
echo
exec "$@"
Ломаться на этапы докера
Этот докер отделен на нескольких этапах, чтобы организовать функцией его этапа сборки. Многоступенчатая строгая полоски нашего применения ненужных файлов.
базовый этап
Первый этап псевдонимой как «база». Эти этапы загрузочные наши необходимые инструкции, которые доля остальных слоев. Пользователь позволяет нам устанавливать требования за пределами пользователя root.
Стадия сборки
Второй этап приносит внешние требования и устанавливает их как Python Пользователь. Это полезно, потому что только пользователь .LOCAL каталог должен быть скопирован на заключительном этапе. Копирование .LOCAL Каталог приносит только требованиям, которые требуются приложение для запуска.
Безымянный этап приложения
Базовое изображение приложения начинается с чистого слоя с первого этапа. Удаление необходимости Redeclare любые уже предоставленные инструкции.
Требования могут быть скопированы на .местный каталог, как они были установлены PIP. Слой приложений не основан на построить слой, чтобы уменьшить оставшиеся влево, приведен PIP Установить Отказ
Наконец, сам приложение копируется в каталог за пределами дома пользователя.
- https://www.docker.com/blog/containerized-python-development-part-1/
- https://stackoverflow.com/a/55757473/12429735
- https://github.com/nodejs/docker-node/blob/master/docker-entrypoint.sh
Оригинал: “https://dev.to/ndfishe/my-favorite-way-to-write-a-dockerfile-for-a-python-app-260i”