Learning Platform
Глоссарий Troubleshooting
Урок 02.01 · 15 мин
Начальный
dockercontainersintrointuition

Зачем контейнеры: на пальцах

Ты уже поставил Docker на Ступени 0. Прежде чем нырять в команды и тем более во внутренности, давай разберёмся с самым главным вопросом: зачем эта штука вообще нужна? Без ответа на него весь курс превратится в зубрёжку команд. А с ответом каждая команда дальше будет ложиться на понятную картинку.

В этом уроке — никакого кода и никаких терминов вроде namespaces. Только интуиция. Команды начнутся в третьем уроке.


Боль, которую решают контейнеры

Представь обычную ситуацию. Ты написал программу. На твоём ноутбуке она запускается и работает. Ты радостно отправляешь её коллеге — и у него она падает с ошибкой. Вы оба смотрите на один и тот же код и не понимаете, в чём дело.

Знаменитая фраза, которую произносят в этот момент: «Ну у меня же работает!» (по-английски — “it works on my machine”).

Почему так выходит? Потому что программа почти никогда не существует сама по себе. Чтобы запуститься, ей нужно окружение:

  • определённая версия языка (например, Python 3.11, а у коллеги стоит 3.9);
  • набор библиотек нужных версий;
  • системные пакеты и утилиты;
  • переменные окружения, настройки, конфиги;
  • иногда — конкретная версия операционной системы.

У тебя на машине всё это сложилось как надо — за месяцы работы ты доустанавливал нужное, не замечая этого. У коллеги набор чуть другой. И программа, которая зависит от этого окружения, ведёт себя по-разному. Это и есть корень боли.

Та же боль повторяется на каждом шаге:

  • код переезжает с ноутбука разработчика на тестовый сервер;
  • с тестового — на боевой (production);
  • новый человек в команде полдня настраивает машину, чтобы просто запустить проект;
  • проект работал год назад, а сейчас собрать его заново — целое приключение.

Везде одна и та же причина: окружение в одном месте не такое, как в другом.


Идея: упаковать приложение вместе с окружением

А что если положить приложение и всё его окружение в одну герметичную коробку? Чтобы внутри коробки уже лежали: сама программа, нужная версия языка, все библиотеки, все настройки. И чтобы эту коробку можно было перенести куда угодно — она везде раскрывается одинаково.

Тогда фраза «у меня работает» превращается в «работает везде одинаково», потому что везде запускается одна и та же коробка, а не «код плюс случайное окружение конкретной машины».

Вот эта коробка и есть контейнер.

Обычный подход:
  [ код ]  +  окружение машины (разное везде)  =  работает по-разному

Контейнер:
  [ код + окружение внутри коробки ]  =  работает одинаково везде

Аналогия: транспортный контейнер

У слова «контейнер» неслучайное происхождение. Вспомни огромные металлические ящики, которые возят на кораблях, поездах и грузовиках — морские транспортные контейнеры.

До их изобретения грузы возили как попало: мешки, бочки, ящики разных форм. Каждую перевалку груза в порту делали вручную, это было медленно, дорого и ненадёжно. Потом придумали стандартный ящик одного размера. И всё изменилось:

  • внутрь можно положить что угодно — бананы, мебель, машины, электронику;
  • снаружи все ящики одинаковые — кран, корабль, поезд и грузовик не интересует содержимое, они работают со стандартной коробкой;
  • ящик грузят и перегружают одинаково, неважно, что внутри.

Программный контейнер устроен по той же идее:

  • внутри — твоё приложение и всё, что ему нужно для работы (его «груз»);
  • снаружи — стандартная форма, с которой Docker умеет работать одинаково;
  • любой компьютер, где стоит Docker (твой ноутбук, сервер, облако), умеет «погрузить» и запустить эту коробку, не вникая в то, что у неё внутри.

[!tip] Запомни картинку: контейнер — это стандартная коробка. Снаружи все коробки одинаковые (поэтому их легко возить), а внутри у каждой свой груз (твоё приложение со своим окружением).


Что значит «изолированная коробка»

Важное слово — изолированная. Контейнер не просто хранит приложение, он ещё и отделяет его от остальной системы и от других контейнеров.

Представь коробку с собственным маленьким миром внутри:

  • у приложения внутри своя файловая система — оно видит свои файлы и не лезет в чужие;
  • ему кажется, что оно одно на машине, хотя рядом могут крутиться десятки других контейнеров;
  • что бы ни происходило внутри одной коробки, соседние коробки этого не замечают.

Из этого получается несколько приятных свойств:

  • Чисто. Контейнер не засоряет твою основную систему. Поставил, попробовал, удалил коробку — и на машине не осталось следов.
  • Безопасно для экспериментов. Можно запустить что угодно внутри коробки, не боясь сломать ноутбук.
  • Параллельно. Можно держать рядом несколько версий одной программы — каждая в своей коробке, они не мешают друг другу.

[!note] «Изолированная» здесь не означает «защищённая от хакеров как сейф». Это про то, что у приложения внутри свой отдельный мирок, отделённый от остальной системы. Насколько прочны эти стенки и как они устроены — разберём гораздо позже. Сейчас достаточно интуиции про коробку со своим миром внутри.


Зачем это лично тебе

Звучит абстрактно? Вот конкретные ситуации, в которых контейнеры выручают почти каждый день:

  • Запустить базу данных за минуту. Нужен Postgres или Redis, чтобы что-то попробовать? Одна команда — и он работает в коробке. Наигрался — удалил коробку, в системе ничего не осталось.
  • Одинаковое окружение у всей команды. Все запускают одни и те же коробки, и проект ведёт себя одинаково у каждого, неважно, Mac у человека или Linux.
  • Спокойно пробовать новое. Хочешь новую версию языка или странную утилиту — запусти в коробке. Не понравилось — удалил, основная система чистая.
  • Перенос на сервер без сюрпризов. То, что работало в коробке у тебя, работает в той же коробке на сервере.

Всё это — следствия одной идеи: приложение и его окружение едут вместе, в стандартной изолированной коробке.


Попробуй сам

Кода пока не будет — это упражнение на понимание. Возьми лист бумаги или заметку и ответь своими словами:

  1. Вспомни случай (свой или из рассказов), когда что-то «работало у одного и не работало у другого». В чём, скорее всего, была причина? Запиши одной фразой.
  2. Нарисуй простую картинку: большой прямоугольник — это коробка-контейнер. Внутри подпиши, что в ней лежит, чтобы приложение точно запустилось (подсказка: сама программа и ещё минимум три вещи из этого урока).
  3. Объясни вслух, как будто другу: чем «возить стандартные коробки» удобнее, чем «возить груз как попало». Свяжи это с программами.

Если смог сделать пункт 3 без подглядывания — главную идею курса ты уже ухватил.


Проверка знанийKnowledge check
Коллега запустил твой код и получил ошибку, хотя у тебя всё работает. Объясни простыми словами, в чём, скорее всего, причина, и как контейнер решает эту проблему.
ОтветAnswer
Причина почти всегда не в коде, а в окружении. Программа зависит от версии языка, набора библиотек, системных пакетов и настроек. У тебя на машине всё это сложилось как надо за время работы, а у коллеги набор чуть другой — другая версия Python, не та библиотека, другой конфиг. Один и тот же код в разных окружениях ведёт себя по-разному. Отсюда классическое «у меня работает». Контейнер решает это так: приложение упаковывается вместе со всем своим окружением в одну стандартную изолированную коробку. Везде запускается не «код плюс случайное окружение машины», а одна и та же коробка целиком. Поэтому она ведёт себя одинаково и у тебя, и у коллеги, и на сервере — «работает у меня» превращается в «работает везде одинаково».

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

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. В чём чаще всего настоящая причина ситуации «у меня работает, а у тебя нет»?

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

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

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

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