L2J Mobius High Five docker setup

This commit is contained in:
2026-09-11 11:54:14 +00:00
commit c2e35cf5ee
27741 changed files with 2714798 additions and 0 deletions
+267
View File
@@ -0,0 +1,267 @@
# L2J Mobius High Five — Docker
L2J Mobius (хроники High Five, `L2J_Mobius_CT_2.6_HighFive`) в Docker Compose.
Три контейнера: `mysql`, `loginserver`, `gameserver`. Исходники сервера лежат
прямо в этом репозитории (`src/`) и собираются локально через Ant — без
внешних зависимостей от GitLab при каждой пересборке.
## Структура проекта
```
l2j-docker/
├── src/ # Исходники L2J Mobius (java/, build.xml, dist/, launcher/) — редактируешь напрямую
├── Dockerfile.build # Собирает src/ через Ant, кладёт результат в /out
├── scripts/
│ ├── collect-dist.sh # Нормализует результат сборки в /out/login, /out/game, /out/sql
│ └── extract-reference.sh # Выгружает /out на хост в reference/ для просмотра
├── login/
│ ├── Dockerfile # Runtime-образ login-сервера (JRE)
│ └── entrypoint.sh # Ждёт mysql, применяет config_override, стартует jar
├── game/
│ ├── Dockerfile # Runtime-образ game-сервера (JDK — нужен для скриптового движка)
│ └── entrypoint.sh # Ждёт mysql+login, применяет config_override, стартует jar
├── mysql/
│ ├── Dockerfile # MySQL 8.0 + автоимпорт SQL-схем при первом старте
│ └── init/
├── config/
│ ├── login/config/ # Override-конфиги login (применяются при каждом старте контейнера)
│ └── game/config/ # Override-конфиги game
├── reference/ # Сгенерированный полный дефолтный дистрибутив (не в git, см. ниже)
├── geodata/ # .l2j файлы геодаты (не входят в репозиторий, кладутся руками)
├── docker-compose.yml
├── .env # Пароли, порты — реальные значения, не в git
└── .env.example # Шаблон .env с плейсхолдерами
```
## Как это работает
1. **`Dockerfile.build`** копирует `src/` в builder-образ и собирает его через
`ant -f build.xml`. Результат — `LoginServer.jar`, `GameServer.jar` и SQL-схемы.
2. **`scripts/collect-dist.sh`** раскладывает собранный архив в `/out/login`,
`/out/game`, `/out/sql` — единую структуру для runtime-образов.
3. **`login/Dockerfile`** и **`game/Dockerfile`** берут готовый `/out/*` из
builder-образа и кладут в финальный контейнер с JRE/JDK.
4. **`config/login/config/`** и **`config/game/config/`** — это **единственное
место, где нужно редактировать конфиги**. При каждом старте контейнера
`entrypoint.sh` копирует всё из этой папки поверх дефолтных файлов внутри
контейнера. Правки здесь переживают любой `docker compose build` /
`--force-recreate`. Редактировать конфиги внутри уже запущенного
контейнера (`docker exec`) — не сохранится после пересборки.
## Запуск с нуля
### 1. Собрать builder-образ
```bash
docker build -f Dockerfile.build -t l2j-build:latest .
```
### 2. Геодата
Скачай геодату для High Five отдельно (она не входит в репозиторий Mobius и
не входит в этот проект — файлы `*.l2j`, обычно раздаются на форумах/трекерах).
Распакуй все `.l2j` файлы (и `geo_index.txt`) прямо в `./geodata/`, без
вложенных подпапок.
### 3. Настроить `.env`
```bash
cp .env.example .env # если только клонировал репозиторий
nano .env
```
Задай `MYSQL_ROOT_PASSWORD` и остальные значения. **Важно**: пароль здесь
должен совпадать с паролем в `config/login/config/Database.ini` и
`config/game/config/Database.ini` (см. ниже).
### ⚠️ Обязательно смени перед первым запуском
Репозиторий содержит рабочие сетевые настройки (`mysql`, `loginserver`
вместо `localhost`), но **пароль и IP — от конкретной машины, на которой
это разворачивалось изначально**. Смени их в трёх местах, иначе:
подключение к БД будет использовать чужой пароль, а клиенты будут
пытаться попасть на чужой IP.
1. **`config/login/config/Database.ini`** и **`config/game/config/Database.ini`**
— строка `Password = ...`. Должна совпадать с `MYSQL_ROOT_PASSWORD` в
`.env`.
2. **`config/game/config/ipconfig.xml`** — атрибут `address="..."` в
корневом теге `<gameserver>`. Это IP/домен, который сервер сообщает
клиенту после выбора сервера в списке (свой локальный/публичный IP,
не `192.168.1.207` — это чужая машина).
Всё остальное (`mysql`, `loginserver`, `0.0.0.0` в `Server.ini`) —
универсальные значения, менять не нужно, они завязаны на имена сервисов
в `docker-compose.yml`, а не на конкретный хост.
### 4. Настроить сетевые конфиги
Login и game сервера по умолчанию слушают/подключаются на `localhost` —
внутри Docker-сети это не работает, контейнеры видят друг друга по именам
сервисов (`mysql`, `loginserver`, `gameserver`). Уже настроено в
`config/*/config/Database.ini` и `config/login/config/Server.ini`:
- `Database.ini` (оба сервера): `URL = jdbc:mysql://mysql/l2jmobiush5?...`
- `login/config/Server.ini`: `LoginHostname = 0.0.0.0`, `LoginHostname` для
приёма game-сервера — `LoginHost = 0.0.0.0` (не `127.0.0.1`, иначе
gameserver не сможет подключиться из своего контейнера)
- `game/config/Server.ini`: `LoginHost = loginserver` (имя сервиса, не IP)
### 5. ipconfig.xml — адрес для клиентов
`config/game/config/ipconfig.xml` определяет, какой IP-адрес game-сервер
сообщает клиенту после выбора сервера в списке. Если клиент подключается:
- **с этого же сервера** — оставь `127.0.0.1`
- **из локальной сети** — укажи локальный IP сервера (например, `192.168.1.207`)
- **из интернета** — укажи публичный IP или домен
Пример минимального конфига:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<gameserver address="192.168.1.207" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../data/xsd/ipconfig.xsd">
</gameserver>
```
### 6. Собрать и запустить
```bash
docker compose build
docker compose up -d
docker compose logs -f mysql loginserver gameserver
```
Ожидаемая последовательность в логах:
1. `mysql` — выполняет SQL-схемы, проходит healthcheck
2. `loginserver` — `LoginServer: Login client listener started on 0.0.0.0:2106`
3. `gameserver` — `LoginServerThread: Registered on login as Server N: <Name>`
Если видишь `Registered on login as Server` — стек полностью поднят.
## Просмотр полного дистрибутива сервера (reference)
`/out` внутри builder-образа (`login/`, `game/`, `sql/` с jar-файлами,
конфигами и data/) существует только как промежуточный слой между стадиями
Docker-сборки — на хосте его не видно напрямую. Чтобы удобно читать
дефолтные файлы сервера (посмотреть, что там есть, прежде чем что-то
копировать в override), используй скрипт `scripts/extract-reference.sh`:
```bash
./scripts/extract-reference.sh
```
Это выгружает полный `/out` из свежего `l2j-build:latest` образа в
`./reference/` — обычную папку на диске:
```
reference/login/config/...
reference/game/config/...
reference/game/data/...
reference/login/libs/...
```
Дальше — смотришь нужный файл и копируешь **только его** в override:
```bash
cat reference/game/config/Rates.ini
cp reference/game/config/Rates.ini config/game/config/Rates.ini
nano config/game/config/Rates.ini
docker compose up -d --force-recreate gameserver
```
`reference/` — сгенерированные файлы, не нужно коммитить их в git (см.
`.gitignore`). После пересборки Java-кода (`docker build -f Dockerfile.build
...`) перезапусти скрипт, чтобы `reference/` отражал актуальную сборку:
```bash
docker build -f Dockerfile.build -t l2j-build:latest . && ./scripts/extract-reference.sh
```
## Редактирование конфигов
Все дефолтные конфиги обоих серверов уже скопированы в
`config/login/config/` и `config/game/config/`. Правь их прямо здесь:
```bash
nano config/game/config/Rates.ini # рейты экспы/дропа
nano config/game/config/NPC.ini # агрессия, respawn
nano config/game/config/Player.ini # лимиты персонажей
```
После правки — пересоздать нужный контейнер (без пересборки образа, если
менялся только конфиг, а не код):
```bash
docker compose up -d --force-recreate gameserver
```
**Важно — не копируй `reference/` в `config/` массово поверх уже
настроенных файлов.** `config/login/config/Database.ini`,
`config/game/config/Database.ini`, `config/game/config/Server.ini` и
`config/game/config/ipconfig.xml` содержат критичные сетевые правки
(`mysql`/`loginserver` вместо `localhost`/`127.0.0.1`) — если их затереть
дефолтными значениями из `reference/`, game-сервер перестанет находить
MySQL или login-сервер (`Connection refused`, `LoginServer not available`).
Копируй в override только конкретные файлы, которые собираешься менять,
не весь каталог целиком.
## Изменение кода сервера
Исходники лежат в `src/java/`. После правки:
```bash
docker build -f Dockerfile.build -t l2j-build:latest .
docker compose build
docker compose up -d
```
Первая команда пересобирает Java-код через Ant, вторая — пересобирает
runtime-образы login/game с новыми jar-файлами, третья — перезапускает стек.
## Память JVM
Размер кучи для game-сервера задан в `game/entrypoint.sh`:
```bash
exec java -Xms1g -Xmx4g -Dfile.encoding=UTF-8 -cp "$CLASSPATH" -jar libs/GameServer.jar
```
Полная геодата High Five (203 региона) требует заметного объёма памяти при
загрузке — при `OutOfMemoryError` на этапе `[ Geodata ]` увеличь `-Xmx`.
После правки:
```bash
docker compose build gameserver
docker compose up -d --force-recreate gameserver
```
## Резервное копирование
Образы и контейнеры полностью воспроизводимы из этого репозитория — бэкапить
нужно только:
1. **Сам репозиторий** (`src/`, конфиги, override) — обычный git.
2. **Данные MySQL** (аккаунты, персонажи) — они живут в Docker-volume
`mysql_data`, не в файлах проекта. Дамп:
```bash
docker exec l2j-mysql mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" l2jmobiush5 > backup_$(date +%Y%m%d_%H%M%S).sql
```
Восстановление:
```bash
docker exec -i l2j-mysql mysql -u root -p"$MYSQL_ROOT_PASSWORD" l2jmobiush5 < backup_ФАЙЛ.sql
```
## Порты
| Сервис | Порт | Назначение |
|---|---|---|
| loginserver | 2106 | Подключение клиента (экран логина) |
| gameserver | 7777 | Подключение клиента (после выбора сервера) |
| gameserver → loginserver | 9014 | Внутренний auth-обмен между серверами |
| mysql | 3306 | БД (не публикуется наружу по умолчанию) |
Меняются в `.env`.