Вы тоже устали вручную заполнять Dockerfile и docker-compose.yaml под каждый новый проект?
Я всегда задумывался, применяю ли я известные best practices, когда пишу конфиг для Docker, и не занесу ли я случайно какие-нибудь уязвимости, вручную заполняя конфиг-файлы.
Что же, теперь мне больше не придется беспокоиться об этом, благодаря добрым людям из Docker, которые недавно реализовали инструмент для этого без лишнего шума.
Они создали CLI-утилиту - docker init .
docker init
Несколько дней назад (6 февраля 2024 - прим. переводчика) компания Docker выпустила docker init. Я попробовал его и теперь хочу использовать его в своих новых проектах.
Почему я должен использовать docker init?
Как уже сказано, docker init - это CLI-утилита, которая создает файлы Dockerfile, docker-compose.yaml и .dockerignore , автоматически определяя некоторые зависимости вашего проекта при деплое.
Это упрощает процесс настройки Docker, экономит время и помогает избежать уязвимостей, которые могли бы появиться при ручной настройке.
Последняя версия docker init поддерживает Go, Python, Node.js, Rust, ASP.NET, PHP и Java. Также она доступна вместе с Docker Desktop.
Как использовать docker init
Давайте создадим простой проект для примера, чтобы посмотреть, как docker init справится с автоматическим определением зависимостей для Dockerfile.
Пусть это будет простое Flask-приложение.
touch app.py requirements.txt
# app.py from flask import Flask app = Flask(__name__) @app.route('/') def hello_docker(): return '<h1> hello world </h1>' if __name__ == '__main__': app.run(debug=True, host='0.0.0.0')
# requirements.txt Flask
docker init просканирует проект и даст вам возможность выбрать наиболее подходящий шаблон. После выбора шаблона docker init уточнит у вас требуемые зависимости и их версии, автоматически добавляя их в генерируемые конфиги.
docker init

В нашем примере мы используем приложение на Python, поэтому выберем автоматически определенный шаблон и укажем, на каком порту и с помощью какой команды запускается наше приложение.


Посмотрим, как выглядят сгенерированные файлы:
# Dockerfile # syntax=docker/dockerfile:1 # Comments are provided throughout this file to help you get started. # If you need more help, visit the Dockerfile reference guide at # https://docs.docker.com/engine/reference/builder/ ARG PYTHON_VERSION=3.11.7 FROM python:${PYTHON_VERSION}-slim as base # Prevents Python from writing pyc files. ENV PYTHONDONTWRITEBYTECODE=1 # Keeps Python from buffering stdout and stderr to avoid situations where # the application crashes without emitting any logs due to buffering. ENV PYTHONUNBUFFERED=1 WORKDIR /app # Create a non-privileged user that the app will run under. # See https://docs.docker.com/go/dockerfile-user-best-practices/ ARG UID=10001 RUN adduser \ --disabled-password \ --gecos "" \ --home "/nonexistent" \ --shell "/sbin/nologin" \ --no-create-home \ --uid "${UID}" \ appuser # Download dependencies as a separate step to take advantage of Docker's caching. # Leverage a cache mount to /root/.cache/pip to speed up subsequent builds. # Leverage a bind mount to requirements.txt to avoid having to copy them into # into this layer. RUN --mount=type=cache,target=/root/.cache/pip \ --mount=type=bind,source=requirements.txt,target=requirements.txt \ python -m pip install -r requirements.txt # Switch to the non-privileged user to run the application. USER appuser # Copy the source code into the container. COPY . . # Expose the port that the application listens on. EXPOSE 5000 # Run the application. CMD gunicorn 'app:app' --bind=0.0.0.0:5000
Сгенерированный файл содержит комментарии ко всем используемым параметрам и соответствует best security practices - например, здесь создается отдельный пользователь без root-прав в контейнере, от имени которого стартует приложение.
А вот так выглядит compose.yaml:

В отличие от Dockerfile, сгенерированный compose-конфиг довольно маленький. Также в него добавлена закомментированная секция с настройкой PostgreSQL - если она вам потребуется (довольно часто встречаю использование PostgreSQL в приложениях на Python), достаточно будет раскомментировать эту секцию.
Почему я должен использовать docker init?
С помощью этой утилиты докеризация вашего приложения становится сильно проще, что актуально для тех, кто только начал изучать Docker. Она экономит время и сводит к минимуму возможные ошибки.
Утилита умеет подстраиваться под ваше приложение (автоматическое определение подходящего шаблона и зависимостей) и следует лучшим отраслевым практикам - это ускоряет работу с контейнерами (например, в сгенерированном конфиге выше применяются переменные окружения для оптимизации Python и аргументы для улучшенного кеширования pip), а также дает возможность задеплоить приложение безопасно, даже если вы не разбираетесь в best practices при работе с Docker.