Skip to content

Game Repository — деплой через отдельный репозиторий

Каждая игра (или среда: staging, production) имеет свой приватный репозиторий с конфигурацией и версией marv. На сервере достаточно ./marv-ctl.sh update для полного обновления.

Game-репозиторий не содержит скриптов управления — только конфиги, версию и один файл marv-ctl.sh. Все рабочие скрипты и бинарники приходят в составе бандла конкретной версии.

Структура game-репозитория

my-game-server/
├── .marv-version            # версия marv (например v2.0.3)
├── .marv-mode               # режим: release, debug, test (опционально)
├── marv-ctl.sh              # единственный скрипт — точка входа
├── config/
│   ├── config.release.yml   # основной конфиг сервера
│   ├── bots.release.json    # конфиг ботов
│   ├── products.release.json # конфиг продуктов
│   └── .env                 # секреты (только на сервере, не в git)
├── marv/                    # ← скачивается автоматически (gitignore)
│   ├── bin/
│   │   ├── marv             # сервер
│   │   ├── hgoose           # утилита миграций
│   │   └── config-migrator  # конвертер legacy-конфигов
│   ├── scripts/
│   │   ├── deploy.sh        # управление (run, migrate, ...)
│   │   └── marv.service.template
│   ├── migrations/
│   │   └── *.sql
│   └── config/              # примеры конфигов из бандла
└── .gitignore

Режим (GIN_MODE)

marv-ctl.sh определяет режим по приоритету:

  1. --mode флаг: ./marv-ctl.sh --mode debug setup
  2. MARV_MODE переменная окружения
  3. .marv-mode файл в корне репозитория
  4. release (по умолчанию)

Режим влияет на:

  • Какой конфиг загружается (config.<mode>.yml, bots.<mode>.json, ...)
  • Значение GIN_MODE в systemd unit
  • Имя файла, требуемое при setup

Путь к конфигам

По умолчанию marv-ctl ищет конфиги в ./config. Можно указать другой путь:

bash
./marv-ctl.sh --config-dir /etc/marv/my-game setup

Путь к конфигам:

  • Передаётся marv-бинарнику через -config-dir
  • Записывается в systemd unit через ExecStart
  • .env из этой же директории загружается через EnvironmentFile

Конфиги не копируются в бандл — marv читает их напрямую по указанному пути.

Создание game-репозитория

1. Инициализация

bash
mkdir my-game-server && cd my-game-server
git init

2. Скопировать marv-ctl.sh

bash
cp /path/to/marv/scripts/game-repo/marv-ctl.sh ./marv-ctl.sh
chmod +x marv-ctl.sh

3. Указать версию и режим

bash
echo "v2.0.3" > .marv-version

# Для production-сервера (release — по умолчанию, файл необязателен):
echo "release" > .marv-mode

# Для dev-сервера:
echo "debug" > .marv-mode

4. Подготовить конфиги

bash
mkdir config

# Скопировать примеры из marv и заполнить (mode = release для production)
cp /path/to/marv/config/config.example.yml config/config.release.yml
cp /path/to/marv/config/bots.example.json config/bots.release.json
cp /path/to/marv/config/products.example.json config/products.release.json

В config/config.release.yml оставить только несекретную часть — модули, роуты, таймауты, размеры пулов. Секреты (пароли, токены, ключи) вынести в .env.

5. Вынести секреты в .env

bash
cp /path/to/marv/config/.env.example config/.env.example

Файл config/.env создаётся только на сервере (не в git). Пример:

bash
MARV__APP__SECURITY__SECRET=my-production-secret
MARV__INFRASTRUCTURE__POSTGRES__HOST=db.internal.example.com
MARV__INFRASTRUCTURE__POSTGRES__PASSWORD=strong-password
MARV__INFRASTRUCTURE__CLOUDFLARE__API_TOKEN=cf-token-xxx
MARV__ALERTS__DESTINATIONS__0__ENDPOINT=https://hooks.slack.com/services/T.../B.../xxx

.env загружается systemd через EnvironmentFile=. Переменные окружения перезаписывают значения из YAML-конфига.

Правило: config.release.yml в git — без секретов. config/.env на сервере — только секреты.

6. Gitignore

bash
cat > .gitignore <<'EOF'
marv/
*.log
config/.env
EOF

7. Первый коммит

bash
git add -A
git commit -m "initial: my-game-server config"
git remote add origin git@gitlab.com:hgstudio/deployments/my-game-server.git
git push -u origin main

Развёртывание на сервере

Предварительные требования (release)

  • Debian/Ubuntu
  • PostgreSQL — отдельный сервер, доступный по сети (порт 5432)
  • Redis — локально на этом же сервере (типичный случай) или удалённо
  • SSH-ключ сервера добавлен в GitLab (Deploy Key с read-only)
  • MARV_DEPLOY_TOKEN задан в окружении

Подготовка сервера

bash
sudo apt update && sudo apt upgrade -y

# Redis (локальный — типичный случай для release)
sudo apt install -y redis-server
sudo systemctl enable redis-server

# Утилиты
sudo apt install -y curl tar git

PostgreSQL не устанавливается на сервер marv — он всегда на отдельной машине.

Первоначальная установка

bash
# 1. Настроить Deploy Token для скачивания бандла
echo 'export MARV_DEPLOY_TOKEN="deployer:gldt-xxxxxxxxxxxxxxxxxxxx"' >> ~/.bashrc
source ~/.bashrc

# 2. Клонировать game-репозиторий
cd /opt
git clone git@gitlab.com:hgstudio/deployments/my-game-server.git
cd my-game-server

# 3. Создать .env с секретами
cp config/.env.example config/.env
nano config/.env

# 4. Запустить установку
./marv-ctl.sh setup

По умолчанию --env-file = config/.env. Для systemd этот путь прописывается в unit как EnvironmentFile.

marv-ctl.sh setup выполнит:

  1. Проверит наличие config.<mode>.yml в директории конфигов
  2. Скачает бандл marv нужной версии из GitLab Packages
  3. Применит миграции
  4. Установит и включит systemd service с GIN_MODE=<mode> и -config-dir

Обновление

bash
cd /opt/my-game-server
./marv-ctl.sh update

marv-ctl.sh update выполнит:

  1. git pull --ff-only
  2. Сравнит .marv-version до и после pull
  3. Если версия изменилась → скачает новый бандл → миграции → рестарт
  4. Если только конфиги → рестарт
  5. Если ничего не изменилось → ничего не делает

Команды marv-ctl.sh

bash
./marv-ctl.sh setup                          # первоначальная установка
./marv-ctl.sh setup --no-service             # без systemd
./marv-ctl.sh update                         # полный цикл: pull + apply
./marv-ctl.sh update --dry-run               # показать что изменится
./marv-ctl.sh update --no-pull               # без git pull
./marv-ctl.sh fetch                          # только скачать бандл
./marv-ctl.sh deploy <cmd>                   # прокси к deploy.sh
./marv-ctl.sh version                        # показать версии

# Глобальные опции (перед или после команды):
./marv-ctl.sh --mode debug setup             # режим debug
./marv-ctl.sh --config-dir /etc/marv setup   # кастомный путь к конфигам
./marv-ctl.sh --env-file /path/to/.env setup # кастомный env-файл (относительный — от корня репо)

Сценарии обновления

Обновление только конфига

На рабочей машине:

bash
cd my-game-server
nano config/config.release.yml
git add config/
git commit -m "config: tune connection pool"
git push

На сервере:

bash
cd /opt/my-game-server
./marv-ctl.sh update
# → git pull → конфиги уже на месте → сервис рестартнут

Обновление версии marv

На рабочей машине:

bash
cd my-game-server
echo "v2.1.0" > .marv-version
git add .marv-version
git commit -m "bump marv to v2.1.0"
git push

На сервере:

bash
cd /opt/my-game-server
./marv-ctl.sh update
# → git pull → скачает v2.1.0 → миграции → рестарт

Обновление версии + конфига одновременно

bash
echo "v2.1.0" > .marv-version
nano config/config.release.yml
git add -A
git commit -m "bump marv v2.1.0, add new module config"
git push

На сервере — тот же ./marv-ctl.sh update.

Deploy Token

Deploy Token нужен чтобы сервер мог скачивать бандл marv из GitLab Packages.

Создание

  1. GitLab → marv-проект → SettingsRepositoryDeploy tokens
  2. Name: marv-deploy
  3. Scopes: read_package_registry
  4. Create deploy token
  5. Сохраните username и token

Настройка на сервере

bash
# В ~/.bashrc или /etc/environment
export MARV_DEPLOY_TOKEN="<username>:<token>"

Один Deploy Token можно использовать на нескольких серверах.

Deploy Key (SSH)

Deploy Key нужен чтобы сервер мог делать git pull game-репозитория.

Создание

bash
# На сервере
ssh-keygen -t ed25519 -C "deploy@my-game-server" -f ~/.ssh/deploy_key -N ""
cat ~/.ssh/deploy_key.pub

Добавление в GitLab

  1. GitLab → game-репозиторий → SettingsRepositoryDeploy keys
  2. Title: my-game-server
  3. Key: содержимое deploy_key.pub
  4. Write access: не нужен (read-only)

Настройка SSH

bash
cat >> ~/.ssh/config <<EOF
Host gitlab.com
    IdentityFile ~/.ssh/deploy_key
    IdentitiesOnly yes
EOF

Управление сервисом

bash
# Имя сервиса = имя директории game-репозитория
sudo systemctl status my-game-server
sudo systemctl start my-game-server
sudo systemctl stop my-game-server
sudo systemctl restart my-game-server

# Логи
sudo journalctl -u my-game-server -f
sudo journalctl -u my-game-server --since "1 hour ago"

Инфраструктура

Development

PostgreSQL и Redis — оба локальные, на машине разработчика:

yaml
infrastructure:
  postgres:
    host: localhost
    port: 5432
  redis:
    address: 127.0.0.1:6379

Release (production / staging)

PostgreSQL — всегда отдельный сервер. Сервер marv должен иметь сетевой доступ к нему (порт 5432):

yaml
infrastructure:
  postgres:
    host: db.internal.example.com
    port: 5432

Redis — обычно локальный (на том же сервере что и marv):

yaml
infrastructure:
  redis:
    address: 127.0.0.1:6379

Если Redis на отдельном сервере — укажите его адрес и уберите зависимость от redis-server.service в systemd unit.

Несколько серверов / сред

Для staging и production — отдельные репозитории:

hgstudio/deployments/
├── my-game-staging/       # .marv-mode = release, bleeding-edge версия
└── my-game-production/    # .marv-mode = release, стабильная версия

Каждый со своим .marv-version, конфигами и адресами инфраструктуры.

Для dev-среды:

hgstudio/deployments/
└── my-game-dev/           # .marv-mode = debug, локальные PG и Redis