Skip to content

Commit

Permalink
Add USER_JVM_ARGS
Browse files Browse the repository at this point in the history
  • Loading branch information
flobernd committed Nov 18, 2024
1 parent ed5b345 commit 9f6c220
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 44 deletions.
70 changes: 50 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
# Docker Minecraft FTB

A Docker image for running [FTB](https://www.feed-the-beast.com/) Minecraft servers.
A Docker image developed to launch Minecraft [FTB](https://www.feed-the-beast.com/) Modpack servers as safely, quickly and easily as possible.

### Example
## Features

- Supports all "Feed The Beast" (FTB) [modpacks](https://www.feed-the-beast.com/modpacks?sort=featured)
- Configurable modpack versions
- Allows pinning to a specific modpack version (see `FTB_MODPACK_VERSION_ID`)
- Installs the latest version of the modpack, if no specific version is configured
- Supports automatic modpack upgrades on container start (see `AUTO_UPDATE`)
- Supports unattended installation (see `ACCEPT_MOJANG_EULA`)
- Supports configuration of user-defined JVM arguments as part of the container configuration (see `USER_JVM_ARGS`)
- Drops `root` privileges after setting up the container and runs the server as an unprivileged user

## Example

```bash
docker run -itd --name minecraft-ftb \
-v "/docker_data/minecraft:/var/lib/minecraft" \
-e "FTB_MODPACK_ID=126" \
-e "ACCEPT_MOJANG_EULA=1" \
-e "USER_JVM_ARGS=-Xms1G -Xmx4G" \
-p "25565:25565" \
--stop-timeout=60 \
ghcr.io/flobernd/minecraft-ftb
```

> [!WARNING]
> The server process does not shut down gracefully, if no TTY is present. Please pass the `--tty`/`-t` switch (Docker) or use `tty: true` (Docker Compose).
> [!WARNING]
> It is strongly recommended to set the `stop-timeout` / `stop_grace_period` to at least `60` seconds to avoid data loss when stopping the container.
> [!NOTE]
> It is recommended to pass the `--interactive`/`-i` switch (Docker) or use `stdin_open: true` (Docker Compose) to be able to use the server console after attaching to the container.
### Docker Compose Example
## Docker Compose Example

```yaml
services:
Expand All @@ -35,24 +38,36 @@ services:
stdin_open: true
stop_grace_period: 1m
environment:
- "FTB_MODPACK_ID=126"
- "ACCEPT_MOJANG_EULA=1"
FTB_MODPACK_ID: 126
ACCEPT_MOJANG_EULA: 1
USER_JVM_ARGS: "-Xms1G -Xmx4G"
volumes:
- ./minecraft:/var/lib/minecraft:rw
ports:
- 25565:25565
```
### Environment
## Notes
#### `FTB_MODPACK_ID`
> [!WARNING]
> The server process does not shut down gracefully, if no TTY is present. Please pass the `--tty`/`-t` switch (Docker) or use `tty: true` (Docker Compose).

> [!WARNING]
> It is strongly recommended to set the `stop-timeout` (Docker) / `stop_grace_period` (Docker Compose) to at least `60` seconds to avoid data loss when stopping the container.

> [!NOTE]
> It is recommended to pass the `--interactive`/`-i` switch (Docker) or use `stdin_open: true` (Docker Compose) to be able to use the server console after attaching to the container.

## Environment

### `FTB_MODPACK_ID`

The FTB modpack ID (*required*).

> [!NOTE]
> The modpack ID and the version ID are displayed on the right-hand side of the modpack info page. For example, the [Direwolf20 1.21 modpack](https://www.feed-the-beast.com/modpacks/126-ftb-presents-direwolf20-121) has the ID `126` and the latest version, as of today, is `12599`.

#### `FTB_MODPACK_VERSION_ID`
### `FTB_MODPACK_VERSION_ID`

The FTB modpack version ID.

Expand All @@ -61,23 +76,38 @@ The FTB modpack version ID.

Default: Latest version of the configured modpack.

#### `ACCEPT_MOJANG_EULA`
### `ACCEPT_MOJANG_EULA`

Set `1` to automatically agree to the [Mojang EULA](https://account.mojang.com/documents/minecraft_eula).

This option enables unattended installation. Otherwise, an interactive session must be used to accept the EULA after installation, or the `eula.txt` must be edited manually and the container restarted.

Default: `0`.

#### `AUTO_UPDATE`
### `USER_JVM_ARGS`

Optional, user-defined JVM arguments.

Use the `-Xms` switch to configure the minimum amount of memory used by the JVM. `-Xms1G` sets the minimum amount of memory to 1 GB. The `M` suffix can be used to specify the amount of memory in megabytes instead of gigabytes.

Use the `-Xmx` switch to configure the maximum amount of memory used by the JVM. `-Xms4G` sets the maximum amount of memory to 4 GB. The `M` suffix can be used to specify the amount of memory in megabytes instead of gigabytes.

To specify multiple arguments, combine them with spaces: `-Xms1G -Xmx4G`.

> [!WARNING]
> Using this option causes the `user_jvm_args.txt` file to be overwritten when the container is started.

Default: *none*

### `AUTO_UPDATE`

Set `1` to automatically update the modpack when the container is started.

If `FTB_MODPACK_VERSION_ID` is set, the configured version number is used, otherwise the latest version of the modpack is determined automatically.

Default: `0`

#### `FORCE_REINSTALL`
### `FORCE_REINSTALL`

Set `1` to force a reinstallation of the modpack when the container is started.

Expand Down
7 changes: 3 additions & 4 deletions minecraft-ftb/data/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ FROM debian:bookworm-slim

ENV FTB_MODPACK_ID=0
ENV FTB_MODPACK_VERSION_ID=0

ENV ACCEPT_MOJANG_EULA=0

ENV JAVA_MEMORY_MIN=
ENV JAVA_MEMORY_MAX=
ENV USER_JVM_ARGS=
ENV AUTO_UPDATE=0
ENV FORCE_REINSTALL=0

# Set up runtime dependencies

Expand Down
63 changes: 45 additions & 18 deletions minecraft-ftb/data/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
#!/bin/bash

set -o pipefail
set -o nounset
set -e

ansi_rst="\e[0m"
ansi_b="\e[94m"
ansi_g="\e[92m"
ansi_r="\e[31m"

echoerr() {
echo "ERROR: $@" 1>&2;
echo -e "${ansi_r}ERROR:${ansi_rst} $@" 1>&2;
}

echoinfo() {
echo -e "${ansi_b}INFO:${ansi_rst} $@"
}

check_environment() {
Expand All @@ -17,7 +27,7 @@ check_environment() {
do
if [ -z "${!value}" ]; then
missing=true
echoerr "Missing mandatory environment variable: '${value}'"
echoerr "Missing mandatory environment variable: '${ansi_b}${value}${ansi_rst}'"
fi
done

Expand All @@ -42,7 +52,7 @@ fetch_modpack_info() {
response=$(curl --fail --connect-timeout 30 --max-time 30 --no-progress-meter "https://api.modpacks.ch/public/modpack/$1") || exit $?

if [ -z "${response}" ] || [ $(echo "${response}" | jq -r '.status') != "success" ]; then
echoerr "Failed to fetch modpack info. Please check if the modpack id [$1] is correct."
echoerr "Failed to fetch modpack info. Please check if the modpack id [${ansi_green}$1${ansi_rst}] is correct."
echoerr "$(echo "${response}" | jq -r '.message')"
return 1
fi
Expand Down Expand Up @@ -70,7 +80,7 @@ query_version_info() {
local result=$(echo "$1" | jq -r ".versions[] | select(.id == $2)")

if [ -z "${result}" ]; then
echoerr "Failed to query version info. Please check if the modpack version id [$2] is correct."
echoerr "Failed to query version info. Please check if the modpack version id [${ansi_green}$2${ansi_rst}] is correct."
return 1
fi

Expand Down Expand Up @@ -108,18 +118,18 @@ patch_start_script() {
# We have to make sure the `start.sh` script uses `exec` to launch the server. SIGINT and
# other signals would not be forwarded to the Java process otherwise.

regex='^("jre/.+/bin/java" .+ nogui)$'
output=""
success=false
local regex='^("jre/.+/bin/java" .+ nogui)$'
local output=""
local success=false

while IFS="" read -r line || [ -n "$line" ]
while IFS="" read -r line || [ -n "${line}" ]
do
if [[ $line =~ $regex ]]; then
output+="exec "
success=true
fi

output+="$line\n"
output+="${line}\n"
done < start.sh

if [ ! success ]; then
Expand All @@ -128,7 +138,16 @@ patch_start_script() {
return 1
fi

printf "$output" > start.sh
printf "${output}" > /var/lib/minecraft/start.sh
}

update_user_jvm_args() {
if [ -z "${USER_JVM_ARGS}" ]; then
exit 0
fi

printf "# Generated by "docker-minecraft-ftb"; DO NOT EDIT.\n\n" > /var/lib/minecraft/user_jvm_args.txt
printf "%s" "${USER_JVM_ARGS}" | xargs -n 1 printf "%s\n" >> /var/lib/minecraft/user_jvm_args.txt
}

if [ "$1" = "/var/lib/minecraft/start.sh" ]; then
Expand All @@ -152,7 +171,8 @@ if [ "$1" = "/var/lib/minecraft/start.sh" ]; then
fi

if [ "${local_pack_id}" -ne "${target_pack_id}" ]; then
echoerr "A modpack is already installed, but the modpack id [${local_pack_id}] does not match the configured modpack id [${target_pack_id}]."
echoerr "A modpack is already installed, but the modpack id [${ansi_green}${local_pack_id}${ansi_rst}] does not " \
"match the configured modpack id [${ansi_green}${target_pack_id}${ansi_rst}]."
exit 1
fi
fi
Expand All @@ -162,7 +182,7 @@ if [ "$1" = "/var/lib/minecraft/start.sh" ]; then
modpack_info=$(fetch_modpack_info "${target_pack_id}")
modpack_name=$(echo "${modpack_info}" | jq -r '.name')

echo "Selected modpack '${modpack_name}' [${target_pack_id}]"
echo -e "Selected modpack '${ansi_b}${modpack_name}${ansi_rst}' [${ansi_g}${target_pack_id}${ansi_rst}]"

# Query latest version

Expand All @@ -186,7 +206,7 @@ if [ "$1" = "/var/lib/minecraft/start.sh" ]; then
# Install modpack

if [ "${local_pack_id}" -eq 0 ] || [ "${FORCE_REINSTALL}" == 1 ]; then
echo "Installing modpack version '${target_version_name}' [${target_version_id}]"
echo -e "Installing modpack version '${ansi_b}${target_version_name}${ansi_rst}' [${ansi_g}${target_version_id}${ansi_rst}]"

if [ "${FORCE_REINSTALL}" != 1 ] && [ $(ls -A . | wc -l) -ne 0 ]; then
echoerr "The destination directory is not empty. Installing the modpack could lead to data loss."
Expand All @@ -207,15 +227,19 @@ if [ "$1" = "/var/lib/minecraft/start.sh" ]; then
# Prevent modpack downgrade

if [ "${local_version_id}" -gt "${target_version_id}" ]; then
echoerr "Detected downgrade from version '${local_version_name}' [${local_version_id}] to '${target_version_name}' [${target_version_id}]."
echoerr "Detected downgrade from version " \
"'${ansi_b}${local_version_name}${ansi_rst}' [${ansi_g}${local_version_id}${ansi_rst}] to " \
"'${ansi_b}${target_version_name}${ansi_rst}' [${ansi_g}${target_version_id}${ansi_rst}]."
echoerr "To continue, set the 'FORCE_REINSTALL' environment variable to '1' and retry."
exit 1
fi

# Upgrade modpack

if [ "${local_version_id}" -lt "${target_version_id}" ]; then
echo "Upgrading modpack from version '${local_version_name}' [${local_version_id}] to '${target_version_name}' [${target_version_id}]."
echo -e "Upgrading modpack from version " \
"'${ansi_b}${local_version_name}${ansi_rst}' [${ansi_g}${local_version_id}${ansi_rst}] to " \
"'${ansi_b}${target_version_name}${ansi_rst}' [${ansi_g}${target_version_id}${ansi_rst}]."

get_and_run_installer "${target_pack_id}" "${target_version_id}"
local_version_id="${target_version_id}"
Expand All @@ -225,7 +249,7 @@ if [ "$1" = "/var/lib/minecraft/start.sh" ]; then
# Show info, if a newer version is available

if [ "${local_version_id}" -lt "${latest_version_id}" ]; then
echo "INFO: A newer version '${latest_version_name}' [${latest_version_id}] is available."
echoinfo "A newer version '${ansi_b}${latest_version_name}${ansi_rst}' [${ansi_g}${latest_version_id}${ansi_rst}] is available."
fi

# Accept Mojang EULA
Expand All @@ -235,11 +259,14 @@ if [ "$1" = "/var/lib/minecraft/start.sh" ]; then
chown minecraft:minecraft eula.txt
fi

# TODO: Set- or update memory arguments in user_jvm_args.txt
# Set- or update JVM arguments in `user_jvm_args.txt`

update_user_jvm_args

# Start modpack

echo "Starting modpack '${modpack_name}' (${target_pack_id}) version '${local_version_name}' [${local_version_id}]"
echo -e "Starting modpack '${ansi_b}${modpack_name}${ansi_rst}' [${ansi_g}${target_pack_id}${ansi_rst}] " \
"version '${ansi_b}${local_version_name}${ansi_rst}' [${ansi_g}${local_version_id}${ansi_rst}]"
fi

# Execute command on behalf of the 'minecraft' user
Expand Down
5 changes: 3 additions & 2 deletions minecraft-ftb/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ services:
stdin_open: true
stop_grace_period: 1m
environment:
- "FTB_MODPACK_ID=126"
- "ACCEPT_MOJANG_EULA=1"
FTB_MODPACK_ID: 126
ACCEPT_MOJANG_EULA: 1
USER_JVM_ARGS: "-Xms1G -Xmx4G"
volumes:
- ./volume:/var/lib/minecraft:rw
ports:
Expand Down
1 change: 1 addition & 0 deletions minecraft-ftb/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ docker run -it --rm --name minecraft-ftb \
-v "$SCRIPT_DIR/volume:/var/lib/minecraft" \
-e "FTB_MODPACK_ID=126" \
-e "ACCEPT_MOJANG_EULA=1" \
-e "USER_JVM_ARGS=-Xms1G -Xmx4G" \
-p "25565:25565" \
--stop-timeout=60 \
flobernd/minecraft-ftb

0 comments on commit 9f6c220

Please sign in to comment.