From c4095615b6e3147e3ce736025135a81468abdfd0 Mon Sep 17 00:00:00 2001 From: andybe <3150627+andybe@users.noreply.github.com> Date: Sun, 9 May 2021 22:11:05 +0200 Subject: [PATCH] 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 --- contrib/docker/Dockerfile | 13 ++ contrib/docker/README.md | 15 ++ contrib/docker/build.sh | 44 ++++++ contrib/docker/doc/DOCKERCOMPOSE.md | 111 +++++++++++++++ contrib/docker/doc/SINGLE.md | 154 +++++++++++++++++++++ contrib/docker/docker-compose.yml | 70 ++++++++++ contrib/docker/mangos.env | 4 + contrib/docker/realm/Dockerfile | 16 +++ contrib/docker/realm/README.md | 41 ++++++ contrib/docker/world/Dockerfile | 25 ++++ contrib/docker/world/README.md | 69 +++++++++ contrib/docker/world/mangosd-entrypoint.sh | 17 +++ 12 files changed, 579 insertions(+) create mode 100644 contrib/docker/Dockerfile create mode 100644 contrib/docker/README.md create mode 100755 contrib/docker/build.sh create mode 100644 contrib/docker/doc/DOCKERCOMPOSE.md create mode 100644 contrib/docker/doc/SINGLE.md create mode 100644 contrib/docker/docker-compose.yml create mode 100644 contrib/docker/mangos.env create mode 100644 contrib/docker/realm/Dockerfile create mode 100644 contrib/docker/realm/README.md create mode 100644 contrib/docker/world/Dockerfile create mode 100644 contrib/docker/world/README.md create mode 100755 contrib/docker/world/mangosd-entrypoint.sh diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile new file mode 100644 index 00000000..fcc6e04a --- /dev/null +++ b/contrib/docker/Dockerfile @@ -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 \ No newline at end of file diff --git a/contrib/docker/README.md b/contrib/docker/README.md new file mode 100644 index 00000000..b14f0cc3 --- /dev/null +++ b/contrib/docker/README.md @@ -0,0 +1,15 @@ +

Documentation for example docker-compose instance

+ +- Install mangos as single instance with mangos-zero + +- The "if and way" about the mangos docker-compose.yml + +- Realmd Dockerfile + +- Mangos world Dockerfile + +
+

Please read up in single instance.

+ +Do not run the build.sh outside the container.
+It is written to be run in the build container as documented *single instance*. \ No newline at end of file diff --git a/contrib/docker/build.sh b/contrib/docker/build.sh new file mode 100755 index 00000000..9e336c68 --- /dev/null +++ b/contrib/docker/build.sh @@ -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 diff --git a/contrib/docker/doc/DOCKERCOMPOSE.md b/contrib/docker/doc/DOCKERCOMPOSE.md new file mode 100644 index 00000000..f0af5d34 --- /dev/null +++ b/contrib/docker/doc/DOCKERCOMPOSE.md @@ -0,0 +1,111 @@ +

The "if and why" about the mangos docker-compose.yml


+There a many ways to write an docker-compose.

+ +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
+ "restart: unless-stopped" +- localtime is mapped into the container and also define in mangos.env
+ This is absolute recommend, because container can run in different timezones. + +

Alle containers depends on the database

+The mariadb:latest is a debian based container.
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.
+
+

Next moangos login server

+ +``` + 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".

+Why? All streams are transported into the container and ip address is changed.
How you wanne ban clients with the right ip address?
The mode "host" makes it possible. In this case it can be define only onces at running the host.

+The configuration and logs are mapped as volume into the container. +
+

Lets jump into the world server

+ +``` + 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.
+In additional we need the world data as volume. + +

The mangos network adapter

+ +At the end we define an network adapter for the inner communication. + +``` +networks: + mangos: + name: mangos + driver: bridge +``` + +Cheers \ No newline at end of file diff --git a/contrib/docker/doc/SINGLE.md b/contrib/docker/doc/SINGLE.md new file mode 100644 index 00000000..0b3c4c68 --- /dev/null +++ b/contrib/docker/doc/SINGLE.md @@ -0,0 +1,154 @@ +

Example container for the mangos zero

+ +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.

+We use a build container? Because realm and world should be small as possible and shippes only +we the nessery binaries. + +

1) Create the build container on ubuntu:focal


+ + ``` + git clone git clone https://github.com/mangoszero/server.git mangos --recursive + + docker build mangos/contrib/docker/ -t mangos-zero-build + ``` +

2) Build the source and create directory structur


+ + 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 + + ``` +

3) (Optional) Extract needed data from client


+ + 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.
+ Now wee need a data directory. + ``` + mkdir data + cd WoW1.12.1 + cp -r Buildings dbc maps mmaps vmaps ../data + ``` +

4) If everything went fine we create our container by


+ + ``` + docker-compose build + ``` + +

5) Intialize the database


+ + 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 + ``` +

6) Configure container


+ + ``` + 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)
+ -> 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)
+ -> 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 ../.. + ``` + +

7) Start the realmd & mangos-one container detached


+ + ``` + docker-compose up -d mangos-realm mangos-one + ``` + take a look with "docker stats". Hopefully all container stay and not reloaded all the time. + +

8) Join the world container to create an admin user


+ + ``` + 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 + ``` + +

9) Don't forget to change the realmlist.wtf from WoW client to localhost.

+ + ``` + set realmlist localhost + ``` \ No newline at end of file diff --git a/contrib/docker/docker-compose.yml b/contrib/docker/docker-compose.yml new file mode 100644 index 00000000..6f4260d3 --- /dev/null +++ b/contrib/docker/docker-compose.yml @@ -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 diff --git a/contrib/docker/mangos.env b/contrib/docker/mangos.env new file mode 100644 index 00000000..0cb5ee36 --- /dev/null +++ b/contrib/docker/mangos.env @@ -0,0 +1,4 @@ +MYSQL_ROOT_PASSWORD=mangos +MYSQL_USER=mangos +MYSQL_PASSWORD=mangos +TZ=Europe/Berlin \ No newline at end of file diff --git a/contrib/docker/realm/Dockerfile b/contrib/docker/realm/Dockerfile new file mode 100644 index 00000000..b1a27e0c --- /dev/null +++ b/contrib/docker/realm/Dockerfile @@ -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"] diff --git a/contrib/docker/realm/README.md b/contrib/docker/realm/README.md new file mode 100644 index 00000000..26a6620e --- /dev/null +++ b/contrib/docker/realm/README.md @@ -0,0 +1,41 @@ +

The realmd Dockerfile

+ +This Dockerfile only is used on running the realmd service. +As you know we got a build container.
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. \ No newline at end of file diff --git a/contrib/docker/world/Dockerfile b/contrib/docker/world/Dockerfile new file mode 100644 index 00000000..91b77a18 --- /dev/null +++ b/contrib/docker/world/Dockerfile @@ -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"] diff --git a/contrib/docker/world/README.md b/contrib/docker/world/README.md new file mode 100644 index 00000000..a214320e --- /dev/null +++ b/contrib/docker/world/README.md @@ -0,0 +1,69 @@ +

The mangosd (world) Dockerfile

+ +This Dockerfile only is used on running the mangosd service. +As you know we got a build container.
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.
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).
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. +

+

The mangosd-entrypoint.sh

+What the script is just simple. Fire up an screen command with the daemon +and watch over it until it ends.
+In case there is no daemon the container will stop.

Please got in mind:
docker-compose "restart: unless-stopped" the container restart endless.

+ +``` +#!/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 +``` \ No newline at end of file diff --git a/contrib/docker/world/mangosd-entrypoint.sh b/contrib/docker/world/mangosd-entrypoint.sh new file mode 100755 index 00000000..76129529 --- /dev/null +++ b/contrib/docker/world/mangosd-entrypoint.sh @@ -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 \ No newline at end of file