From fe8f82625cf1ca0bf4dfb3f38540d0072a2be3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20P=C4=99dzich?= Date: Thu, 20 Nov 2025 20:51:07 +0100 Subject: [PATCH] Initial commit --- .dockerignore | 8 ++++ .gitattributes | 1 + .gitignore | 1 + Dockerfile | 11 ++++++ README.md | 29 ++++++++++++++ compose.yml | 38 ++++++++++++++++++ index.toml | 2 + pack.toml | 16 ++++++++ setup.sh | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 210 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 compose.yml create mode 100644 index.toml create mode 100644 pack.toml create mode 100755 setup.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..5217557 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.dockerignore +.env +.gitattributes +.gitignore +compose.yml +Dockerfile +README.md +setup.sh diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fa1385d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..89573a6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM busybox:stable + +RUN adduser -D packwiz +USER packwiz +WORKDIR /home/packwiz + +COPY . . +CMD ["busybox", "httpd", "-f", "-p", "3000"] + +HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ + CMD ["wget", "http://localhost:3000/pack.toml", "-O", "/dev/null", "-q"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..e00e499 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# mc-server-packwiz-docker + +If you like Docker and keeping all your Minecraft Java server mods in one place using [packwiz](https://packwiz.infra.link/), as well as keeping track of all changes with Git, then this template repository is for you! + +It comes with: + +- a sample packwiz modpack +- a lightweight HTTP server image based on [BusyBox](https://hub.docker.com/_/busybox) that's used with [`packwiz-installer`](https://packwiz.infra.link/tutorials/installing/packwiz-installer) by [Minecraft Server on Docker](https://docker-minecraft-server.readthedocs.io/en/latest) +- a setup script, which not only lets you reinitialise the modpack, but also generates a minimal `.env` file for the Minecraft Server along with Git hooks for automatically refreshing the modpack's index (while also preventing files in `.dockerignore` from getting listed) + +## Initial setup + +> [!WARNING] +> Make sure to audit the contents of `setup.sh` before running it! +> If you've noticed potentially malicious code, notify me immediately [via email](mailto:contact@maciejpedzi.ch). + +```sh +git clone https://github.com/maciejpedzich/mc-server-packwiz-docker +cd mc-server-packwiz-docker +sudo chmod +x setup.sh +./setup.sh +``` + +## Launching the Minecraft server + +```sh +sudo docker compose build +sudo docker compose up -d +``` diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..07faca3 --- /dev/null +++ b/compose.yml @@ -0,0 +1,38 @@ +services: + packwiz: + build: + context: . + dockerfile: Dockerfile + hostname: packwiz + expose: + - 3000 + minecraft: + image: itzg/minecraft-server + ports: + - 25565:25565 + # NOTE: exposing the RCON port is generally not recommended. + # It's best to send commands via `rcon-cli` inside the container instead. + # Uncomment the line below if you *really* need external access to the console. + # - 25575:25575 + depends_on: + packwiz: + condition: service_healthy + restart: true + env_file: .env + volumes: + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + - minecraft-data:/data + healthcheck: + test: + - CMD + - /usr/local/bin/mc-monitor + - status + - "--host" + - localhost + interval: 3s + timeout: 10s + retries: 15 +volumes: + minecraft-data: + external: false diff --git a/index.toml b/index.toml new file mode 100644 index 0000000..6b2764f --- /dev/null +++ b/index.toml @@ -0,0 +1,2 @@ +hash-format = "sha256" +files = [] diff --git a/pack.toml b/pack.toml new file mode 100644 index 0000000..29fe470 --- /dev/null +++ b/pack.toml @@ -0,0 +1,16 @@ +name = "Empty Modpack" +author = "Maciej Pędzich" +version = "1.0.0" +pack-format = "packwiz:1.1.0" + +[index] +file = "index.toml" +hash-format = "sha256" +hash = "7b81c9e9d9e6e21a9865a2dded0dfd77e7683d679b98fe5b0114eaed9a31f17e" + +[versions] +minecraft = "1.21.10" +quilt = "0.29.3-beta.1" + +[options] +no-internal-hashes = true diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..12fac0e --- /dev/null +++ b/setup.sh @@ -0,0 +1,104 @@ +#!/bin/bash + +if [[ ! -x "$(command -v packwiz)" ]]; then + echo -e "Setup Error: packwiz is not installed in PATH!\n" >&2 + echo "Installation instructions can be found here:" >&2 + echo "https://packwiz.infra.link/installation" >&2 + exit 1 +fi + +echo "Initialising packwiz modpack..." +packwiz init -r + +if [[ $? -ne 0 ]] || [[ ! -f pack.toml ]]; then + echo "Setup Error: failed to initialise packwiz modpack!" >&2 + exit 1 +fi + +grep -q liteloader pack.toml + +if [[ $? -eq 0 ]]; then + echo "Setup Error: LiteLoader is not supported!" >&2 + exit 1 +fi + +VERSION_FIELDS=$(cat pack.toml | tail -n 2 | tr -d ' "') +FIRST_FIELD=$(echo "$VERSION_FIELDS" | head -n 1) +SECOND_FIELD=$(echo "$VERSION_FIELDS" | tail -n 1) +MINECRAFT_FIELD=$([[ "$FIRST_FIELD" =~ minecraft ]] && echo "$FIRST_FIELD" || echo "$SECOND_FIELD") +MOD_LOADER_FIELD=$([[ "$FIRST_FIELD" =~ minecraft ]] && echo "$SECOND_FIELD" || echo "$FIRST_FIELD" ) + +MINECRAFT_VERSION=$(echo "$MINECRAFT_FIELD" | cut -d '=' -f 2) +MOD_LOADER_NAME=$(echo "$MOD_LOADER_FIELD" | cut -d '=' -f 1 | tr '[:lower:]' '[:upper:]') +MOD_LOADER_VERSION=$(echo "$MOD_LOADER_FIELD" | cut -d '=' -f 2) +LOADER_VERSION_VAR_NAME=$([[ "$MOD_LOADER_NAME" = "FORGE" ]] && echo "FORGE_VERSION" || echo "${MOD_LOADER_NAME}_LOADER_VERSION") +RCON_PASSWORD=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 24) + +echo "# For a complete list of environment variables and their defaults, see: +# https://docker-minecraft-server.readthedocs.io/en/latest/variables + +EULA=true +PACKWIZ_URL=http://packwiz:3000/pack.toml +RCON_PASSWORD=${RCON_PASSWORD} +TYPE=${MOD_LOADER_NAME} +VERSION=${MINECRAFT_VERSION} +${LOADER_VERSION_VAR_NAME}=${MOD_LOADER_VERSION}" > .env + +echo "Created .env file for the Minecraft server container!" + +echo "[options] +no-internal-hashes = true" >> pack.toml + +echo '#!/bin/bash + +if ! [ -x "$(command -v packwiz)" ]; then + echo "Error: packwiz is not installed!" >&2 + exit 1 +fi + +readarray ignored_files < .dockerignore + +for file in ${ignored_files[@]}; do + mv $file "/tmp/$file" +done + +packwiz refresh --build +touch /tmp/.commit' > .git/hooks/pre-commit + +echo '#!/bin/bash + +if [ -e /tmp/.commit ]; then + rm /tmp/.commit + readarray ignored_files < /tmp/.dockerignore + + for file in ${ignored_files[@]}; do + mv "/tmp/$file" $file + done + + git add -A + git commit --amend -C HEAD --no-verify +fi' > .git/hooks/post-commit + +echo "Created pre/post-commit Git hooks to prevent indexing of files in .dockerignore!" +echo "Making new hooks executable..." +sudo chmod +x .git/hooks/pre-commit .git/hooks/post-commit + +if [[ $? -eq 0 ]]; then + echo "Successfully updated hooks' permissions!" +else + echo "Setup Error: failed to update hooks' permissions!" >&2 + exit 1 +fi + +echo "Committing modpack manifest and index..." + +git add -A +git commit -m "(re)init modpack" -q + +if [[ $? -eq 0 ]]; then + echo "Successfully committed changes!" + echo "Setup complete!" +else + echo "Setup Error: failed to commit changes!" >&2 + exit 1 +fi