diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..4820e286 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.env +.env.example +.gitattributes +.gitignore +compose.yml +Dockerfile +LICENSE.txt +README.md +.github +.vscode \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..0ecf32c2 --- /dev/null +++ b/.env.example @@ -0,0 +1,26 @@ +# Server +SERVER_BIND=0.0.0.0 +SERVER_PORT=12321 + +# Rcon +RCON_BIND=0.0.0.0 +RCON_PORT=12309 + +# Mus +MUS_BIND=0.0.0.0 +MUS_PORT=12322 + +# Database +MYSQL_HOSTNAME=mariadb +MYSQL_PORT=3306 +MYSQL_USER=kepler +MYSQL_PASSWORD=verysecret +MYSQL_DATABASE=kepler +MARIADB_ROOT_PASSWORD=veryverysecret + +# Logging +LOG_RECEIVED_PACKETS=false +LOG_SENT_PACKETS=false + +# Console +DEBUG=false \ No newline at end of file diff --git a/.gitignore b/.gitignore index e1b8000b..c21a73af 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ error.log .env Kepler-Server/src/main/java/META-INF/MANIFEST.MF *.log +.env +.vscode \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..32acfd17 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,56 @@ +############## +# BASE STAGE # +############## + +FROM alpine:3.20 AS base + +# Add OpenJDK17 +RUN apk add openjdk17=17.0.12_p7-r0 + +# Uses /kepler directory +WORKDIR /kepler + +############### +# BUILD STAGE # +############### + +FROM base AS build + +# Add unzip +RUN apk add unzip=6.0-r14 + +# Copy every files/folders that are not in .dockerignore +COPY . . + +# Convert CRLF to LF executable files (failing build for Windows without this) +RUN sed -i 's/\r$//' gradlew tools/scripts/run.sh entrypoint.sh + +# Make gradlew, entrypoint.sh and run.sh executable +RUN chmod +x gradlew entrypoint.sh tools/scripts/run.sh + +# Run gradle build +RUN ./gradlew distZip + +# Unzip builded Kepler server +RUN unzip -qq ./Kepler-Server/build/distributions/Kepler-Server.zip -d ./release + +# Prepare build directory +RUN rm -rf ./release/Kepler-Server/bin && \ + mkdir -p ./build/lib && \ + mv ./release/Kepler-Server/lib/Kepler-Server.jar ./build/kepler.jar && \ + mv ./release/Kepler-Server/lib/* ./build/lib && \ + mv ./entrypoint.sh ./build/entrypoint.sh && \ + cp tools/scripts/run.sh ./build/ + +#################### +# PRODUCTION STAGE # +#################### + +FROM base AS production + +# Copy builded Kepler server +COPY --from=build /kepler/build ./ + +ENTRYPOINT [ "sh", "entrypoint.sh" ] + +CMD [ "sh", "run.sh" ] \ No newline at end of file diff --git a/README.md b/README.md index f8925de3..3b3ea9b2 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,58 @@ As for the client, you can find version 14 DCRs [here](https://web.archive.org/w Setup the loader files on a web server, and once Kepler is started, ensure the loader is connecting to the correct IP and ports for both the standard connection and MUS connection. The MUS connection is used for the camera. +# Docker installation + +Install [Docker](https://docs.docker.com/engine/install/) and [git](https://git-scm.com/downloads) (optional) on your device. + +### 1. Clone repository + +```shell +git clone https://github.com/Quackster/Kepler.git +``` + +_You can also [download](https://github.com/Quackster/Kepler/archive/refs/heads/master.zip) this repository and unzip it._ + +### 2. Configure variables + +Copy `.env.example` file to `.env` : + +```shell +cp .env.example .env +``` + +You can now configure all variables in `.env` file with values needed. + +_Don't change `MYSQL_HOST` except if you change the name of the service `mariadb` in Docker compose file._ + +_You neither should change `MYSQL_PORT`._ + +### 3. Start Kepler + +You just need to run Docker compose inside of Kepler directory : + +```shell +docker compose up -d +``` + +To stop Kepler : + +```shell +docker compose down +``` + +### Docker FAQ + +#### Reset MariaDB database + +You need to first stop Kepler, then remove MariaDB volume : + +```shell +docker compose down && docker volume rm kepler-mariadb +``` + +You can now start Kepler again, database will be wiped out ! + ## License This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. diff --git a/compose.yml b/compose.yml new file mode 100644 index 00000000..d1ecde8d --- /dev/null +++ b/compose.yml @@ -0,0 +1,33 @@ +services: + kepler: + build: . + container_name: kepler + restart: unless-stopped + env_file: + - .env + depends_on: + mariadb: + condition: service_healthy + ports: + - "${SERVER_PORT}:${SERVER_PORT}" + - "${RCON_PORT}:${RCON_PORT}" + - "${MUS_PORT}:${MUS_PORT}" + mariadb: + image: mariadb:11.4 + container_name: kepler-mariadb + restart: unless-stopped + env_file: + - .env + volumes: + - mariadb:/var/lib/mysql + - ./tools/kepler.sql:/docker-entrypoint-initdb.d/kepler.sql + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + start_period: 10s + interval: 10s + timeout: 5s + retries: 3 + +volumes: + mariadb: + name: kepler-mariadb \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 00000000..0ac77e06 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,79 @@ +#!/bin/bash +set -e + +INI_FILE="/kepler/server.ini" + +# Function to check for the existence of server.ini +check_for_ini_file() { + if [ -f $INI_FILE ]; then + return 0 + else + return 1 + fi +} + +if ! check_for_ini_file; then + echo "[+] server.ini file not detected, running Kepler to create it..." + ./run.sh &> /dev/null + echo "[+] Cleaning up logs..." + rm -f server.log error.log +fi + +echo "[+] server.ini file detected !" + +# Function to update the .ini file +update_ini_file() { + local key=$1 + local value=$2 + local ini_file=$3 + local default_value=$4 + + if [ -n "$value" ]; then + if grep -q "^$key=" "$ini_file"; then + sed -i "s|^$key=.*|$key=$value|" "$ini_file" + else + echo "$key=$value" >> "$ini_file" + fi + else + if grep -q "^$key=" "$ini_file"; then + sed -i "s|^$key=.*|$key=$default_value|" "$ini_file" + else + echo "$key=$default_value" >> "$ini_file" + fi + fi + + +} + +echo "[+] Configuring server.ini with environment variables..." + +# Server +update_ini_file "server.bind" "$SERVER_BIND" "$INI_FILE" "127.0.0.1" +update_ini_file "server.port" "$SERVER_PORT" "$INI_FILE" "12321" + +# Rcon +update_ini_file "rcon.bind" "$RCON_BIND" "$INI_FILE" "127.0.0.1" +update_ini_file "rcon.port" "$RCON_PORT" "$INI_FILE" "12309" + +# Mus +update_ini_file "mus.bind" "$MUS_BIND" "$INI_FILE" "127.0.0.1" +update_ini_file "mus.port" "$MUS_PORT" "$INI_FILE" "12322" + +# Database +update_ini_file "mysql.hostname" "$MYSQL_HOSTNAME" "$INI_FILE" "127.0.0.1" +update_ini_file "mysql.port" "$MYSQL_PORT" "$INI_FILE" "3306" +update_ini_file "mysql.username" "$MYSQL_USER" "$INI_FILE" "kepler" +update_ini_file "mysql.password" "$MYSQL_PASSWORD" "$INI_FILE" "verysecret" +update_ini_file "mysql.database" "$MYSQL_DATABASE" "$INI_FILE" "kepler" + +# Logging +update_ini_file "log.received.packets" "$LOG_RECEIVED_PACKETS" "$INI_FILE" "false" +update_ini_file "log.sent.packets" "$LOG_SENT_PACKETS" "$INI_FILE" "false" + +# Console +update_ini_file "debug" "$DEBUG" "$INI_FILE" "false" + +echo "[+] Running Kepler..." + +# Execute the command passed to the entrypoint +exec "$@" \ No newline at end of file