Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
VMaNGOS: продакшен через Docker Compose
Конфигурация для одного сервера Vanilla 1.12.1 (build 5875), realm ID 1,
PvP, patch 1.12, рейты ядра по умолчанию, начальный лимит 100 игроков.
Ядро собирается из текущего checkout, без git pull при запуске.
База MariaDB 10.11 хранится в volume и не публикует порт на хост.
Наружу доступны TCP 3724 (авторизация) и 8085 (мир).
RA, SOAP, интерактивная консоль и Warden (Windows/macOS) отключены.
Первый запуск
Нужны Docker Engine, Compose v2, Python 3, curl, openssl и 7z
(на Debian/Ubuntu пакет p7zip-full). Команды выполняются из этой папки.
cd deploy/production
cp .env.example .env
# В .env замените REALM_ADDRESS на публичный IPv4 или DNS сервера.
# REALM_NAME — латиница, цифры, пробелы/дефисы, до 32 символов.
mkdir -p secrets data
# Каталог закрыт для других пользователей хоста.
chmod 0700 secrets
(umask 077; openssl rand -hex 32 > secrets/db_password)
(umask 077; openssl rand -hex 32 > secrets/db_root_password)
(umask 077; openssl rand -hex 32 > secrets/voice_secret)
chmod 0444 secrets/db_password secrets/db_root_password secrets/voice_secret
./prepare-db.sh
# Необязательное дополнение к штатной русской локализации:
# python3 prepare-russian.py
prepare-db.sh скачивает закреплённый world dump от 14 июня 2021 года и
проверяет SHA256. При первой инициализации применяются все миграции именно
из текущего checkout. Не подставляйте сюда свежий db_latest: он уже
содержит миграции, и повторное применение сломает инициализацию.
Файлы паролей, дампы, данные клиента, .env и backups исключены из Git и
контекста Docker-сборки. В обычном Compose secrets являются файлами на хосте;
храните каталог на защищённом сервере. Для смены пароля требуется также
ALTER USER в базе и пересоздание контейнеров ядра.
В data/ положите 5875/dbc/, maps/, vmaps/, mmaps/, извлечённые
инструментами этого ядра из поддерживаемого клиента. Каталоги и файлы
должны читаться UID 10001. Инициализация базы не требует этих данных,
но mangosd без них не запускается. Патчи для realmd здесь не настроены;
используйте подходящий клиент 1.12.1.
docker compose config --quiet
docker compose build
docker compose up -d db
# После окончания импорта настройте запись realm:
docker compose run --rm realm-config
docker compose up -d realmd mangosd
docker compose ps
docker compose logs --tail=100 realmd mangosd
Для новой установки с прерванным импортом используйте
восстановление в новом volume: прежний volume сохраняется,
а обновлённый init-db.sh выводит этапы и имена SQL-файлов без паролей.
Первый импорт может занять несколько минут. Healthcheck БД требует маркер
успешного импорта; частично заполненная база не позволит ядру стартовать.
Если первый импорт прервался, изучите docker compose logs db. Удалять
volume и начинать заново допустимо только для новой, пустой установки;
рабочую БД восстанавливают из резервной копии.
В firewall разрешите TCP 3724 и 8085; доступ к SSH ограничьте своей сетью.
В клиенте укажите set realmlist <REALM_ADDRESS> в realmlist.wtf.
DNS должен иметь A-запись сервера. После изменения адреса/имени повторите
docker compose run --rm realm-config. Эта команда не создаёт аккаунты.
Русский язык
Штатный world dump уже содержит русские _loc8: в исходном дампе
проверены 14 418 предметов, 4 261 квест, 10 316 существ и 11 028 записей
locales_broadcast_text. Миграции ядра продолжают обновлять переводы.
Это основной, совместимый с VMaNGOS источник; отдельно заменять базу
на «русскую» не нужно. Эти числа отражают наличие непустых полей,
а не проверку качества или полноты перевода.
Необязательный дополнительный источник SQL: WoWruRU/classicdb_ruRU,
файл Full_DB/ClassicDB_ruRU_1_0_2.sql, commit
93f8aabbde2a7328a1f27f86539393471ed32b6c. Загрузка проверяет SHA256.
Оригинал рассчитан на CMaNGOS Classic и целиком не совместим с VMaNGOS.
prepare-russian.py извлекает только вставки в семь совместимых таблиц:
locales_creature: имена и подписи существ;locales_gameobject: названия объектов;locales_item: предметы и описания;locales_quest: тексты квестов;locales_page_text: книги;locales_gossip_menu_option: пункты меню NPC;locales_points_of_interest: подписи точек интереса.
При конфликте ключа заполняются только пустые поля _loc8; существующие
переводы VMaNGOS и другие языки сохраняются. SQL применяется автоматически при первом создании БД.
Для существующей БД сначала сделайте backup, остановите mangosd, затем:
docker compose exec -T db bash -c 'export MYSQL_PWD=$(cat /run/secrets/db_root_password); exec mariadb -uroot mangos' < database/ruRU.sql
docker compose up -d mangosd
Дополнительный импорт покрывает только семь таблиц. locales_npc_text, creature_ai_texts,
dbscript_string, gossip_texts, системные и скриптовые сообщения из
CMaNGOS не импортируются: в VMaNGOS другие схемы и/или идентификаторы.
Штатная база уже содержит русские locales_broadcast_text. Для переноса
дополнительных диалогов из CMaNGOS требуется сопоставление с broadcast_text.
Отдельных русских файлов в sql/translations этого checkout нет.
Локализация VMaNGOS
выбирается по языку клиента: ruRU имеет индекс 8 и использует _loc8.
Клиент должен действительно отправлять ruRU при авторизации; простая
замена шрифтов/английского текста этого не гарантирует. realmd сохраняет
язык в realmd.account.locale при каждом входе, поэтому ручное изменение
account.locale не является постоянным решением. Интерфейс, звуки и часть
названий требуют русифицированного клиента.
RealmZone=12 и DeclinedNames=1 включены; DBC.Locale=255 остаётся
автоопределением данных Vanilla и не переключает язык БД.
Проверка после входа русского клиента:
docker compose exec db bash -c 'export MYSQL_PWD=$(cat /run/secrets/db_root_password); mariadb -uroot -e "SELECT id,username,locale FROM realmd.account; SELECT COUNT(*) AS russian_items FROM mangos.locales_item WHERE LENGTH(name_loc8)>0;"'
Для проверки в игре используйте NPC, предмет, квест и книгу; удалите соответствующий клиентский WDB-кэш при закрытой игре, если видите старые тексты. Непереведённые поля возвращают английский текст.
PartyBot и BattleBot
В .env задайте PARTY_BOT_MAX_BOTS=4 и BATTLE_BOT_AUTO_JOIN=1.
Первый параметр ограничивает размер группы при призыве компаньонов,
второй добавляет временных ботов в очередь БГ до минимального числа
участников, когда туда встаёт настоящий игрок. Доступность самих БГ
определяется текущим этапом прогрессии. Случайные боты мира
для этого не требуются. Entrypoint мира подключён с хоста только для
чтения: параметры конфигурации применяются без пересборки ядра.
Чтобы открыть игрокам команды компаньонов, после резервного копирования примените SQL к world-базе и перезапустите мир:
docker compose exec -T db sh -c 'MYSQL_PWD="$(cat /run/secrets/db_password)" exec mariadb -uvmangos mangos' < enable-partybots.sql
docker compose up -d --no-deps --no-build mangosd
В игре: .partybot add tank, .partybot add healer, .partybot add dps.
Для удаления выделите бота и выполните .partybot remove.
Боты появляются на уровне игрока; штатные проверки призыва остаются
включены (PartyBot.SkipChecks=0). Загрузка чужого персонажа, клонирование
и ручное управление BattleBot остаются командами администраторов.
Эксплуатация
Контейнер мира использует TZ=Europe/Moscow: игровые часы и локальное
время процессов мира идут по Москве. Образ должен содержать tzdata для
Europe/Moscow. Параметр ядра TimeZoneOffset влияет на расчёт дня для
чести, а часы, отправляемые клиенту, используют часовой пояс процесса.
./backup.sh
Backup всех четырёх БД сохраняется в backups/*.sql.gz. Из-за MyISAM он
использует глобальную блокировку таблиц и временно задерживает запись:
запланируйте на период низкой активности. Настройте cron, внешнее хранение,
срок хранения и проверку восстановления. Пароли/.env и данные клиента
сохраняйте отдельно.
Пример восстановления выбранной копии (перезаписывает данные БД):
docker compose stop mangosd realmd
gunzip -c backups/SELECTED_BACKUP.sql.gz | docker compose exec -T db bash -c 'export MYSQL_PWD=$(cat /run/secrets/db_root_password); exec mariadb -uroot'
docker compose up -d realmd mangosd
Дамп не содержит пользователей MariaDB: при восстановлении на новом хосте сначала выполните начальную инициализацию, затем восстановите дамп.
Обновление ядра: backup, остановка мира и авторизации, сборка нового image, применение только новых миграций в соответствующие четыре базы, запуск и проверка логов. Автоматический импорт работает только на пустом volume; он не обновляет существующую БД. Откат image после миграций может потребовать восстановления старой БД. Сохраняйте предыдущий image и commit. Базовые Docker images закреплены по digest. Для повторяемого релиза сохраняйте проверенный commit ядра и digest собранного image. APT-пакеты и зависимости сборки могут меняться; разворачивайте сохранённый image вместо повторной сборки одного commit.
Docker stdout/stderr ограничен 5 файлами по 10 MB на контейнер. Файлы
игровых логов в auth_logs и world_logs требуют отдельной ротации
(например, logrotate с copytruncate на хосте) и мониторинга свободного места.
В конфиги попадают все штатные параметры из шаблонов текущего ядра;
entrypoint проверяет переопределяемые ключи и создаёт конфиги с правами 0600
в tmpfs. Настройки подключения к БД отсутствуют в stdout.
MariaDB 10.11 выбрана как поддерживаемая ветка. Upstream проверяет дампы на MySQL 5.6; совместимость этого варианта следует проверять на копии базы при каждом обновлении. Полный игровой smoke test требует клиентских данных и входа клиента. Под реальный онлайн настройте PLAYER_LIMIT, ресурсы БД, потоки карт и мониторинг по результатам нагрузочного теста.
Выполненная проверка
Собран Linux image ядра. На изолированной БД выполнены импорт закреплённого
world dump, всех миграций этого checkout и дополнительного русского SQL.
Проверены сохранение заполненных русских полей/других языков и заполнение
пустого русского поля. Compose создал БД с нуля и запустил realmd до
healthy; TCP 3724 отвечает. Проверены генерация world-конфига и backup.
Игровой вход, загрузка карт и полный запуск mangosd требуют клиентских
данных и пока не проверены.
Голосовой чат MoonWell
Голос идёт через отдельный контейнер voice-relay (UDP 3725, наружу), mangosd только выдаёт
клиентам подписанные тикеты (.mwvoice) и передаёт relay положение, группу и гильдию каждого
персонажа по внутренней сети compose. Голос в mangosd выключен, пока .env не включит его:
# Бинарник relay собирается в репозитории клиента: cargo build --release -p moonwell-voice
# --bin moonwell-voice-relay (под Linux), и кладётся сюда:
mkdir -p voice && cp moonwell-voice-relay voice/ && chmod 0755 voice/moonwell-voice-relay
(umask 077; openssl rand -hex 32 > secrets/voice_secret); chmod 0444 secrets/voice_secret
# В .env:
# MOONWELL_VOICE_ENABLE=1
# MOONWELL_VOICE_ADDRESS=play.moon-well.online:3725
docker compose up -d voice-relay mangosd
Секрет voice_secret нужен compose всегда (он объявлен для mangosd), даже при выключенном голосе.
Открыть в файрволе хоста нужно только UDP 3725.