Установка Docker Compose на Linux: полный гайд 2026

Как установить Docker Compose на Ubuntu, Debian, CentOS и macOS. Команды, примеры docker-compose.yml, типичные ошибки и их решения от практикующего SRE

<!-- META DESCRIPTION (до 155 символов): Как установить Docker Compose на Ubuntu, Debian, CentOS и macOS. Команды, примеры docker-compose.yml, типичные ошибки и их решения от практикующего SRE. -->

Установка Docker Compose на Linux: от нуля до рабочего стека

Коротко: что получишь на выходе
Docker Compose устанавливается как плагин для Docker CLI командой apt install docker-compose-plugin (Ubuntu/Debian) или через ручное скачивание бинарника с GitHub. После установки проверяй командой docker compose version — без дефиса. Весь процесс занимает 3-5 минут при наличии Docker Engine.

1. Диагноз: зачем вообще это нужно

Поднял приложение. Nginx стоит отдельно, база — отдельно, Redis — третьей командой в другом терминале. Через неделю добавился Celery. Потом RabbitMQ. Потом ты забыл, с какими флагами запускал базу, и она поднялась без volume. Данные потеряны. Знакомо?

Docker Compose решает именно это. Весь стек описывается в одном YAML-файле. Одна команда — весь стек поднят. Ещё одна — убран. Никаких bash-скриптов на 400 строк, которые никто не трогал с 2019 года и которые «просто работают.

Что будет в статье:

  • Установка на Ubuntu/Debian, CentOS/RHEL, macOS и Windows
  • Разница между старым docker-compose и новым docker compose
  • Настройка прав без sudo
  • Три готовых примера docker-compose.yml — от простого к сложному
  • Типичные ошибки и их решения

Времени нужно: 15-20 минут на установку и первый запуск. Предполагается, что Docker Engine уже стоит. Если нет — сначала туда.

2. Базовые требования

Перед тем как что-то ставить — проверь среду. Это не занудство, это экономия времени.

Системные требования

Компонент Минимум Рекомендуется
Docker Engine 19.03.0+ последняя стабильная
ОС 64-bit Linux/macOS/Windows Ubuntu 22.04 LTS
RAM 2 ГБ 4+ ГБ
Диск 2 ГБ свободно 20+ ГБ
Права sudo пользователь в группе docker

Проверка Docker Engine

Сначала убедись, что Docker Engine работает:


docker --version
docker ps
sudo systemctl status docker

Должно быть: версия Docker и статус «active (running)». Если Docker не запущен:


sudo systemctl start docker
sudo systemctl enable docker

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

Совместимость версий

ОС Версия Метод установки Compose версия
Ubuntu 20.04, 22.04, 24.04 apt plugin v2.x
Debian 11, 12 apt plugin v2.x
CentOS/RHEL 8, 9 dnf plugin v2.x
Fedora 38+ dnf plugin v2.x
macOS 12+ Docker Desktop / brew v2.x
Windows 10/11 + WSL2 Docker Desktop v2.x

На момент публикации актуальна версия Compose v2.27+. Перед установкой проверяй свежие релизы на GitHub.

3. Архитектура: как это работает

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#ffffff',
    'primaryTextColor': '#1e293b',
    'primaryBorderColor': '#94a3b8',
    'lineColor': '#64748b',
    'fontSize': '15px',
    'fontFamily': 'ui-sans-serif, system-ui, sans-serif'
  },
  'flowchart': {'curve': 'linear', 'nodeSpacing': 50, 'rankSpacing': 50}
}}%%
flowchart TD
    A["docker compose up"] --> B["Docker CLI Plugin"]
    B --> C["docker-compose.yml"]
    C --> D["Service: web"]
    C --> E["Service: db"]
    C --> F["Service: redis"]
    D --> G["Container: nginx"]
    E --> H["Container: postgres"]
    F --> I["Container: redis"]
    G --> J["Network: app-network"]
    H --> J
    I --> J
    style A fill:#f8fafc,stroke:#3b82f6,stroke-width:2px,color:#1e40af
    style B fill:#f8fafc,stroke:#3b82f6,stroke-width:2px,color:#1e40af
    style C fill:#f8fafc,stroke:#f97316,stroke-width:2px,color:#c2410c
    style J fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d

Docker Compose читает твой YAML, создаёт контейнеры, настраивает сеть между ними и запускает всё в нужном порядке. Контейнеры видят друг друга по именам сервисов — db, redis, web — без hardcode IP-адресов.

4. Установка: выбери свою ОС

Ubuntu / Debian — способ 1: через apt (рекомендую)

Если Docker ставился через официальный репозиторий — плагин уже может быть установлен. Проверь:


docker compose version

Видишь версию — можно пропускать. Нет — ставим:


sudo apt update
sudo apt install docker-compose-plugin
docker compose version

Должно вывести что-то вроде: Docker Compose version v2.27.1

Ubuntu / Debian — способ 2: ручная установка

Нужна конкретная версия или репозиторий недоступен — берём бинарник напрямую:


mkdir -p ~/.docker/cli-plugins/

DOCKER_COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d'"' -f4)

curl -SL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-x86_64" \
  -o ~/.docker/cli-plugins/docker-compose

chmod +x ~/.docker/cli-plugins/docker-compose

docker compose version

Скрипт сам определяет последнюю версию через GitHub API. Не нужно лезть на сайт руками.

CentOS / RHEL / Fedora


sudo dnf update
sudo dnf install docker-compose-plugin
docker compose version

Для старых версий CentOS 7 через прямое скачивание:


sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64" \
  -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

docker-compose --version

macOS

Docker Desktop для Mac уже включает Compose. Поставил Desktop — Compose есть. Если нужна отдельная установка через Homebrew:


brew install docker-compose

Для Apple Silicon (M1/M2/M3) — отдельный бинарник:


mkdir -p ~/.docker/cli-plugins

curl -SL "https://github.com/docker/compose/releases/latest/download/docker-compose-darwin-aarch64" \
  -o ~/.docker/cli-plugins/docker-compose

chmod +x ~/.docker/cli-plugins/docker-compose
docker compose version

Windows

Docker Desktop для Windows включает Compose из коробки. Если нужна ручная установка через PowerShell:


mkdir -p "$env:USERPROFILE\.docker\cli-plugins"

Invoke-WebRequest "https://github.com/docker/compose/releases/latest/download/docker-compose-windows-x86_64.exe" `
  -OutFile "$env:USERPROFILE\.docker\cli-plugins\docker-compose.exe"

docker compose version

Если используешь WSL2 — рекомендую. Устанавливай Compose внутри WSL по инструкции для Ubuntu.

5. Настройка прав — убираем sudo

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


sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
docker ps
Важно про безопасность
Пользователи в группе docker фактически имеют root-доступ к системе через монтирование томов. Не добавляй туда всех подряд. В продакшене — лучше настроить sudoers с конкретными разрешёнными командами.

Если не хочешь добавлять пользователя в группу — создай алиасы:


echo "alias dc='sudo docker compose'" >> ~/.bashrc
source ~/.bashrc
dc up -d

6. Структура docker-compose.yml

Прежде чем запускать примеры — понимай, что читаешь. Базовая структура файла:


version: '3.8'

services:
  имя-сервиса:
    image: образ:тег
    ports:
      - "порт-хоста:порт-контейнера"
    volumes:
      - путь-хоста:путь-контейнера
    environment:
      - ПЕРЕМЕННАЯ=значение
    depends_on:
      - другой-сервис
    restart: unless-stopped

networks:
  имя-сети:
    driver: bridge

volumes:
  имя-тома:
    driver: local

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

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

7. Три практических примера

Пример 1: Nginx со статикой

Простейший старт. Создай папку проекта и файл docker-compose.yml:


version: '3.8'

services:
  web:
    image: nginx:alpine
    container_name: my-nginx
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped

Создай папку html и тестовый файл:


mkdir html
echo '

Docker Compose работает

' > html/index.html docker compose up -d curl http://localhost:8080

Результат: HTML-ответ в терминале и страница в браузере по адресу localhost:8080. Флаг -d запускает в фоне.

Пример 2: WordPress + MySQL

Классика жанра. Два сервиса с зависимостью и персистентными данными:


version: '3.8'

services:
  db:
    image: mysql:8.0
    container_name: wp-db
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    restart: unless-stopped
    networks:
      - wp-net

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    container_name: wp-app
    ports:
      - "8000:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wp_data:/var/www/html
    restart: unless-stopped
    networks:
      - wp-net

networks:
  wp-net:
    driver: bridge

volumes:
  db_data:
  wp_data:

Создай файл .env рядом с docker-compose.yml:


MYSQL_ROOT_PASSWORD=strong_root_pass_here
MYSQL_PASSWORD=strong_wp_pass_here

Добавь .env в .gitignore — обязательно. Пароли в публичных репозиториях это не инцидент, это катастрофа.


echo ".env" >> .gitignore
docker compose up -d
docker compose ps

Через 30-40 секунд (пока MySQL инициализируется) открывай localhost:8000 — будет мастер установки WordPress. Данные сохраняются в именованных volumes и переживут пересоздание контейнеров.

Пример 3: Fullstack — React + Node.js + PostgreSQL + Redis

Реальный рабочий стек с healthcheck-ами и правильными зависимостями:

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#ffffff',
    'primaryTextColor': '#1e293b',
    'primaryBorderColor': '#94a3b8',
    'lineColor': '#64748b',
    'fontSize': '15px',
    'fontFamily': 'ui-sans-serif, system-ui, sans-serif'
  },
  'flowchart': {'curve': 'linear', 'nodeSpacing': 50, 'rankSpacing': 50}
}}%%
flowchart TD
    A["Nginx :80"] --> B["Frontend :3000"]
    A --> C["Backend :3001"]
    C --> D["PostgreSQL :5432"]
    C --> E["Redis :6379"]
    style A fill:#f8fafc,stroke:#3b82f6,stroke-width:2px,color:#1e40af
    style B fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d
    style C fill:#f8fafc,stroke:#22c55e,stroke-width:2px,color:#15803d
    style D fill:#f8fafc,stroke:#f97316,stroke-width:2px,color:#c2410c
    style E fill:#f8fafc,stroke:#f97316,stroke-width:2px,color:#c2410c

version: '3.8'

services:
  postgres:
    image: postgres:15-alpine
    container_name: app-postgres
    environment:
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: appdb
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    container_name: app-redis
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - app-net
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5

  backend:
    build:
      context: ./backend
    container_name: app-backend
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      NODE_ENV: production
      DATABASE_URL: postgresql://appuser:${DB_PASSWORD}@postgres:5432/appdb
      REDIS_URL: redis://redis:6379
      JWT_SECRET: ${JWT_SECRET}
    ports:
      - "3001:3000"
    networks:
      - app-net
    restart: unless-stopped

  frontend:
    build:
      context: ./frontend
    container_name: app-frontend
    depends_on:
      - backend
    ports:
      - "3000:80"
    networks:
      - app-net
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    container_name: app-nginx
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    ports:
      - "80:80"
    depends_on:
      - frontend
      - backend
    networks:
      - app-net
    restart: unless-stopped

networks:
  app-net:
    driver: bridge

volumes:
  postgres_data:
  redis_data:

Вот тут важно: condition: service_healthy в depends_on. Без healthcheck сервис запускается как только контейнер стартовал — но база данных ещё может быть не готова принимать подключения. С healthcheck backend ждёт реальной готовности PostgreSQL. Это решает 90% проблем с «база не успела подняться».


docker compose up -d --build
docker compose ps
docker compose logs -f backend

8. Порты сервисов

Сервис Порт контейнера Порт хоста (пример) Протокол
Nginx 80, 443 80, 443 HTTP/HTTPS
PostgreSQL 5432 5432 TCP
MySQL/MariaDB 3306 3306 TCP
Redis 6379 6379 TCP
Node.js 3000 3001 HTTP
Flask/Django 5000 / 8000 5000 / 8000 HTTP
Prometheus 9090 9090 HTTP
Grafana 3000 3000 HTTP

9. Проверка установки и работы

После установки Compose и первого запуска — проверяй так:


# Версия Compose
docker compose version

# Статус всех сервисов
docker compose ps

# Логи в реальном времени
docker compose logs -f

# Логи конкретного сервиса
docker compose logs -f web

# Ресурсы контейнеров
docker stats --no-stream

# Проверка конфига на ошибки
docker compose config

Команда docker compose config особенно полезна — она парсит твой YAML, подставляет переменные из .env и показывает итоговый конфиг. Если там ошибка синтаксиса — найдёт сразу.

10. Безопасность

Несколько правил, которые обязательны в продакшене.

Файрвол


# UFW - разреши только нужные порты
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Внимание: Docker и UFW
Docker по умолчанию обходит правила UFW через прямые правила iptables. Если пробросил порт в docker-compose.yml — он открыт снаружи, даже если UFW говорит иначе. Чтобы это исправить, используй 127.0.0.1:8080:80 вместо просто 8080:80 для портов, которые не должны быть публичными.

Непривилегированный пользователь в контейнере


# В Dockerfile
RUN addgroup -g 1000 appgroup && \
    adduser -D -u 1000 -G appgroup appuser
USER appuser

# В docker-compose.yml
services:
  app:
    user: "1000:1000"

Ротация логов


services:
  app:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Без ротации логи заполнят диск. Это случается быстрее, чем думаешь.

Лимиты ресурсов


services:
  app:
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 512M

11. Резервное копирование

Данные в named volumes переживают пересоздание контейнеров. Но не пересоздание volumes.


# Бэкап PostgreSQL
docker compose exec db pg_dump -U appuser appdb > backup_$(date +%Y%m%d_%H%M%S).sql

# Бэкап MySQL
docker compose exec db mysqldump -u wpuser -p${MYSQL_PASSWORD} wordpress > backup_$(date +%Y%m%d_%H%M%S).sql

# Бэкап volume целиком
docker run --rm \
  -v имя_проекта_volume:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/volume_backup.tar.gz -C /data .

# Восстановление PostgreSQL
docker compose exec -T db psql -U appuser appdb < backup.sql

Что бэкапить: volumes с данными баз, volumes с файлами приложения, сам docker-compose.yml и .env.example (не .env с паролями). Частота: для баз - ежедневно минимум. Для файлов приложения - при каждом деплое. Хранить: не на том же сервере.

12. Обновление Docker Compose


# Через apt
sudo apt update && sudo apt upgrade docker-compose-plugin

# Проверка текущей версии
docker compose version

# Ручное обновление бинарника
DOCKER_COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d'"' -f4)
curl -SL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-x86_64" \
  -o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose
docker compose version

Перед обновлением: проверь changelog на предмет breaking changes. Сделай бэкап данных. Протестируй на staging. Compose v2 обратно совместим с синтаксисом v1 файлов, но иногда бывают нюансы.

13. Миграция с docker-compose v1 на v2

Если ещё используешь старый docker-compose с дефисом - переходи. Он больше не получает обновлений.

Основное изменение - команды:


# Старый синтаксис (v1)
docker-compose up -d
docker-compose logs
docker-compose down

# Новый синтаксис (v2)
docker compose up -d
docker compose logs
docker compose down

Для плавного перехода создай алиас:


echo "alias docker-compose='docker compose'" >> ~/.bashrc
source ~/.bashrc

Конфиги docker-compose.yml полностью совместимы. Менять файлы не нужно. Проверь конфиг на совместимость:


docker compose config

Если команда выполнилась без ошибок и показала итоговый конфиг - всё в порядке.

14. Шпаргалка по командам


# Запуск
docker compose up -d                  # фоновый режим
docker compose up --build             # с пересборкой образов
docker compose up --force-recreate    # пересоздать контейнеры

# Остановка
docker compose down                   # остановить и удалить контейнеры
docker compose down -v                # + удалить volumes (осторожно!)
docker compose stop                   # только остановить

# Информация
docker compose ps                     # статус сервисов
docker compose ps -a                  # включая остановленные
docker compose logs -f                # логи всех сервисов
docker compose logs --tail=100 web    # последние 100 строк
docker compose top                    # процессы в контейнерах
docker compose stats                  # использование ресурсов

# Выполнение команд
docker compose exec web bash          # интерактивная оболочка
docker compose exec web ls -la        # выполнить команду
docker compose run --rm web python test.py  # одноразовый контейнер

# Сборка
docker compose build --no-cache       # пересборка без кэша
docker compose pull                   # обновить образы
docker compose config                 # проверить конфиг

# Масштабирование
docker compose up -d --scale web=3   # 3 инстанса web

15. Осложнения: типичные ошибки и решения

command not found: docker compose

Причина: плагин не установлен или не в PATH.


# Проверяем где плагины
ls ~/.docker/cli-plugins/
ls /usr/lib/docker/cli-plugins/

# Устанавливаем заново
sudo apt install docker-compose-plugin

# Проверяем
docker compose version

permission denied при запуске

Причина: пользователь не в группе docker.


# Проверяем группы текущего пользователя
groups $USER

# Добавляем в группу docker
sudo usermod -aG docker $USER

# Применяем без перелогина
newgrp docker

# Проверяем
docker ps

Cannot connect to Docker daemon

Причина: Docker Engine не запущен.


sudo systemctl status docker
sudo systemctl start docker
sudo systemctl enable docker

Контейнер постоянно рестартует

Причина: ошибка в приложении или неправильный healthcheck.


# Смотрим логи падающего сервиса
docker compose logs --tail=50 имя-сервиса

# Смотрим статус с причиной
docker compose ps

# Запускаем без restart для дебага
docker compose run --rm имя-сервиса

depends_on не помогает - сервис стартует раньше базы

Причина: depends_on без condition только ждёт старта контейнера, не готовности сервиса внутри.


# Неправильно - просто ждёт старта контейнера
depends_on:
  - db

# Правильно - ждёт healthcheck
depends_on:
  db:
    condition: service_healthy

Плюс добавь healthcheck в сервис db (пример для PostgreSQL выше в статье).

Порты заняты

Причина: на хосте уже что-то слушает этот порт.


# Найти что занимает порт
sudo ss -tlnp | grep :8080
sudo lsof -i :8080

# Убить процесс или поменять порт в compose
ports:
  - "8081:80"   # поменяли 8080 на 8081

Volume не монтируется - файлы не видны

Причина: неправильный путь или проблемы с правами.


# Проверяем абсолютный путь
pwd
ls -la ./html

# Смотрим что примонтировано в контейнере
docker compose exec web ls -la /usr/share/nginx/html

# Проверяем права
ls -la ./html/index.html
chmod 644 ./html/index.html

Ошибка синтаксиса YAML

Причина: табы вместо пробелов или неправильные отступы.


# Проверяем конфиг
docker compose config

# Онлайн-валидатор: yamllint.com
# Или через CLI
sudo apt install yamllint
yamllint docker-compose.yml

16. Альтернативные решения

Docker Compose - не единственный вариант. Для понимания картины:

Инструмент Когда использовать Сложность
Docker Compose 1 сервер, dev/staging/простой prod низкая
Docker Swarm несколько серверов, знакомый синтаксис Compose средняя
Kubernetes большой кластер, автомасштабирование, сложные требования высокая
Podman Compose нужен rootless по умолчанию, RHEL-среда низкая
Nomad гетерогенная инфраструктура, не только контейнеры средняя

Kubernetes - мощный инструмент. Но его сложность оправдана не всегда. Если Compose покрывает твои задачи - используй Compose. Я знаю продакшен-системы с миллионами запросов в сутки на Docker Compose. Всё нормально работает.

17. Профилактика: как не сломать

Несколько правил, которые сэкономят тебе нервы в будущем.

Первое - всегда указывай конкретный тег образа в продакшене. latest сегодня и latest через три месяца - это разные образы. Обновления без тестирования прилетают в самый неподходящий момент.

Второе - именованные volumes для данных. Не bind-mount к случайной папке, а нормальный named volume. Данные должны жить дольше контейнеров.

Третье - .env.example в репозитории, .env в .gitignore. Всегда. Без исключений. Одна утечка пароля к базе данных в публичный репозиторий - и ты потратишь день на смену всех учёток и проверку логов.

Четвёртое - настрой ротацию логов. Диск заполняется быстрее, чем думаешь, особенно если приложение многословное.

Пятое - проверяй конфиг перед деплоем командой docker compose config. Поймаешь синтаксические ошибки раньше, чем они проявятся в продакшене в три часа ночи.

Шестое - документируй нестандартные решения прямо в комментариях docker-compose.yml. Ты не запомнишь через полгода, почему именно так.


# Плохо - загадочная конфигурация
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru

# Хорошо - понятно зачем
# appendonly yes - WAL для надёжности данных
# maxmemory 256mb - ограничение памяти для кэша
# allkeys-lru - вытеснение редко используемых ключей при достижении лимита
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru

18. FAQ

Почему docker compose вместо docker-compose?

В версии 2.x Docker Compose переехал из отдельной утилиты в плагин Docker CLI. Команда стала docker compose (без дефиса). Старый docker-compose (с дефисом, версия 1.x) устарел и больше не получает обновлений. Создай алиас alias docker-compose='docker compose' если привык к старому синтаксису - файлы конфигурации совместимы.

Как проверить, что Docker Compose установлен правильно?


# Проверка версии
docker compose version

# Проверка работоспособности - запускаем тестовый контейнер
docker compose -f - up -d <<EOF
version: '3'
services:
  test:
    image: hello-world
EOF

# Смотрим логи
docker compose logs test

# Убираем
docker compose down

Что если сервисы поднялись, но не видят друг друга по сети?

Скорее всего, они в разных сетях или сеть не указана. Проверь:


# Какие сети созданы
docker network ls | grep название_проекта

# К каким сетям подключён контейнер
docker inspect имя-контейнера | grep -A 20 '"Networks"'

# Проверь ping между контейнерами
docker compose exec web ping db

Если сервисы в одном docker-compose.yml и сеть не указана явно - Compose создаёт default сеть и подключает все сервисы к ней автоматически. Проблема возникает когда ты явно указал networks для одних сервисов, но забыл про другие.

Как откатиться если обновление сломало приложение?


# Остановить новую версию
docker compose down

# Откатить образ в docker-compose.yml к предыдущей версии
# image: myapp:v1.2.3  (было v1.2.4)

# Поднять предыдущую версию
docker compose up -d

# Если нет конкретных тегов - ищи предыдущий образ локально
docker images myapp
docker tag myapp:old-hash myapp:rollback

Именно поэтому в продакшене никогда не используй latest - невозможно откатиться к "прошлому latest".

Почему данные исчезают после docker compose down -v?

Флаг -v удаляет volumes вместе с контейнерами. Это деструктивная операция. Используй docker compose down без флага -v для сохранения данных. Volumes удаляются только явно: через docker compose down -v или docker volume rm.

19. Итог

Docker Compose установлен. Первый стек поднят. Теперь у тебя есть инструмент, который описывает инфраструктуру как код, запускает всё одной командой и сохраняет данные между перезапусками.

Следующий шаг - добавь мониторинг. Prometheus + Grafana + Node Exporter поднимаются за 10 минут через Compose и дают полную картину того, что происходит с твоими контейнерами. Без мониторинга ты узнаёшь о проблемах от пользователей.

Не заработало - разберёмся
Если что-то пошло не так — смотри секцию «Осложнения» выше. Если не помогло — пиши в комментарии: версию ОС, версию Docker, текст ошибки из docker compose logs. Разберём конкретную ситуацию.

Оставайтесь на связи

Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.

Подписаться на IT-Аптеку →

Мы ВКонтакте

IT-Аптека — советы, новости и помощь рядом.

Вступить в группу ВКонтакте →
Поделитесь:

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх