Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM gradle:jdk11-alpine as builder

WORKDIR /app
COPY ./build.gradle /app/build.gradle
COPY ./src /app/src
COPY ./version.txt /app/version.txt
COPY ./www /app/www

RUN gradle jarCli && \
gradle copyWww

FROM adoptopenjdk/openjdk11:alpine-jre

COPY --from=builder /app/build/libs/MinecraftStatsCLI.jar /app/MinecraftStatsCLI.jar
# copy from raw_www to www in entrypoint.sh
COPY --from=builder /app/build/www /app/raw_www

COPY ./stats /app/raw_stats
COPY ./entrypoint.sh /app/entrypoint.sh

ENTRYPOINT [ "/app/entrypoint.sh" ]

15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,18 @@ When using the CLI, the data for the web frontend needs to be updated by executi
java -jar MinecraftStatsCLI.jar config.json
```

#### CLI in Docker

Instead of running the CLI on the host you can place it neatly separated into multiple container using Docker.
The [Dockerfile](./Dockerfile) builds the image [chrisbesch/minecraft_stats](https://hub.docker.com/r/chrisbesch/minecraft_stats).
Here is an example deployment using Docker Compose: [example_docker_compose](./example_docker_compose)
Run it with `docker compose up` and you should have a Minecraft Server (on localhost:25565), MinecraftStats with the accompanying Cron job and web server running on [http://localhost:80](http://localhost:80).

If you want to [add custom awards](#custom-awards), run the docker compose project without your custom awards first.
The `./stats` and `./web_server` dirs will be populated.
Now you can add your custom awards.
To update the container, delete these dirs, update and start the container and add your custom awards again.

##### Automatic Updates

The CLI does not include any means for automatic updates - you need to take care of this yourself. The following lists some possibilities you might have.
Expand Down Expand Up @@ -236,7 +248,7 @@ As a hint, if you wish to create a custom award, it is a good idea to find an al
Readers define how an award score is determined from a player's statistics JSON. There are different types of readers that can be selected using the **`$type`** field. The other fields that are available depend on the selected type. The following is a listing of the available reader types, each with an example award (ID) for reference.

* **`int`**: Reads a single integer from the nested object given by the `path` array. The final entry in `path` is the name of the field to read. Example: `jump`.
* **`match-sum`**: Reads multiple integers from the nested bject given by `path`. The fields that are read are given in the `patterns` array, which may contain [regular expressions](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html). Example: `break_tools`.
* **`match-sum`**: Reads multiple integers from the nested object given by `path`. The fields that are read are given in the `patterns` array, which may contain [regular expressions](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html). Example: `break_tools`.
* **`set-count`**: Counts the number of distinct entries in the nested object or array given by `path`. Example: `biomes`.

#### Advancements
Expand Down Expand Up @@ -269,6 +281,7 @@ Here is some help troubleshooting common issues.
* Any file not found (code 404) errors may hint that data has not been generated. Make sure there is a `data` folder in your webserver's document root. If not, chances are you did not run any update, or the data was written to a wrong location (double-check the configuration).
* If there is anything logged about a *CORS Policy*, chances are you are trying to open `index.html` from your filesystem directly. As a security measure, most browsers do not support loading JavaScript from the filesystem, hence the frontend will not work. Please use a local webserver instead.
* In case you have configured your webserver to compress files before transfer to the client, this may cause it to compress the `.json.gz` files of *MinecraftStats* and confuse the frontend, rendering it unable to properly decompress them. Please make sure that there is an exception for `*.gz` files – they are already compressed!
* If you're getting an error like this in the browser console `Uncaught incorrect header check` there might not be any active players. Try setting `minPlaytime` to `0` and `inactiveDays` to something large.

## History

Expand Down
27 changes: 27 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/sh
# This is the entrypoint for the Docker installation.
# It waits patiently for a SIGHUP from the DockerCron container.
# Once it receives one it performs an update.

mkdir -p /app/www
# only copy the localization files if /app/www is empty
if [ -z "$(ls -A /app/www)" ]; then
echo 'copy static html files into /app/www'
cp -fr /app/raw_www/* /app/www
else
echo '/app/www is already filled; delete that dir to repopulate'
fi

echo 'copy stat files into /app/stats'
mkdir -p /app/stats
cp -fr /app/raw_stats/* /app/stats

echo 'running initial update after boot'
java -jar /app/MinecraftStatsCLI.jar /app/config.json || true

# make sure that you don't `set -e` because that causes the trap to exit the script
# await SIGHUP and then run the actual job
trap 'java -jar /app/MinecraftStatsCLI.jar /app/config.json' HUP
while :; do
sleep 10 & wait ${!}
done
3 changes: 3 additions & 0 deletions example_docker_compose/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data
web_server
stats
36 changes: 36 additions & 0 deletions example_docker_compose/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"server": {
"sources": [
{
"path": "/app/serverfiles",
"worldName": "world"
}
]
},
"data": {
"documentRoot": "/app/www",
"eventsDir": "/app/events",
"statsDir": "/app/stats"
},
"crown": {
"silver": 2,
"gold": 4,
"bronze": 1
},
"client": {
"defaultLanguage": "en",
"playersPerPage": 100,
"playerCacheUUIDPrefix": 2,
"serverName": null,
"showLastOnline": true
},
"players": {
"inactiveDays": 7,
"updateInactive": false,
"profileUpdateInterval": 3,
"minPlaytime": 0,
"excludeBanned": true,
"excludeOps": false,
"excludeUUIDs": []
}
}
53 changes: 53 additions & 0 deletions example_docker_compose/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
version: "3.4"

services:
# You can use any minecraft server—if you like even running without Docker on the host.
MinecraftJava:
image: ghcr.io/gameservermanagers/gameserver:mc
environment:
- TZ=Europe/Berlin
volumes:
# expose the serverfiles on the host machine
- ./data:/data
ports:
- 25565:25565
restart: unless-stopped

MinecraftStats:
image: chrisbesch/minecraft_stats
environment:
- TZ=Europe/Berlin
# configures the DockerCron container to send a SIGHUP to this container every five minutes
- "CRON_TIME=*/5 * * * *"
volumes:
# make sure this points to the location of the serverfiles on the host
- ./data/serverfiles:/app/serverfiles:ro
# You can configure the application here.
# But remember that all paths (like for documentRoot) are inside the Docker container.
# So you probably don't have to touch any of the paths
- ./config.json:/app/config.json:ro
# this is where the static web files end up
# if you want any custom stats, put them here after running the docker compose setup once
- ./web_server:/app/www
# this is only needed if you want custom stats
# if you want any custom stats, put them here after running the docker compose setup once
- ./stats:/app/stats
restart: unless-stopped

# You can use any webserver—if you like even running on the host without Docker.
WebServer:
image: nginx
volumes:
- ./web_server:/usr/share/nginx/html:ro
ports:
- 80:80
restart: unless-stopped

# This is used to send a SIGHUP to the MinecraftStats container in regular intervals.
DockerCron:
image: chrisbesch/docker_cron
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:rw"
environment:
- TZ=Europe/Berlin
restart: unless-stopped