docker contribution for linux (#153)

* initial review for docker

* update link

* more typos

* hight letter

* it's realm.rft

* realm.rtf

* remove legacy code from dockerfiles

* docker-compose cleanup,- documented clone the right database

* add timezone to mangos.env

* add more at the build command

* double only

* it's a script not a container

* more documentation and moved into seperate folder

* revert back the openssl

* reformat documentation

* high letter

* timezone

* reduce dockerfiles and add documentation

* removed mangos user from build script

* correct links for realmd and world

* fixing small things, after railroid the documentation.

* command is called restart

* hold the documentation line

* add the changes for realmlist.wtf

Co-authored-by: AndyBe <andreas.benzler@gmail.com>
This commit is contained in:
andybe 2021-05-09 22:11:05 +02:00 committed by GitHub
parent 3c361078f8
commit c4095615b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 579 additions and 0 deletions

13
contrib/docker/Dockerfile Normal file
View File

@ -0,0 +1,13 @@
from ubuntu:focal
RUN apt update && apt dist-upgrade -y
# we need to setup tzdata otherwise focal ask for time zone
RUN DEBIAN_FRONTEND=noninteractive \
TZ=Europe/Berlin \
apt install -y build-essential cmake git-core libbz2-dev \
libmariadb-dev libmariadbclient-dev libmariadb-dev-compat \
libssl-dev
WORKDIR /work
ENTRYPOINT /bin/bash

15
contrib/docker/README.md Normal file
View File

@ -0,0 +1,15 @@
<h3>Documentation for example docker-compose instance</h3>
- <a href="https://github.com/andybe/server/blob/master/contrib/docker/doc/SINGLE.md" >Install mangos as single instance with mangos-zero</a>
- <a href="https://github.com/andybe/server/blob/master/contrib/docker/doc/DOCKERCOMPOSE.md" >The "if and way" about the mangos docker-compose.yml</a>
- <a href="https://github.com/andybe/server/tree/master/contrib/docker/realm#readme" >Realmd Dockerfile</a>
- <a href="https://github.com/andybe/server/tree/master/contrib/docker/world#readme" >Mangos world Dockerfile</a>
<br>
<h3>Please read up in single instance.</h3>
Do not run the build.sh outside the container.<br>
It is written to be run in the build container as documented *single instance*.

44
contrib/docker/build.sh Executable file
View File

@ -0,0 +1,44 @@
#!/bin/bash
CMAKE_COMMANDS='-DCMAKE_INSTALL_PREFIX=/app -DCONF_INSTALL_DIR=/app/etc -DBUILD_EXTRACTORS=ON -DBUILD_PLAYERBOT=ON'
# container application
if [ ! -d "app/bin" ]; then
mkdir -p app/bin
fi
# needed for mangos container - from docker-compose build
if [ ! -f "app/bin/mangosd-entrypoint.sh" ]; then
cp mangos/contrib/docker/world/mangosd-entrypoint.sh app/bin/mangosd-entrypoint.sh
fi
# docker env
if [ ! -f "mangos.env" ]; then
cp mangos/contrib/docker/mangos.env .
fi
# the compose file for all 3 containers (db /realm /world)
if [ ! -f "docker-compose.yml" ]; then
cp mangos/contrib/docker/docker-compose.yml .
fi
# update git source
if [ -d "mangos" ]; then
cd mangos
git pull
cd ..
fi
#create a build directory
if [ ! -d "build" ]; then
mkdir build
fi
cd build
cmake $CMAKE_COMMANDS ../mangos
# build mangos with all available cores
make -j$(nproc --all)
# install binaries and default configurations into
# /app/bin/{tools}
# /app/etc
make install

View File

@ -0,0 +1,111 @@
<h1>The "if and why" about the mangos docker-compose.yml</h1><br>
There a many ways to write an docker-compose.<br><br>
For best practice
- keep it simple as possible
- all container named
- network is defined as mangos
- every container starts automatical, but can be stopped at any time<br>
"restart: unless-stopped"
- localtime is mapped into the container and also define in mangos.env<br>
This is absolute recommend, because container can run in different timezones.
<h1>Alle containers depends on the database</h1>
The mariadb:latest is a debian based container.<br> Nothing needs to be rethink - debian and ubuntu - use the same command lines.
```
mangos-db:
container_name: mangos-db
image: mariadb:latest
restart: unless-stopped
env_file:
- mangos.env
networks:
- mangos
volumes:
- /etc/localtime:/etc/localtime:ro
- ./mariadb/:/var/lib/mysql
- ./zero-database:/zero-database
```
As you can see at the last line the source from database is mapped into the container. This is normal needed once for initialization.<br>
<br>
<h1>Next moangos login server</h1>
```
mangos-realm:
image: mangos-realm
build:
context: ./app
dockerfile: ../mangos/contrib/docker/realm/Dockerfile
container_name: mangos-realm
restart: unless-stopped
ports:
- target: 3724
published: 3724
protocol: tcp
mode: host
env_file:
- mangos.env
volumes:
- /etc/localtime:/etc/localtime:ro
- ./app/etc:/app/etc
- ./logs:/app/logs
depends_on:
- mangos-db
networks:
- mangos
```
The part of ports is a little bit different and live on "host".<br><br>
Why? All streams are transported into the container and ip address is changed.<br>How you wanne ban clients with the right ip address?<br> The mode "host" makes it possible. In this case it can be define only onces at running the host.<br><br>
The configuration and logs are mapped as volume into the container.
<br>
<h1>Lets jump into the world server</h1>
```
mangos:
image: mangos
build:
context: app
dockerfile: ../mangos/contrib/docker/world/Dockerfile
container_name: mangos
restart: unless-stopped
ports:
- target: 8085
published: 8085
protocol: tcp
mode: host
- 7878:7878
env_file:
- mangos.env
volumes:
- /etc/localtime:/etc/localtime:ro
- ./app/etc:/app/etc
- ./data:/app/data
- ./logs:/app/logs
depends_on:
- mangos-db
- mangos-realm
networks:
- mangos
```
In principal same stuff as on the realm service.<br>
In additional we need the world data as volume.
<h1>The mangos network adapter</h1>
At the end we define an network adapter for the inner communication.
```
networks:
mangos:
name: mangos
driver: bridge
```
Cheers

View File

@ -0,0 +1,154 @@
<h1>Example container for the mangos zero</h1>
What you need to know:
- How docker works (docker.io - https://www.docker.com/)
- linux commandline standards
- sql statments
This example works only on local(host) machine. For the cloud the database must be changed.
Not here documented.<br><br>
We use a build container? Because realm and world should be small as possible and shippes only
we the nessery binaries.
<h3>1) Create the build container on ubuntu:focal</h3><br>
```
git clone git clone https://github.com/mangoszero/server.git mangos --recursive
docker build mangos/contrib/docker/ -t mangos-zero-build
```
<h3>2) Build the source and create directory structur</h3><br>
Create a build script
```
echo "docker run -v$(pwd)/app:/app -v $(pwd):/work " \
"--rm -it --entrypoint ./mangos/contrib/docker/build.sh \
mangos-zero-build" > build.sh
chmod +x build.sh
```
For a rebuild next time we only need
```
./build.sh (&& docker-compose build && docker-compose restart)
```
(Optional) Create an extractor container script for the maps
```
echo "docker run -v$(pwd)/app:/app -v $(pwd):/work " \
"--rm -it mangos-zero-build bash" > extract.sh
```
<h3>3) (Optional) Extract needed data from client</h3><br>
Copy the full client into you work directory like
(here from linux lutris)
```
cp -r /home/XXX/Games/WorldOfWarcraft/drive_c/WoW1.12.1 .
```
Join into the extractor container (build)
```
./extract.sh
(container) cd WoW1.12.1
(container) cp -r ../app/bin/tools/* .
(container) chmod +x Extractor.sh
(container) ./Extractor.sh
(container) exit
```
This may take a while.<br>
Now wee need a data directory.
```
mkdir data
cd WoW1.12.1
cp -r Buildings dbc maps mmaps vmaps ../data
```
<h3>4) If everything went fine we create our container by</h3><br>
```
docker-compose build
```
<h3>5) Intialize the database</h3><br>
We need the right database for the server.
```
git clone https://github.com/mangoszero/database zero-database --recursive
```
Now we can start the database container.
```
docker-compose up -d mangos-db
docker exec -it mangos-db bash
(container) cd zero-database
(container) ./InstallDatabases.sh
Database (root for now)
- host: localhost
- user: "root"
- password: "mangos"
(container) exit
```
<h3>6) Configure container</h3><br>
```
cd app/etc
sudo cp realmd.conf.dist realmd.conf
sudo cp mangosd.conf.dist mangosd.conf
sudo cp ahbot.conf.dist ahbot.conf
```
For realmd change follow lines in realmd.conf (wee need to root)<br>
-> sudo nano realmd.conf
```
LoginDatabaseInfo = "localhost;3306;root;mangos;realmd"
LogsDir = ""
```
into
```
LoginDatabaseInfo = "mangos-db;3306;root;mangos;realmd"
LogsDir = "/app/logs"
```
For mangosd we update mangosd.conf (wee need to root)<br>
-> sudo nano mangosd.conf
```
DataDir = ""
LogsDir = ""
LoginDatabaseInfo = "127.0.0.1;3306;root;mangos;realmd"
WorldDatabaseInfo = "127.0.0.1;3306;root;mangos;mangos0"
CharacterDatabaseInfo = "127.0.0.1;3306;root;mangos;character0"
```
into
```
DataDir = "/app/data"
LogsDir = "/app/logs"
LoginDatabaseInfo = "mangos-db;3306;root;mangos;realmd"
WorldDatabaseInfo = "mangos-db;3306;root;mangos;mangos0"
CharacterDatabaseInfo = "mangos-db;3306;root;mangos;character0"
```
Back to the workspace
```
cd ../..
```
<h3>7) Start the realmd & mangos-one container detached</h3><br>
```
docker-compose up -d mangos-realm mangos-one
```
take a look with "docker stats". Hopefully all container stay and not reloaded all the time.
<h3>8) Join the world container to create an admin user</h3><br>
```
docker exec -it mangos-zero bash
(container) screen -r (go into screen)
(container - screen) account create testuser mypassword
(container - screen) strg + a + d (detache from screen)
(container) exit
```
<h3>9) Don't forget to change the realmlist.wtf from WoW client to localhost.</h3>
```
set realmlist localhost
```

View File

@ -0,0 +1,70 @@
version: '3'
services:
mangos-db:
container_name: mangos-db
image: mariadb:latest
restart: unless-stopped
env_file:
- mangos.env
networks:
- mangos
volumes:
- /etc/localtime:/etc/localtime:ro
- ./mariadb/:/var/lib/mysql
- ./zero-database:/zero-database
mangos-realm:
image: mangos-realm
build:
context: ./app
dockerfile: ../mangos/contrib/docker/realm/Dockerfile
container_name: mangos-realm
restart: unless-stopped
ports:
- target: 3724
published: 3724
protocol: tcp
mode: host
env_file:
- mangos.env
volumes:
- /etc/localtime:/etc/localtime:ro
- ./app/etc:/app/etc
- ./logs:/app/logs
depends_on:
- mangos-db
networks:
- mangos
mangos-zero:
image: mangos-zero
build:
context: app
dockerfile: ../mangos/contrib/docker/world/Dockerfile
container_name: mangos-zero
restart: unless-stopped
ports:
- target: 8085
published: 8085
protocol: tcp
mode: host
- 7878:7878
env_file:
- mangos.env
volumes:
- /etc/localtime:/etc/localtime:ro
- ./app/etc:/app/etc
- ./data:/app/data
- ./logs:/app/logs
depends_on:
- mangos-db
- mangos-realm
networks:
- mangos
networks:
mangos:
name: mangos
driver: bridge

View File

@ -0,0 +1,4 @@
MYSQL_ROOT_PASSWORD=mangos
MYSQL_USER=mangos
MYSQL_PASSWORD=mangos
TZ=Europe/Berlin

View File

@ -0,0 +1,16 @@
from ubuntu:focal
RUN apt update && apt dist-upgrade -y --no-install-recommends \
openssl \
libmariadb3
RUN mkdir -p /app/bin
COPY bin/realmd /app/bin/
RUN mkdir /app/etc
COPY etc/realmd.conf.dist /app/etc/
EXPOSE 3724
WORKDIR "/app/bin"
CMD [ "./realmd"]

View File

@ -0,0 +1,41 @@
<h1>The realmd Dockerfile</h1>
This Dockerfile only is used on running the realmd service.
As you know we got a build container.<br>Most docker instance
not use this way, but this is the cleanest way.
We use ubuntu focal as base system because of longterm
```
from ubuntu:focal
```
Update the container and add neccesary parts to run the realmd binary
```
RUN apt update && apt dist-upgrade -y --no-install-recommends \
openssl \
libmariadb3
```
Create the bin directory and copy in realmd service
```
RUN mkdir -p /app/bin
COPY bin/realmd /app/bin/
```
We save the configuration in the container. It will not be used in
our process, but we got it handy in te container.
```
RUN mkdir /app/etc
COPY etc/realmd.conf.dist /app/etc/
```
Now we expose the port that the client login will looking for
```
EXPOSE 3724
```
Define the app/bin as start point ...
```
WORKDIR "/app/bin"
```
The run command is the realmd for sure.
```
CMD [ "./realmd"]
```
We can protect the server more if we run the realmd as seperate user.
In the matter of simplicty this is a future step.

View File

@ -0,0 +1,25 @@
from ubuntu:focal
RUN apt update && apt dist-upgrade -y --no-install-recommends init \
libmariadb3 mariadb-client screen \
openssl \
procps nano less
COPY bin/mangosd-entrypoint.sh /usr/bin/entrypoint.sh
RUN chmod +x /usr/bin/entrypoint.sh
RUN mkdir -p /app/bin/tools
COPY bin/mangosd /app/bin/
COPY bin/tools/* /app/bin/tools/
RUN mkdir /app/etc
COPY etc/mangosd.conf.dist /app/etc/
COPY etc/ahbot.conf.dist /app/etc/
EXPOSE 8085
EXPOSE 7878
WORKDIR "/app"
ENTRYPOINT ["/usr/bin/entrypoint.sh"]

View File

@ -0,0 +1,69 @@
<h1>The mangosd (world) Dockerfile</h1>
This Dockerfile only is used on running the mangosd service.
As you know we got a build container.<br>Most docker instance
not use this way, but this is the cleanest way.
We use ubuntu focal as base system because of longterm
```
from ubuntu:focal
```
Update the container and add neccesary parts to run the realmd binary
```
RUN apt update && apt dist-upgrade -y --no-install-recommends \
openssl \
libmariadb3
```
Create the bin directory, copy in mangosd service and tools
```
RUN mkdir -p /app/bin/tools
COPY bin/mangosd /app/bin/
COPY bin/tools/* /app/bin/tools/
```
We save the configuration the container.<br> It will not be used in
our process, but we got it handy in te container.
```
RUN mkdir /app/etc
COPY etc/mangosd.conf.dist /app/etc/
COPY etc/ahbot.conf.dist /app/etc/
```
Now we expose the ports that the client listen on the first one for the world game play. (8085). <br>This has to be declared in the database realmd
```
EXPOSE 8085
EXPOSE 7878
```
Define the app/bin as start point ...
```
WORKDIR "/app/bin"
```
We got a diffrent entrypoint - the run script.
```
ENTRYPOINT ["/usr/bin/entrypoint.sh"]
```
We can protect the server more if we run the mangosd as seperate user.
In the matter of simplicty this is a future step.
<br><br>
<h1>The mangosd-entrypoint.sh</h1>
What the script is just simple. Fire up an screen command with the daemon
and watch over it until it ends.<br>
In case there is no daemon the container will stop.<br><br>Please got in mind:<br>docker-compose "restart: unless-stopped" the container restart endless.<br><br>
```
#!/bin/bash
DAEMON=mangosd
cd /app/bin
# run daemon as mangos user
screen -dmS mangos-zero "./$DAEMON"
echo "MaNGOS zero world daemon started"
UP_AND_RUNNING=2
# mangos server still up?
while [ $UP_AND_RUNNING -gt 1 ] ;
do
sleep 1;
UP_AND_RUNNING="$(ps uax | grep $DAEMON | wc -l)";
done
```

View File

@ -0,0 +1,17 @@
#!/bin/bash
DAEMON=mangosd
cd /app/bin
# run daemon as mangos user
screen -dmS mangos-zero "./$DAEMON"
echo "MaNGOS zero world daemon started"
UP_AND_RUNNING=2
# mangos server still up?
while [ $UP_AND_RUNNING -gt 1 ] ;
do
sleep 1;
UP_AND_RUNNING="$(ps uax | grep $DAEMON | wc -l)";
done