Урок 4 из 8 · 20 мин · обновлено
Контейнеры: Docker
Зачем DevOps-инженеру контейнеры: проблема «у меня работает», Dockerfile для приложения, образы и реестр, Docker Compose для сайта с базой данных.
«У меня работает»
Разработчик «Чайной лавки» проверил новую версию у себя — всё отлично. На сервере сайт падает: там другая версия Python и не хватает одной библиотеки. Знакомая ситуация в любой команде.
Контейнер решает это: приложение упаковывается вместе со всем, что ему нужно, — нужной версией языка, библиотеками, настройками. Такой «ящик» работает одинаково на ноутбуке разработчика, в конвейере сборки и на сервере. Самый популярный инструмент для контейнеров — Docker. Подробный курс — «Docker для начинающих».
Dockerfile и образ
Инструкция, как собрать «ящик», — Dockerfile:
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "shop.wsgi"]
По шагам: взять готовый образ с Python, перейти в папку /app, установить библиотеки, скопировать код и запустить сайт.
По Dockerfile собирают образ — шаблон, а по образу запускают контейнеры:
docker build -t shop:1.4.0 .
docker run -d -p 8000:8000 shop:1.4.0
Реестр и версии
Собранные образы хранят в реестре — хранилище образов. Конвейер из урока 3 после тестов собирает образ и отправляет его в реестр, а сервер забирает оттуда.
Каждый образ помечают версией: shop:1.4.0 или номером коммита. Если новая версия оказалась с ошибкой, откат — это просто запуск предыдущего образа, а не восстановление файлов по памяти.
Docker Compose: несколько контейнеров
Сайту «Чайной лавки» нужна база данных. Удобно описать оба контейнера в одном файле compose.yaml:
services:
web:
image: registry.example.ru/shop:1.4.0
ports:
- "8000:8000"
environment:
DATABASE_HOST: db
depends_on:
- db
db:
image: postgres:17
env_file: .env
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
Одна команда поднимает всё сразу:
docker compose up -d
✔ Container shop-db-1 Started
✔ Container shop-web-1 Started
Обратите внимание на две вещи:
volumes— данные базы лежат в томеdb-data, отдельно от контейнера. Контейнер пересоздают при каждом обновлении, и всё, что было внутри, исчезает. Том — нет.env_file: .env— пароль базы лежит в файле.envна сервере. Этот файл не добавляют в Git, как и любые секреты из урока 3.
Попробуйте сами. Добавьте в compose.yaml «Чайной лавки» кэш Redis — контейнер cache из образа redis:7, — и сделайте так, чтобы сайт запускался после него.
Пример ответа
services:
web:
image: registry.example.ru/shop:1.4.0
ports:
- "8000:8000"
environment:
DATABASE_HOST: db
CACHE_HOST: cache
depends_on:
- db
- cache
cache:
image: redis:7
db:
image: postgres:17
env_file: .env
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
Порт кэша наружу не открываем: сайт обращается к нему по имени cache внутри общей сети Compose.
Мини-тест · 4 вопроса
Проверьте себя
Выберите вариант, который кажется вам правильным. В конце вы увидите свой результат и объяснение к каждому вопросу.
-
Какую проблему решают контейнеры?
В контейнере лежат приложение и всё нужное ему окружение, поэтому оно работает одинаково на ноутбуке, в конвейере и на сервере.
-
Чем образ отличается от контейнера?
Из одного образа можно запустить сколько угодно одинаковых контейнеров — как из одного чертежа построить много домов.
-
Зачем помечать образы номером версии, а не только latest?
latest каждый раз указывает на новое. С версиями всегда можно вернуть конкретную работавшую сборку.
-
Где хранить данные базы данных, запущенной в контейнере?
Контейнеры пересоздают при каждом обновлении. Всё, что внутри, при этом исчезает, а том сохраняется.