Зачем контейнеры: на пальцах
Ты уже поставил Docker на Ступени 0. Прежде чем нырять в команды и тем более во внутренности, давай разберёмся с самым главным вопросом: зачем эта штука вообще нужна? Без ответа на него весь курс превратится в зубрёжку команд. А с ответом каждая команда дальше будет ложиться на понятную картинку.
В этом уроке — никакого кода и никаких терминов вроде namespaces. Только интуиция. Команды начнутся в третьем уроке.
Боль, которую решают контейнеры
Представь обычную ситуацию. Ты написал программу. На твоём ноутбуке она запускается и работает. Ты радостно отправляешь её коллеге — и у него она падает с ошибкой. Вы оба смотрите на один и тот же код и не понимаете, в чём дело.
Знаменитая фраза, которую произносят в этот момент: «Ну у меня же работает!» (по-английски — “it works on my machine”).
Почему так выходит? Потому что программа почти никогда не существует сама по себе. Чтобы запуститься, ей нужно окружение:
- определённая версия языка (например, Python 3.11, а у коллеги стоит 3.9);
- набор библиотек нужных версий;
- системные пакеты и утилиты;
- переменные окружения, настройки, конфиги;
- иногда — конкретная версия операционной системы.
У тебя на машине всё это сложилось как надо — за месяцы работы ты доустанавливал нужное, не замечая этого. У коллеги набор чуть другой. И программа, которая зависит от этого окружения, ведёт себя по-разному. Это и есть корень боли.
Та же боль повторяется на каждом шаге:
- код переезжает с ноутбука разработчика на тестовый сервер;
- с тестового — на боевой (production);
- новый человек в команде полдня настраивает машину, чтобы просто запустить проект;
- проект работал год назад, а сейчас собрать его заново — целое приключение.
Везде одна и та же причина: окружение в одном месте не такое, как в другом.
Идея: упаковать приложение вместе с окружением
А что если положить приложение и всё его окружение в одну герметичную коробку? Чтобы внутри коробки уже лежали: сама программа, нужная версия языка, все библиотеки, все настройки. И чтобы эту коробку можно было перенести куда угодно — она везде раскрывается одинаково.
Тогда фраза «у меня работает» превращается в «работает везде одинаково», потому что везде запускается одна и та же коробка, а не «код плюс случайное окружение конкретной машины».
Вот эта коробка и есть контейнер.
Обычный подход:
[ код ] + окружение машины (разное везде) = работает по-разному
Контейнер:
[ код + окружение внутри коробки ] = работает одинаково везде
Аналогия: транспортный контейнер
У слова «контейнер» неслучайное происхождение. Вспомни огромные металлические ящики, которые возят на кораблях, поездах и грузовиках — морские транспортные контейнеры.
До их изобретения грузы возили как попало: мешки, бочки, ящики разных форм. Каждую перевалку груза в порту делали вручную, это было медленно, дорого и ненадёжно. Потом придумали стандартный ящик одного размера. И всё изменилось:
- внутрь можно положить что угодно — бананы, мебель, машины, электронику;
- снаружи все ящики одинаковые — кран, корабль, поезд и грузовик не интересует содержимое, они работают со стандартной коробкой;
- ящик грузят и перегружают одинаково, неважно, что внутри.
Программный контейнер устроен по той же идее:
- внутри — твоё приложение и всё, что ему нужно для работы (его «груз»);
- снаружи — стандартная форма, с которой Docker умеет работать одинаково;
- любой компьютер, где стоит Docker (твой ноутбук, сервер, облако), умеет «погрузить» и запустить эту коробку, не вникая в то, что у неё внутри.
[!tip] Запомни картинку: контейнер — это стандартная коробка. Снаружи все коробки одинаковые (поэтому их легко возить), а внутри у каждой свой груз (твоё приложение со своим окружением).
Что значит «изолированная коробка»
Важное слово — изолированная. Контейнер не просто хранит приложение, он ещё и отделяет его от остальной системы и от других контейнеров.
Представь коробку с собственным маленьким миром внутри:
- у приложения внутри своя файловая система — оно видит свои файлы и не лезет в чужие;
- ему кажется, что оно одно на машине, хотя рядом могут крутиться десятки других контейнеров;
- что бы ни происходило внутри одной коробки, соседние коробки этого не замечают.
Из этого получается несколько приятных свойств:
- Чисто. Контейнер не засоряет твою основную систему. Поставил, попробовал, удалил коробку — и на машине не осталось следов.
- Безопасно для экспериментов. Можно запустить что угодно внутри коробки, не боясь сломать ноутбук.
- Параллельно. Можно держать рядом несколько версий одной программы — каждая в своей коробке, они не мешают друг другу.
[!note] «Изолированная» здесь не означает «защищённая от хакеров как сейф». Это про то, что у приложения внутри свой отдельный мирок, отделённый от остальной системы. Насколько прочны эти стенки и как они устроены — разберём гораздо позже. Сейчас достаточно интуиции про коробку со своим миром внутри.
Зачем это лично тебе
Звучит абстрактно? Вот конкретные ситуации, в которых контейнеры выручают почти каждый день:
- Запустить базу данных за минуту. Нужен Postgres или Redis, чтобы что-то попробовать? Одна команда — и он работает в коробке. Наигрался — удалил коробку, в системе ничего не осталось.
- Одинаковое окружение у всей команды. Все запускают одни и те же коробки, и проект ведёт себя одинаково у каждого, неважно, Mac у человека или Linux.
- Спокойно пробовать новое. Хочешь новую версию языка или странную утилиту — запусти в коробке. Не понравилось — удалил, основная система чистая.
- Перенос на сервер без сюрпризов. То, что работало в коробке у тебя, работает в той же коробке на сервере.
Всё это — следствия одной идеи: приложение и его окружение едут вместе, в стандартной изолированной коробке.
Попробуй сам
Кода пока не будет — это упражнение на понимание. Возьми лист бумаги или заметку и ответь своими словами:
- Вспомни случай (свой или из рассказов), когда что-то «работало у одного и не работало у другого». В чём, скорее всего, была причина? Запиши одной фразой.
- Нарисуй простую картинку: большой прямоугольник — это коробка-контейнер. Внутри подпиши, что в ней лежит, чтобы приложение точно запустилось (подсказка: сама программа и ещё минимум три вещи из этого урока).
- Объясни вслух, как будто другу: чем «возить стандартные коробки» удобнее, чем «возить груз как попало». Свяжи это с программами.
Если смог сделать пункт 3 без подглядывания — главную идею курса ты уже ухватил.