September 16, 2022

Python + Docker multi-stage build

Все началось с того, как я по привычке использовал в учебном проекте venv в Docker-контейнере, на что мне в код-ревью сказали, что это просто трата ресурсов. Поискал в инете, люди говорят, что на самом деле особо пофиг, есть venv или же нет — как удобно, так и делай.
Однако, еще нашлось одно очень хорошее применение для использования виртуальной среды: раздельная установка зависимостей и запуск кода с помощью билда контейнера в несколько (2.00) этапов.

Суть в том, что можно создать venv на одном этапе, установить в него зависимости, а потом на новом этапе просто скопировать venv целиком с предыдущего этапа.
Такой подход позволяет использовать на последнем этапе более легковесные образы python (в моем случае для запуска хватило 3.10-alpine), при этом сохраняя все необходимое для установки зависимостей (много где требуется наличие gcc, например).
В моем случае вес итогового образа уменьшился практически в 8 раз (1.03GB -> 146MB).


Но.. даже тут я умудрился споткнуться и у меня произошла интересная ситуация (picrelated): вроде бы исполняемый файл есть, а запустить его нельзя.
Я так и не выяснил конкретную суть проблемы, но ради интереса заглянув в .venv/bin/activate обнаружил, что пути там указаны как /.venv а не /app/.venv, как это должно быть.

Оказалось, что на первом этапе нужно было создавать виртуальную среду по тому же пути, по которому она должна быть на последнем этапе. Тогда все пути внутри будут нормально матчиться.
Теперь я, довольный как енот, пойду пушить новую версию образа и дальше делать лабу... Опять затуплю где-нибудь, чтоб найти повод для нового поста :)