· 15 мин чтения

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

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

Меня зовут Семёнов Евгений Сергеевич, и я руковожу компанией АйТи Фреш. За 15 лет в IT я не раз видел одно и то же: админы прямо-таки боятся 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. Обновить его было равносильно самоубийству для сайта — разработчик испарился года три назад, никаких контактов. Что мы предложили? Упаковали весь этот портал в три аккуратных контейнера: 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 подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.