· 15 мин чтения

Docker для начинающих на Linux: от первой установки до работающего compose

Меня зовут Семёнов Евгений Сергеевич, я руковожу компанией АйТи Фреш. За 15 лет я перевидал как админы боятся Docker, пока не поставят его один раз руками и не поднимут свой первый контейнер. У нас на практике Docker в инфраструктуре почти везде: на 8 серверах Dell Xeon Platinum 8280 в дата-центре МТС Москва, на клиентских виртуалках, на ноутбуках разработчиков. Эта статья — первый шаг для тех, кто админит Linux, но ещё не работал с контейнерами.

Зачем вообще нужен Docker

Контейнеризация решает старую головную боль: «у меня работает, у тебя нет». Упаковали приложение со всеми библиотеками в образ — и он одинаково запускается на ноуте разработчика, на стейджинге и на боевом сервере. Никаких плясок с зависимостями, разными версиями Python или libc.

Практические выигрыши, которые я вижу у клиентов:

Установка Docker на Ubuntu 22.04 / Debian 12

Не ставьте apt install docker.io, там обычно старая версия. Берите официальный репозиторий Docker. Последовательность одинаковая для Ubuntu и Debian, меняется только дистрибутив в URL.

sudo apt update
sudo apt install -y ca-certificates curl gnupg

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

sudo systemctl enable --now docker
sudo usermod -aG docker $USER
# Перезайдите в систему, чтобы группа применилась

Проверяем:

docker version
docker run --rm hello-world

Первые команды: образ, контейнер, логи

Коротко о терминологии. Образ (image) — это шаблон, неизменяемая файловая система. Контейнер — запущенный инстанс образа с добавленным писчим слоем. Образы живут в реестре (Docker Hub, GitLab Registry, свой Harbor). Запуск контейнера скачивает образ, если его нет локально.

# Скачать образ без запуска
docker pull nginx:1.27-alpine

# Запустить в фоне с пробросом порта
docker run -d --name web -p 8080:80 nginx:1.27-alpine

# Посмотреть бегущие контейнеры
docker ps

# Логи
docker logs -f web

# Зайти внутрь
docker exec -it web sh

# Остановить и удалить
docker stop web && docker rm web

Флаг --rm говорит Docker удалить контейнер после остановки — удобно для разовых команд. -it — интерактивный TTY для shell-а. Я всегда даю контейнерам имена через --name, иначе Docker генерирует забавные, но неудобные hungry_turing.

Тома и постоянные данные

Файловая система контейнера пропадает вместе с ним. Чтобы сохранить базу, загрузки, настройки — используйте volume или bind mount.

ТипГде хранитсяКогда применять
Named volume/var/lib/docker/volumes/Продакшн, базы данных, чистые бэкапы
Bind mountЛюбой путь хостаРазработка, доступ к коду, логи наружу
tmpfsОЗУСекреты, временные кеши
# Named volume — рекомендую для продакшна
docker volume create pgdata
docker run -d --name pg \
  -e POSTGRES_PASSWORD=secret \
  -v pgdata:/var/lib/postgresql/data \
  -p 5432:5432 postgres:16

# Bind mount — удобно на разработке
docker run -d --name web \
  -v /srv/sites/mysite:/usr/share/nginx/html:ro \
  -p 80:80 nginx:alpine

Сети Docker

По умолчанию Docker создаёт bridge-сеть, где контейнеры видят друг друга по IP. Для удобства делайте именованные сети — тогда контейнеры резолвятся по именам.

docker network create app-net

docker run -d --name db --network app-net \
  -e POSTGRES_PASSWORD=secret postgres:16

docker run -d --name api --network app-net \
  -e DB_HOST=db -p 8000:8000 myapp:latest

Из контейнера api база доступна по имени db — DNS работает автоматически. Это база для микросервисов.

Dockerfile: свой образ за 5 минут

Dockerfile — рецепт сборки образа. Начинаем с базового, копируем файлы, ставим зависимости, задаём точку входа. Пример для простого Python-приложения:

FROM python:3.12-slim

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

COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
docker build -t myapp:0.1 .
docker run -d --name myapp -p 8000:8000 myapp:0.1

Правила, которые экономят часы в будущем: ставьте зависимости ДО копирования кода (кеш слоёв), фиксируйте версии базовых образов (python:3.12-slim, а не python:latest), используйте .dockerignore, чтобы не тащить в образ .git, node_modules и виртуалки.

Docker Compose: оркестрация для маленьких

Запускать по пять docker run подряд неудобно. Compose описывает все сервисы в одном YAML. Файл docker-compose.yml:

services:
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

  api:
    build: .
    restart: unless-stopped
    depends_on: [db]
    environment:
      DB_HOST: db
    ports:
      - "8000:8000"

volumes:
  pgdata:
docker compose up -d
docker compose logs -f
docker compose down

Реальный кейс: миграция самописного PHP на Docker

Однажды в 2024 году мы забирали на обслуживание небольшую логистическую компанию в Химках, 42 рабочих места. У клиента был самописный PHP-портал заказов на стареньком CentOS 7. Обновить CentOS без риска уронить сайт было нельзя — разработчик исчез три года назад. Мы упаковали всё в три контейнера: php-fpm 8.1, nginx, mariadb 10.11. Dockerfile собрался за вечер, миграция базы заняла 40 минут.

Результаты: портал переехал на свежий Ubuntu 22.04 с полной поддержкой безопасности. Срок работ — 4 рабочих дня, стоимость 78 000 руб. Через полгода клиент сам попросил перенести в контейнеры 1С веб-клиент, потому что понравилась простота обновлений.

Грабли, на которые наступают все новички

Поможем перевести инфраструктуру на Docker

У нас 8 серверов Dell Xeon Platinum 8280 с 40G Mellanox в дата-центре МТС Москва. Упакуем ваши приложения в контейнеры, настроим compose или Swarm, организуем логирование и бэкапы. Бесплатный аудит по telegram — за час.

Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш

FAQ — частые вопросы по Docker

Чем Docker отличается от виртуальной машины?
Контейнер Docker использует ядро хоста и изолирует только процессы и файловую систему через namespaces и cgroups. Виртуалка эмулирует железо и запускает своё ядро. Контейнер стартует за секунду, весит десятки мегабайт, ВМ — за минуту и гигабайты.
Можно ли ставить Docker в продакшн на Ubuntu Server?
Да, это стандартная практика. Docker CE на Ubuntu LTS (22.04, 24.04) работает стабильно. Ставьте из официального репозитория docker.com, а не apt-овский docker.io — там версия отстаёт.
Что делать, если контейнер завис и не останавливается?
Сначала пробуем docker stop — он шлёт SIGTERM и ждёт 10 секунд. Если не помогло — docker kill шлёт SIGKILL. В крайнем случае можно перезапустить демон systemctl restart docker, но это убьёт все контейнеры.
Куда Docker складывает данные?
По умолчанию — в /var/lib/docker. Там образы, контейнеры, тома. Если диск маленький — перенесите на отдельный раздел через daemon.json: "data-root": "/data/docker".
Нужен ли root для работы с Docker?
Для команд docker — не обязательно. Добавьте пользователя в группу docker (usermod -aG docker user) и перезайдите. Но помните: членство в этой группе фактически равно root на хосте, поэтому давайте осторожно.

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.