Docker большой исчерпывающий курс. Глава 2. Сборка собственного образа: Dockerfile

В первой главе мы использовали готовые образы (python, nginx). Это эквивалентно использованию стандартных библиотек языка. Теперь мы напишем свой «класс» — создадим кастомный образ для вашего приложения.

Главный инструмент здесь — Dockerfile. Это инструкция по сборке, которую Docker читает сверху вниз.

2.1. Подготовка проекта

Создайте пустую папку и два файла в ней.

  1. main.py (наше “сложное” приложение):codePythonimport os print(f"Приложение запущено! Версия: {os.getenv('APP_VERSION', '1.0')}")
  2. Dockerfile (без расширения, просто имя файла):

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

Откройте Dockerfile и впишите следующее. Разберем каждую строку как код:codeDockerfile

# 1. Наследование (Inheritance)
# Мы не пишем ОС с нуля, мы наследуемся от готового образа.
FROM python:3.9-slim

# 2. Рабочая директория
# Это как 'cd /app' внутри образа. Все дальнейшие команды будут выполняться здесь.
WORKDIR /app

# 3. Копирование файлов
# Синтаксис: COPY <откуда_на_хосте> <куда_в_образе>
# Точка во втором аргументе означает "в текущую папку WORKDIR"
COPY main.py .

# 4. Переменные окружения (Дефолтное значение)
ENV APP_VERSION=2.0

# 5. Команда запуска (Entrypoint)
# То, что выполнится, когда вы сделаете 'docker run'
CMD ["python", "main.py"]

2.3. Сборка (Build)

Находясь в терминале в папке с этими файлами, выполните:codeBash

docker build -t my-python-app .

Разбор команды:

  • -t my-python-app: Тег (имя) для вашего образа.
  • . (точка в конце): Критически важный момент. Это указание на Build Context.

Что такое Build Context?
Когда вы запускаете билд, Docker CLI упаковывает всё содержимое указанной папки (где стоит точка) и отправляет это демону Docker.

Ошибка новичка: Если у вас в папке лежит файл на 10 Гб, билд “зависнет” в начале, потому что он отправляет этот файл демону, даже если вы не делаете COPY этого файла.

2.4. Слои и Кеширование (Docker Layer Caching)

Посмотрите на вывод терминала при сборке. Вы увидите Step 1/5, Step 2/5…
Каждая инструкция в Dockerfile (FROM, COPY, RUN) создает новый слой (Layer). Слои накладываются друг на друга как коммиты в Git.

Запустите команду сборки еще раз:codeBash

docker build -t my-python-app .

Вы увидите надпись Using cache напротив каждого шага. Сборка прошла мгновенно.

Золотое правило оптимизации:
Docker пересобирает слой, только если изменилась инструкция или файлы, которые она затрагивает. Если слой изменился, все последующие слои сбрасывают кеш и пересобираются заново.

Поэтому, порядок команд критичен. Сначала копируем то, что меняется редко (зависимости), потом то, что меняется часто (код).

Пример (плохо):codeDockerfile

COPY . .           # Копируем весь код
RUN pip install -r requirements.txt  # Устанавливаем либы

Почему плохо: Вы поменяли одну строчку в коде -> кеш первого шага слетел -> Docker заново качает все библиотеки.

Пример (хорошо):codeDockerfile

COPY requirements.txt .
RUN pip install -r requirements.txt  # Этот слой закешируется надолго
COPY . .           # Этот слой будет пересобираться при каждом изменении кода

2.5. RUN vs CMD

Программисты часто путают эти две инструкции.

  1. RUN — выполняется во время сборки (Build time).
    • Результат команды сохраняется в образе.
    • Пример: RUN pip install pandas, RUN apt-get update.
    • Аналог: Компиляция кода.
  2. CMD — выполняется во время запуска контейнера (Runtime).
    • В Dockerfile может быть только один CMD (точнее, сработает только последний).
    • Пример: CMD [“python”, “app.py”].
    • Аналог: Выполнение .exe файла.

2.6. .dockerignore

Это аналог .gitignore. Вы же не хотите копировать в образ папку .git, локальные конфиги .env, временные файлы или огромную папку node_modules (ее нужно устанавливать внутри через RUN npm install).

Создайте файл .dockerignore:codeText

.git
__pycache__
*.md

2.7. Проверка результата

Запустим наш свежеиспеченный образ:codeBash

docker run --rm my-python-app

Вывод: Приложение запущено! Версия: 2.0

Попробуем переопределить переменную окружения при запуске (без пересборки!):codeBash

docker run --rm -e APP_VERSION="3.5-beta" my-python-app

Вывод: Приложение запущено! Версия: 3.5-beta


Резюме главы

  1. Dockerfile — это исходный код для создания образа.
  2. FROM — наследование от базового образа.
  3. WORKDIR — задает рабочую директорию (избегайте работы в корне /).
  4. Слои и кеш: ставьте COPY requirements.txt и RUN pip install ДО копирования основного кода COPY . .. Это ускорит сборку в разы.
  5. RUN — для установки зависимостей (во время билда), CMD — для старта приложения (во время запуска).
  6. Всегда используйте .dockerignore.

В следующей главе мы решим проблему “У меня 5 микросервисов, база данных и редис, я устал запускать их руками”. Встречайте Docker Compose.

 Глава 1. Архитектура, понятия и первый запуск

Глава 2. Сборка собственного образа: Dockerfile

+1
0
+1
5
+1
0
+1
0
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *