commit fe8f82625cf1ca0bf4dfb3f38540d0072a2be3d7 Author: Maciej Pędzich Date: Thu Nov 20 20:51:07 2025 +0100 Initial commit 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