Docker & Containers — the friendly introDocker и контейнеры — дружелюбное введение

Package your code with everything it needs to run, so it behaves the same on your laptop, in CI, and in production. Plain words. Упакуй код вместе со всем, что ему нужно для запуска, чтобы он вёл себя одинаково на ноутбуке, в CI и в проде. Простыми словами.
🐳 Docker ☸️ Kubernetes 🚀 Flyte

1. What is Docker?1. Что такое Docker?

Docker is a tool for containers. A container packages your application together with everything it needs to run — code, runtime, libraries, system tools — into one isolated, portable unit. That unit runs the same way anywhere Docker is installed, regardless of what's on the host machine.

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

AnalogyАналогия A container is a shipping container for software. Before standardized containers, loading a ship meant repacking every odd-shaped crate. Now everything goes in identical boxes that any crane, truck or ship can handle. Docker does that for code: one standard box that runs anywhere. Контейнер — это морской контейнер для софта. До стандартных контейнеров загрузка корабля означала перепаковку каждого ящика странной формы. Теперь всё едет в одинаковых коробках, которые поднимет любой кран, грузовик или корабль. Docker делает то же для кода: одна стандартная коробка, запускающаяся где угодно.
One lineОдной строкой Docker = "it works on my machine" → it works on every machine, by shipping the whole environment, not just the code. Docker = «у меня же работает» → работает на любой машине, потому что отгружается всё окружение, а не только код.

2. Why does it exist?2. Зачем он нужен?

The classic problem: code runs on the developer's laptop but breaks in production because the Python version, a library, or a system package differs. Docker kills that whole class of bugs:

Классическая проблема: код работает на ноутбуке разработчика, но падает в проде, потому что отличается версия Python, библиотека или системный пакет. Docker убивает целый класс таких багов:

  • Consistency. The exact same image runs in dev, CI, and prod. No "works on my machine".
  • Isolation. Each container has its own dependencies; two apps needing different Python versions coexist peacefully.
  • Portability. Build once, run on any host (laptop, server, any cloud) with Docker.
  • Lightweight & fast. Containers share the host OS kernel, so they start in seconds and use far less than a full virtual machine.
  • Консистентность. Один и тот же образ бежит в dev, CI и проде. Никаких «у меня работает».
  • Изоляция. У каждого контейнера свои зависимости; два приложения с разными версиями Python мирно сосуществуют.
  • Переносимость. Собери один раз, запускай на любом хосте (ноутбук, сервер, любое облако) с Docker.
  • Легковесность и скорость. Контейнеры используют ядро ОС хоста, поэтому стартуют за секунды и тратят куда меньше, чем полноценная виртуальная машина.
The core promiseГлавное обещание Build the environment once, freeze it into an image, and that frozen environment is what runs everywhere — reproducibly. Собери окружение один раз, заморозь его в образ, и именно это замороженное окружение бежит везде — воспроизводимо.

3. Core concepts3. Ключевые понятия

① Image① Image (образ)

A read-only template: the frozen snapshot of your app + its environment. Built from a Dockerfile. Think "the recipe baked into a ready-to-ship package".

Read-only шаблон: замороженный снимок приложения + его окружения. Собирается из Dockerfile. Думай «рецепт, запечённый в готовый к отгрузке пакет».

② Container② Container (контейнер)

A running instance of an image. One image → many containers, like one class → many objects. Containers are disposable: you start, stop, and throw them away.

Запущенный экземпляр образа. Один образ → много контейнеров, как один класс → много объектов. Контейнеры одноразовые: запускаешь, останавливаешь и выбрасываешь.

③ Dockerfile③ Dockerfile

A text recipe describing how to build the image, step by step: base image, copy code, install deps, set the start command. Each line becomes a cached layer.

Текстовый рецепт, описывающий сборку образа по шагам: базовый образ, копирование кода, установка зависимостей, команда запуска. Каждая строка становится кэшируемым слоем (layer).

④ Registry④ Registry (реестр)

Where images are stored and shared — Docker Hub, AWS ECR, GCP Artifact Registry. You push an image up and pull it down elsewhere, like GitHub for images.

Где хранятся и раздаются образы — Docker Hub, AWS ECR, GCP Artifact Registry. Ты делаешь push образа наверх и pull в другом месте — как GitHub для образов.

⑤ Volumes & ports⑤ Volumes и порты

Containers are ephemeral, so data written inside disappears when they're removed. Volumes persist data outside the container; port mapping exposes a container's port to the host.

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

⑥ Docker Compose⑥ Docker Compose

A tool to define and run multiple containers together (e.g. app + database + queue) from one YAML file. Great for local dev of a multi-service stack.

Инструмент, чтобы описать и запустить несколько контейнеров вместе (например приложение + база + очередь) из одного YAML-файла. Отлично для локальной разработки многосервисного стека.

4. A minimal example4. Минимальный пример

A Dockerfile for a small Python data job, then the two commands to build and run it.

Dockerfile для небольшого Python-джоба по данным, затем две команды, чтобы собрать и запустить его.

# Dockerfile
FROM python:3.12-slim          # base image (a frozen mini-OS + Python)
WORKDIR /app                    # working dir inside the container
COPY requirements.txt .         # copy deps first → layer caching
RUN pip install -r requirements.txt
COPY . .                        # copy the rest of the code
CMD ["python", "pipeline.py"]  # what runs when the container starts
# build an image named "my-pipeline"
docker build -t my-pipeline .

# run a container from it
docker run --rm my-pipeline
Why COPY requirements first?Почему COPY requirements первым? Each Dockerfile line is a cached layer. By copying requirements.txt and installing deps before copying your code, a code change doesn't re-run the slow pip install — only the layers after the change rebuild. This caching trick is a classic interview point. Каждая строка Dockerfile — кэшируемый слой. Копируя requirements.txt и ставя зависимости до копирования кода, изменение кода не перезапускает медленный pip install — пересобираются только слои после изменения. Этот трюк с кэшем — классический вопрос на интервью.

5. Containers vs Virtual Machines5. Контейнеры vs виртуальные машины

Both isolate workloads, but at different levels. This is one of the most common Docker interview questions.

Оба изолируют нагрузки, но на разном уровне. Это один из самых частых вопросов про Docker на интервью.

Virtual MachineContainer (Docker)
Isolates atHardware level (full guest OS)Process level (shares host kernel)
SizeGigabytes (whole OS)Megabytes (just app + deps)
StartupMinutes (boots an OS)Seconds (starts a process)
OverheadHeavy (hypervisor + N OSes)Light (one kernel shared)
Isolation strengthStronger (full separation)Weaker (shared kernel)
Виртуальная машинаКонтейнер (Docker)
Изолирует на уровнеЖелеза (полная гостевая ОС)Процесса (общее ядро хоста)
РазмерГигабайты (целая ОС)Мегабайты (только приложение + зависимости)
СтартМинуты (грузит ОС)Секунды (запускает процесс)
Накладные расходыТяжёлые (гипервизор + N ОС)Лёгкие (одно общее ядро)
Сила изоляцииСильнее (полное разделение)Слабее (общее ядро)
One lineОдной строкой A VM virtualizes a whole machine; a container virtualizes just an app's environment on a shared kernel. Containers trade a bit of isolation for huge gains in speed and density. ВМ виртуализирует целую машину; контейнер виртуализирует только окружение приложения на общем ядре. Контейнеры жертвуют чуть-чуть изоляцией ради огромного выигрыша в скорости и плотности.

6. Why a data engineer cares6. Почему это важно дата-инженеру

  • Reproducible pipelines. Pin Python + libraries in an image so a job runs identically today and in a year.
  • It's the unit of work for orchestrators. Flyte, Airflow (KubernetesExecutor), and Kubernetes all run your task as a container.
  • Clean local dev. Spin up Postgres, Kafka, or Spark locally with one docker compose up — no messy host installs.
  • CI/CD. Tests and builds run in containers for a clean, consistent environment every time.
  • Dependency hell, solved. Conflicting library versions across jobs simply don't collide — each lives in its own image.
  • Воспроизводимые пайплайны. Зафиксируй Python + библиотеки в образе, чтобы джоб бежал одинаково сегодня и через год.
  • Это единица работы для оркестраторов. Flyte, Airflow (KubernetesExecutor) и Kubernetes запускают твою таску как контейнер.
  • Чистая локальная разработка. Подними Postgres, Kafka или Spark локально одной docker compose up — без грязных установок на хост.
  • CI/CD. Тесты и сборки бегут в контейнерах ради чистого консистентного окружения каждый раз.
  • Ад зависимостей решён. Конфликтующие версии библиотек между джобами просто не сталкиваются — каждый в своём образе.
Docker → KubernetesDocker → Kubernetes Docker makes one container. When you need to run thousands across many machines — with restarts, scaling and networking — you need an orchestrator: that's Kubernetes. Docker делает один контейнер. Когда нужно запускать тысячи на множестве машин — с рестартами, масштабированием и сетью — нужен оркестратор: это Kubernetes.

7. Quick self-check7. Быстрая самопроверка

Answer in your head, then tap to flip.Ответь про себя, потом нажми, чтобы перевернуть.

Image vs Container?Image vs Container?
tapнажми
An image is the read-only template (frozen app + env). A container is a running instance of it. One image → many containers (like class → objects).Image — read-only шаблон (замороженное приложение + окружение). Container — его запущенный экземпляр. Один образ → много контейнеров (как класс → объекты).
What problem does Docker solve?Какую проблему решает Docker?
tapнажми
"Works on my machine" inconsistencies. It ships the whole environment (runtime, libs, tools) so code runs identically in dev, CI and prod.Несоответствия «у меня же работает». Он отгружает всё окружение (рантайм, библиотеки, утилиты), чтобы код бежал одинаково в dev, CI и проде.
Container vs VM — key difference?Контейнер vs ВМ — ключевая разница?
tapнажми
A VM bundles a full guest OS (GBs, boots in minutes). A container shares the host kernel and packs only the app + deps (MBs, starts in seconds).ВМ несёт полную гостевую ОС (ГБ, грузится минутами). Контейнер использует ядро хоста и пакует только приложение + зависимости (МБ, стартует за секунды).
What is a Dockerfile, and what's a layer?Что такое Dockerfile и что такое слой?
tapнажми
A recipe to build an image, step by step. Each instruction becomes a cached layer — unchanged layers are reused, so rebuilds are fast.Рецепт сборки образа по шагам. Каждая инструкция — кэшируемый слой; неизменившиеся слои переиспользуются, поэтому пересборка быстрая.
Why copy requirements before code?Зачем копировать requirements до кода?
tapнажми
Layer caching: installing deps in an earlier layer means a code change doesn't re-trigger the slow pip install — only later layers rebuild.Кэш слоёв: установка зависимостей в раннем слое означает, что изменение кода не запускает заново медленный pip install — пересобираются только поздние слои.
Containers are ephemeral — how to keep data?Контейнеры эфемерны — как сохранить данные?
tapнажми
Use volumes — storage mounted outside the container's lifecycle, so data survives when the container is removed or replaced.Использовать volumes — хранилище вне жизненного цикла контейнера, чтобы данные пережили удаление или замену контейнера.