Docker большой исчерпывающий курс. Глава 1. Архитектура, понятия и первый запуск

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

t.me/docker – если хотите больше полезного лучший обучающий телеграм по docker и devops

1.1. Три кита Docker

Вам нужно запомнить всего три сущности, на которых строится вся работа:

  1. Image (Образ) — это Класс.
    • Это неизменяемый (read-only) шаблон.
    • Содержит ОС (усеченную), код приложения, библиотеки и переменные окружения.
    • Пример: ubuntu:22.04, python:3.9, postgres:14.
  2. Container (Контейнер) — это Объект (инстанс).
    • Это запущенный экземпляр Образа.
    • У него есть состояние (пока он работает), свой IP-адрес внутри сети Docker и свои процессы.
    • Вы можете создать 100 контейнеров из одного образа, как 100 объектов из одного класса.
  3. Registry (Реестр) — это Git-репозиторий (но для бинарников).
    • Место, где хранятся образы.
    • Самый известный публичный реестр — Docker Hub.
    • Вы делаете docker pull (аналог git pull) и docker push (аналог git push).

1.2. Проверка установки

Я исхожу из того, что Docker Desktop или Docker Engine у вас уже установлен.
Откройте терминал и проверьте связь клиента с демоном:codeBash

docker version

Если вы видите вывод и для Client, и для Server — всё готово. Если видите ошибку “Cannot connect to the Docker daemon” — запустите Docker Desktop или службу dockerd.

1.3. Анатомия команды run

Запустим самый простой контейнер. Введите:codeBash

docker run hello-world

Что именно произошло за эти секунды?
Это ключевой момент для понимания работы Docker “под капотом”.

  1. Поиск локально: Docker Client спросил у Docker Daemon: «У нас есть образ hello-world на диске?»
  2. Скачивание (Pull): Демон ответил «Нет» и пошел на Docker Hub. Он скачал слои образа hello-world:latest.
  3. Создание контейнера: Из скачанного образа демон создал новый контейнер (инстанс).
  4. Запуск: Внутри контейнера запустился процесс (entrypoint). В данном случае это скрипт, выводящий текст.
  5. Завершение: Скрипт отработал и процесс завершился (код выхода 0). Контейнер остановился, но не удалился.

1.4. Интерактивный режим и изоляция

Контейнеры бесполезны, если они просто выводят текст и умирают. Запустим что-то полезное, например, Python, и “провалимся” внутрь.codeBash

docker run -it python:3.9 bash

Флаги:

  • -i (interactive): держит поток ввода (STDIN) открытым.
  • -t (tty): выделяет псевдо-терминал.
  • python:3.9: имя образа.
  • bash: команда, которую мы хотим выполнить внутри контейнера (переопределяет стандартную команду).

Теперь вы внутри контейнера. Обратите внимание, что приглашение командной строки изменилось (например, на root@1a2b3c4d5e6f:/#).

Проверка изоляции:
Находясь внутри контейнера, выполните:codeBash

ls /home   # Скорее всего пусто, это не ваш /home
cat /etc/os-release # Покажет Debian (на котором основан образ python), даже если у вас macOS или Windows
exit       # Выход из контейнера

Вы вышли из изолированной среды. Все файлы, которые вы создали внутри того контейнера, остались в нем (и исчезнут при его удалении, если не примонтировать том, но об этом позже).

1.5. Жизненный цикл и уборка

Программисты часто забывают про мусор. Каждый раз, когда вы делаете docker run, создается новый контейнер.

Посмотрим список запущенных контейнеров:codeBash

docker ps

Скорее всего, список пуст. Почему? Потому что hello-world и python уже завершили работу.

Посмотрим все контейнеры (включая остановленные):codeBash

docker ps -a

Вы увидите список “мертвых” контейнеров со странными именами (типа zealous_khorana), которые Docker генерирует случайно, если вы не задали имя явно.

Удаление контейнера:
Возьмите CONTAINER ID (первые несколько символов) из списка выше и выполните:codeBash

docker rm <id_контейнера>

Лайфхак для разработки:
Чтобы не плодить мусор при экспериментах, запускайте контейнеры с флагом –rm. Как только процесс внутри завершится, Docker сам удалит контейнер.codeBash

docker run --rm hello-world
# После выполнения docker ps -a покажет, что контейнера нет.

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

1.6. Фоновый режим (Detached mode)

В реальной жизни вы не хотите держать открытым терминал для базы данных или веб-сервера. Вы хотите запустить их как службу (демона).

Для этого используется флаг -d.codeBash

docker run -d nginx

Docker вернет длинный хеш (ID контейнера) и вернет управление терминалу. Контейнер работает в фоне.
Проверьте это через docker ps.

1.7. Проброс портов (Port Mapping)

Вы запустили nginx в прошлом шаге, но если вы откроете в браузере localhost, то ничего не увидите.
Почему?
По умолчанию сеть контейнера полностью изолирована. Порт 80 открыт внутри контейнера, но закрыт снаружи. Вам нужно «прокинуть кабель» от вашего компьютера внутрь контейнера.

Синтаксис: -p <порт_хоста>:<порт_контейнера>

Убьем старый контейнер и запустим правильно:codeBash

# Остановить и удалить (если знаете имя или ID)
docker rm -f <id_предыдущего_nginx>

# Запустить с пробросом порта и человеческим именем
docker run -d --name my-web-server -p 8080:80 nginx

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

  • –name my-web-server: теперь к контейнеру можно обращаться по этому имени, а не по ID.
  • -p 8080:80: Все запросы на ваш локальный localhost:8080 будут перенаправлены на порт 80 внутри контейнера.

Теперь откройте браузер и введите http://localhost:8080. Вы увидите приветствие Nginx.

Важно: Если вы попытаетесь запустить второй контейнер на порту 8080 (-p 8080:…), получите ошибку Bind for 0.0.0.0:8080 failed: port is already allocated. Порт хоста — ресурс уникальный.

1.8. run vs exec: Главная ошибка новичка

Это самый частый источник путаницы.

  1. docker run — создает НОВЫЙ контейнер (новый объект) и запускает его.
  2. docker exec — подключается к УЖЕ ЗАПУЩЕННОМУ контейнеру.

Сценарий: Вы запустили Nginx (как в пункте 1.7) и хотите поправить в нем конфиг-файл.

  • ❌ Неправильно: docker run -it nginx bash
    Вы создадите новый, чистый контейнер с Nginx, где нет ваших прошлых изменений, и удивитесь, почему там пусто.
  • ✅ Правильно: docker exec -it my-web-server bash
    Вы запускаете процесс bash внутри того самого контейнера my-web-server, который уже крутится и обслуживает порт 8080.

Попробуйте:codeBash

docker exec -it my-web-server bash
# внутри:
ls /etc/nginx
exit

Сервер Nginx при этом не остановился, вы просто вышли из сеанса bash.


Обновленное резюме главы (дополненное)

  1. Image — класс, Container — объект.
  2. Изоляция полная: файловая система и сеть закрыты по умолчанию.
  3. -d запускает контейнер в фоне (как сервис).
  4. -p HOST:CONTAINER открывает доступ к приложению снаружи.
  5. docker run создает новое, docker exec входит в существующее.
  6. –rm удаляет контейнер после выхода (для одноразовых задач).

Теперь вы умеете управлять готовыми кирпичиками. В Главе 2 мы начнем обжигать свои собственные кирпичи: разберем Dockerfile.

Резюме главы

  1. Image — класс (шаблон), Container — объект (процесс).
  2. docker run = pull (если нет образа) + create + start.
  3. Контейнеры изолированы от хост-системы (своя файловая система, свои процессы).
  4. Остановленные контейнеры занимают место на диске, их нужно удалять (docker rm).

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

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

+1
0
+1
1
+1
2
+1
0
+1
0

Ответить

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