С нуля до Junior DevOps в 2026 году. Часть 4. Docker: почему контейнеризация изменила разработку

от автора

Введение

В предыдущих статьях мы научились работать с Linux, освоили Bash, познакомились с Git и GitHub. Следующий шаг — Docker.

Если посмотреть на любую вакансию Junior DevOps, Backend-разработчика или SRE, среди требований почти всегда можно встретить Docker. Почему так?

Потому что Docker решил фундаментальную проблему: как гарантировать, что приложение будет работать одинаково на любом компьютере. Вот поэтому контейнеризация стала одним из важнейших изменений в современной разработке программного обеспечения.

В этой статье мы разберёмся:

  • что такое контейнеризация;

  • какие проблемы она решает;

  • почему виртуальных машин оказалось недостаточно;

  • как устроен Docker;

  • что такое Image и Container;

  • зачем нужен Docker Hub.


Почему виртуальных машин стало недостаточно?

До появления Docker большинство компаний использовали виртуальные машины (Virtual Machines, VM).

Идея была простой: вместо установки приложения напрямую на сервер создавалась отдельная виртуальная машина с собственной операционной системой. Внутрь устанавливались все необходимые зависимости, после чего запускалось приложение.

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

Но со временем проявились серьёзные недостатки.

1. Большой расход ресурсов

Каждая виртуальная машина содержит полноценную операционную систему. Это означает:

  • собственное ядро;

  • системные службы;

  • драйверы;

  • библиотеки;

  • фоновые процессы.

Даже если приложение занимает всего несколько десятков мегабайт, виртуальная машина может потреблять несколько гигабайт оперативной памяти и десятки гигабайт дискового пространства.


2. Медленный запуск

Запуск виртуальной машины не существенно отличается от включения обычного компьютера. Необходимо:

  • загрузить BIOS или UEFI;

  • запустить операционную систему;

  • дождаться запуска служб;

  • только после этого запустить приложение.


3. Масштабирование

Представьте интернет-магазин. В обычный день ему достаточно двух серверов. Но во время большой распродажи количество пользователей возрастает в десять раз.

Если используются виртуальные машины, необходимо создать множество новых экземпляров, установить операционную систему, настроить окружение и только потом запустить приложение. Это занимает слишком много времени.


Контейнеризация — другой подход

Docker не пытался сделать виртуальные машины быстрее. Он предложил совершенно другую модель. Вместо запуска отдельной операционной системы для каждого приложения контейнеры используют общее ядро хостовой операционной системы.

Контейнеры

Контейнеру не требуется собственная операционная система. Он использует ядро хостовой системы, но при этом остаётся изолированным от остальных контейнеров. Благодаря этому контейнеры:

  • занимают значительно меньше места;

  • требуют меньше оперативной памяти;

  • позволяют запускать значительно больше приложений на одном сервере.


Что такое контейнеризация?

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

  • само приложение;

  • необходимые библиотеки;

  • интерпретатор языка (например, Python или Node.js);

  • системные зависимости;

  • файлы конфигурации.

При этом контейнер не содержит полноценную операционную систему. Благодаря этому один и тот же контейнер можно запускать:

  • на устройстве разработчика;

  • на тестовом сервере;

  • в облаке;

  • в Kubernetes-кластере.

Если окружение Docker одинаковое, поведение приложения тоже будет одинаковым. Именно это и сделало контейнеризацию стандартом современной разработки.


Почему это важно для DevOps?

Для DevOps контейнеризация означает гораздо больше, чем просто удобный способ запуска программ. Она позволяет:

  • исключить различия между окружениями разработки и продакшена;

  • быстро разворачивать новые экземпляры приложений;

  • автоматизировать доставку программного обеспечения;

  • эффективно использовать ресурсы серверов;

  • сделать инфраструктуру предсказуемой и воспроизводимой.

Поэтому сегодня Docker стал одной из базовых технологий, которую ожидают увидеть в резюме практически любого Junior DevOps.


Архитектура Docker: что происходит после команды docker run

Сейчас, когда мы понимаем, зачем появилась контейнеризация, пора заглянуть «под капот» Docker. На первый взгляд всё выглядит очень просто. Мы выполняем команду:

docker run nginx

Через несколько секунд контейнер уже работает. Но за этой одной командой скрывается целая цепочка взаимодействий между несколькими компонентами Docker.

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


Docker Client

Docker Client — это программа, с которой работает пользователь. Когда вы вводите команду

docker ps

или

docker run ubuntu

вы взаимодействуете с Docker Client. Сам клиент практически ничего не делает самостоятельно. Его задача — принять введённую команду, преобразовать её в запрос к Docker API и отправить Docker Daemon.

Поэтому можно сказать:

Docker Client — это интерфейс управления Docker.


Docker Daemon

Самый важный компонент Docker называется Docker Daemon (dockerd). Это постоянно работающий системный процесс (служба), который отвечает за всю работу Docker.

Именно он:

  • создаёт контейнеры;

  • запускает и останавливает их;

  • скачивает образы;

  • создаёт сети;

  • управляет томами;

  • освобождает ресурсы после удаления контейнеров.

На Linux обычно можно проверить его состояние командой:

systemctl status docker

Если Daemon остановлен, команды вроде docker run или docker ps не смогут выполниться.


Docker Engine

Термин Docker Engine часто вызывает путаницу. Новички нередко считают, что Docker Engine и Docker Daemon — одно и то же. На самом деле Docker Engine — это вся платформа Docker, включающая:

  • Docker Daemon;

  • Docker API;

  • Docker Client.

Проще говоря:

  • Docker Client — принимает команды пользователя;

  • Docker Daemon — выполняет их;

  • Docker Engine — объединяет все эти компоненты в единую систему.

Следовательно, именно Docker Engine устанавливается на сервер или рабочую станцию.


Docker Registry

Для запуска контейнера сначала необходим образ. Возникает вопрос:

Где Docker берёт этот образ?

Ответ — из Docker Registry. Registry — это хранилище Docker-образов.

Самым известным публичным реестром является Docker Hub, но существуют и частные Registry, которые компании разворачивают внутри своей инфраструктуры. Когда вы выполняете:

docker run nginx

Docker сначала проверяет:

Есть ли образ nginx на локальном компьютере?

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


Что происходит после команды docker run?

Теперь рассмотрим весь процесс целиком. Допустим, вы выполнили:

docker run nginx

Docker выполняет следующие шаги.

Шаг 1. Клиент получает команду

Docker Client анализирует параметры команды и формирует запрос.

Шаг 2. Запрос отправляется Docker Daemon

Клиент обращается к Docker API. Daemon принимает запрос.

Шаг 3. Проверяется наличие образа

Daemon ищет образ nginx среди локальных образов. Если его нет, происходит загрузка из Registry.

Шаг 4. Создаётся контейнер

На основе образа создаётся новый контейнер. На этом этапе формируется:

  • собственная файловая система;

  • сетевой интерфейс;

  • процессы контейнера;

  • пространство имён (Namespaces);

  • ограничения ресурсов (при необходимости).

Важно понимать: контейнер не является копией виртуальной машины. Он использует ядро операционной системы хоста и изолируется средствами Linux.

Шаг 5. Запускается основной процесс

У каждого контейнера есть главный процесс (PID 1). Для образа nginx это веб-сервер Nginx. Пока этот процесс работает, контейнер считается запущенным. Если главный процесс завершится, контейнер тоже остановится.

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


Почему Docker работает так быстро?

Контейнер не устанавливает операционную систему заново. Не загружает отдельное ядро. Не запускает десятки системных служб. Он лишь создаёт изолированную среду и запускает нужный процесс.

Поэтому:

  • можно одновременно использовать десятки и сотни контейнеров на одном сервере;

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

Таким образом, это стало одной из причин стремительного распространения Docker.


Images и Containers: два понятия, без которых невозможно понять Docker

Сейчас разберём два самых важных понятия Docker — Image и Container. Их часто путают новички. На собеседованиях вопрос «Чем Image отличается от Container?» можно услышать практически так же часто, как вопрос про разницу между Git и GitHub.

На первый взгляд оба термина похожи, но они обозначают совершенно разные вещи.


Что такое Docker Image?

Docker Image (образ) — это неизменяемый шаблон, содержащий всё необходимое для запуска приложения. В образ входят:

  • само приложение;

  • библиотеки;

  • системные зависимости;

  • переменные окружения (при необходимости);

  • инструкции по запуску.

Сам по себе образ ничего не выполняет. Его можно описать как Image — это шаблон (или трафарет), а Container — работающий экземпляр этого шаблона.


Из чего состоит Image?

Допустим, необходимо создать образ для небольшого Python-приложения. В него могут входить:

Python 3.12├── Flask├── requests├── gunicorn├── app.py└── requirements.txt

Все эти файлы объединяются в единый Docker Image. После этого его можно запускать сколько угодно раз.


Почему Image неизменяемый?

Это один из главных принципов Docker. После создания образ считается неизменяемым (Immutable). Если нужно обновить приложение, обычно не изменяют существующий образ.

Создают новый.

Такой подход позволяет легко откатываться к предыдущим версиям, если после обновления возникли проблемы. Именно поэтому образы часто называют артефактами сборки (Build Artifacts): они создаются один раз и затем используются без изменений.


Что такое Docker Container?

Контейнер — это уже запущенный экземпляр образа.

Если образ — это ISO-файл Windows, контейнер — установленная и запущенная операционная система. Сам контейнер содержит:

  • работающий процесс;

  • собственное файловое пространство, изолированное от других контейнеров;

  • сетевой интерфейс;

  • таблицу процессов;

  • выделенные ресурсы.

Именно контейнер выполняет приложение.


Один Image — много Containers

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

Все контейнеры используют один и тот же образ, но работают независимо друг от друга. Если один контейнер завершится с ошибкой, остальные продолжат работу. Благодаря этому контейнеры удобно использовать для масштабирования приложений. Например, вместо одного экземпляра веб-приложения можно одновременно запустить десять одинаковых контейнеров.


Просмотреть работающие контейнеры

docker ps

Результат:

CONTAINER ID   IMAGE     STATUSd7e2ab3        nginx     Up 5 minutes

Если добавить параметр -a, Docker покажет и остановленные контейнеры.

docker ps -a

Запуск контейнера

Самая известная команда Docker:

docker run nginx

Если образ уже существует локально, Docker сразу создаст контейнер. Если нет — автоматически скачает его из Registry.


Остановить контейнер

docker stop <container_id>

Пример:

docker stop d7e2ab3

Контейнер перестанет выполнять процессы, но останется на компьютере. При необходимости его можно снова запустить.


Запуск остановленного контейнера

docker start <container_id>

Пример:

docker start d7e2ab3

Это быстрее, чем создавать новый контейнер.


Удаление контейнера

Если контейнер больше не нужен:

docker rm <container_id>

После удаления восстановить его уже нельзя. Если требуется сохранить состояние приложения, данные необходимо хранить во внешнем томе (Volume), о котором мы поговорим чуть дальше.


Что происходит при повторном запуске?

Допустим, выполнена команда:

docker run nginx

Docker создаёт первый контейнер. Если выполнить её ещё раз:

docker run nginx

создастся второй контейнер, а не будет использован первый. Это ещё одна распространённая ошибка новичков. Команда docker run не запускает существующий контейнер, а создаёт новый экземпляр образа.

Для запуска уже существующего контейнера используется:

docker start

Где хранятся образы?

Все локальные образы можно посмотреть командой:

docker images

Результат:

REPOSITORY   TAG       IMAGE IDnginx        latest    a13f2dubuntu       24.04     94fcb1python       3.12      e85c9d

Каждый образ имеет:

  • имя (Repository);

  • тег (Tag);

  • уникальный идентификатор (Image ID).


Docker Hub

Большинство разработчиков используют Docker Hub — официальный публичный реестр Docker-образов. Его можно представить как GitHub, только вместо исходного кода здесь хранятся Docker Images.

На Docker Hub находятся тысячи готовых образов:

  • Ubuntu;

  • Debian;

  • Alpine Linux;

  • Nginx;

  • Apache;

  • PostgreSQL;

  • Redis;

  • MySQL;

  • Python;

  • Node.js;

  • Java;

  • MongoDB и многих других.

Поэтому для запуска большинства популярных технологий достаточно одной команды.

К примеру:

docker run postgres

или

docker run redis

Docker автоматически загрузит нужный образ и подготовит контейнер.


Образы и теги

Практически каждый образ имеет несколько версий.

Например:

python:3.10python:3.11python:3.12python:latest

Часть после двоеточия называется тегом (Tag). Теги позволяют явно указать, какую версию необходимо использовать.

В реальных проектах рекомендуется указывать конкретную версию, python:3.12, а не latest. Это делает окружение воспроизводимым: через несколько месяцев или на другом сервере будет использована та же версия образа, а не новая, которая могла выйти за это время.

Однако до сих пор мы рассуждали только о готовых образах из Docker Hub. В реальной работе DevOps-инженеры гораздо чаще создают собственные Docker-образы, в которых уже содержится всё необходимое для запуска приложения. Именно для этого используется Dockerfile.

После этого мы разберём ещё две важные технологии Docker:

  • Volumes — позволяют сохранять данные вне контейнера;

  • Networks — обеспечивают взаимодействие контейнеров между собой.

Без понимания этих механизмов невозможно собрать даже простое многокомпонентное приложение.


Что такое Dockerfile?

Dockerfile — это обычный текстовый файл с инструкциями, по которым Docker создаёт новый образ. Dockerfile работает по принципу рецепта, где используются программные компоненты, а результатом становится готовый Docker Image.

Главное преимущество такого подхода — воспроизводимость. Любой разработчик, имея Dockerfile, сможет собрать точно такой же образ, независимо от операционной системы или компьютера.


Структура Dockerfile

Рассмотрим простой пример для Python-приложения.

FROM python:3.12-slimWORKDIR /appCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txtCOPY . .CMD ["python", "app.py"]

Разберём его построчно.

FROM

FROM python:3.12-slim

Определяет базовый образ. В данном случае новый образ будет построен поверх официального образа Python 3.12. Практически любой Dockerfile начинается именно с инструкции FROM.


WORKDIR

WORKDIR /app

Создаёт рабочую директорию внутри контейнера и делает её текущей. Все последующие команды будут выполняться относительно этого каталога.


COPY

COPY requirements.txt .

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

COPY . .

RUN

RUN pip install -r requirements.txt

Команда выполняется во время сборки образа. Именно здесь обычно:

  • устанавливаются библиотеки;

  • скачиваются зависимости;

  • обновляются пакеты;

  • компилируются программы.

После завершения сборки результат сохраняется внутри образа.


CMD

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

Определяет команду, которая будет выполнена при запуске контейнера. Именно она становится главным процессом контейнера (PID 1).

Если этот процесс завершится, контейнер автоматически остановится.


Как собрать собственный образ?

Предположим, Dockerfile находится в текущей директории. Для сборки используется команда:

docker build -t myapp:1.0 .

Разберём параметры:

  • build — собрать образ;

  • -t — присвоить имя и тег;

  • myapp:1.0 — имя будущего образа;

  • . — использовать текущую директорию как контекст сборки.

После успешной сборки можно увидеть образ командой:

docker images

Запуск собственного контейнера

Дальше образ можно использовать так же, как и любой официальный образ.

docker run myapp:1.0

Docker создаст новый контейнер и запустит приложение. Именно так распространяется большинство современных сервисов.


Почему данные исчезают?

Допустим, внутри контейнера работает база данных. Пользователь добавил тысячи записей. После этого контейнер удалили. Все данные тоже исчезли.

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

Эту проблему решают Volumes.


Docker Volumes

Volume (том) — это специальное хранилище данных, которое существует независимо от контейнера. Получается следующая схема. Даже если контейнер удалить и создать заново, данные в Volume останутся. Из-за этого практически все базы данных в Docker используют тома.


Когда используют Volumes?

Практически всегда, когда необходимо сохранить информацию на будущее.

  • PostgreSQL;

  • MySQL;

  • MongoDB;

  • Redis (при включённом сохранении);

  • пользовательские файлы;

  • резервные копии;

  • журналы работы приложений.

Без Volumes контейнеры можно рассматривать как временные процессы.


Другие способы подключения данных

Docker поддерживает не только Volumes. Существует ещё два распространённых способа предоставить контейнеру доступ к файлам.

Bind Mounts

Bind Mount позволяет подключить к контейнеру существующую папку или файл с компьютера хоста.

Например:

docker run \-v $(pwd):/app \python:3.12

В этом случае текущая директория компьютера будет доступна внутри контейнера по пути /app.

Это особенно удобно во время разработки. Разработчик изменяет исходный код в привычном редакторе, а контейнер сразу использует обновлённые файлы без пересборки образа.

Однако Bind Mount сильнее зависит от конкретной операционной системы и структуры каталогов. Если проект перенести на другой компьютер, путь к папке может отличаться, поэтому для хранения важных данных в продакшене чаще используют Volumes.

tmpfs

Иногда данные вообще не нужно сохранять после остановки контейнера.

Для таких случаев Docker поддерживает tmpfs — временную файловую систему, которая хранится только в оперативной памяти. Благодаря хранению данных в оперативной памяти tmpfs обеспечивает очень высокую скорость работы.

Например, её используют для:

  • временных кэш-файлов;

  • промежуточных вычислений;

  • чувствительных данных, которые не должны записываться на диск.

После остановки контейнера всё содержимое tmpfs полностью исчезает.


Docker Networks

Давайте представим другую ситуацию. Есть два контейнера:

  • веб-приложение;

  • PostgreSQL.

Как веб-приложение сможет подключиться к базе данных? Для этого используются Docker Networks. Сеть позволяет контейнерам находить друг друга по имени и безопасно обмениваться данными.

Контейнеры внутри одной сети могут обращаться друг к другу без указания IP-адресов.

Например:

Host = postgres

где postgres — имя контейнера. Это значительно упрощает настройку многокомпонентных приложений.


Какие сети создаёт Docker?

По умолчанию Docker поддерживает несколько типов сетей. Наиболее часто используются:

  • Bridge — стандартная сеть для контейнеров на одном сервере;

  • Host — контейнер использует сетевой стек хостовой системы;

  • None — сеть полностью отключена.

В большинстве проектов применяется Bridge, поэтому новичку надо достаточно хорошо понимать этот режим.


Docker Compose

Даже небольшое веб-приложение обычно состоит из нескольких компонентов:

  • веб-сервера (Nginx);

  • приложения (Python, Java, Node.js и т.д.);

  • базы данных (PostgreSQL или MySQL);

  • кэша (Redis);

  • иногда очереди сообщений (RabbitMQ или Kafka).

Каждый из этих компонентов обычно запускается в отдельном контейнере. Возникает проблема. Представьте, что для запуска проекта необходимо выполнить пять длинных команд:

docker network create app-networkdocker volume create postgres-datadocker run ...docker run ...docker run ...

Нужно помнить:

  • порядок запуска;

  • названия контейнеров;

  • настройки сети;

  • тома;

  • проброс портов;

  • переменные окружения.

Стоит забыть один параметр — приложение уже не работает. Эту проблему решает Docker Compose.


Что такое Docker Compose?

Docker Compose — это инструмент, который позволяет описать многоконтейнерное приложение в одном YAML-файле, а затем запускать или останавливать всю инфраструктуру одной командой.

Вместо нескольких десятков команд достаточно написать:

docker compose up

Docker самостоятельно:

  • создаст необходимые сети, если они ещё не существуют;

  • создаст тома;

  • скачает необходимые образы;

  • соберёт собственные образы (если нужно);

  • создаст контейнеры;

  • подключит их друг к другу;

  • запустит всё приложение.

Именно поэтому Docker Compose часто называют инфраструктурой как код (Infrastructure as Code) для локальной разработки.


Почему Docker Compose стал стандартом?

Представим небольшую команду из четверых разработчиков. Если каждый запускает проект вручную, очень быстро возникают проблемы:

  • один использует PostgreSQL 15;

  • второй — PostgreSQL 16;

  • третий забыл открыть нужный порт;

  • четвёртый неправильно настроил переменные окружения.

Docker Compose решает эту проблему. В репозитории хранится один файл конфигурации. Все разработчики используют одинаковые настройки и запускают проект одинаковой командой. Это делает окружение воспроизводимым и значительно снижает количество ошибок.


Почему используется YAML?

Конфигурация Docker Compose описывается в файле:

docker-compose.yml

или (в современных версиях Docker):

compose.yml

Этот файл написан на языке YAML.

YAML (YAML Ain’t Markup Language) — это простой формат хранения конфигурации. Он используется не только в Docker Compose, но и во многих других DevOps-инструментах:

  • Kubernetes;

  • GitHub Actions;

  • Ansible;

  • Prometheus;

  • GitLab CI;

Поэтому умение читать YAML пригодится каждому DevOps-инженеру. Главная особенность YAML — он использует отступы вместо фигурных скобок.

Например:

services:    web:        image: nginx

Два пробела здесь имеют значение. Если нарушить структуру отступов, файл станет недействительным.


Из чего состоит compose.yml?

Почти любой Compose-файл содержит несколько основных разделов:

servicesvolumesnetworks

Services

Описывает контейнеры приложения. Например:

  • веб-сервер;

  • база данных;

  • Redis;

  • API.

Каждый сервис соответствует одному контейнеру.


Volumes

Создают постоянное хранилище данных. Даже если контейнер будет удалён, информация сохранится.


Networks

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


Минимальный пример

Рассмотрим простейший Compose-файл.

services:     web:    image: nginx        ports:           - "80:80"

После выполнения команды

docker compose up

Docker автоматически:

  • скачает образ Nginx (если его нет);

  • создаст контейнер;

  • откроет 80-й порт.

Без Compose для этого пришлось бы использовать длинную команду docker run с множеством параметров.


Переменные окружения

Практически любое приложение использует параметры конфигурации:

  • пароль к базе данных;

  • имя пользователя;

  • адрес сервера;

  • секретные ключи.

Не рекомендуется хранить их прямо в Compose-файле. Вместо этого используется файл .env

Например:

POSTGRES_USER=adminPOSTGRES_PASSWORD=secret123POSTGRES_DB=mydb

Compose автоматически подставит эти значения при запуске. Такой подход позволяет использовать один и тот же Compose-файл для разработки, тестирования и продакшена, меняя только содержимое .env.


Основные команды Docker Compose

Запуск проекта:

docker compose up

Запуск в фоновом режиме:

docker compose up -d

Остановка:

docker compose down

Просмотр журналов:

docker compose logs

Просмотр работающих контейнеров:

docker compose ps

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

Неправильные отступы в YAML

YAML чувствителен к пробелам. Лишний или отсутствующий отступ может сделать конфигурацию недействительной.


Использование latest

Запись

image: postgres:latest

может привести к неожиданному обновлению базы данных после выхода новой версии. Лучше явно указывать номер версии:

image: postgres:16

Отсутствие Volumes

Если не подключить том для базы данных, после удаления контейнера будут потеряны все данные.


Хранение секретов в Compose-файле

Пароли, токены и ключи доступа не стоит записывать непосредственно в docker-compose.yml. Для этого используют .env или специализированные системы управления секретами.


Первое знакомство с Docker: установка и запуск первого контейнера

До этого момента мы говорили только о теории. Теперь пора установить Docker и запустить первый контейнер. Для примера будем использовать Ubuntu Linux. На других дистрибутивах команды могут немного отличаться, но общий принцип остаётся тем же.


Установка Docker

Сначала обновим список пакетов:

sudo apt update

Установим Docker из официальных репозиториев Ubuntu:

sudo apt install docker.io

После установки запустим службу Docker:

sudo systemctl enable --now docker

Проверим её состояние:

sudo systemctl status docker

Если всё прошло успешно, вы увидите статус:

Active: active (running)

Это означает, что Docker Engine запущен и готов принимать команды.

Примечание. Для разработки часто рекомендуется устанавливать Docker из официального репозитория Docker, так как там быстрее появляются новые версии. Для первых шагов достаточно пакета docker.io, который доступен в большинстве дистрибутивов Linux.


Проверяем установку

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

sudo docker version

Вы увидите информацию о версии Docker Client и Docker Engine.

Также можно проверить состояние системы:

sudo docker info

Эта команда выводит сведения о контейнерах, образах, драйверах хранения, сети и других компонентах Docker.


Первый контейнер

Исторически первым примером почти во всех руководствах является контейнер hello-world. Запустим его:

sudo docker run hello-world

Если образ отсутствует локально, Docker сообщит об этом:

Unable to find image 'hello-world:latest' locally

Затем автоматически скачает его из Docker Hub:

Pulling from library/hello-world

После завершения загрузки контейнер будет создан и выполнится небольшая программа, которая выведет сообщение:

Hello from Docker!

Если вы увидели этот текст — Docker установлен и работает корректно.


Первый «настоящий» контейнер

Контейнер hello-world завершается сразу после выполнения программы. Попробуем запустить сервис, который продолжает работать. Для этого используем Nginx:

sudo docker run -d -p 8080:80 --name my-nginx nginx

Разберём параметры:

  • -d — запуск в фоновом режиме (detached);

  • -p 8080:80 — перенаправление порта 8080 на компьютере в порт 80 внутри контейнера;

  • --name my-nginx — присвоить контейнеру имя;

  • nginx — образ, из которого будет создан контейнер.

Проверить, что контейнер работает, можно командой:

sudo docker ps

Например:

CONTAINER ID   IMAGE   STATUS       PORTSf8c1b9...      nginx   Up 2 minutes 0.0.0.0:8080->80/tcp

Теперь откройте браузер и перейдите по адресу:

http://localhost:8080

Если вы работаете на удалённом сервере или виртуальной машине, вместо localhost используйте её IP-адрес.Вы увидите стандартную страницу приветствия Nginx.

Поздравляю — вы только что развернули свой первый веб-сервер в контейнере.


Работа без sudo

По умолчанию Docker требует права суперпользователя. Чтобы не вводить sudo перед каждой командой, добавьте своего пользователя в группу docker:

sudo usermod -aG docker $USER

После этого выйдите из системы и войдите снова (или перезагрузите компьютер), чтобы изменения вступили в силу. Проверить можно командой:

docker run hello-world

Если она выполняется без sudo, настройка завершена успешно.

Ресурсы для обучения

Официальная документация

Это лучшие источники информации, к которым DevOps-инженеры обращаются постоянно.

  • Docker Documentation — официальная документация Docker.

  • Docker Hub — каталог официальных Docker-образов.

  • Docker Samples — готовые примеры проектов на Docker Compose.


Бесплатные курсы

Подойдут новичкам.

  • Play with Docker — бесплатная облачная лаборатория, позволяющая работать с Docker прямо в браузере без установки на компьютер.

  • Katacoda Archive (через Killercoda) — интерактивная платформа с практическими сценариями по Docker, Docker Compose, Kubernetes и другим DevOps-инструментам

  • LabEx Docker Skill Tree — большая коллекция практических заданий по Docker, Dockerfile, Compose и контейнеризации.

  • Docker Get Started — официальный интерактивный курс от разработчиков Docker. Здесь вы научитесь запускать контейнеры, создавать собственные образы, работать с Dockerfile и Docker Compose.

Что дальше?

Что делать, если приложение нужно запустить не на одном сервере, а на десятках или сотнях? Как автоматически распределять нагрузку, заменять отказавшие контейнеры и обновлять приложение без остановки сервиса?

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

ссылка на оригинал статьи https://habr.com/ru/articles/1060718/