← КурсСамостоятельный просмотрПульт

Пара 13 / ноябрь

Docker: образ, контейнер и границы изоляции

Запустить контейнер и объяснить различия между образом, процессом и виртуальной машиной.

Контекст

Контейнер запускается из образа и получает собственное состояние.

Запустить контейнер и объяснить различия между образом, процессом и виртуальной машиной.

Образ — рецепт готовой среды

Контейнер запускается из образа и получает собственное состояние.

01Dockerfile
02Образ
03Контейнер A
04Контейнер B

Аналогия: чертёж формы, готовая форма и отдельные отливки.

Контейнер и VM

Контейнеры разделяют ядро среды, но имеют ограничения и пространства имён.

01Windows
02WSL2 / Linux
03Docker Engine
04Контейнеры

Аналогия: комнаты в одном здании и отдельные здания имеют разные границы.

Docker Desktop и WSL2

Выбираем один Docker Engine и проверяем контекст.

01Ubuntu CLI
02Docker context
03Engine
04Контейнер

Ошибка подключения к daemon не равна ошибке Dockerfile.

Команды и наблюдения

Ubuntu / Bash с Docker

docker version
docker context show
docker run --rm hello-world
docker run --rm --name demo-clock alpine:3.22 date -u
docker image ls
docker ps -a

Разбор результата

CLI видит сервер Docker; hello-world успешно завершается; demo-clock удаляется после выполнения из-за --rm.

Теги закрепляют версию по соглашению, но могут изменяться; строгая идентичность образа задаётся digest. При проблеме сначала проверяем Desktop и WSL integration.

На macOS

На macOS Docker Desktop запускает Linux-контейнеры в Linux-VM, не на ядре XNU. Установите вариант Desktop для Apple Silicon или Intel. Docker Engine для Ubuntu напрямую на macOS не ставится. Apple Silicon обычно использует arm64; контейнерный uname отражает архитектуру выбранного образа.

docker version
docker context show
docker run --rm hello-world
docker run --rm alpine:3.22 uname -m

Жизненный цикл контейнера

  1. Запустите alpine:3.22 с командой sleep 120 в фоне через -d и имя student-sleep.
  2. Посмотрите docker ps, docker logs и docker inspect для своего контейнера.
  3. Остановите docker stop student-sleep и сравните ps с ps -a.
  4. Удалите только student-sleep; объясните, почему образ ещё виден.

Что должно получиться

Схема образ → запуск → остановка → удаление.

Удаляется только собственный учебный контейнер; образ и контейнер различаются.

Ошибка для диагностики

Завершение hello-world принимают за аварию.

Симптом→Гипотеза→Проверка

Основные выводы

  1. Его процесс завершился; ps без -a показывает работающие контейнеры.
  2. Нет, используется ядро среды исполнения.

После пары

Установить и проверить Docker до следующей пары; объяснить текущий context.

Конспект, команды и разбор →

Пара 14 / ноябрь

Dockerfile: сборка StudyPulse

Собрать образ сервиса и проверить воспроизводимый запуск без ручных правок контейнера.

Контекст

Сборка создаёт образ; CMD задаёт запуск.

Собрать образ сервиса и проверить воспроизводимый запуск без ручных правок контейнера.

Инструкции Dockerfile

Сборка создаёт образ; CMD задаёт запуск.

01FROM
02WORKDIR / COPY
03USER
04CMD

Аналогия: последовательная инструкция сборки и отдельная кнопка запуска.

Контекст и кеш

Сборка видит только переданный контекст и учитывает его изменения.

01Контекст
02dockerignore
03Слои / кеш
04Образ

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

Пользователь и постоянные данные

Код в образе, изменяемые данные — в специально выбранном месте.

01Образ: код
02USER: app
03/data: данные
04Окружение: настройки

Аналогия: запечатанный прибор и отдельная сменная кассета с результатами.

Команды и наблюдения

Ubuntu / Bash, lab

cd ~/devops-course/lab
docker build -t studypulse:v1 .
docker run --rm --name studypulse-demo -p 127.0.0.1:8000:8000 -e HOST=0.0.0.0 studypulse:v1
# In another terminal
curl -i http://127.0.0.1:8000/healthz
docker logs studypulse-demo
docker inspect --format "{{.Config.User}}" studypulse-demo

Разбор результата

API доступен на localhost хоста; пользователь образа не root; журнал содержит старт и запрос.

HOST=0.0.0.0 внутри контейнера позволяет принять трафик с его сети; публикация 127.0.0.1 на хосте ограничивает внешний доступ.

На macOS

Dockerfile курса переносим при наличии образа для вашей архитектуры. Локальная ARM64-сборка не является автоматически AMD64-образом для сервера. Для рабочего выпуска используйте явно целевую платформу или multi-platform build и проверку. Эмуляция может замедлить сборку и нагрузочные измерения.

docker build -t studypulse:v1 .
docker run --rm -p 127.0.0.1:8000:8000 -e HOST=0.0.0.0 studypulse:v1

Собрать и проверить

  1. Прочитайте предоставленный Dockerfile; подпишите роль каждой инструкции.
  2. Соберите образ дважды и найдите cached-слои.
  3. Запустите сервис, проверьте healthz и корректный/некорректный predict.
  4. Измените небольшую часть документации, затем код в отдельной копии; сравните влияние на сборку и восстановите исходный код.

Что должно получиться

Образ studypulse:v1, ответы API и объяснение кеша.

Контейнер работает non-root; .env и .venv не попали в образ; EXPOSE не путают с -p.

Ошибка для диагностики

Приложение слушает 127.0.0.1 внутри контейнера и недоступно через опубликованный порт.

Симптом→Гипотеза→Проверка

Основные выводы

  1. Нет, RUN выполняется при сборке образа.
  2. Нет, публикация задаётся при запуске.

После пары

Добавить Docker-запуск в README и зафиксировать Dockerfile и dockerignore в Git.

Конспект, команды и разбор →