ДокументацияРуководство РазработчикаПолное Руководство по Docker Деплою 10 Сервисов

🐳 Полное Руководство по Деплою через Docker Compose

Пошаговая инструкция по развертыванию всех 10 сервисов экосистемы Loomix на едином VPS с максимальной безопасностью, отказоустойчивостью и стабильностью.

1. Требования к Серверу (Prerequisites)

Перед началом подготовьте VPS с операционной системой Ubuntu 22.04 LTS или 24.04 LTS:

  • Минимум RAM: 4 ГБ физической памяти с минимум 4 ГБ Swap (для быстрых сборок рекомендуется 8 ГБ RAM).
  • Процессор: Минимум 2 ядра vCPU (для быстрой сборки Docker-образов рекомендуется 4 vCPU).

Права на Docker Сокет

Docker и Docker Compose должны быть установлены, а текущий пользователь добавлен в группу docker.

Права на Docker Сокет
bash
sudo usermod -aG docker $USER
newgrp docker # or log out and SSH back in
docker ps # should work without sudo

2. Перенос Исходного Кода на Сервер

Перенести проект на ваш VPS можно одним из двух удобных способов:

Способ 1: Прямое Клонирование через Git (Рекомендуется)

Храните Переменные Окружения в Безопасности

Команда клонирования через Git:
bash
git clone https://github.com/<YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME>.git
cd <YOUR_REPOSITORY_NAME>

Клонирование Приватного Репозитория по SSH-Ключам

  • 1. Сгенерируйте пару SSH-ключей на сервере: ssh-keygen -t ed25519
  • 2. Выведите и скопируйте публичный ключ: cat ~/.ssh/id_ed25519.pub
  • 3. Добавьте этот ключ в раздел Deploy Keys вашего репозитория на GitHub.
  • 4. Склонируйте репозиторий по SSH напрямую.
Команда клонирования по SSH:
bash
git clone git@github.com:<YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME>.git
cd <YOUR_REPOSITORY_NAME>

Клонирование через Personal Access Token (PAT)

Команда клонирования с токеном PAT:
bash
git clone https://<YOUR_GITHUB_USERNAME>:<PERSONAL_ACCESS_TOKEN>@github.com/<YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME>.git
cd <YOUR_REPOSITORY_NAME>

Способ 2: Загрузка Архива (ZIP / Tarball)

Если вы скачали архив с кодом, загрузите его на сервер через scp или rsync:

Команда загрузки через SCP / rsync:
bash
rsync -avz --exclude 'node_modules' --exclude '.git' --exclude '.next' ./ user@your_vps_ip:/root/next-strapi-medusa

3. Мастер Автоматической Настройки (Quick Wizard)

Чтобы установка заняла считанные минуты, мы создали скрипт server-setup.sh, который настраивает Swap, проверяет порты и запускает контейнеры:

Команда запуска мастера установки:
bash
chmod +x server-setup.sh
bash server-setup.sh
Совет Эксперта:
Скрипт проверяет ресурсы сервера, генерирует надежные пароли и автоматически сохраняет их в ваш файл .env.

4. Выбор Профиля Развертывания (Deployment Profiles)

Система поддерживает 3 профиля развертывания под разные сценарии использования:

Нужен ли Собственный Домен?
Да, для профилей B и C рекомендуется реальный домен, чтобы Let's Encrypt мог автоматически выпустить бесплатные SSL-сертификаты.
Рекомендуется для Большинства

Запускает все 10 сервисов на одном VPS с поддоменами и автоматическими SSL-сертификатами через Caddy.

Шаги Настройки Профиля B:

  • 1. Направьте DNS A-записи домена на IP-адрес вашего сервера.
  • 2. Выберите Профиль B при запуске скрипта server-setup.sh.
  • 3. Введите ваш основной домен (напр. vashdomen.ru).
  • 4. Caddy автоматически получит SSL-сертификаты для всех сервисов.
  • 5. Все панели управления сразу готовы к работе по защищенному протоколу HTTPS.
.env (Фрагмент Профиля B)
env
# Profile B: VM / LAN HTTPS (.local hostnames) - Recommended ★
STOREFRONT_PUBLIC_URL=https://store.local
MEDUSA_BACKEND_PUBLIC_URL=https://api.local
STRAPI_PUBLIC_URL=https://admin.local
MEILISEARCH_PUBLIC_URL=https://search.local
MINIO_PUBLIC_URL=https://api.local/minio/mystore
GOOGLE_CALLBACK_URL=https://store.local/ir/account/auth/callback
STOREFRONT_URL=http://storefront:8000
MEDUSA_NODE_ENV=production
MEDUSA_ALLOW_HTTP_COOKIES=false
CLOUDFLARE_TUNNEL_TOKEN=
Ссылки Профиля B:
• Витрина: https://vashdomen.ru
• Medusa: https://api.vashdomen.ru/app
• Strapi: https://admin.vashdomen.ru/admin
• Umami: https://analytics.vashdomen.ru
• OpenObserve: https://monitor.vashdomen.ru

Руководство по Защите в Cloudflare Edge

Перед Делегированием DNS в Cloudflare:

Во избежание бесконечных редиректов (Redirect Loops) установите режим SSL в Cloudflare на Full (Strict).

2. После запуска сервисов (Настройка безопасности после развертывания):

Режим шифрования SSL/TLS: Установите в Full (Strict).
Сертификаты Edge: Включите Always Use HTTPS, Automatic HTTPS Rewrites и задайте минимальную версию TLS TLS 1.2 (или 1.3).
Проксирование DNS: Переведите все DNS-записи в статус с оранжевым облаком (Proxied) для ускорения через CDN и защиты от DDoS-атак на сервер источника.
Безопасность / WAF: Включите Bot Fight Mode.
Сеть: Убедитесь, что WebSockets и gRPC включены.
Кэширование: В разделе Caching > Configuration проверьте, чтобы Browser Cache TTL стоял в значении Respect Existing Headers для сохранения мгновенного обновления корзины и остатков товаров.

HTTP Basic Auth и защита периметра с Caddy:

Панель администратора Strapi (admin.yourdomain.com/admin* и /): Защищена с помощью HTTP Basic Auth для предотвращения брутфорс-атак. Публичные маршруты API (/api/*) и медиафайлы (/uploads/*) остаются открытыми, чтобы Storefront и Medusa могли обращаться к данным без ошибок 401.
Панель OpenObserve (monitor.yourdomain.com): Защищена HTTP Basic Auth как второй рубеж защиты в дополнение к внутренним учетным записям OpenObserve.

Сгенерируйте надежный хэш bcrypt для переменной BASIC_AUTH_HASH в .env:

Генерация хэша пароля Bcrypt для Caddy
bash
docker run --rm caddy:latest caddy hash-password --plaintext "your_secret_password"

Матрица Адресов и Портов по Профилям

СервисПрофиль A (Локально)Профиль B (Один VPS)Профиль C (Корпоративный)
Витрина Next.jshttp://<VM_IP>:8000https://store.localhttps://yourdomain.com
Бэкенд Medusahttp://<VM_IP>:9000/apphttps://api.local/apphttps://api.yourdomain.com/app
Панель Strapi CMShttp://<VM_IP>:1337/adminhttps://admin.local/adminhttps://admin.yourdomain.com/admin
Аналитика Umamihttp://<VM_IP>:3005https://analytics.localhttps://analytics.yourdomain.com
Мониторинг OpenObservehttp://<VM_IP>:5080https://monitor.localhttps://monitor.yourdomain.com
Поисковый движок (Meilisearch)127.0.0.1:7700https://search.localhttps://search.yourdomain.com

Назначение каждого публичного URL в .env:

  • STOREFRONT_PUBLIC_URL: Витрина Next.js (порт 8000 внутри Docker или публичный домен).
  • MEDUSA_BACKEND_PUBLIC_URL: API Medusa и Панель администратора (/app).
  • STRAPI_PUBLIC_URL: Strapi CMS (/admin); ссылки предпросмотра используют STOREFRONT_PUBLIC_URL.
  • MEILISEARCH_PUBLIC_URL: Публичный URL для мгновенного клиентского поиска (Профиль A: http://127.0.0.1:7700, Профиль B: https://search.local, Профиль C: https://search.yourdomain.com).
  • MINIO_PUBLIC_URL: Публичный префикс для медиафайлов (Профиль A: http://IP:9001/mystore, Профиль B/C: https://api.*/minio/mystore).
  • STOREFRONT_URL: Только для внутренней сети Docker (http://storefront:8000), используется для ревалидации кэша Medusa -> Storefront.

ОБЯЗАТЕЛЬНО настроить до запуска Фазы 1:

Секретные ключи (openssl rand -hex 32): POSTGRES_PASSWORD, MEILI_MASTER_KEY, все ключи STRAPI_*, MEDUSA_JWT_SECRET, MEDUSA_COOKIE_SECRET, REVALIDATE_SECRET, UMAMI_APP_SECRET.
Учетные записи администраторов: MEDUSA_ADMIN_EMAIL, MEDUSA_ADMIN_PASSWORD, MINIO_ROOT_USER, MINIO_ROOT_PASSWORD, UMAMI_USERNAME, UMAMI_PASSWORD.
Публичные URL: Выберите Профиль A, B или C, как описано выше.

Оставить пустыми до выполнения соответствующей фазы:

• Фаза 4: STRAPI_API_TOKEN_FOR_MEDUSA, STRAPI_API_TOKEN_FOR_FRONT
• Фаза 6: MEDUSA_PUBLISHABLE_KEY
• Фаза 7: MEILI_SEARCH_KEY
• Фаза 8: UMAMI_WEBSITE_ID

Правило панели Medusa: Всегда сохраняйте MEDUSA_NODE_ENV=production в Docker. Никогда не указывайте development: панель скомпилирована под продакшен, а режим dev приводит к белому экрану.

5. Автодеплой через GitHub Actions CI/CD

Проект включает готовые пайплайны для автоматической сборки Docker-контейнеров и доставки на сервер при каждом git push:

  1. Добавьте IP сервера и приватный SSH-ключ в Repository Secrets на GitHub.
  2. Каждый коммит в ветку main запускает сборку оптимизированных контейнеров Next.js и Medusa.
  3. На сервер отправляется сигнал для бесшовного обновления контейнеров без простоя (Zero-Downtime).
  4. 4. (Приватный репозиторий) Создайте GitHub Personal Access Token (Classic) с правами repo, workflow и read:packages, затем выполните вход в GitHub Container Registry на вашем VPS:
Авторизация в Docker Registry на VPS
bash
echo "<YOUR_PAT>" | docker login ghcr.io -u <YOUR_GITHUB_USERNAME> --password-stdin

Процесс Развертывания в 10 Фаз (Phases 1-10)

ФазаЗапускаемые СервисыПрофиль AПрофиль B / C (Локальная сеть и Продакшен)
Фаза 1:Базы данных и инфраструктура (Postgres, Redis, MinIO, Meilisearch)
Фаза 2:Обратный прокси Caddy и автоматический SSL (hosts в Профиле B)⏭ Пропустить (Не требуется в Профиле A)✅ Сразу после Фазы 1, до запуска Strapi
Фаза 3:Движок Strapi CMS (Загрузка образа из GHCR)
Фаза 4:API-токены Strapi -> сохранить в .env
Фаза 5:Коммерческое ядро Medusa 2.0 (Загрузка образа из GHCR)
Фаза 6:Публичный ключ Medusa -> сохранить в .env
Фаза 7:Ключ поиска Meilisearch -> сохранить в .env
Фаза 8:Аналитика Umami (До запуска витрины)Необязательно
Фаза 9:Фронтенд Next.js (Сборка и развертывание с GitHub Actions)
Фаза 10:Стек наблюдаемости и логов (OpenObserve, Vector, cAdvisor)НеобязательноРекомендуется

Фаза 1: Запуск Баз Данных (PostgreSQL & Redis)

Запуск PostgreSQL с изолированными схемами под Medusa, Strapi и Umami, а также Redis для сессий и кэша.

Команда для Фазы 1:
bash
docker compose up -d postgres redis meilisearch minio minio-setup

Дождитесь перехода всех сервисов в статус healthy: docker compose ps

Фаза 2: Шлюз Caddy и Автоматические Сертификаты SSL

Запуск обратного прокси Caddy для автоматического получения и продления SSL-сертификатов Let's Encrypt.

Команда для Фазы 2:
bash
docker compose up -d caddy
docker compose logs -f caddy

Настройка файла hosts в Windows для Профиля B:

Откройте C:\Windows\System32\drivers\etc\hosts от имени Администратора и добавьте строку:
192.168.1.103 store.local api.local admin.local analytics.local monitor.local
(Замените 192.168.1.103 на IP вашей виртуальной машины. Не добавляйте Meilisearch — он должен оставаться строго внутренним).

Фаза 3: Запуск Strapi CMS v5

Скачивание образа Strapi CMS, подключение к базе данных и ожидание готовности порта 1337.

Команда для Фазы 3:
bash
docker compose pull strapi
docker compose up -d strapi
docker compose logs -f strapi

Дождитесь, пока сервер начнет слушать порт 1337 (1–3 минуты при первом запуске). Откройте панель Strapi (Профиль B: https://admin.local/admin, Профиль A: http://<VM_IP>:1337/admin) и зарегистрируйте учетную запись администратора.

Фаза 4: Извлечение Токенов Strapi и Запись в .env

Автоматическая генерация сервисного токена для доступа фронтенда Next.js к блокам Strapi.

  1. Скрипт strapi-token-init.js извлекает административный токен.
  2. Переменная STRAPI_API_TOKEN сохраняется в файл .env.
  3. 3. Для витрины (STRAPI_API_TOKEN_FOR_FRONT): Выберите токен Read-Only, нажмите Regenerate и скопируйте полученное значение в переменную STRAPI_API_TOKEN_FOR_FRONT в файле .env.

Фаза 5: Запуск Движка MedusaJS v2

Запуск контейнера Medusa, применение миграций базы данных и создание учетной записи супер-администратора.

Команда для Фазы 5:
bash
docker compose pull medusa
docker compose up -d medusa
docker compose logs -f medusa

Автоматические шаги при первом запуске: Миграции БД через db:migrate (2–5 минут) -> создание суперпользователя -> готовность API на порту 9000. Откройте Medusa Admin по адресу https://api.local/app (Профиль B) или http://<VM_IP>:9000/app (Профиль A) и войдите с помощью MEDUSA_ADMIN_EMAIL и MEDUSA_ADMIN_PASSWORD.

Фаза 6: Каналы Продаж и Публичные Ключи Medusa

Генерация ключа Publishable Key для взаимодействия витрины с корзиной и каталогом товаров.

  1. Создание и авторизация администратора.
  2. Ключ привязывается к переменной NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY.
  3. 3. ОЧЕНЬ ВАЖНО: Откройте созданный ключ > вкладка Sales Channels > привяжите к Default Sales Channel. Без этого шага товары не будут отображаться на витрине.

Фаза 7: Развертывание Поискового Движка Meilisearch

Запуск контейнера Meilisearch для мгновенного поиска товаров с автодополнением и опечаткоустойчивостью.

Команда для Фазы 7:
bash
curl -H "Authorization: Bearer <MEILI_MASTER_KEY>" http://127.0.0.1:7700/keys

Скопируйте Default Search API Key и вставьте в переменную MEILI_SEARCH_KEY в файле .env (интерактивный скрипт извлекает его автоматически).

Фаза 8: Запуск Аналитики Umami

Запуск независимой аналитической платформы Umami без использования cookies и генерация ID веб-сайта.

Команда для Фазы 8:
bash
docker compose up -d umami

Откройте панель Umami (Профиль B: https://analytics.local, Профиль A: http://<VM_IP>:3005). Войдите (admin / umami), перейдите в Settings > Websites > Add website и скопируйте сгенерированный Website ID в переменную UMAMI_WEBSITE_ID в .env.

Фаза 9: Запуск Витрины Next.js 16

Сборка фронтенда, подключение к готовым сервисам и открытие доступа к главной странице магазина.

1. Переменные Сборки и API-Ключи:

Пути к Medusa и Strapi передаются в контейнер на этапе сборки.

1. STOREFRONT_BUILD_ARGS (Переменные сборки)

Содержит переменные сборки Next.js. Скопируйте шаблон выше и подставьте ключи, сгенерированные на предыдущих фазах.

Аргументы Сборки (Build Args):
env
MEDUSA_BACKEND_URL=http://medusa:9000
NEXT_PUBLIC_MEDUSA_BACKEND_URL=https://api.yourdomain.com
NEXT_PUBLIC_STRAPI_URL=https://admin.yourdomain.com
NEXT_PUBLIC_BASE_URL=https://store.yourdomain.com
NEXT_PUBLIC_MEILISEARCH_HOST=https://search.yourdomain.com
NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_...
NEXT_PUBLIC_MEILISEARCH_SEARCH_KEY=...
NEXT_PUBLIC_UMAMI_WEBSITE_ID=...
NEXT_PUBLIC_DEFAULT_REGION=US
DEFAULT_LOCALE=en-US
NEXT_PUBLIC_MEILISEARCH_INDEX_NAME=products
NEXT_PUBLIC_ENABLE_IRAN_FEATURES=false

2. REGISTRY_URL

URL реестра компонентов. Значение по умолчанию — публичный реестр Loomix Blocks:
https://raw.githubusercontent.com/landa33/loom-blocks-registry/main/src/modules

3. GITHUB_PAT (Опционально)

GitHub Personal Access Token (Classic). Требуются разрешения repo, workflow и read:packages. Используется для загрузки образов GHCR, запуска CI/CD и доступа к приватным реестрам.

4. DEPLOY_PATH

Абсолютный путь к директории проекта на вашем Linux VPS (напр., /root/loomix-commerce). Необходим для того, чтобы Self-Hosted Runner мог найти проект Docker Compose.

2. Ультралегкая Standalone-Сборка:

Режим Standalone в Next.js снижает размер итогового Docker-образа до менее чем 150 МБ.

3. Проверка Сети и Доступности:

Проверка порта 8000 и подключение к внутренней сети прокси Caddy.

4. Запуск Витрины в Продакшене:

Команда запуска витрины:
bash
docker compose pull storefront
docker compose up -d storefront

Фаза 10: Мониторинг и Логирование (OpenObserve & Vector)

Запуск Vector и OpenObserve для мониторинга системных метрик, памяти, нагрузки на CPU и сбора логов.

Команда для Фазы 10:
bash
docker compose up -d openobserve vector cadvisor docker-stats-exporter

Центральная панель управления OpenObserve:

Откройте https://monitor.yourdomain.com (Профиль C), https://monitor.local (Профиль B) или http://<VM_IP>:5080 (Профиль A). Войдите с root-учетными данными OpenObserve.

Потоки телеметрии и собираемые журналы:

docker_logs: Единый журнал всех контейнеров и мгновенный поиск ошибок по микросервисам.

caddy_access: Входящий веб-трафик HTTP, IP-адреса клиентов, HTTP-коды статусов (2xx/4xx/5xx) и пути запросов, отправляемые напрямую из JSON-логов Caddy через Vector.

docker_stats: Потребление оперативной памяти в реальном времени, нагрузка на CPU % и сетевой ввод/вывод по каждому контейнеру через cAdvisor.

host_metrics: Общая загрузка процессора, использование оперативной памяти и статистика дискового ввода-вывода хост-сервера.

Мгновенные оповещения в Telegram:

В панели OpenObserve перейдите в Reliability > Destinations для подключения вебхука вашего Telegram-бота (https://api.telegram.org/bot<TOKEN>/sendMessage), затем создайте правила оповещений в Reliability > Alerts для уведомлений в реальном времени при ошибках 500.

6. Первичная Синхронизация Данных между Medusa и Strapi

Автоматическая процедура, которая считывает товары из Medusa и создает соответствующие блоки в Strapi.

Запуск Первой Синхронизации:

Выполните команду внутри контейнера Strapi для генерации структуры главной страницы:

2. Синхронизация модульных блоков Loomix (sync-loom-component.js)

В панели Strapi в разделе Storefront Management нажатие + Add to Storefront (Queue) или Remove Style (Queue) помещает изменения в очередь в sync-history.json. При нажатии Update Storefront пресеты синхронизируются и запускается процесс сборки и развертывания в GitHub Actions.

Переменные окружения для синхронизации в продакшене:

Задайте эти переменные в website-admin/.env и в корневом файле .env сервера. Убедитесь, что токен имеет разрешения 'repo' и 'workflow':

Переменные синхронизации для GitHub CI/CD
env
GITHUB_DEPLOY_TOKEN=ghp_your_personal_access_token # Requires 'repo' and 'workflow' scopes
GITHUB_DEPLOY_REPO=your_username/your_repo_name

7. Переключение между Профилями Развертывания

Инструкция по миграции с Профиля A на Профиль B или изменению доменных имен:

Тип ИзмененияПерезапускаемые Сервисы
Публичные URL в .envStrapi, Medusa, Storefront (сначала запустите экшен в GitHub Actions, затем скачайте образ)
Настройка MEDUSA_ALLOW_HTTP_COOKIESТолько контейнер Medusa
Добавление Caddy (Переход от Профиля A к B)Запуск Caddy (docker compose up -d caddy); загрузка новых образов
Файл hosts (Профиль B)На сервере перезапуск не требуется; отредактируйте файл hosts в Windows на вашей рабочей машине
Пример переключения профиля
bash
# 1. Edit .env — switch to Profile B URLs, set MEDUSA_ALLOW_HTTP_COOKIES=false
nano .env
# 2. Add hosts entry on Windows
# 3. Start Caddy
docker compose up -d caddy
# 4. Pull new images:
docker compose pull strapi medusa && docker compose up -d strapi medusa

8. Обновление Сервисов до Последних Версий

Запустите скрипт server-update.sh для загрузки свежих релизов без риска потери данных в БД.

9. Полезные Команды Администрирования и Обслуживания

Команды Docker для просмотра логов, перезапуска сервисов и резервного копирования:

Команды Регулярного Обслуживания:
bash
./setup.sh # On Linux / macOS
.\setup.bat # On Windows

10. Внутренняя Сеть и Карта Портов

Внутренняя Сеть Контейнеров (Internal Bridge Network):

  • Витрина (Storefront): :8000
  • Medusa API + Панель управления: :9000
  • Strapi CMS: :1337
  • Meilisearch: :7700
  • Консоль MinIO: :9001
  • Аналитика Umami: :3005
  • Мониторинг OpenObserve: :5080

Доменные Имена, Обрабатываемые Caddy:

  • https://store.local -> storefront:8000
  • https://api.local -> medusa:9000
  • https://admin.local -> strapi:1337
  • https://analytics.local -> umami:3000
  • https://monitor.local -> openobserve:5080
  • https://api.local/minio/ -> minio:9000

Изолированная Сеть loomix-network:

Контейнеры связываются между собой внутри сети по стандартным именам сервисов (напр., http://storefront:8000, http://medusa:9000, http://meilisearch:7700). Сервис Meilisearch является строго внутренним и никогда не должен публиковаться во внешнюю сеть.

Сводка Основных Команд Управления

Просмотр логов всех сервисов в реальном времени:
bash
docker compose ps
Перезапуск конкретного контейнера:
bash
docker compose logs -f medusa
docker compose logs -f strapi
docker compose logs -f storefront
docker compose logs -f openobserve
Остановка всей экосистемы:
bash
docker builder prune -f
docker system prune -f
Полный перезапуск (с сохранением томов и баз данных)
bash
docker compose down
docker compose up -d