Python имеет несколько различных форматов для пакетов. Обычно они распространяются в виде исходного кода, который может запускаться везде, где работает Python, но иногда имеют расширения C (или FORTRAN!), Для сборки которых требуется внешний компилятор. Текущий рекомендуемый формат - wheel , который может быть специфичен для конкретной ОС и определенных параметров сборки Python, но не зависит ни от чего на уровне ОС вне Python. Руководство пользователя по упаковке Python содержит более подробные сведения об этом.
Том build
содержит .whl
файлов для вашего приложения;том wheelhouse
содержит файлы .whl
для других пакетов Python;том cache
содержит файлы .tar.gz
или .whl
, которые загружаются из PyPI. Том cache
используется только при загрузке;тома build
и wheelhouse
используются для установки кода без необходимости загрузки вообще.
Опция pip --no-index
говорит: "не связываться с публичным PyPI";-f /build
говорит "использовать артефакты, расположенные здесь". Переменные окружения, упоминающие /wheelhouse
, также имеют эффект. Они позволяют вам устанавливать пакеты, используя только то, что вы уже собрали.
Настройка Docker Compose - это довольно долгий способ построить ваше приложение в виде колес, а затем сделать его доступным дляобраз времени выполнения, в котором нет цепочки инструментов.
Контейнер cache
буквально ничего не делает. Он имеет две директории, которые вы показываете: /cache
- это каталог, смонтированный на хосте, а /build
- анонимный том. Другие контейнеры имеют volumes_from: cache
для повторного использования этих томов. (По стилю добавление именованного volumes:
к docker-compose.yml
почти определенно лучше.)
Контейнер builder
работает только pip wheel
. Он устанавливает дополнительный каталог, ./target
с точки зрения Dockerfile
, на /wheelhouse
. В документации pip install
обсуждается, как работает кэширование: если он загружает файлы, они попадают в $XDG_CACHE_DIR
(каталог томов /cache
), а если он создает колеса, они переходят в каталог томов /wheelhouse
. Вывод pip wheel
попадет в каталог тома /build
.
Контейнер test
во время запуска загружает некоторые дополнительные пакеты и помещает их в том build
. Затем он pip install --no-index
устанавливает пакеты только с использованием томов build
и wheelhouse
, вообще не обращаясь к PyPI.
Эта установка довольно сложна для того, что она делает. Некоторые общие рекомендации, которые я бы предложил здесь:
- Предпочитайте именованные тома контейнерам томов данных. (У очень ранних версий Docker не было именованных томов, но все, что работает в современном дистрибутиве Linux, будет.)
- Не устанавливайте виртуальную среду внутри вашего образа;просто установите непосредственно в системное дерево Python.
- Установите программное обеспечение во время создания образа (в Dockerfile), а не во время запуска образа (в сценарии точки входа).
- Не объявлять
VOLUME
в Dockerfile почти всегда;это не нужно для этой настройки, и когда она имеет эффекты, она обычно более запутанная, чем полезная.
Более типичная установка будет заключаться в том, чтобы собрать все это за один выстрел в этап сборки . Единственным недостатком этого является то, что загрузки не кэшируются между сборками: если ваш список требований не меняется, то Docker будет использовать его как набор, но если вы добавите или удалите какую-либо одну вещь, Docker повторит pip
Команда для загрузки всего набора.
Это будет выглядеть примерно (не проверено):
# First stage: build and download wheels
FROM python:3 AS build
# Bootstrap some Python dependencies.
RUN pip install --upgrade pip \
&& pip install wheel
# This stage can need some extra host dependencies, like
# compilers and C libraries.
RUN apt-get update && \
apt-get install -qy python-dev libmysqlclient-dev
# Create a directory to hold built wheels.
RUN mkdir /wheel
# Install the application's dependencies (only).
WORKDIR /app
COPY requirements.txt .
RUN pip wheel --wheel-dir=/wheel -r requirements.txt \
&& pip install --no-index --find-links=/wheel -r requirements.txt
# Build a wheel out of the application.
COPY . .
RUN pip wheel --wheel-dir=/wheel --no-index --find-links=/wheel .
# Second stage: actually run the application.
FROM python:3
# Bootstrap some Python dependencies.
RUN pip install --upgrade pip \
&& pip install wheel
# Get the wheels from the first stage.
RUN mkdir /wheel
COPY --from=build /wheel /wheel
# Install them.
RUN pip install --no-index --find-links=/wheel /wheel/*.whl
# Standard application metadata.
# The application should be declared as entry_points in setup.py.
EXPOSE 3000
CMD ["the_application"]