Learning Platform
Глоссарий Troubleshooting
Урок 02.03 · 20 мин
Начальный
dockerdocker-runclihands-on

Первый запуск: 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. Это интересно и важно — но прямо сейчас об этом думать рано. Сначала нужно уверенно освоиться с самими контейнерами на уровне команд и интуиции. К внутренностям мы перейдём дальше, со следующего модуля, уже подготовленными. А пока твоя задача — привыкнуть запускать, осматривать и выкидывать коробки.


Попробуй сам

  1. Запусти docker run hello-world ещё раз. Обрати внимание: строчек про загрузку (Pulling) больше нет — коробка уже скачана и лежит на машине. Почему так? Объясни себе одной фразой.
  2. Зайди в alpine: docker run -it alpine sh. Внутри выполни whoami (узнаешь, под кем ты внутри) и hostname (имя «машины» внутри коробки). Затем exit.
  3. Запусти контейнер с осмысленным именем: docker run --name proba -it alpine sh, осмотрись и выйди. Теперь найди его в docker ps -a — там должно быть имя proba вместо случайного.
  4. Загляни в docker ps -a и посчитай, сколько остановленных контейнеров у тебя накопилось за урок.

Проверка знанийKnowledge check
Ты выполнил docker run -it alpine sh, внутри сделал ls / и увидел не свои файлы, а чужую файловую систему, потом exit. После этого docker ps показывает пустой список, а docker ps -a — этот контейнер со статусом Exited. Объясни, что здесь произошло на каждом шаге.
ОтветAnswer
Команда docker run -it alpine sh скачала (если ещё не было) образ alpine — сложенную «коробку» с крошечным Linux — и создала из него работающий контейнер, запустив внутри командную оболочку sh. Флаги -it подключили твою клавиатуру и дали интерактивную сессию, поэтому приглашение сменилось на приглашение уже внутри контейнера. ls / показал файлы не твоего компьютера, а изолированной файловой системы внутри коробки: у контейнера свой отдельный набор файлов и своя ОС (Alpine), даже если хост — Mac или Windows. Это и есть изоляция «коробки со своим миром». Команда exit завершила оболочку sh; раз главная программа контейнера закончилась, сам контейнер остановился. Поэтому docker ps (показывает только запущенные) теперь пуст. Но контейнер не исчез — он просто в состоянии Exited, поэтому docker ps -a (показывает все, включая остановленные) всё ещё его видит. Это иллюстрирует разницу: ps — только живые контейнеры, ps -a — все, включая завершённые.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Зачем вообще запускают docker run hello-world?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 3