Improved docker support

Updated README for docker
Cleaned up run and build bash scripts
This commit is contained in:
Sinipelto 2025-08-31 12:10:54 +03:00 committed by Ryan
parent a5b5fdf4d6
commit 3dd189d0f3
9 changed files with 191 additions and 149 deletions

30
.dockerignore Normal file
View file

@ -0,0 +1,30 @@
# Local volumes
/config
/data
/db
# Updated through volumes
Server/data
Server/worldprops
# Env files containing secrets
/.env
/*.env
# Log files
logs
*.log
# Git files
.git
.gitattributes
.gitignore
# Basic stuff
*.md
LICENSE
.gitlab-ci.yml
# Docker files
docker-compose.yml
Dockerfile

12
.gitignore vendored
View file

@ -18,7 +18,8 @@ Server/data/global_kill_stats.json
Server/ge_test.db Server/ge_test.db
Server/latestdump.txt Server/latestdump.txt
Management-Server/managementprops/ Management-Server/managementprops/
Server/worldprops/ Server/worldprops/*
!Server/worldprops/default.conf
**/.idea/workspace.xml **/.idea/workspace.xml
**/.idea/tasks.xml **/.idea/tasks.xml
@ -32,3 +33,12 @@ gradle
build/kotlin/sessions/ build/kotlin/sessions/
**/*.iml **/*.iml
Server/hasRan.txt Server/hasRan.txt
# Local volumes
/config
/data
/db
# Env files containing secrets
/.env
/*.env

View file

@ -4,14 +4,8 @@ FROM maven:3-openjdk-11-slim
# Set working directory to /app # Set working directory to /app
WORKDIR /app WORKDIR /app
# Update apt; install git and git-lfs # Copy all sources etc
RUN apt-get update && apt-get -qq -y install git git-lfs COPY . .
# Clone the 2009scape repository
RUN git clone --depth=1 https://gitlab.com/2009scape/2009scape.git
# Fake it til you make it - let's go home
WORKDIR /app/2009scape
# Make sure ./run has permissions # Make sure ./run has permissions
RUN chmod +x run RUN chmod +x run

View file

@ -125,6 +125,78 @@ Start the game server with the included run script. Use `./run -h` for more info
Start the game server with `run-server.bat` Start the game server with `run-server.bat`
#### Docker
Make sure [Docker Engine](https://docs.docker.com/engine/install/) & [Docker Compose](https://docs.docker.com/compose/install/) plugin are installed first:
Go to the project root where the git repository is cloned into:
```bash
cd /path/to/project-dir
```
To configure the database, copy the mysql env file template to a env file in the project root:
```bash
cp mysql.env.example mysql.env
```
Customize the env file however necessary.
Create a new directory called 'config' into the project root.
```bash
mkdir config
```
Copy the server config file template in the config directory:
```bash
cp Server/worldprops/default.conf config/default.conf
```
Edit the server configuration file as per needed.
Go to the project root directory and execute:
```bash
docker compose up --build
```
Which will build the docker image using the local Dockerfile and starts the server and database containers.
The previous up command should be run every time the server sources are modified to propagate the changes to the container.
For the first time, the server compilation process takes a long time. Grab some coffee in the meanwhile.
You can check (and follow) the containers logs by running the following in the project root directory (-f for follow and Ctrl+C to stop):
```bash
docker compose logs -f
```
Any compilation or runtime errors will be logged here.
If you have already compiled the server and made no changes to the sources, you can simply run without the build option (however it will be cached anyways):
```bash
docker compose up
```
To later restart the server to apply simple configuration changes, in the project root directory run:
```bash
docker compose restart server
```
To shut down / take down the server, in the project root directory run:
```bash
docker compose up --build
```
The database files, build cache and config files will be persisted on the host filesystem for easy backup management.
### License ### License
We use the AGPL 3.0 license, which can be found [here](https://www.gnu.org/licenses/agpl-3.0.en.html). Please be sure to read and understand the license. Failure to follow the guidelines outlined in the license will result in legal action. If you know or hear of anyone breaking this license, please send a report, with proof, to Red Bracket#8151, ceikry#2724, or woahscam#8535 on discord or email woahscam@hotmail.com. **We WILL NOT change the license to fit your needs.** We use the AGPL 3.0 license, which can be found [here](https://www.gnu.org/licenses/agpl-3.0.en.html). Please be sure to read and understand the license. Failure to follow the guidelines outlined in the license will result in legal action. If you know or hear of anyone breaking this license, please send a report, with proof, to Red Bracket#8151, ceikry#2724, or woahscam#8535 on discord or email woahscam@hotmail.com. **We WILL NOT change the license to fit your needs.**

91
build
View file

@ -2,139 +2,90 @@
SCRIPT_DIR=$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P) SCRIPT_DIR=$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)
BUILD_MS=0 CLEAN=0
BUILD_GS=0 BUILD_GS=0
CLEAN_MS=0
CLEAN_GS=0
SKIPTEST="" SKIPTEST=""
GS_SRC=$SCRIPT_DIR/Server GS_SRC=$SCRIPT_DIR/Server
MS_SRC=$SCRIPT_DIR/Management-Server
CLEANOPT=""
_JAR_DIR="$SCRIPT_DIR/builddir" _JAR_DIR="$SCRIPT_DIR/builddir"
help() help()
{ {
echo "Usage: $0 [-h] <-m | -g> [-c <m|g>] [-o <path>]"; echo "Usage: $0 [-h] [-q] <-g|-c> [-o <path>]";
echo " -h: Display this message."; echo " -h: Display this message.";
echo " -m: Build the management server.";
echo " -g: Build the game server."; echo " -g: Build the game server.";
echo " -c: Clean: m: management, g: gameserver. " echo " -c: Clean previous build.";
echo " Can specify both. Need at least one if present."; echo " -o: Specify jar-file directory.";
echo " -o: Specify jar-file directory."
echo " -q: Quick build - will skip tests."; echo " -q: Quick build - will skip tests.";
} }
error() error()
{ {
echo $1; echo "$1";
exit -1; exit 1;
}
clean_ms()
{
cd $MS_SRC
if [[ "$CLEANOPT" == *"m"* ]]; then
echo "Cleaning the management server."
sh mvnw clean || error "Failed to clean the MS."
fi
} }
clean_gs() clean_gs()
{ {
cd $GS_SRC; cd $GS_SRC || error "Could not change dir to game server directory."
if [[ "$CLEANOPT" == *"g"* ]]; then
echo "Cleaning the game server." echo "Cleaning the game server."
sh mvnw clean || error "Failed to clean the game server. Giving up." sh mvnw clean || error "Failed to clean the game server. Giving up."
fi
}
build_ms()
{
cd $MS_SRC
sh mvnw package $SKIPTEST || \
error "Failed to build the management server. Giving up";
} }
build_gs() build_gs()
{ {
cd $GS_SRC; cd "$GS_SRC" || error "ERROR: Could not chdir to server src. Abort."
sh mvnw package $SKIPTEST || \ sh mvnw package $SKIPTEST || \
error "Failed to build the game server. Giving up." error "Failed to build the game server. Giving up."
} }
while getopts "hqmgc:o:d" arg; do while getopts "hqgc:o:d" arg; do
case $arg in case $arg in
h) h)
help help
exit 0 exit 0
;; ;;
m)
BUILD_MS=1
;;
g) g)
BUILD_GS=1 BUILD_GS=1
;; ;;
c) c)
CLEANOPT=${OPTARG} CLEAN=1
;; ;;
o) o)
_JAR_DIR=${OPTARG} _JAR_DIR=${OPTARG}
;; ;;
d) d)
echo "BUILD_MS=$BUILD_MS"
echo "BUILD_GS=$BUILD_GS"
echo "CLEANOPT=$CLEANOPT"
echo "_JAR_DIR=$_JAR_DIR" echo "_JAR_DIR=$_JAR_DIR"
;; ;;
q) q)
SKIPTEST="-DskipTests" SKIPTEST="-DskipTests"
;; ;;
*)
error "Argument -$arg is not a known or valid argument."
;;
esac esac
done done
if [[ $CLEANOPT != "m" ]] \ if [ $BUILD_GS -eq 0 ] && [ $CLEAN -eq 0 ]; then
&& [[ $CLEANOPT != "g" ]] \ error "Need to either build or clean at least. See -h for details."
&& [[ $CLEANOPT != "mg" ]] \
&& [[ $CLEANOPT != "" ]];
then
error "Invalid cleaning option '$CLEANOPT'. Valid options are 'm', 'g', 'mg' or none."
fi fi
if [ $BUILD_MS -eq 0 ] && [ $BUILD_GS -eq 0 ] && [[ $CLEANOPT == "" ]]; then # Inside func is cd so mgmt prob fails if no condition
error "Need to build or clean at least one of the modules. See -h for details." (( CLEAN )) && clean_gs
fi
# Conditionals inside the functions.
clean_gs
clean_ms
# ----------- # -----------
if [ -d $_JAR_DIR ]; then if [ -d "$_JAR_DIR" ]; then
rm -r $_JAR_DIR rm -r "$_JAR_DIR"
fi fi
if [ $BUILD_MS -ne 1 ] && [ $BUILD_GS -ne 1 ]; then mkdir -p "$_JAR_DIR" || error "Failed to create build directory.";
echo "No build options specified. Stop."
exit 0
fi
mkdir -p $_JAR_DIR || error "Failed to create build directory.";
if [ $BUILD_MS -eq 1 ]; then
build_ms
# Will never execute if build_ms fails because it quits upon failure.
mv -v $MS_SRC/target/*-with-dependencies.jar $_JAR_DIR/ms.jar
fi
if [ $BUILD_GS -eq 1 ]; then if [ $BUILD_GS -eq 1 ]; then
build_gs build_gs
# Will never execute if build_gs fails because it quits upon failure. # Will never execute if build_gs fails because it quits upon failure.
mv -v $GS_SRC/target/*-with-dependencies.jar $_JAR_DIR/server.jar mv -v "$GS_SRC"/target/*-with-dependencies.jar "$_JAR_DIR"/server.jar
fi fi

View file

@ -1,29 +1,33 @@
version: '3.3'
services: services:
app: server:
build: . build: .
container_name: "2009scape_app"
depends_on: depends_on:
- database - db
restart: unless-stopped
volumes:
- "2009scape_app:/app"
ports:
- "43595:43595"
database:
image: mysql:5.7
container_name: "2009scape_db"
restart: always restart: always
ports:
- "3306:3306"
volumes: volumes:
- "2009scape_db:/var/lib/mysql" - "bcache:/app/Server/target"
- "mcache:/root/.m2"
- "./Server/data:/app/Server/data"
- "./config:/app/Server/worldprops"
ports:
- "43594-43600:43594-43600"
db:
# current LTS (Long-Term Support) version
image: mariadb:11.4-noble
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 30s
interval: 60s
timeout: 10s
retries: 3
restart: always
volumes:
- "./db:/var/lib/mysql"
- "./Server/db_exports/global.sql:/docker-entrypoint-initdb.d/global.sql" - "./Server/db_exports/global.sql:/docker-entrypoint-initdb.d/global.sql"
environment: env_file:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes" - mysql.env
MYSQL_ROOT_PASSWORD: ""
MYSQL_ROOT_USER: "root"
volumes: volumes:
2009scape_app: bcache:
2009scape_db: mcache:

20
mysql.env.example Normal file
View file

@ -0,0 +1,20 @@
# Prefer no and generating a strong password for the root (+ special) user
MYSQL_ALLOW_EMPTY_PASSWORD="no"
# You can change the db name also for obscurity.
# Has to be changed in the default.conf and in the global.sql init file then also.
MYSQL_DATABASE="global"
# Beware: if not using root user, the database 'global' requires granting permissions for that user
# Root user is created automatically so dont provide it here.
#MYSQL_USER="dbuser"
#MYSQL_PASSWORD="CHANGEMEIFNOTUSINGROOTANDINGLOBALCONF"
# Comment this out if you are using random root pw (below).
MYSQL_ROOT_PASSWORD="ALWAYSCHANGEMEHEREANDINGLOBALCONFIFUSINGROOT"
# Or you can use a special non-root db user and generate a random pw for the root user instead.
# To improve security
# However, either initial root user access
# or editing Server/db_exports/global.sql to add grants for 'global' to the special user above.
MYSQL_RANDOM_ROOT_PASSWORD="no"

43
run
View file

@ -3,15 +3,11 @@ SCRIPT_DIR=$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)
LOG_DIR=$SCRIPT_DIR/logs LOG_DIR=$SCRIPT_DIR/logs
BUILD_DIR=$SCRIPT_DIR/builddir BUILD_DIR=$SCRIPT_DIR/builddir
GS_SRC=$SCRIPT_DIR/Server GS_SRC=$SCRIPT_DIR/Server
MS_SRC=$SCRIPT_DIR/Management-Server
FORCE_REBUILD=0 FORCE_REBUILD=0
REFRESH_BUILD=1 REFRESH_BUILD=1
GAMESERVER_ONLY=1
GS_EXEC="cd $GS_SRC && java -Dnashorn.args=--no-deprecation-warning -jar $BUILD_DIR/server.jar" GS_EXEC="cd $GS_SRC && java -Dnashorn.args=--no-deprecation-warning -jar $BUILD_DIR/server.jar"
MS_EXEC="cd $MS_SRC && java -Dnashorn.args=--no-deprecation-warning -jar $BUILD_DIR/ms.jar"
# 0: parallel # 0: parallel
# 1: fancy tmux # 1: fancy tmux
@ -20,13 +16,12 @@ RUN_MODE=0
help() help()
{ {
echo "Usage: $0 [-h] [-q] [-r] [-t] [-x] [-g] [-e <filename>] [-o <filename>]" echo "Usage: $0 [-h] [-q] [-r] [-t] [-x] [-e <filename>] [-o <filename>]"
echo " -h: Display this message." echo " -h: Display this message."
echo " -q: Don't perform the incremental build." echo " -q: Don't perform the incremental build."
echo " -r: Force clean rebuild." echo " -r: Force clean rebuild."
echo " -t: Only run tests, not the JARs." echo " -t: Only run tests, not the JARs."
echo " -x: Run in a fancy tmux session." echo " -x: Run in a fancy tmux session."
echo " -g: Build + run only the game server (no management server)."
echo " -e: Write STDERR to 'logs/filename' as well as the terminal."; echo " -e: Write STDERR to 'logs/filename' as well as the terminal.";
echo " -o: Write STDOUT to 'logs/filename' as well as the terminal." echo " -o: Write STDOUT to 'logs/filename' as well as the terminal."
} }
@ -39,31 +34,17 @@ error()
rebuild_project() rebuild_project()
{ {
if [ $GAMESERVER_ONLY ]; then "$SCRIPT_DIR/build" -qgc
$SCRIPT_DIR/build -qgcg
else
$SCRIPT_DIR/build -qmgcmg
fi
} }
refresh_project() refresh_project()
{ {
if [ $GAMESERVER_ONLY ]; then "$SCRIPT_DIR/build" -qg
$SCRIPT_DIR/build -qg
else
$SCRIPT_DIR/build -qmg
fi
} }
verify_binaries_exist() verify_binaries_exist()
{ {
if ! [ $GAMESERVER_ONLY ]; then if [ ! -f "$SCRIPT_DIR/build/server.jar" ]; then
if [ ! -f $SCRIPT_DIR/builddir/ms.jar ]; then
error "Management server binary does not exist.";
fi
fi
if [ ! -f $SCRIPT_DIR/build/server.jar ]; then
error "Game server binary does not exist."; error "Game server binary does not exist.";
fi fi
} }
@ -76,11 +57,7 @@ run_server_parallel()
echo "Running in parallel. All logs redirected to proper files." echo "Running in parallel. All logs redirected to proper files."
if [ $GAMESERVER_ONLY ]; then
sh -c "$GS_EXEC" & wait sh -c "$GS_EXEC" & wait
else
sh -c "$MS_EXEC > $LOG_DIR/ms_stdout.log 2> $LOG_DIR/ms_stderr.log & $GS_EXEC" & wait
fi
} }
run_server_tmux() run_server_tmux()
@ -89,21 +66,16 @@ run_server_tmux()
error "tmux is not installed. Install tmux or don't use this option." error "tmux is not installed. Install tmux or don't use this option."
fi fi
if [ $GAMESERVER_ONLY ]; then
tmux new-session "$GS_EXEC" tmux new-session "$GS_EXEC"
else
tmux new-session "$MS_EXEC" \; \
split-window -h "$GS_EXEC"
fi
} }
run_server_tests() run_server_tests()
{ {
cd "$GS_SRC" || error "Could not change to GameServer source directory." cd "$GS_SRC" || error "Could not change to game server source directory."
sh mvnw test sh mvnw test
} }
while getopts ":ghqrtxe:o:" arg; do while getopts ":hqrtxe:o:" arg; do
case $arg in case $arg in
h) h)
help help
@ -127,9 +99,6 @@ while getopts ":ghqrtxe:o:" arg; do
x) x)
RUN_MODE=1 RUN_MODE=1
;; ;;
g)
GAMESERVER_ONLY=0
;;
*) *)
error "Argument -$arg is not a known or valid argument." error "Argument -$arg is not a known or valid argument."
;; ;;

View file

@ -1,8 +0,0 @@
@echo off
cd Management-Server
if NOT exist DoNotCreateThisFile.txt (
.\mvnw.cmd package -DskipTests
xcopy /Y target\*-with-dependencies.jar ms.jar*
java -jar ms.jar
)