Найти в Дзене
КУЗИНОБИТ

Урок 7: Dockerfile, создание и оптимизация.

В предыдущем уроке мы познакомились с Docker Compose и научились описывать многоконтейнерные приложения с помощью YAML-файлов. Теперь пришло время углубиться в создание собственных образов Docker с помощью Dockerfile. В этом уроке мы подробно рассмотрим, как писать Dockerfile, оптимизировать образы и применять лучшие практики при их создании. Dockerfile — это текстовый файл, содержащий последовательность команд и инструкций для сборки образа Docker. С помощью Dockerfile вы можете автоматизировать процесс создания образов, описывая все необходимые шаги: выбор базового образа, установка зависимостей, копирование файлов, настройка переменных окружения и т.д. Давайте рассмотрим основные команды, используемые в Dockerfile: FROM Указывает базовый образ, от которого будет строиться ваш образ. FROM python:3.9-slim WORKDIR Задает рабочую директорию внутри контейнера. WORKDIR /app COPY Копирует файлы и директории с хоста в образ. COPY requirements.txt ./ RUN Выполняет команду в процессе сборк
Оглавление

В предыдущем уроке мы познакомились с Docker Compose и научились описывать многоконтейнерные приложения с помощью YAML-файлов. Теперь пришло время углубиться в создание собственных образов Docker с помощью Dockerfile. В этом уроке мы подробно рассмотрим, как писать Dockerfile, оптимизировать образы и применять лучшие практики при их создании.

Что такое Dockerfile?

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

Основные инструкции Dockerfile.

Давайте рассмотрим основные команды, используемые в Dockerfile:

FROM

Указывает базовый образ, от которого будет строиться ваш образ.

FROM python:3.9-slim

WORKDIR

Задает рабочую директорию внутри контейнера.

WORKDIR /app

COPY

Копирует файлы и директории с хоста в образ.

COPY requirements.txt ./

RUN

Выполняет команду в процессе сборки образа.

RUN pip install --no-cache-dir -r requirements.txt

CMD и ENTRYPOINT

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

CMD ["python", "app.py"]

ENV

Устанавливает переменные окружения внутри контейнера.

ENV APP_ENV=production

EXPOSE

Документирует, какой порт будет использоваться приложением внутри контейнера.

EXPOSE 80

ADD

Похоже на COPY, но может распаковывать архивы и загружать файлы по URL.

ADD https://example.com/app.tar.gz /app/

Пример создания Dockerfile для веб-приложения на Python.

Давайте создадим Dockerfile для простого веб-приложения на Flask.

Шаг 1: Создайте директорию проекта.

mkdir myflaskapp
cd myflaskapp

Шаг 2: Создайте файл app.py с простым приложением Flask.

from flask import Flask
app = Flask(__name__)
@app.route('/') def hello():
return 'Hello from Docker!'
if __name__ == '__main__':
app.run(host='0.0.0.0')

Шаг 3: Создайте файл requirements.txt с зависимостями

flask

Шаг 4: Напишите Dockerfile.

# Используем официальный образ Python 3.9 на базе slim
FROM python:3.9-slim
# Устанавливаем переменную окружения для предотвращения буферизации вывода
ENV PYTHONUNBUFFERED=1
# Устанавливаем рабочую директорию
WORKDIR /app
# Копируем файл зависимостей
COPY requirements.txt ./
# Устанавливаем зависимости
RUN pip install --no-cache-dir -r requirements.txt
# Копируем исходный код приложения
COPY . .
# Указываем порт, который будет использован
EXPOSE 5000
# Определяем команду запуска приложения
CMD ["python", "app.py"]

Разбор Dockerfile:

  • FROM python:3.9-slim: Используем легковесный образ Python 3.9.
  • ENV PYTHONUNBUFFERED=1: Обеспечиваем немедленный вывод логов в терминал.
  • WORKDIR /app: Устанавливаем рабочую директорию внутри контейнера.
  • COPY requirements.txt ./: Копируем файл с зависимостями.
  • RUN pip install --no-cache-dir -r requirements.txt: Устанавливаем зависимости без сохранения кеша.
  • COPY . .: Копируем все файлы проекта в контейнер.
  • EXPOSE 5000: Документируем использование порта 5000.
  • CMD ["python", "app.py"]: Определяем команду для запуска приложения.

Сборка и запуск образа.

Сборка образа:

docker build -t myflaskapp .

-t myflaskapp: Присваиваем имя образу.

.: Указываем контекст сборки (текущая директория).

Запуск контейнера:

docker run -d -p 5000:5000 myflaskapp

-d: Запуск в фоновом режиме.

-p 5000:5000: Переадресация порта хоста на порт контейнера.

Проверьте работу приложения, открыв в браузере http://localhost:5000.

Оптимизация Dockerfile.

Использование многоэтапной сборки (Multi-stage builds).

Позволяет уменьшить размер конечного образа, исключив ненужные зависимости и файлы.

# Первый этап — сборка
FROM python:3.9-slim AS builder
WORKDIR /app
COPY requirements.txt ./
RUN pip install --user --no-cache-dir -r requirements.txt
# Второй этап — создание финального образа
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]

Минимизация слоёв.

Каждая инструкция RUN, COPY, ADD создаёт новый слой. Объединяйте команды, чтобы уменьшить количество слоёв.

RUN apt-get update && apt-get install -y package1 package2 && rm -rf /var/lib/apt/lists/*

Использование .dockerignore.

Создайте файл .dockerignore, чтобы исключить ненужные файлы из контекста сборки. Пример содержимого .dockerignore:

.git
*.pyc
__pycache__

Лучшие практики при создании Dockerfile.

Используйте официальные базовые образы: Они регулярно обновляются и поддерживаются сообществом.

Минимизируйте размер образа: Используйте легковесные базовые образы (например, alpine).

Избегайте хранения секретов: Не включайте пароли и ключи API в образ.

Документируйте: Используйте инструкции LABEL для добавления метаданных об образе.

LABEL maintainer="yourname@example.com"
LABEL version="1.0"
LABEL description="Example Flask application"

Домашнее задание.

Задание 1: Создание Dockerfile для Node.js приложения.

  1. Создайте простое приложение на Node.js, которое возвращает "Hello from Node.js in Docker!".
  2. Напишите Dockerfile для этого приложения.
  3. Соберите образ и запустите контейнер.
  4. Убедитесь, что приложение работает корректно.

Задание 2: Оптимизация Dockerfile.

  1. Модифицируйте Dockerfile из задания 1, используя многоэтапную сборку для уменьшения размера образа.
  2. Добавьте файл .dockerignore, чтобы исключить ненужные файлы и директории.

Задание 3*: Исследование базовых образов.

  1. Попробуйте использовать разные базовые образы для вашего приложения (например, node:alpine).
  2. Сравните размеры полученных образов и время их сборки.
  3. Сделайте выводы о том, какие образы предпочтительнее использовать в разных ситуациях.

Что дальше?

В следующем уроке мы рассмотрим безопасность контейнеров. Продолжайте практиковаться и изучать Docker, чтобы стать профессионалом в контейнеризации приложений!