Docker-контейнер как ланч-бокс: код, зависимости и ОС упакованы вместе — запускается на ноутбуке, сервере и в облаке

Docker упаковывает приложение и его окружение в изолированный контейнер, чтобы оно работало одинаково везде. Разбираемся, как установить Docker, написать первый Dockerfile и запустить проект локально — без боли и «works on my machine».

Знакомая ситуация: ты отправляешь код коллеге, а у него ничего не запускается. «На моей машине всё работает», — говоришь ты. И это правда. На твоей машине установлен Python 3.11, определённая версия библиотеки, нужные переменные окружения и системные пакеты. У коллеги — Python 3.8, другие версии зависимостей и ничего не работает.

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

Содержание

  1. Что такое Docker и зачем он разработчику
  2. Установка Docker и первый запуск
  3. Ключевые понятия: образ, контейнер, Dockerfile, реестр
  4. Пишем первый Dockerfile
  5. Файл .dockerignore: не тащи лишнее в образ
  6. Запускаем контейнер и пробрасываем порты
  7. Данные в контейнере: зачем нужны volumes
  8. Docker Compose: управляем несколькими сервисами
  9. Типичные ошибки новичков
  10. Что дальше
  11. Шпаргалка: основные команды Docker
  12. Заключение

Ты уже освоил терминал и Git. Теперь пора научиться упаковывать свои проекты так, чтобы они запускались везде и всегда. К концу этой статьи ты установишь Docker, напишешь Dockerfile, соберёшь образ, запустишь контейнер и опишешь многоконтейнерное приложение в Docker Compose. Это не магия. Это навык. И он проще, чем кажется.

Статья получилась насыщенной. Если тебе нужен быстрый старт — пройди разделы 1, 4 и 6. Остальное добирай по мере необходимости. Docker Compose и volumes подождут, пока ты не освоишь базу.

Что такое Docker и зачем он разработчику

Представь ланч-бокс. Ты собираешь его утром: кладёшь обед, приборы, салфетку. Закрываешь крышку. Теперь этот ланч-бокс можно открыть где угодно — в офисе, в парке, в поезде. Содержимое будет одинаковым. Docker-контейнер — это такой же ланч-бокс для твоего приложения. Внутри него: код, зависимости, системные библиотеки, настройки. Всё, что нужно для работы.

Чем контейнер отличается от виртуальной машины? Виртуальная машина — это целый компьютер внутри твоего компьютера. Ей нужна своя операционная система, свои драйверы, своё ядро. Она тяжёлая и медленно запускается. Контейнер — легче. Он использует ядро твоей операционной системы и изолирует только пользовательское пространство. Запускается за секунды. Занимает мегабайты, а не гигабайты.

Для разработчика Docker решает три главные проблемы. Первая — воспроизводимость окружения. Код запускается одинаково у всех членов команды. Вторая — изоляция проектов. Один проект требует Python 3.8, другой — Python 3.11. С Docker они не конфликтуют. Третья — лёгкое развёртывание. Запустил контейнер — приложение работает. Не нужно настраивать сервер вручную.

Что мы узнали: Docker упаковывает приложение и его окружение в изолированный контейнер — как ланч-бокс. Контейнеры легче виртуальных машин: они используют ядро хостовой ОС и запускаются за секунды. Это решает проблему «на моей машине работает» и позволяет изолировать проекты с разными зависимостями.
Проверь себя: чем контейнер отличается от виртуальной машины? Почему контейнер запускается быстрее?
Метафора ланч-бокса: внутри контейнера — иконки приложения, библиотек и ОС, снаружи — ноутбук, сервер и облако.
Docker-контейнер как ланч-бокс: упаковал один раз — запускаешь где угодно

Установка Docker и первый запуск

Docker работает на Windows, macOS и Linux. Самый простой способ установки на Windows и macOS — Docker Desktop. Это приложение с графическим интерфейсом, которое включает всё необходимое. На Linux Docker ставится через пакетный менеджер.

Windows:

  1. Скачай Docker Desktop с официального сайта.
  2. Запусти установщик и следуй инструкциям.
  3. После установки перезагрузи компьютер.
  4. Открой терминал (PowerShell или CMD) и введи: docker --version

macOS:

  1. Скачай Docker Desktop для Mac (выбери версию для твоего процессора — Intel или Apple Silicon).
  2. Перетащи иконку Docker в папку «Программы».
  3. Запусти Docker из Launchpad и дождись, пока он запустится.
  4. Открой терминал и введи: docker --version

Linux (Ubuntu/Debian):

  1. Обнови индекс пакетов: sudo apt update
  2. Установи Docker: sudo apt install docker.io
  3. Добавь своего пользователя в группу docker: sudo usermod -aG docker $USER
  4. Выйди из системы и войди снова (или введи newgrp docker).
  5. Проверь, что Docker запущен: systemctl status docker. Если статус не active — запусти: sudo systemctl start docker.
  6. Убедись, что ты в группе docker: id -nG. Если в списке нет docker — повтори шаг 3 и перезайди в систему.
  7. Проверь: docker --version
⚠️ Осторожно: виртуализация и WSL2. На Windows Docker Desktop требует включённой виртуализации в BIOS и установленного WSL2. Если после установки Docker не запускается — проверь, что виртуализация включена в настройках BIOS. Для этого открой «Диспетчер задач» → вкладка «Производительность» → посмотри на строку «Виртуализация». Если «Отключено» — перезагрузи компьютер, зайди в BIOS и включи Intel VT-x или AMD-V. WSL2 устанавливается автоматически при установке Docker Desktop, но если что-то пошло не так — выполни wsl --install в PowerShell от имени администратора.

Теперь самое важное — проверка. Выполни команду:

docker run hello-world

Если Docker установлен правильно, ты увидишь приветственное сообщение. Что сейчас произошло? Docker проверил, есть ли у тебя образ hello-world. Не нашёл — скачал его из Docker Hub. Создал контейнер из этого образа. Запустил его. Контейнер вывел сообщение и завершился. Ты только что запустил свой первый Docker-контейнер.

Что мы узнали: Docker Desktop — самый простой способ установки на Windows и macOS. На Linux Docker ставится через пакетный менеджер. Команда docker run hello-world проверяет, что всё работает: Docker скачивает образ, создаёт контейнер и запускает его.
Попробуй сам. Установи Docker и выполни docker run hello-world. Сделай скриншот успешного вывода — это доказательство, что Docker работает.
Сравнение виртуальной машины и контейнеров: слева несколько VM со своими гостевыми ОС, справа — контейнеры на общем движке Docker.
Контейнеры используют ядро хостовой ОС — поэтому они легче и быстрее виртуальных машин

Ключевые понятия: образ, контейнер, Dockerfile, реестр

В Docker есть четыре ключевых понятия. Сейчас разложим их по полочкам, используя нашу метафору ланч-бокса.

Dockerfile — это рецепт. Текстовый файл с инструкциями: что положить в ланч-бокс, в каком порядке, как настроить. Ты пишешь Dockerfile один раз, а использовать его можно бесконечно.

Образ (image) — это заготовка ланч-бокса. Готовый, собранный по рецепту, но ещё не используемый. Образ — это неизменяемый файл, из которого создаются контейнеры. Его можно сравнить с ISO-файлом или установочным диском.

Контейнер (container) — это открытый и работающий ланч-бокс. Запущенный экземпляр образа. Ты можешь запустить сколько угодно контейнеров из одного образа — так же, как запустить одну и ту же программу на разных компьютерах.

Реестр (registry) — это библиотека готовых рецептов и образов. Самый популярный — Docker Hub. Там лежат официальные образы Python, Node.js, PostgreSQL и тысяч других проектов. Когда ты выполняешь docker run python, Docker скачивает образ Python именно оттуда.

Что мы узнали: Dockerfile — рецепт. Образ — собранный по рецепту ланч-бокс. Контейнер — работающий ланч-бокс. Реестр — библиотека готовых образов. Эти четыре понятия — фундамент Docker.
Проверь себя: что хранится в Docker Hub? Чем образ отличается от контейнера?

Пишем первый Dockerfile

Хватит теории. Пишем Dockerfile. Мы возьмём Python и Flask — это лаконичный и понятный стек. Flask требует минимум кода для веб-приложения, поэтому мы сосредоточимся на Docker, а не на особенностях языка. Тот же подход работает для Node.js, Go, C++ и любого другого языка — меняется только синтаксис установки зависимостей.

Создай новую папку для проекта и в ней два файла. Первый — app.py:

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return 'Hello from Docker! 🐳'


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Второй файл — requirements.txt. В нём перечислены зависимости проекта:

flask==3.1.0

Теперь Dockerfile. Создай файл с именем Dockerfile (без расширения) в той же папке:

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 5000

CMD ["python", "app.py"]

Разберём каждую инструкцию. FROM python:3.11-slim — базовый образ. Мы берём официальный образ Python версии 3.11, вариант slim (облегчённый). Это как выбор основы для ланч-бокса. WORKDIR /app — задаём рабочую директорию внутри контейнера. Все последующие команды будут выполняться в этой папке. COPY requirements.txt . — копируем файл с зависимостями в контейнер. Точка означает текущую директорию (которую мы задали в WORKDIR).

RUN pip install --no-cache-dir -r requirements.txt — выполняем команду при сборке образа. Это Build-time инструкция: она срабатывает один раз, когда мы собираем образ. Флаг --no-cache-dir уменьшает размер образа — pip не сохраняет кэш установленных пакетов. COPY . . — копируем все остальные файлы проекта в контейнер.

EXPOSE 5000 — сообщаем, что контейнер будет слушать порт 5000. Это документация, а не действие. Порт нужно будет явно пробросить при запуске. CMD ["python", "app.py"] — команда, которая выполнится при запуске контейнера. Это Run-time инструкция: она срабатывает каждый раз при старте контейнера, а не при сборке образа.

А знаете ли вы? Тот же подход работает для любого языка. Для C++ вместо pip install ты будешь копировать исходники и запускать g++ или CMake в RUN, а вместо CMD ["python", "app.py"]CMD ["./my_app"]. Для Node.js — RUN npm install и CMD ["node", "index.js"]. Концепция Dockerfile остаётся той же.
⚠️ Осторожно: порядок инструкций и кэширование. Docker кэширует каждый слой образа. Если слой не изменился, Docker использует кэш и не выполняет инструкцию заново. Поэтому COPY requirements.txt . и RUN pip install идут до COPY . .. Если ты изменишь код приложения, но не менял зависимости — Docker возьмёт закэшированный слой с установленными пакетами и пересоберёт только последний слой с кодом. Сборка ускоряется в разы. Если поменять порядок и копировать всё сразу — pip install будет выполняться при каждом изменении любого файла.

Собираем образ. Открой терминал в папке с Dockerfile и выполни:

docker build -t my-first-app .

-t my-first-app — задаём имя образу (тег). . — путь к контексту сборки, то есть к папке с Dockerfile. Docker отправит содержимое этой папки демону и начнёт сборку. Ты увидишь, как выполняются шаги: Pulling image, Installing packages, Copying files. Через минуту образ готов.

Что мы узнали: Dockerfile — это текстовый файл с инструкциями. FROM задаёт базовый образ. RUN выполняется при сборке (Build-time). CMD выполняется при запуске (Run-time). Порядок инструкций важен для кэширования: сначала зависимости, потом код.
Попробуй сам. Создай папку проекта, напиши app.py, requirements.txt и Dockerfile. Собери образ командой docker build -t my-first-app ..
Анатомия Dockerfile: блок кода с цветовой подсветкой и выносками к каждой инструкции — FROM, WORKDIR, COPY, RUN, EXPOSE, CMD.
Каждая инструкция Dockerfile — это слой будущего образа

Файл .dockerignore: не тащи лишнее в образ

Когда ты выполняешь docker build ., Docker отправляет демону всю папку проекта. Всю. Включая виртуальное окружение, кэш, скрытые файлы, временные файлы редактора. Если не сказать Docker, что игнорировать — в образ попадёт мусор. Он замедлит сборку, раздует размер образа и может создать проблемы с безопасностью.

Решение — файл .dockerignore. Он работает как .gitignore: перечисляет файлы и папки, которые Docker должен игнорировать при сборке. Создай его в той же папке, что и Dockerfile:

__pycache__
*.pyc
*.pyo
.env
.venv
venv
.git
.gitignore
*.md
.DS_Store

Теперь Docker не потащит в образ виртуальное окружение, скомпилированные Python-файлы, системные файлы macOS и файлы вроде .env. Остановимся на .env отдельно. В этом файле часто хранятся пароли, API-ключи и токены. Их нельзя отправлять в общий доступ вместе с образом — это всё равно что оставить ключи от квартиры в почтовом ящике. .dockerignore защищает тебя от случайной утечки секретов.

Образ станет легче и безопаснее. Создавай .dockerignore сразу при старте проекта — это привычка профессионала.

Что мы узнали: .dockerignore исключает файлы из контекста сборки — как .gitignore для Git. Без него в образ попадает мусор: виртуальное окружение, кэш, секреты. Это замедляет сборку, раздувает образ и увеличивает поверхность атаки.

Запускаем контейнер и пробрасываем порты

Образ собран. Запускаем контейнер:

docker run -p 5000:5000 my-first-app

Что здесь происходит? docker run создаёт и запускает контейнер из образа my-first-app. -p 5000:5000 пробрасывает порт: первый порт — на твоей машине (host), второй — внутри контейнера. Это два разных порта. Первый ты открываешь в браузере. Второй слушает приложение внутри контейнера. Флаг -p связывает их — как дверь в изолированной комнате.

Открой браузер и перейди на http://localhost:5000. Ты увидишь «Hello from Docker! 🐳». Твоё приложение работает внутри контейнера и доступно снаружи.

Несколько полезных команд для управления контейнерами. docker ps — показать запущенные контейнеры. docker ps -a — показать все контейнеры, включая остановленные. docker logs <container_id> — посмотреть вывод контейнера (полезно для отладки). docker stop <container_id> — остановить. docker start <container_id> — запустить остановленный. docker rm <container_id> — удалить контейнер.

Что мы узнали: docker run -p host_port:container_port запускает контейнер и пробрасывает порт — связывает порт на хосте с портом в контейнере. Это два разных порта. docker ps -a показывает все контейнеры. docker logs помогает при отладке.
Проверь себя: что делает флаг -p в команде docker run -p 8080:5000 my-app? Какой порт нужно открыть в браузере?
Попробуй сам. Запусти контейнер с пробросом портов. Открой приложение в браузере. Останови контейнер через docker stop. Запусти снова через docker start. Посмотри логи через docker logs.

Данные в контейнере: зачем нужны volumes

У контейнеров есть важная особенность — они эфемерны. Всё, что создано внутри контейнера, исчезает при его удалении. Файлы, базы данных, загруженные пользователем картинки — всё пропадёт. Это не баг, а фича: контейнеры не должны хранить состояние. Но как быть, если данные всё-таки нужны?

Решение — volumes (тома). Это папки на твоём хосте, которые монтируются внутрь контейнера. Метафора: volumes — это USB-флешка, которую ты подключаешь к ланч-боксу. Данные на флешке живут отдельно от ланч-бокса. Выбросил ланч-бокс — флешка осталась.

Давай проверим. Создай на хосте папку data и положи в неё файл hello.txt с любым текстом. Теперь запусти контейнер с подключением этой папки:

macOS / Linux:

docker run -p 5000:5000 -v $(pwd)/data:/app/data my-first-app

Windows (PowerShell):

docker run -p 5000:5000 -v ${PWD}\data:/app/data my-first-app

Что произошло? Папка data с хоста примонтирована в контейнер по пути /app/data. Всё, что ты положишь в эту папку на хосте, появится в контейнере. И наоборот — файлы, созданные в /app/data внутри контейнера, сохранятся на хосте и переживут удаление контейнера.

Для реальных проектов вместо примонтированных папок используют именованные тома (managed volumes). Docker управляет ими сам, и они не привязаны к конкретному пути на хосте. Создать такой том: docker volume create mydata. Использовать: docker run -v mydata:/app/data my-app. Это надёжнее и переносимее.

Что мы узнали: контейнеры эфемерны — данные внутри исчезают при удалении. Volumes решают эту проблему: монтируют папку хоста или именованный том в контейнер. Это как USB-флешка для ланч-бокса — данные живут отдельно.
Попробуй сам. Создай папку data на хосте, положи туда файл. Запусти контейнер с подключением этой папки. Удали контейнер, создай новый — убедись, что файл сохранился.

Мини-чек-лист для самопроверки:

  1. Образ собран без ошибок.
  2. Контейнер запущен и слушает нужный порт.
  3. Приложение доступно по localhost:5000.
  4. Данные в volume сохраняются после удаления и пересоздания контейнера.

Docker Compose: управляем несколькими сервисами

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

Docker Compose позволяет описать все сервисы в одном YAML-файле и запустить их одной командой. Давай добавим Redis в наш проект — он будет хранить счётчик посещений. Обновлённый app.py:

from flask import Flask
import redis

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)


@app.route('/')
def hello():
    count = cache.incr('hits')
    return f'Hello from Docker! This page has been viewed {count} times. 🐳'


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Добавь redis==5.2.1 в requirements.txt. Теперь создай файл compose.yaml в корне проекта (современный стандарт; старые проекты могут использовать docker-compose.yml — оба имени работают):

services:
  web:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - redis

  redis:
    image: "redis:alpine"

Разберём. services — список сервисов. web — наше приложение, собирается из текущей папки (build: .). ports пробрасывает порт 5000. depends_on — управляет порядком запуска: сначала Redis, потом web.

⚠️ Осторожно: depends_on не гарантирует готовность. Флаг depends_on управляет порядком запуска контейнеров, но не ждёт, пока сервис внутри контейнера будет готов принимать соединения. Redis может стартовать, но ещё не слушать порт — и приложение упадёт с ошибкой соединения. Для продакшен-конфигураций используют healthcheck и логику повторных попыток в коде, либо скрипты ожидания вроде wait-for-it.

Запускаем всё одной командой (используем современный синтаксис Docker Compose V2 — без дефиса):

docker compose up

Docker Compose соберёт образ для web (если нужно), скачает Redis и запустит оба контейнера. Ты увидишь логи обоих сервисов в одном окне. Открой http://localhost:5000 — счётчик посещений растёт с каждым обновлением. Остановить всё: Ctrl+C или docker compose down в другом терминале.

А знаете ли вы? На старых системах, где Docker Compose установлен как отдельный плагин, может потребоваться синтаксис с дефисом: docker-compose up. Это устаревший формат, но он всё ещё работает. Современные версии Docker Desktop используют интегрированный docker compose (без дефиса).
Что мы узнали: Docker Compose описывает многоконтейнерное приложение в YAML-файле. depends_on задаёт порядок запуска, но не гарантирует готовность сервиса. docker compose up запускает все сервисы одной командой. docker compose down останавливает и удаляет всё.
Попробуй сам. Создай compose.yaml для связки Flask + Redis. Запусти docker compose up и проверь счётчик посещений. Останови всё через docker compose down.
Связка контейнеров в Docker Compose: три блока (App, Redis), соединённые стрелками, и файл compose.yaml как «дирижёр».
Docker Compose управляет несколькими контейнерами как единым приложением

Типичные ошибки новичков

Ошибки — это часть обучения. Вот шесть ситуаций, в которые попадает почти каждый новичок. Разбери их сейчас, чтобы не тратить часы на отладку потом.

Ошибка 1: порт уже занят. Симптом: Error: port is already allocated. Решение: найти процесс, который занял порт, и освободить его. На macOS/Linux: lsof -i :5000, затем kill -9 PID. На Windows: netstat -ano | findstr :5000, затем taskkill /PID PID /F. Либо просто используй другой порт на хосте: -p 5001:5000.

Ошибка 2: забыли пересобрать образ. Симптом: изменил код, перезапустил контейнер — ничего не поменялось. Решение: контейнер использует старый образ. Пересобери образ: docker build -t my-first-app ., затем удали старый контейнер и запусти новый. Или одной командой: docker compose up --build.

Ошибка 3: неправильный порядок в Dockerfile. Симптом: сборка занимает много времени при каждом изменении кода. Решение: кэш не работает, потому что порядок инструкций неправильный. Сначала копируй файл зависимостей и устанавливай пакеты, потом копируй код. Тогда при изменении кода пересобирается только последний слой.

Ошибка 4: localhost внутри контейнера. Симптом: приложение в контейнере не может подключиться к базе данных по localhost:5432. Решение: localhost внутри контейнера — это сам контейнер, а не хост и не другой контейнер. В Docker Compose используй имя сервиса: redis, db, web. Docker Compose автоматически создаёт сеть, где сервисы видят друг друга по именам.

Ошибка 5: огромный размер образа. Симптом: образ весит 1.5 ГБ, хотя приложение маленькое. Решение: проверь .dockerignore — возможно, в образ попали node_modules, .venv, кэш и системные файлы. Используй slim-версии базовых образов (python:3.11-slim вместо python:3.11). Удаляй временные файлы в том же слое RUN, где они создаются.

Ошибка 6: Permission denied при записи в volume. Симптом: приложение падает с ошибкой доступа при попытке записать файл в примонтированную папку. Решение: процессы внутри Linux-контейнера по умолчанию работают от root, но некоторые образы используют ограниченного пользователя. Файлы, созданные от root, могут быть недоступны пользователю на хосте. Либо запускай контейнер с флагом --user, либо настрой права в Dockerfile через RUN chown.

Что мы узнали: ошибки — это нормально. Главное — знать, как их читать и исправлять. Порт занят — освободи или используй другой. Забыл пересобрать — docker compose up --build. Неправильный порядок — кэш не работает. localhost — не тот, что ты думаешь. Большой образ — проверь .dockerignore. Permission denied — проверь права пользователя.
Проверь себя: ты изменил код, перезапустил контейнер, но ничего не изменилось. В чём причина и как исправить?

Что дальше

Ты установил Docker, написал Dockerfile, собрал образ, запустил контейнер, подключил volumes и описал многоконтейнерное приложение в Docker Compose. Это основа. С ней ты уже можешь упаковывать свои проекты и запускать их где угодно.

Куда двигаться дальше?

  • Оптимизация образов. Изучи multi-stage builds — они позволяют разделить сборку и рантайм, уменьшая итоговый образ в разы.
  • Docker Networks. Узнай, как работают сети в Docker: bridge, host, overlay. Это пригодится, когда сервисов станет больше двух.
  • Деплой в облако. Docker-образы можно развернуть в AWS ECS, Google Cloud Run, Azure Container Instances. Контейнер — это стандарт, который понимают все облака.

Полезные ресурсы:

Следующая статья по плану: «Алгоритмы и структуры данных: базовые понятия и примеры на Python/C++». Это фундамент для любого разработчика. Docker поможет тебе создать изолированное окружение для экспериментов с алгоритмами — без страха сломать системный Python.

Что мы узнали: Docker — это только начало. Впереди оптимизация образов, сети, деплой в облако. А пока — закрепи базу практикой. Следующая статья — алгоритмы и структуры данных.

Шпаргалка: основные команды Docker

Сохрани эту шпаргалку. Она выручит в первые недели работы с Docker. Команды сгруппированы по задачам.

Команда
Описание
Пример
docker build
Собрать образ из Dockerfile
docker build -t name .
docker run
Запустить контейнер из образа
docker run -p 5000:5000 name
docker ps
Показать запущенные контейнеры
docker ps
docker ps -a
Показать все контейнеры
docker ps -a
docker logs
Посмотреть вывод контейнера
docker logs container_id
docker stop
Остановить контейнер
docker stop container_id
docker start
Запустить остановленный контейнер
docker start container_id
docker rm
Удалить контейнер
docker rm container_id
docker rmi
Удалить образ
docker rmi my-first-app
docker volume create
Создать именованный том
docker volume create mydata
docker compose up
Запустить все сервисы
docker compose up
docker compose down
Остановить и удалить всё
docker compose down
Жизненный цикл Docker-образа: блок-схема Dockerfile → docker build → Образ → docker run → Контейнер.
Путь от рецепта до работающего приложения — четыре шага

Заключение

Ты больше не заложник фразы «на моей машине работает». Ты умеешь упаковывать свои проекты в Docker-контейнеры — герметичные ланч-боксы, которые запускаются везде одинаково. Установка Docker, написание Dockerfile, сборка образа, запуск контейнера, подключение volumes, Docker Compose — ты прошёл этот путь за одну статью.

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

Что сделать прямо сейчас? Собери образ своего pet-проекта. Упакуй его в Docker. Запусти. Покажи кому-нибудь результат. Докажи себе: «Я могу упаковать приложение и запустить его где угодно». Потому что это правда. Ты можешь.

Скачай PDF-шпаргалку «Docker для начинающего разработчика»

Внутри: расширенная таблица команд с флагами, анатомия Dockerfile с подробными комментариями, разбор 6 типичных ошибок и способов их решения, пример compose.yaml с пояснением каждого поля и чек-лист проверки проекта перед деплоем. Этого материала нет в статье — только в PDF.

Скачать PDF