Вы должны перестать вручную писать Dockerfile’ы

в 11:10, , рубрики: docker, docker-compose, деплой

Вы тоже устали вручную заполнять 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
Вы должны перестать вручную писать Dockerfile'ы - 1

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

Вы должны перестать вручную писать Dockerfile'ы - 2
docker init выведет созданные файлы с конфигами и покажет инструкции по запуску

docker init выведет созданные файлы с конфигами и покажет инструкции по запуску

Посмотрим, как выглядят сгенерированные файлы:

# 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'ы - 4

В отличие от Dockerfile, сгенерированный compose-конфиг довольно маленький. Также в него добавлена закомментированная секция с настройкой PostgreSQL - если она вам потребуется (довольно часто встречаю использование PostgreSQL в приложениях на Python), достаточно будет раскомментировать эту секцию.

Почему я должен использовать docker init?

С помощью этой утилиты докеризация вашего приложения становится сильно проще, что актуально для тех, кто только начал изучать Docker. Она экономит время и сводит к минимуму возможные ошибки.

Утилита умеет подстраиваться под ваше приложение (автоматическое определение подходящего шаблона и зависимостей) и следует лучшим отраслевым практикам - это ускоряет работу с контейнерами (например, в сгенерированном конфиге выше применяются переменные окружения для оптимизации Python и аргументы для улучшенного кеширования pip), а также дает возможность задеплоить приложение безопасно, даже если вы не разбираетесь в best practices при работе с Docker.

Автор: Mark Fomin

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js