17 августа 2020 г.

Итак, у меня есть API, который делает что-то полуинтересное, пора его развернуть. На самом деле нет никакого смысла иметь аккуратный код на вашем ноутбуке, и когда дело доходит до машинного обучения, вы узнаете, работает ли что-то, только если оно находится в производстве.

Цель состоит в том, чтобы использовать файл CI gilab для последовательного выполнения следующих заданий.

  1. Запустите несколько модульных и интеграционных тестов (пока я просто выведу что-нибудь на экран)
  2. Создайте образ докера для API
  3. Отправьте контейнер в реестр артефактов Google Cloud.
  4. Разверните образ в Cloud Run в среде разработки.
  5. Запустите приемочные тесты для разработчиков (вызовите маршруты API и убедитесь, что они работают).
  6. Разверните образ в Cloud Run в prod
  7. Проведите несколько приемочных тестов для продукта

Сейчас я сосредоточусь только на 1–4

Взглянем на файл Dockerfile, который входит в стандартный репозиторий:

Они используют инструмент под названием dockerize, который выглядит интересно, никогда не использовал его раньше.

Вот файл startup.sh, указанный в строке 14.

Круто, так что он в основном ждет соединений на 3306, который, я думаю, является стандартным портом SQL. Обратите внимание на команду перегонного куба, которая помогает сделать код пригодным для миграции (я думаю? Никогда раньше не использовал этот инструмент, так что буду учиться по ходу дела)

Сначала попробуем локально

Вот модификации Dockerfile с pip вместо pipenv и многоэтапной сборкой.

Я сохраню файл Dockerfile в корневом каталоге и изменю его, чтобы использовать файл src/docker/api в качестве ссылки. Я буду создавать только API прямо сейчас

## build stage
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 as build
WORKDIR /app
# tell python not to write to .pyc files and instead write bytes
ENV PYTHONWRITEBYTECODE 1
# force stdout and stderr to be unbuffered
ENV PYTHONBUFFERED 1
COPY . /app
# COPY src ./src
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt
## main stage
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
WORKDIR /home
COPY --from=build /app/wheels /wheels
COPY --from=build /app .
RUN pip install --no-cache /wheels/*
ENV DOCKERIZE_VERSION v0.6.1
ENV ENV=dev
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
RUN chmod +x src/docker/api/startup.sh
ENTRYPOINT src/docker/api/startup.sh

Одна вещь, которую я не очень люблю, — это размер изображения Fastapi.

Как видите, в зависимостях моего приложения разница составляет всего 13 МБ, но fastapi действительно тяжелый. Возможно, стоит построить его самому на этапе сборки с колесами, но не сейчас.

Чтобы запустить контейнер, я сделал

export PORT=8000

Затем ./dev_scripts/launch_container.sh

В Google Cloud я создал новый проект и назвал его news-to-data.

Вы знаете, что я разверну это как следует завтра, я сегодня очень устал. Но если вы дошли до этого момента, теперь у вас есть способ развернуть контейнер fastAPI в выбранном вами кластере, если хотите, поскольку контейнеры переносимы. Имейте в виду, что он развертывает только API, а не базу данных/кеш.