diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6c5156b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +data +.env diff --git a/Dockerfile b/Dockerfile index e1f6ed7..882898f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,34 +1,62 @@ -FROM debian:stable +FROM debian:stable-slim -ENV VERSION=1.20.1 -ENV JVM_OPTS="-Xmx2G -Xms1G" +ARG VERSION=latest +ARG JAVA_VERSION=latest ENV DEBIAN_FRONTEND=noninteractive -ARG EULA=false - -# Install dependencies -RUN apt-get update && \ - apt-get install -y curl default-jre jq && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* # Create minecraft user RUN groupadd -g 1000 minecraft && \ - useradd -m -u 1000 -g 1000 -d /home/minecraft minecraft + useradd -m -u 1000 -g 1000 -d /app minecraft -# Create directory -RUN mkdir /app && \ - chown minecraft:minecraft /app +# Install scripting dependencies +RUN apt-get update && \ + apt-get install -y curl gpg jq screen && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Eclipse Adoptium DEB installer package +RUN set -ux && \ + # Download the Eclipse Adoptium GPG key + curl -s https://packages.adoptium.net/artifactory/api/gpg/key/public \ + | gpg --dearmor | tee /etc/apt/trusted.gpg.d/adoptium.gpg > /dev/null && \ + # Configure the Eclipse Adoptium apt repository + VERSION_CODENAME="$(awk -F= '/^VERSION_CODENAME/{print $2}' /etc/os-release)" && \ + echo "deb https://packages.adoptium.net/artifactory/deb $VERSION_CODENAME main" \ + | tee /etc/apt/sources.list.d/adoptium.list + +# Install Adoptium Temurin (OpenJDK Distribution) +RUN set -ux && \ + # Grab latest LTS version if not specified + if [ "$JAVA_VERSION" = "latest" ]; then \ + JAVA_VERSION="$( \ + curl -s https://api.adoptium.net/v3/info/available_releases \ + | jq '.most_recent_lts' \ + )"; \ + fi && \ + # Install the Temurin version + apt-get update && \ + apt-get install -y "temurin-${JAVA_VERSION}-jre" && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Download files and run as user +USER minecraft +WORKDIR /app # Download and verify sha1sum for server.jar -WORKDIR /app -USER minecraft -RUN set -ux; \ +RUN set -ux && \ + # Grab latest version if not specified + if [ "$VERSION" = "latest" ]; then \ + VERSION="$( \ + curl -s https://launchermeta.mojang.com/mc/game/version_manifest.json \ + | jq -r '.latest.release' \ + )"; \ + fi && \ # Get server.jar based on $VERSION curl -s https://launchermeta.mojang.com/mc/game/version_manifest.json \ - | jq -r --arg id "$VERSION" '.versions[] | select(.id == $id) | .url' | xargs curl -s \ - | jq -r '.downloads.server' | tee "/tmp/dl.json" | jq -r '.url' | xargs curl -s -o server.jar && \ - java -jar server.jar --initSettings --nogui && \ - sed -i "s/^eula=.*\$/eula=$EULA/" eula.txt && \ + | jq -r --arg id "$VERSION" '.versions[] | select(.id == $id) | .url' \ + | xargs curl -s | jq -r '.downloads.server' | tee "/tmp/dl.json" \ + | jq -r '.url' | xargs curl -s -o server.jar && \ # Get SHA1 hash of server.jar and compare SHA1="$(sha1sum server.jar | awk '{print $1}')" && \ EXPECTED="$(jq -r .sha1 /tmp/dl.json)"; rm /tmp/dl.json && \ @@ -37,5 +65,21 @@ RUN set -ux; \ exit 1; \ fi +# Generate initial settings +RUN java -jar server.jar --initSettings --nogui + +# Back to root to copy the entrypoint in +USER root +WORKDIR /app + +# Copy in entrypoint script +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +# Run app as minecraft user +USER minecraft +WORKDIR /app + +# Expose port and run entrypoint script EXPOSE 25565 -CMD ["java", "-jar", "server.jar", "$JVM_OPTS", "--nogui"] +ENTRYPOINT ["entrypoint.sh"] diff --git a/README.md b/README.md index 426a540..12a8e76 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,17 @@ # Minecraft Docker Image +This Dockerfile sets up a Minecraft server based on the `debian-slim` image. -This Dockerfile sets up a Minecraft server based on Debian stable. WIP. - -To test image creation, run: +By running the following and building this image, you are agreeing to +[Minecraft's EULA](https://www.minecraft.net/en-us/eula): ``` -docker build --build-arg EULA=true -t minecraft . && \ -docker run -d --name minecraft --rm minecraft && \ -docker logs -f minecraft +echo "EULA=true" > .env +``` + +To build and test the image: +``` +docker compose build +docker compose up -d +docker logs -f minecraft-minecraft-1 ``` ## Copyright and License diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..bc34f4a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,24 @@ +volumes: + minecraft: + +services: + minecraft: + build: + context: . + dockerfile: Dockerfile + args: + VERSION: ${VERSION:-latest} + JAVA_VERSION: ${JAVA_VERSION:-latest} + image: ${IMAGE:-minecraft}:${TAG:-latest} + ports: + - "0.0.0.0:25565:25565" + #volumes: + # - minecraft:/app/world + environment: + EULA: "${EULA:-false}" + DEBUG: "${DEBUG:-false}" + JVM_OPTS: "-Xms1G -Xmx2G" + SETTINGS_gamemode: "${GAMEMODE:-survival}" + SETTINGS_hardcore: "${HARDCORE:-false}" + SETTINGS_motd: "${MOTD:-A Minecraft Server}" + SETTINGS_pvp: "${PVP:-true}" diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..6ea47b4 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# Enable debug mode +DEBUG="${DEBUG:-false}" +if [ "$DEBUG" = "true" ]; then + echo "[DEBUG] Running entrypoint script at $(which entrypoint.sh)" + sleep 0.2 + set -ux +fi + +# Settings +FILE="${FILE:-/app/server.properties}" +EULAFILE="${EULAFILE:-/app/eula.txt}" +PREFIX="${PREFIX:-SETTINGS_}" +JVM_OPTS="${JVM_OPTS:--Xms1G -Xmx2G}" + +# Set EULA +sed -i.bak "s/^eula=.*\$/eula=${EULA:-false}/" "$EULAFILE" +diff --unified=1 "${EULAFILE}.bak" "$EULAFILE" +rm "${EULAFILE}.bak" + +# Update server.properties using env +while IFS='=' read -r ENVVAR VALUE ; do + if echo "$ENVVAR" | grep -q "^${PREFIX}.*$"; then + KEY="${ENVVAR#"$PREFIX"}" + if ! grep -q "^${KEY}=" "$FILE"; then + echo "[WARN]: \"$KEY\" does not exist in $FILE and was not updated" + else + [ "$DEBUG" = "true" ] && echo "[DEBUG] Updating \"$KEY\" to \"$VALUE\"" + sed -i.bak "s/^${KEY}=.*/${KEY}=${VALUE}/" "$FILE" + diff --unified=1 "${FILE}.bak" "$FILE" + rm "${FILE}.bak" + fi + else + [ "$DEBUG" = "true" ] && \ + echo "[DEBUG] \"$ENVVAR\" doesn't have the prefix \"$PREFIX\"" + fi +done < <(env) + +# Show server.properties in DEBUG mode +if [ "$DEBUG" = "true" ]; then + echo "[DEBUG] Showing ${FILE}:" + cat "$FILE" +fi + +# Pre-create the screen log +touch screenlog.0 + +# Run server in screen (without attaching) +/usr/bin/screen -dmS minecraft -L \ + bash -c " + sleep 0.5 + [ $DEBUG = true ] && echo '[DEBUG] Starting server' + /usr/bin/java $JVM_OPTS -jar server.jar --nogui + " + +# Tail screen log to container stdout +[ "$DEBUG" = "true" ] && echo "[DEBUG] Tailing screenlog.0" +tail -f screenlog.0