Compare commits

..

No commits in common. "7dc6ebffa251b90e98c1d083ba42466009d0535d" and "0a497f5a69fa2e1be6746b86940a4843b2cb794d" have entirely different histories.

4 changed files with 98 additions and 200 deletions

View File

@ -1,24 +1,22 @@
################################################################################ ################################################################################
# Docker images # MySQL settings
################################################################################ ################################################################################
GAME_IMAGE=git.old-metin2.com/metin2/server:latest MYSQL_HOST=mysql
WEB_IMAGE=git.old-metin2.com/metin2/web:latest MYSQL_USER=root
MYSQL_PASSWORD=metin2
################################################################################ MYSQL_PORT=3306
# MariaDB settings MYSQL_EXTERNAL_PORT=3306
################################################################################ MYSQL_DB_ACCOUNT=account
MARIADB_HOST=mariadb MYSQL_DB_PLAYER=player
MARIADB_USER=root MYSQL_DB_COMMON=common
MARIADB_PASSWORD=metin2 MYSQL_DB_LOG=log
MARIADB_PORT=3306
MARIADB_EXTERNAL_PORT=3306
MARIADB_DB=metin2
################################################################################ ################################################################################
# Web app settings # Web app settings
################################################################################ ################################################################################
# General configuration # General configuration
WEB_IMAGE=git.old-metin2.com/metin2/website:nightly
WEB_APP_NAME=Metin2 WEB_APP_NAME=Metin2
WEB_APP_ENV=production WEB_APP_ENV=production
WEB_APP_URL=http://metin2.local WEB_APP_URL=http://metin2.local
@ -48,4 +46,5 @@ DB_PORT=15000
# Game settings # Game settings
PUBLIC_IP=127.0.0.1 PUBLIC_IP=127.0.0.1
GAME_IMAGE=git.old-metin2.com/metin2/server:nightly
GAME_MAX_LEVEL=105 GAME_MAX_LEVEL=105

139
README.md
View File

@ -1,140 +1,29 @@
# The Metin2 Deployment Files # The Metin2 Deployment Files
The Old Metin2 Project aims at improving and maintaining the 2014 Metin2 game The Old Metin2 Project aims at improving and maintaining the 2014 Metin2 game files up to modern standards. The goal is to archive the game as it was in order to preserve it for the future and enable nostalgic players to have a good time.
files up to modern standards. The goal is to archive the game as it was in
order to preserve it for the future and enable nostalgic players to have a
good time.
For-profit usage of this material is certainly illegal without the proper For-profit usage of this material is certainly illegal without the proper licensing agreements and is hereby discouraged (not legal advice). Even so, the nature of this project is HIGHLY EXPERIMENTAL - bugs are to be expected for now.
licensing agreements and is hereby discouraged (not legal advice). Even so, the
nature of this project is HIGHLY EXPERIMENTAL - bugs are to be expected for now.
## Quick start guide ## Usage
The deployment strategy for this project is based around Docker Compose. Make The deployment strategy for this project is based around Docker Compose. For now, no images are published, so building your own server image is required. Also, for now, you need to provide your own database schema.
sure that you have a compatible Linux + Docker environment - for more
information, check out the [compatibility matrix](https://git.old-metin2.com/metin2/deploy#compatibility-matrix).
### Architecture description ### Building the server image
The MySQL database is currently pinned on version 5.5. We're using the This process requires that you do the following steps on a Linux environment with Docker installed and running.
[biarms/mysql](https://github.com/biarms/mysql) project in order to provide ARM
compatibility for such an old version of MySQL.
The game cores (`db`, `auth`, `game-*`) are ran by using pre-built images Clone the Server project repository:
containing the server binaries and game files, provided in the
[Server repository](https://git.old-metin2.com/metin2/server/packages).
The web application provides the actual website, item mall and autopatcher
functionality. Moreover, it is responsible with maintaining the database schema,
creating and updating tables when needed. Pre-built images containing the web
application are provided in the
[Website repository](https://git.old-metin2.com/metin2/web/packages).
### Preparing the server
Clone this repository and access its root directory. For instance, on Linux you
would do this:
```shell ```shell
git clone --depth 1 https://git.old-metin2.com/metin2/deploy.git metin2-deploy git clone https://git.old-metin2.com/metin2/server.git
cd metin2-deploy/
``` ```
Now, we need to copy the example environment file and name it `.env`. This file Build the image:
contains all settings used by Docker Compose to start up our project.
```shell ```shell
cp .env.example .env cd server
docker build -t metin2/server:test .
``` ```
Some settings aren't yet filled out. The actual settings will differ based on
your setup. We'll assume that you're using WSL and Docker on your own computer,
and you want to run the server locally, just for yourself. Start with opening
the newly copied `.env` file.
Firstly, we need to configure the web application. Find `WEB_APP_URL` and change
it to the URL you would use to access the machine you're installing this on
(without a trailing slash!). In our case, simply set it to `http://localhost`.
You might already use port 80 on your machine for something else, in which case
we need to configure the app to use another port. Simply change `WEB_EXTERNAL_PORT`
to another value, for example `8080`. Don't forget to change `WEB_APP_URL`
accordingly, in our case to `http://localhost:8080`.
Next, we need to generate a cryptographic key. We'll make use of Laravel's
generator feature, as follows:
```shell
docker run --rm git.old-metin2.com/metin2/web:latest "php artisan key:generate --show"
```
Run the above command and configure `WEB_APP_KEY` with the output. You should
end up with something like: `WEB_APP_KEY=base64:<your-key-here>`.
Lastly, let's switch our focus to the game server. Make sure that `PUBLIC_IP` is
set to a value at which you can access your machine. As a rule of thumb, this
should be the same value you set in your client's `serverinfo.py`. In our case,
leaving a value of `127.0.0.1` should work just fine.
Don't forget to save your `.env` file!
### Starting the server ### Starting the server
You're ready to start the server. Simply run the following command to start up Clone this repository and open a terminal window in its root directory. Then, simply bring up the Compose project:
the server:
```shell ```shell
docker compose up -d --pull always docker compose up -d
``` ```
On the first run, your database tables will be created and populated with default data. On the first run, you might need to connect to port 3306 with your favourite MySQL client (Navicat, DBeaver, phpMyAdmin etc.) and install a Metin2 database schema.
### Stopping the server
Should you want to stop the server, simply bring down the Docker Compose stack:
```shell
docker compose down
```
### Only start some services
This deployment environment can also be used for development purposes. If you
need a database and website, but want to run the server in some other way (for
example, in an IDE), you can just bring up only the services you need:
```shell
docker compose up -d mysql web
```
## Compatibility matrix
| **Operating system** | amd64 | i386 | arm64 | armv7 | Notes |
|------------------------|-------|------|-------|-------|------------------------------------------------------------|
| **Debian 11** | ⚠️ | ❔ | ❔ | ❌ | Requires `EVENT_NOEPOLL=1` environment variable to be set. |
| **Debian 12** | ✅ | ❔ | ❔ | ❌ | |
| **Ubuntu 22.04.5 LTS** | ✅ | N/A | ❔ | ❌ | |
| **Ubuntu 24.04.1 LTS** | ❔ | N/A | ❔ | ❌ | |
| **Docker on WSL** | ✅ | N/A | ❔ | N/A | |
| **Docker on macOS** | ❔ | N/A | ✅ | N/A | |
### What about Windows, FreeBSD? macOS?
As described above, the deployment system for The Old Metin2 Project is based
on Docker and Docker Compose. Since support for native Windows, FreeBSD or
macOS Docker containers is experimental at best and unavailable at worst,
the auto-magical deployment system in this repository is not compatible with
these OSs.
Compiling [the server](https://git.old-metin2.com/metin2/server)
binary and running it on these systems should be possible, but you have to come
up with your own deployment strategy, be it shell scripts, a custom watchdog
program, or simply manually starting the binaries. Moreover, this is currently
outside the scope of the project and unsupported for the time being.
## Help!
### `epoll_wait` issues
On some Linux distributions, kernels are shipped without `epoll_wait` support,
which in turn might lead to the following error being shown (and the server
naturally won't start):
```
[warn] epoll_wait: Function not implemented
```
Luckily, there is a workaround: disabling the `epoll` backend of libevent. In
order to do this, modify your `&common-environment` section in your
`docker-compose.yml` file by adding the following line:
```
EVENT_NOEPOLL: 1
```

View File

@ -1 +1,5 @@
CREATE DATABASE metin2 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE DATABASE account CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE common CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE log CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE player CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE website CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

View File

@ -1,9 +1,13 @@
x-environment: &common-environment x-environment:
MARIADB_HOST: ${MARIADB_HOST} &common-environment
MARIADB_USER: ${MARIADB_USER} MYSQL_HOST: ${MYSQL_HOST}
MARIADB_PASSWORD: ${MARIADB_PASSWORD} MYSQL_USER: ${MYSQL_USER}
MARIADB_PORT: ${MARIADB_PORT} MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MARIADB_DB: ${MARIADB_DB} MYSQL_PORT: ${MYSQL_PORT}
MYSQL_DB_ACCOUNT: ${MYSQL_DB_ACCOUNT}
MYSQL_DB_PLAYER: ${MYSQL_DB_PLAYER}
MYSQL_DB_COMMON: ${MYSQL_DB_COMMON}
MYSQL_DB_LOG: ${MYSQL_DB_LOG}
TEST_SERVER: ${TEST_SERVER} TEST_SERVER: ${TEST_SERVER}
@ -15,32 +19,23 @@ x-environment: &common-environment
WEB_APP_URL: ${WEB_APP_URL} WEB_APP_URL: ${WEB_APP_URL}
WEB_APP_KEY: ${WEB_APP_KEY} WEB_APP_KEY: ${WEB_APP_KEY}
name: Metin2
services: services:
# MariaDB Database # MySQL Database
mariadb: mysql:
image: mariadb:lts image: mysql:5.5
restart: always restart: on-failure
environment: environment:
# Password for root access # Password for root access
MARIADB_ROOT_PASSWORD: ${MARIADB_PASSWORD} MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}
ports: ports:
- "${MARIADB_EXTERNAL_PORT}:${MARIADB_PORT}" - '${MYSQL_EXTERNAL_PORT}:${MYSQL_PORT}'
expose: expose:
- ${MARIADB_PORT} - ${MYSQL_PORT}
volumes: volumes:
- ./storage/database/:/var/lib/mysql/ - ./storage/database/:/var/lib/mysql/
- ./assets/db-init/:/docker-entrypoint-initdb.d/:ro - ./assets/db-init/:/docker-entrypoint-initdb.d/:ro
healthcheck: healthcheck:
test: test: mysqladmin ping -h localhost -u root -p$$MYSQL_ROOT_PASSWORD
[
"CMD",
"healthcheck.sh",
"--su-mysql",
"--connect",
"--innodb_initialized",
]
interval: 10s interval: 10s
timeout: 5s timeout: 5s
retries: 5 retries: 5
@ -48,7 +43,7 @@ services:
# Web management system # Web management system
web: web:
image: ${WEB_IMAGE} image: ${WEB_IMAGE}
restart: always restart: on-failure
environment: environment:
# Application config # Application config
APP_NAME: ${WEB_APP_NAME} APP_NAME: ${WEB_APP_NAME}
@ -57,11 +52,10 @@ services:
APP_URL: ${WEB_APP_URL} APP_URL: ${WEB_APP_URL}
# Database credentials # Database credentials
DB_HOST: ${MARIADB_HOST} DB_HOST: ${MYSQL_HOST}
DB_PORT: ${MARIADB_PORT} DB_PORT: ${MYSQL_PORT}
DB_DATABASE: ${MARIADB_DB} DB_USERNAME: ${MYSQL_USER}
DB_USERNAME: ${MARIADB_USER} DB_PASSWORD: ${MYSQL_PASSWORD}
DB_PASSWORD: ${MARIADB_PASSWORD}
# E-mail config # E-mail config
MAIL_MAILER: ${WEB_MAIL_MAILER} MAIL_MAILER: ${WEB_MAIL_MAILER}
@ -73,11 +67,11 @@ services:
MAIL_FROM_ADDRESS: ${WEB_MAIL_FROM_ADDRESS} MAIL_FROM_ADDRESS: ${WEB_MAIL_FROM_ADDRESS}
MAIL_FROM_NAME: ${WEB_MAIL_FROM_NAME} MAIL_FROM_NAME: ${WEB_MAIL_FROM_NAME}
ports: ports:
- "${WEB_EXTERNAL_PORT}:80" - '${WEB_EXTERNAL_PORT}:80'
volumes: volumes:
- ./storage/web/:/app/storage/ - ./storage/web/:/app/storage/
depends_on: depends_on:
mariadb: mysql:
condition: service_healthy condition: service_healthy
healthcheck: healthcheck:
test: curl --fail http://localhost:80/ || exit 1 test: curl --fail http://localhost:80/ || exit 1
@ -88,7 +82,7 @@ services:
# DBCache Server # DBCache Server
db: db:
image: ${GAME_IMAGE} image: ${GAME_IMAGE}
restart: always restart: on-failure
environment: *common-environment environment: *common-environment
expose: expose:
- ${DB_PORT} - ${DB_PORT}
@ -96,16 +90,18 @@ services:
volumes: volumes:
- ./storage/log/db/:/app/log/ - ./storage/log/db/:/app/log/
depends_on: depends_on:
mariadb: mysql:
condition: service_healthy
web:
condition: service_healthy condition: service_healthy
# Auth server # Auth server
auth: auth:
image: ${GAME_IMAGE} image: ${GAME_IMAGE}
restart: always restart: on-failure
environment: environment:
<<: *common-environment <<: *common-environment
MARIADB_DB: ${MARIADB_DB} MYSQL_DB_PLAYER: ${MYSQL_DB_ACCOUNT}
GAME_HOSTNAME: auth GAME_HOSTNAME: auth
GAME_CHANNEL: 1 GAME_CHANNEL: 1
GAME_AUTH_SERVER: master GAME_AUTH_SERVER: master
@ -115,18 +111,20 @@ services:
- 11000 - 11000
- 12000 - 12000
ports: ports:
- "11000:11000" - '11000:11000'
command: game command: game
volumes: volumes:
- ./storage/log/auth/:/app/log/ - ./storage/log/auth/:/app/log/
depends_on: depends_on:
mariadb: mysql:
condition: service_healthy
web:
condition: service_healthy condition: service_healthy
# Game server (CH1) # Game server (CH1)
ch1_first: ch1_first:
image: ${GAME_IMAGE} image: ${GAME_IMAGE}
restart: always restart: on-failure
environment: environment:
<<: *common-environment <<: *common-environment
GAME_HOSTNAME: ch1_first GAME_HOSTNAME: ch1_first
@ -139,18 +137,20 @@ services:
- 13000 - 13000
- 14000 - 14000
ports: ports:
- "13000:13000" - '13000:13000'
command: game command: game
volumes: volumes:
- ./storage/log/ch1/first/:/app/log/ - ./storage/log/ch1/first/:/app/log/
- ./storage/mark/:/app/mark/ - ./storage/mark/:/app/mark/
depends_on: depends_on:
mariadb: mysql:
condition: service_healthy
web:
condition: service_healthy condition: service_healthy
ch1_game1: ch1_game1:
image: ${GAME_IMAGE} image: ${GAME_IMAGE}
restart: always restart: on-failure
environment: environment:
<<: *common-environment <<: *common-environment
GAME_HOSTNAME: ch1_game1 GAME_HOSTNAME: ch1_game1
@ -163,17 +163,19 @@ services:
- 13001 - 13001
- 14001 - 14001
ports: ports:
- "13001:13001" - '13001:13001'
command: game command: game
volumes: volumes:
- ./storage/log/ch1/game1/:/app/log/ - ./storage/log/ch1/game1/:/app/log/
depends_on: depends_on:
mariadb: mysql:
condition: service_healthy
web:
condition: service_healthy condition: service_healthy
ch1_game2: ch1_game2:
image: ${GAME_IMAGE} image: ${GAME_IMAGE}
restart: always restart: on-failure
environment: environment:
<<: *common-environment <<: *common-environment
GAME_HOSTNAME: ch1_game2 GAME_HOSTNAME: ch1_game2
@ -186,18 +188,20 @@ services:
- 13002 - 13002
- 14002 - 14002
ports: ports:
- "13002:13002" - '13002:13002'
command: game command: game
volumes: volumes:
- ./storage/log/ch1/game2/:/app/log/ - ./storage/log/ch1/game2/:/app/log/
depends_on: depends_on:
mariadb: mysql:
condition: service_healthy
web:
condition: service_healthy condition: service_healthy
# Game server (game99) # Game server (game99)
game99: game99:
image: ${GAME_IMAGE} image: ${GAME_IMAGE}
restart: always restart: on-failure
environment: environment:
<<: *common-environment <<: *common-environment
GAME_HOSTNAME: game99 GAME_HOSTNAME: game99
@ -210,10 +214,12 @@ services:
- 13099 - 13099
- 14099 - 14099
ports: ports:
- "13099:13099" - '13099:13099'
command: game command: game
volumes: volumes:
- ./storage/log/game99/:/app/log/ - ./storage/log/game99/:/app/log/
depends_on: depends_on:
mariadb: mysql:
condition: service_healthy
web:
condition: service_healthy condition: service_healthy