MAATRIX / Блог / Микросервисы на одном VPS через docker-compose

Микросервисы на одном VPS через docker-compose

Микросервисы на одном VPS через docker-compose
Блог MAATRIX · 2026-07-07

Не всякой микросервисной архитектуре нужен Kubernetes. На старте несколько сервисов прекрасно живут на одном VPS под docker-compose. Соберём стек с reverse proxy, внутренней сетью, healthcheck и централизованными логами.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Когда достаточно одного VPS

Kubernetes оправдан, когда сервисов десятки и нужен автоскейлинг между нодами. Пока их 3–8 и трафик умеренный, docker-compose на одном сервере проще в эксплуатации и дешевле: один VPS вместо кластера.

compose даёт всё нужное: изолированные контейнеры, общую сеть по именам, healthcheck, лимиты ресурсов и одну команду для подъёма всего стека.

Несколько сервисов делят одно ядро и диск, поэтому важна производительность на ядро. AMD EPYC + NVMe у MAATRIX держит и БД, и очередь, и веб одновременно без деградации отклика. Именно IO-latency обычно становится первым узким местом при уплотнении сервисов на одну машину, и здесь NVMe даёт запас, которого нет у SATA-виртуалок.

Важно и то, что миграция на Kubernetes позже пройдёт безболезненно: те же образы, те же переменные окружения, те же healthcheck. docker-compose — это не тупик, а естественная первая ступень, с которой вы в любой момент шагнёте в k3s, когда сервисов станет по-настоящему много.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.

Арендовать VPS для микросервисов

Структура стека

Возьмём типичный набор: reverse proxy (Caddy), два бэкенд-сервиса (api, worker), база (Postgres) и брокер (Redis). Все — в одной compose-сети, наружу торчит только прокси.

services:
  proxy:
    image: caddy:2-alpine
    ports: [ "80:80", "443:443" ]
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
    depends_on: [ api ]

  api:
    build: ./api
    environment:
      DATABASE_URL: postgres://app:secret@db:5432/app
      REDIS_URL: redis://cache:6379
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      retries: 3
    depends_on:
      db: { condition: service_healthy }

  worker:
    build: ./api
    command: python worker.py
    depends_on: [ cache, db ]

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
    volumes: [ pgdata:/var/lib/postgresql/data ]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 10s
      retries: 5

  cache:
    image: redis:7-alpine

volumes:
  pgdata:

Сеть и обращение по именам

compose автоматически создаёт общую сеть, и сервисы видят друг друга по имени. Внутри контейнера api адрес базы — просто db:5432, брокера — cache:6379. Никаких IP руками прописывать не нужно.

Наружу выставлен только proxy. Порты db и cache не публикуйте через ports — иначе база окажется в открытом интернете. Доступ к ней только изнутри сети compose.

Reverse proxy Caddy автоматически получает Let's Encrypt-сертификат. Минимальный Caddyfile:

api.example.com {
    reverse_proxy api:8000
}

Запуск, логи и масштабирование

Поднимаем весь стек и смотрим статус healthcheck:

docker compose up -d
docker compose ps
docker compose logs -f api

Отдельный сервис можно масштабировать в несколько реплик — прокси распределит нагрузку, если сервис stateless:

docker compose up -d --scale worker=3

Ограничьте ресурсы, чтобы один сервис не съел весь VPS. В compose это делается через deploy.resources.limits:

    deploy:
      resources:
        limits:
          cpus: "0.50"
          memory: 256M

Лимит памяти особенно важен для сервисов с потенциальными утечками: контейнер, упёршийся в свой memory-лимит, будет перезапущен, а не утянет за собой весь VPS. Это дешёвая страховка, которую часто забывают выставить.

Частые ошибки

  • Сервис стартует раньше БДdepends_on без condition: service_healthy не ждёт готовности, только запуска. Всегда добавляйте healthcheck базе.
  • БД доступна из интернета — опубликовали порт 5432 наружу. Убирайте ports у внутренних сервисов.
  • Диск забит логами — настройте ротацию через logging.options.max-size.
  • Один сервис положил сервер — нет лимитов CPU/RAM, утечка памяти съела весь VPS.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.

Арендовать VPS для микросервисов

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Частые вопросы

Сколько сервисов потянет один VPS?

Зависит от нагрузки, но 5–10 лёгких сервисов на VPS с 4 ГБ RAM работают комфортно. Следите за суммарным потреблением памяти.

Как обновить один сервис без остановки остальных?

Выполните docker compose up -d --no-deps --build api — пересоберётся и перезапустится только указанный сервис.

Нужен ли отдельный сервер под базу?

На старте нет. Когда БД станет узким местом, вынесете её на отдельный VPS, изменив DATABASE_URL.