БОЛЬ
Пятница, 18:47. Вы обновляете Python на сервере, где крутятся 5 микросервисов. apt upgrade python3 – и бот в Telegram падает, потому что ему нужен Python 3.10, а вы только что поставили 3.12. Заодно сломался Flask-сервис, который зависел от libssl1.1, а теперь стоит libssl3.
Знакомо? Это классика: конфликт зависимостей на общем хосте. Один apt update может положить всё, потому что 5 сервисов делят одну файловую систему, одни библиотеки, один Python.
Docker решает эту боль изоляцией: каждый сервис живёт в своём контейнере со своими зависимостями. Обновление Python в одном контейнере не трогает остальные.
КАК УСТРОЕНО
docker run – это точка входа в мир контейнеров. Одна команда берёт образ (image) и запускает из него изолированный процесс (контейнер).
Что происходит при docker run nginx:
- Docker ищет образ
nginxлокально - Если нет – скачивает из Docker Hub
- Создаёт изолированный контейнер (namespaces + cgroups)
- Запускает процесс nginx внутри
Ключевые флаги, которые нужно знать:
| Флаг | Что делает | Пример |
|---|---|---|
-d | Фоновый режим (detach) | docker run -d nginx |
-p | Проброс порта host:container | -p 8080:80 |
--name | Имя контейнера | --name web |
-e | Переменная окружения | -e DB_HOST=postgres |
-v | Том (volume) | -v ./data:/app/data |
--rm | Удалить после остановки | docker run --rm alpine echo hi |
--network | Сеть | --network backend |
ПРАКТИКА
Вам нужно запустить веб-приложение в контейнере: фоновый режим, проброс порта 8080 на 80, имя webapp, переменная NODE_ENV=production, том для данных.
Расставьте части команды docker run в правильном порядке
- ⠿ --name webapp
- ⠿ -v ./data:/app/data
- ⠿ -e NODE_ENV=production
- ⠿ node:22-alpine
- ⠿ -p 8080:80
- ⠿ docker run -d
docker run -d, затем все флаги (--name, -p, -e, -v), и в самом конце – имя образа. Образ всегда идёт последним, после него можно указать только команду для запуска внутри контейнера. Порядок флагов между собой не критичен, но образ обязательно в конце.РАЗБОР
# Полная команда
docker run -d \
--name webapp \
-p 8080:80 \
-e NODE_ENV=production \
-v ./data:/app/data \
node:22-alpine
Что здесь происходит:
docker run -d– запускаем контейнер в фоне, терминал не блокируется--name webapp– даём контейнеру понятное имя вместо случайногоangry_turing-p 8080:80– порт 8080 на хосте проксируется на порт 80 контейнера-e NODE_ENV=production– переменная окружения, приложение знает что это прод-v ./data:/app/data– локальная папка./dataмонтируется внутрь контейнера, данные переживут рестартnode:22-alpine– образ (всегда последний аргумент перед командой)
ВОПРОС НА СОБЕСЕ
Вопрос: Чем отличается контейнер от виртуальной машины?