Первый запуск: hello-world и загляни внутрь
Хватит теории — пора потрогать руками. В этом уроке ты запустишь свой первый контейнер, заглянешь внутрь живой коробки и посмотришь список запущенного. Всё, о чём мы говорили на пальцах в прошлых уроках, ты сейчас увидишь вживую.
Предполагается, что Docker уже установлен (Ступень 0). Проверим и поехали.
Проверка, что Docker на месте
Открой терминал и спроси у Docker его версию:
docker --version
Ожидаемый вывод (числа у тебя могут отличаться — это нормально):
Docker version 27.3.1, build ce12230
Если вместо версии видишь ошибку вроде command not found или Cannot connect to the Docker daemon — значит, Docker не установлен или не запущен. Вернись к Ступени 0: на Mac и Windows обычно нужно просто запустить приложение Docker Desktop (или OrbStack) и дождаться, пока значок перестанет мигать.
Шаг 1. docker run hello-world
Это традиционный самый первый контейнер. Он ничего не делает полезного — только печатает приветствие и сразу завершается. Его задача — проверить, что вся цепочка работает.
docker run hello-world
В первый раз Docker не найдёт нужную коробку у себя на машине и сначала скачает её из интернета, поэтому увидишь несколько строк про загрузку, а затем приветствие:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:d000bc569937abbe195e20322a0bde6b2922d805332fd6d8a68b19f524b7d21d
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client.
Главное здесь — строчка Hello from Docker!. Если ты её видишь, всё работает: Docker скачал коробку, создал из неё контейнер, запустил приложение внутри и показал тебе результат. Этот контейнер сделал своё дело и сразу остановился.
[!tip] Слово
image(образ) — это «шаблон коробки», заготовка, из которой Docker создаёт работающий контейнер. Из одного образа можно наделать сколько угодно одинаковых контейнеров. Пока достаточно интуиции «образ — это коробка в сложенном виде, контейнер — она же, но запущенная». Подробно образы разберём в отдельном модуле.
Шаг 2. docker run -it alpine sh — зайди внутрь коробки
hello-world промелькнул и исчез. Теперь запустим коробку, в которую можно зайти и осмотреться. Возьмём alpine — это крошечный Linux (всего несколько мегабайт), идеальный для экспериментов.
docker run -it alpine sh
Расшифруем команду по кусочкам:
docker run— запусти контейнер;-it— два флажка вместе: «дай мне интерактивную сессию» и «подключи мою клавиатуру», то есть пусти меня внутрь поговорить;alpine— какую коробку (образ) брать;sh— какую программу запустить внутри;shэто командная оболочка, то есть приглашение, куда можно вводить команды.
Скачается крошечный образ, и приглашение в терминале изменится — ты внутри контейнера:
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
9824c27679d3: Pull complete
Status: Downloaded newer image for alpine:latest
/ #
Этот / # — приглашение командной строки уже внутри коробки, а не на твоей машине.
Шаг 3. Осмотрись внутри
Ты в отдельном маленьком мире. Давай в этом убедимся. Посмотри, какие файлы лежат в корне:
ls /
bin dev etc home lib media mnt opt proc root
run sbin srv sys tmp usr var
Это не файлы твоего компьютера — это файловая система внутри контейнера. Твоих личных папок и проектов тут нет: коробка изолирована, у неё свой набор файлов. Спросим, что это вообще за система:
cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.20.3
PRETTY_NAME="Alpine Linux v3.20"
Внутри — Alpine Linux, даже если твой компьютер это Mac или Windows. Вот она, «коробка со своим окружением».
Теперь выйди обратно на свою машину:
exit
Приглашение вернётся к обычному виду твоего терминала. Контейнер при этом остановился — ты вышел, и программе sh внутри стало незачем работать.
[!warning] Всё, что ты создашь внутри такого контейнера (например, файл командой
touch test.txt), исчезнет после выхода и удаления контейнера. По умолчанию содержимое коробки не сохраняется между запусками. Как сделать так, чтобы данные жили дольше контейнера — отдельный важный модуль про тома (volumes). Пока просто знай: запущенная-выкинутая коробка не хранит изменения.
Шаг 4. docker ps — что сейчас запущено
Вернувшись на свою машину, спроси у Docker список запущенных контейнеров:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Список пустой (только заголовки) — это правильно. Оба наших контейнера уже остановились: hello-world сам, а alpine — когда ты вышел. docker ps показывает только то, что прямо сейчас работает.
Чтобы увидеть и остановленные контейнеры тоже, добавь флаг -a (от англ. all — все):
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
3f1a9c2b7e4d alpine "sh" 2 minutes ago Exited (0) 1 minute ago brave_kepler
8b2d4e6f1a9c hello-world "/hello" 5 minutes ago Exited (0) 5 minutes ago nice_turing
Вот они, оба контейнера, со статусом Exited (завершён). Имена вроде brave_kepler Docker придумывает сам, если ты не задал своё.
Мостик: а как это устроено внутри?
Ты только что вживую увидел всё, о чём мы говорили: скачал стандартную коробку, запустил из неё контейнер, зашёл внутрь изолированного мира со своей файловой системой и своей ОС, вышел и посмотрел список.
Закономерный вопрос: а как Docker вообще делает эту изоляцию? Откуда у контейнера своя файловая система, почему он видит себя одним на машине, как ему дают «общее ядро», но при этом отдельный мир?
За этим стоят вполне конкретные механизмы ядра Linux с названиями вроде namespaces и cgroups. Это интересно и важно — но прямо сейчас об этом думать рано. Сначала нужно уверенно освоиться с самими контейнерами на уровне команд и интуиции. К внутренностям мы перейдём дальше, со следующего модуля, уже подготовленными. А пока твоя задача — привыкнуть запускать, осматривать и выкидывать коробки.
Попробуй сам
- Запусти
docker run hello-worldещё раз. Обрати внимание: строчек про загрузку (Pulling) больше нет — коробка уже скачана и лежит на машине. Почему так? Объясни себе одной фразой. - Зайди в alpine:
docker run -it alpine sh. Внутри выполниwhoami(узнаешь, под кем ты внутри) иhostname(имя «машины» внутри коробки). Затемexit. - Запусти контейнер с осмысленным именем:
docker run --name proba -it alpine sh, осмотрись и выйди. Теперь найди его вdocker ps -a— там должно быть имяprobaвместо случайного. - Загляни в
docker ps -aи посчитай, сколько остановленных контейнеров у тебя накопилось за урок.