Compare commits

..
60 Commits
Author SHA1 Message Date
dependabot[bot] 13fff11fcf build(deps): bump the patches group in /docs with 2 updates (#4265) 2026-09-02 07:15:30 -05:00
82d89ee4eb Honor cd failure when starting a CurseForge pack (#4257)
Co-authored-by: LCB <me@lbellows.com>
Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
2026-09-01 20:40:27 -05:00
LBandLCB b0fbd35f7d Resolve SpongeVanilla latest version and fail closed on download (#4255)
Co-authored-by: LCB <me@lbellows.com>
2026-09-01 19:58:33 -05:00
LBandLCB 99f3a841f4 Do not mark an FTB App pack installed after a failed installer (#4251)
Co-authored-by: LCB <me@lbellows.com>
2026-09-01 17:16:40 -05:00
LBandLCB 3eaa1be6fb Stop startup when a MODPACK zip cannot be extracted (#4254)
Co-authored-by: LCB <me@lbellows.com>
2026-09-01 16:59:22 -05:00
LBandLCB f4fc9382ca Prune CurseForge libraries/mods using relative find paths (#4259)
Co-authored-by: LCB <me@lbellows.com>
2026-09-01 16:58:25 -05:00
Alexey Potsetsuev f7f115182b Fix Fantasy MC Fabric failing to start due to excluded server-required mods (#4264) 2026-09-01 07:11:16 -05:00
LBandLCB 9100b32093 Fail closed when CUSTOM_SERVER download returns an HTTP error (#4258)
Co-authored-by: LCB <me@lbellows.com>
2026-08-31 21:28:45 -05:00
LBandLCB bbc31603e2 Compute percentage memory sizes with integer arithmetic (#4252)
Co-authored-by: LCB <me@lbellows.com>
2026-08-31 21:21:42 -05:00
LBandLCB 430805da64 Detect Fabric FTB App packs from run.sh (#4250)
Co-authored-by: LCB <me@lbellows.com>
2026-08-31 21:10:13 -05:00
LBandLCB dd7644daf5 fix: drop extra brace in Forge/NeoForge FORCE_REINSTALL defaults (#4249)
Co-authored-by: LCB <me@lbellows.com>
2026-08-31 20:38:44 -05:00
renovate[bot] 235be828d8 Update dependency itzg/mc-image-helper to v1.67.1 (#4243)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-30 16:34:29 -05:00
LB 3f7737bc05 Note java8 CurseForge installs need CF_API_KEY (#4262) 2026-08-28 22:39:41 -05:00
LB 319582ae22 Stop figura exclude from matching configurable jars (#4261) 2026-08-28 22:34:50 -05:00
Echo Nar 8df827ed27 fix quadlet example socket access (#4260) 2026-08-28 07:25:50 -05:00
renovate[bot] 9f8248206c Update dependency itzg/mc-server-runner to v1.15.2 (#4237)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-27 14:55:06 -05:00
LCB 6d6c99ff6b pin gosu, fail closed on BuildTools download, reject zip slip (#4247) 2026-08-27 12:38:41 -05:00
dependabot[bot] 6417a93920 build(deps): bump deepmerge from 2.1.0 to 3.0 in /docs (#4246) 2026-08-26 16:37:38 -05:00
dependabot[bot] 2a0a0e651f build(deps): bump the patches group in /docs with 5 updates (#4245) 2026-08-26 07:18:53 -05:00
Harrison Black f61f72196b Fixed extra appended "s" in STOP_SERVER_DELAY_COMMAND (#4242) 2026-08-19 19:40:50 -05:00
dependabot[bot] 9d6aefc153 build(deps): bump the patches group in /docs with 2 updates (#4240) 2026-08-19 08:14:00 -05:00
Eirik H d62afadb5d Add missing HARDCORE environment variable to variables docs (#4239) 2026-08-18 15:03:14 -05:00
renovate[bot] f5d94230e8 Update dependency itzg/easy-add to v0.8.17 (#4235) 2026-08-16 16:34:22 -05:00
renovate[bot] cfceb23ae4 Update dependency itzg/rcon-cli to v1.7.7 (#4238) 2026-08-16 16:12:38 -05:00
renovate[bot] f0e8df639d Update dependency itzg/mc-image-helper to v1.66.1 (#4228) 2026-08-16 13:15:17 -05:00
renovate[bot] d8e2c90d5c Update dependency itzg/mc-monitor to v0.17.1 (#4236) 2026-08-16 12:26:15 -05:00
Alexey Potsetsuev 68d99f434d Fix two Modrinth packs that fail to start due to excluded server-required mods (#4232) 2026-08-14 12:41:45 -05:00
Criseda f93230f6a8 docs: add AutoStopper to related projects (#4231) 2026-08-13 20:52:05 -05:00
Leon Kampwerth 2826f51f5f Add warning for missing .gtnh-version file when using SKIP_GTNH_UPDATE_CHECK (#4230) 2026-08-13 14:48:48 -05:00
dependabot[bot] 218826cba0 build(deps): bump the patches group in /docs with 3 updates (#4224) 2026-08-12 12:44:46 -05:00
Columbus Labs 91b98bcc7b Document Java profile names for user management (#4225) 2026-08-12 08:41:03 -05:00
Harrison Black 21b134fd2b docs: Add docs for CurseForge regex filename matcher (#4223) 2026-08-09 08:09:24 -05:00
renovate[bot] 9b12eb6a6c Update dependency itzg/mc-image-helper to v1.66.0 (#4222) 2026-08-08 16:55:21 -05:00
renovate[bot] 14c83f1015 Update dependency itzg/easy-add to v0.8.16 (#4219) 2026-08-08 12:56:31 -05:00
Andrew Barnes 7ba5a858b9 Remove redundant CF_API_KEY_FILE handling (#4220) 2026-08-07 07:26:34 -05:00
dependabot[bot] 8bf8a7bc8d build(deps): bump the patches group in /docs with 2 updates (#4217)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-05 22:04:30 -05:00
renovate[bot] bbb8f7ffec Update dependency itzg/mc-image-helper to v1.65.0 (#4215) 2026-08-05 12:25:01 -05:00
dependabot[bot] 4657c5f8f3 build(deps): bump docker/login-action from 4.5.2 to 4.6.0 in the updates group (#4216) 2026-08-05 07:01:48 -05:00
renovate[bot] 4fc54b9e43 Update dependency itzg/mc-image-helper to v1.64.2 (#4214) 2026-08-04 10:31:27 -05:00
renovate[bot] 1e2d375dba Update dependency itzg/mc-image-helper to v1.64.1 (#4213) 2026-08-03 21:50:05 -05:00
Geoff Bourne 865d8e89cd Enhance SECURITY.md with automated scan information (#4212) 2026-08-03 14:30:13 -05:00
OowhitecatoO 8651291543 Enable compact object headers on Java 24+ (#4211) 2026-08-03 07:10:14 -05:00
renovate[bot] ec489685e3 Update dependency itzg/mc-monitor to v0.17.0 (#4209) 2026-08-02 16:12:38 -05:00
OowhitecatoO 0f809e27bb Restore the GraalVM image variants (#4205) 2026-08-02 06:54:08 -05:00
Geoff Bourne d85904036f Ensure debugging starts after loading CF_API_KEY_FILE (#4208) 2026-08-01 09:33:18 -05:00
Geoff Bourne fa1b930094 Add SECURITY.md for security policy and reporting (#4207) 2026-08-01 09:09:00 -05:00
OowhitecatoO 6fa08c7067 Fix GraalVM flag selection when USE_MEOWICE_FLAGS is not set (#4204) 2026-08-01 07:44:30 -05:00
renovate[bot] 56c6635604 Update dependency itzg/mc-image-helper to v1.64.0 (#4202)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-31 21:25:48 -05:00
OowhitecatoO 1e4602a82e Fix build workflow conditionals that always evaluated true (#4203) 2026-07-31 15:50:08 -05:00
OowhitecatoO 749f8f635f Fix NanoLimbo port not applying to an existing settings.yml (#4201) 2026-07-31 07:56:18 -05:00
renovate[bot] 8fde0cac2a Update dependency itzg/mc-image-helper to v1.63.2 (#4198) 2026-07-30 17:07:45 -05:00
dependabot[bot] 162bd9b5f1 build(deps): bump docker/login-action from 4.4.0 to 4.5.2 in the updates group (#4195) 2026-07-29 08:06:30 -05:00
dependabot[bot] 614d3f481b build(deps): bump actions/stale from 10 to 11 (#4196) 2026-07-29 07:01:03 -05:00
Jasper ca381904ad docs: add seedloaf sponsor (#4197) 2026-07-29 06:52:47 -05:00
Geoff Bourne 9a2348cadd Use Metalcape knockd by default for java25 (#4194) 2026-07-27 13:40:32 -05:00
Geoff Bourne 33159ddd83 Move knockd config out of /tmp (#4193) 2026-07-27 11:09:57 -05:00
Leon Kampwerth 7e1c26a18f Add daily build options to gtnh example (#4191) 2026-07-25 22:52:09 -05:00
Leon KampwerthandSgtMate 0459532398 Implement GTNH daily build support (#4190)
Co-authored-by: SgtMate <SgtMate@users.noreply.github.com>
2026-07-24 18:06:52 -05:00
renovate[bot] 99d4481c01 Update dependency itzg/mc-image-helper to v1.63.1 (#4189) 2026-07-23 14:48:40 -05:00
dependabot[bot] 194accb407 build(deps): bump the patches group in /docs with 2 updates (#4187) 2026-07-22 07:20:45 -05:00
43 changed files with 447 additions and 157 deletions
+23 -8
View File
@@ -30,10 +30,13 @@ jobs:
- java25
- java25-alpine
- java25-jdk
- java25-graalvm
- java21
- java21-alpine
- java21-graalvm
- java21-jdk
- java17
- java17-graalvm
- java16
- java11
- java8
@@ -46,8 +49,6 @@ jobs:
baseImage: eclipse-temurin:25-jre-noble
platforms: linux/amd64,linux/arm64,linux/riscv64
mcVersion: latest
# forked build that include riscv64
knockdRepoOrg: Opvolger/knock
- variant: java25-alpine
baseImage: eclipse-temurin:25-jre-alpine
platforms: linux/amd64,linux/arm64
@@ -56,6 +57,10 @@ jobs:
baseImage: eclipse-temurin:25
platforms: linux/amd64,linux/arm64
mcVersion: latest
- variant: java25-graalvm
baseImage: container-registry.oracle.com/graalvm/jdk:25-ol10
platforms: linux/amd64,linux/arm64
mcVersion: latest
# JAVA 21:
- variant: java21
baseImage: eclipse-temurin:21-jre
@@ -69,12 +74,20 @@ jobs:
baseImage: eclipse-temurin:21-jre-alpine
platforms: linux/amd64,linux/arm64
mcVersion: 1.21.11
- variant: java21-graalvm
baseImage: container-registry.oracle.com/graalvm/jdk:21-ol10
platforms: linux/amd64,linux/arm64
mcVersion: 1.21.11
# JAVA 17:
- variant: java17
# jammy doesn't work until minecraft updates to https://github.com/netty/netty/issues/12343
baseImage: eclipse-temurin:17-jre-focal
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.20.4
- variant: java17-graalvm
baseImage: container-registry.oracle.com/graalvm/jdk:17-ol10
platforms: linux/amd64,linux/arm64
mcVersion: 1.20.4
# JAVA 16
- variant: java16
baseImage: adoptopenjdk:16-jre-hotspot
@@ -106,6 +119,8 @@ jobs:
# Assume they line up, but when forked change to your Docker Hub username
DOCKER_HUB_ORG: ${{ github.repository_owner }}
IMAGE_TO_TEST: "${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}"
# NOTE: env values are always strings, so the boolean-valued ones below have to be
# compared with == 'true'. Used bare, the string "false" evaluates as true.
HAS_IMAGE_REPO_ACCESS: ${{ secrets.DOCKER_USER != '' && secrets.DOCKER_PASSWORD != '' }}
MAIN_VARIANT: java25
PUSH: ${{ github.repository_owner == 'itzg' }}
@@ -180,15 +195,15 @@ jobs:
tests/test.sh
- name: Login to DockerHub
uses: docker/login-action@v4.4.0
if: env.HAS_IMAGE_REPO_ACCESS
uses: docker/login-action@v4.6.0
if: env.HAS_IMAGE_REPO_ACCESS == 'true'
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v4.4.0
if: env.HAS_IMAGE_REPO_ACCESS
uses: docker/login-action@v4.6.0
if: env.HAS_IMAGE_REPO_ACCESS == 'true'
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -201,13 +216,13 @@ jobs:
platforms: ${{ matrix.platforms }}
push: >
${{
env.PUSH &&
env.PUSH == 'true' &&
(
github.ref_type == 'tag'
|| github.ref_name == github.event.repository.default_branch
|| startsWith(github.ref_name, 'test/')
|| ( github.event_name == 'pull_request'
&& env.HAS_IMAGE_REPO_ACCESS
&& env.HAS_IMAGE_REPO_ACCESS == 'true'
&& contains(github.event.pull_request.labels.*.name, 'ci/push-image')
)
)
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
pull-requests: write
steps:
- name: Process Stale Issues
uses: actions/stale@v10
uses: actions/stale@v11
with:
stale-issue-label: status/stale
stale-pr-label: status/stale
+9
View File
@@ -24,6 +24,7 @@ jobs:
variant:
- java25
- java25-alpine
- java25-graalvm
- java17
- java8
include:
@@ -39,6 +40,11 @@ jobs:
mcVersion: latest
# For GLIBC_2.34 support (and Alpine)
knockdRepoOrg: Metalcape/knock
- variant: java25-graalvm
# stay aligned with build.yml
baseImage: container-registry.oracle.com/graalvm/jdk:25-ol10
platforms: linux/amd64,linux/arm64
mcVersion: latest
# JAVA 17:
- variant: java17
# jammy doesn't work until minecraft updates to https://github.com/netty/netty/issues/12343
@@ -69,6 +75,9 @@ jobs:
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v4.2.0
- name: Confirm multi-arch build
uses: docker/build-push-action@v7
with:
+6 -6
View File
@@ -17,7 +17,7 @@ ARG KNOCKD_REPO_ORG=Metalcape/knock
RUN --mount=target=/build,source=build \
TARGET=${TARGETARCH}${TARGETVARIANT} \
/build/run.sh install-packages
COPY --from=tianon/gosu /gosu /usr/local/bin/
COPY --from=tianon/gosu:1.19 /gosu /usr/local/bin/
RUN --mount=target=/build,source=build \
/build/run.sh setup-user
@@ -28,7 +28,7 @@ ARG APPS_REV=1
ARG GITHUB_BASEURL=https://github.com
# renovate: datasource=github-releases packageName=itzg/easy-add
ARG EASY_ADD_VERSION=0.8.15
ARG EASY_ADD_VERSION=0.8.17
ADD ${GITHUB_BASEURL}/itzg/easy-add/releases/download/${EASY_ADD_VERSION}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
RUN chmod +x /usr/bin/easy-add
@@ -39,25 +39,25 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
# renovate: datasource=github-releases packageName=itzg/rcon-cli
ARG RCON_CLI_VERSION=1.7.6
ARG RCON_CLI_VERSION=1.7.7
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=${RCON_CLI_VERSION} --var app=rcon-cli --file {{.app}} \
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
# renovate: datasource=github-releases packageName=itzg/mc-monitor
ARG MC_MONITOR_VERSION=0.16.11
ARG MC_MONITOR_VERSION=0.17.1
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=${MC_MONITOR_VERSION} --var app=mc-monitor --file {{.app}} \
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
# renovate: datasource=github-releases packageName=itzg/mc-server-runner
ARG MC_SERVER_RUNNER_VERSION=1.15.1
ARG MC_SERVER_RUNNER_VERSION=1.15.2
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=${MC_SERVER_RUNNER_VERSION} --var app=mc-server-runner --file {{.app}} \
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
# renovate: datasource=github-releases packageName=itzg/mc-image-helper versioning=loose
ARG MC_HELPER_VERSION=1.63.0
ARG MC_HELPER_VERSION=1.67.1
ARG MC_HELPER_BASE_URL=${GITHUB_BASEURL}/itzg/mc-image-helper/releases/download/${MC_HELPER_VERSION}
# used for cache busting local copy of mc-image-helper
ARG MC_HELPER_REV=1
+8 -1
View File
@@ -6,9 +6,10 @@
[![](https://img.shields.io/badge/Donate-Buy%20me%20a%20coffee-orange.svg)](https://www.buymeacoffee.com/itzg)
[![Documentation Status](https://readthedocs.org/projects/docker-minecraft-server/badge/?version=latest)](https://docker-minecraft-server.readthedocs.io/en/latest/?badge=latest)
[![Read the docs](docs/img/banner-docs.png)](https://docker-minecraft-server.readthedocs.io/)
[![Read the docs](docs/img/banner-docs.png)](https://docker-minecraft-server.readthedocs.io/)
There you will find things like
- [Quick start with Docker Compose](https://docker-minecraft-server.readthedocs.io/en/latest/#using-docker-compose)
- Running [different versions of Minecraft](https://docker-minecraft-server.readthedocs.io/en/latest/versions/minecraft/) and using [various server types](https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/) for Java Edition
- [Setting server properties via container environment variables](https://docker-minecraft-server.readthedocs.io/en/latest/configuration/server-properties/)
@@ -36,6 +37,12 @@ This image only supports Java edition natively; however, if looking for a server
<br clear="left" />
<a href="https://seedloaf.com"><img src="https://seedloaf.com/images/logo.webp" alt="Seedloaf logo" width="48" align="left" /></a>
<a href="https://seedloaf.com"><b>Seedloaf</b></a> - Built from scratch (by two nerds) on top of <code>itzg/minecraft-server</code>. Seedloaf offers free, and premium Minecraft servers where you have full control!
<br clear="left" />
<!-- additional sponsors repeat the pattern above: floated logo + blurb + clear-left break -->
<!-- logo image preferrably hosted on an external, stable site at a size of 48x48px -->
<!-- link to sponsor site -->
+39
View File
@@ -0,0 +1,39 @@
# Security Policy
## Supported Versions
Only the latest release or `latest` Docker tag receives security updates. If you discover a vulnerability, please test against the latest image version before reporting.
## Automated Scans & Base Image Dependency Updates
- **Automated Dependency Updates:** This repository utilizes automated background workflows to continuously upgrade base images, underlying dependencies, and the Go toolchain. Because CVE scanning tools flag vulnerabilities as soon as they are logged it is not practical to address them any faster than the automation is doing.
- **Image Scan Reports & Triaging:** Please refrain from submitting raw scanner reports or screenshots (e.g., outputs from Trivy, Grype, or Docker Scout). CVEs in upstream base packages or system libraries are often constrained by upstream package maintainers. Submitting an issue or advisory for a scanner report does not accelerate a fix if the patch is not yet available in the upstream base image.
- **Actionable PRs Welcome:** If a fix or patched package version **is** available upstream and has not yet been picked up by our automated build pipelines, submitting a pull request that updates the specific version pin or dependency is the best way to help speed up integration.
## Reporting a Vulnerability
**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.**
To report a vulnerability privately:
1. Navigate to the **[Security](https://github.com/itzg/docker-minecraft-server/security)** tab of this repository.
2. Select **Report a vulnerability** to open a private security advisory.
This allows us to review, reproduce, and resolve the issue in a private environment before public disclosure.
---
## Important Expectations & Bug Bounties
* **No Financial Bounties:** This is an open-source, community-maintained project. We **do not** offer financial rewards, gift cards, or monetary bounties for vulnerability reports.
* **Non-Critical & Automated Findings:** Reports generated purely by automated scanners (such as generic HTTP headers, low-severity container base image updates, or standard configuration warnings) without a working, practical proof-of-concept specific to this container will generally be closed.
---
## Dependency Upgrades & Pull Requests
We welcome and appreciate community contributions!
If you identify an outdated or vulnerable upstream dependency (such as base packages, utilities, or underlying binaries), **we strongly encourage you to submit a Pull Request directly**.
Community-contributed PRs targeting dependency patches are the fastest way to get updates validated, built, and merged into the main release.
+17 -5
View File
@@ -3,6 +3,13 @@
set -e
set -o pipefail
# Patched knockd is only available for amd64 on Alpine, so install the package for other architectures
knockPkg=""
if [ "$TARGETARCH" != amd64 ]; then
knockPkg="knock"
echo "Installing knock package for $TARGETARCH architecture"
fi
# Install necessary packages
# shellcheck disable=SC2086
apk add --no-cache -U \
@@ -36,13 +43,18 @@ apk add --no-cache -U \
numactl \
jattach \
gcompat \
"$knockPkg" \
${EXTRA_ALPINE_PACKAGES}
# Download and install patched knockd
curl -fsSL -o /tmp/knock.tar.gz "https://github.com/${KNOCKD_REPO_ORG}/releases/download/${KNOCKD_VERSION}/knock-${KNOCKD_VERSION}-alpine-amd64.tar.gz"
tar -xf /tmp/knock.tar.gz -C /usr/local/ && rm /tmp/knock.tar.gz
ln -s /usr/local/sbin/knockd /usr/sbin/knockd
setcap cap_net_raw=ep /usr/local/sbin/knockd
if ! [ "$knockPkg" ]; then
# Download and install patched knockd
knockdUrl="https://github.com/${KNOCKD_REPO_ORG}/releases/download/${KNOCKD_VERSION}/knock-${KNOCKD_VERSION}-alpine-amd64.tar.gz"
echo "Downloading knockd from $knockdUrl"
curl -fsSL -o /tmp/knock.tar.gz "$knockdUrl"
tar -xf /tmp/knock.tar.gz -C /usr/local/ && rm /tmp/knock.tar.gz
ln -s /usr/local/sbin/knockd /usr/sbin/knockd
setcap cap_net_raw=ep /usr/local/sbin/knockd
fi
# Set Git credentials globally
cat <<EOF >> /etc/gitconfig
+6 -10
View File
@@ -66,16 +66,12 @@ fi
# Clean up DNF when done
dnf clean all
cat <<EOF > /usr/local/sbin/knockd
#!/bin/sh
echo "Auto-pause (using knockd) is currently unavailable on graalvm image variants"
echo "Consider using a different image variant https://docker-minecraft-server.readthedocs.io/en/latest/versions/java/"
echo "or mc-router's auto scale up/down feature https://github.com/itzg/mc-router#docker-auto-scale-updown"
exit 2
EOF
chmod 755 /usr/local/sbin/knockd
# TODO restore retrieval from https://github.com/Metalcape/knock when tar's "Cannot open: Invalid argument" is solved
# Download and install patched knockd
curl -fsSL -o /tmp/knock.tar.gz https://github.com/Metalcape/knock/releases/download/0.8.1/knock-0.8.1-$TARGET.tar.gz
tar -xf /tmp/knock.tar.gz -C /usr/local/ && rm /tmp/knock.tar.gz
ln -s /usr/local/sbin/knockd /usr/sbin/knockd
ls -l /usr/local/sbin/knockd
setcap cap_net_raw=ep /usr/local/sbin/knockd
# Set git credentials globally
cat <<EOF >> /etc/gitconfig
+4
View File
@@ -1,2 +1,6 @@
#!/bin/sh
set -e
groupadd --gid 1000 minecraft
useradd --system --shell /bin/false --uid 1000 -g minecraft --home /data minecraft
+6 -1
View File
@@ -37,8 +37,13 @@ apt-get install -y \
# Clean up APT when done
apt-get clean
if [ "$TARGETARCH" = riscv64 ]; then
KNOCKD_REPO_ORG=Opvolger/knock
fi
# Download and install patched knockd
curl -fsSL -o /tmp/knock.tar.gz "https://github.com/${KNOCKD_REPO_ORG}/releases/download/${KNOCKD_VERSION}/knock-${KNOCKD_VERSION}-$TARGET.tar.gz"
knockdUrl="https://github.com/${KNOCKD_REPO_ORG}/releases/download/${KNOCKD_VERSION}/knock-${KNOCKD_VERSION}-$TARGET.tar.gz"
echo "Downloading knockd from $knockdUrl"
curl -fsSL -o /tmp/knock.tar.gz "$knockdUrl"
tar -xf /tmp/knock.tar.gz -C /usr/local/ && rm /tmp/knock.tar.gz
ln -s /usr/local/sbin/knockd /usr/sbin/knockd
setcap cap_net_raw=ep /usr/local/sbin/knockd
+3 -1
View File
@@ -168,7 +168,9 @@ To [enforce the whitelist changes immediately](https://minecraft.wiki/w/Server.p
!!! tip "Changing user API provider"
The usernames provided for whitelist and ops processing are resolved using either [PlayerDB](https://playerdb.co/) or [Mojang's API](https://wiki.vg/Mojang_API#Username_to_UUID). The default uses PlayerDB, but can be changed by setting the environment variable `USER_API_PROVIDER` to "mojang". Sometimes one or the other service can become overloaded, which is why there is the ability to switch providers.
When specifying usernames for whitelist and ops processing, use Minecraft: Java Edition profile names, not Xbox gamertags. They can differ even when they belong to the same Microsoft account. A player can review or change their Java profile name on the [Minecraft profile page](https://www.minecraft.net/en-us/msaprofile/mygames/editprofile).
Usernames are resolved using either [PlayerDB](https://playerdb.co/) or [Mojang's API](https://wiki.vg/Mojang_API#Username_to_UUID). The default uses PlayerDB, but can be changed by setting the environment variable `USER_API_PROVIDER` to "mojang". Sometimes one or the other service can become overloaded, which is why there is the ability to switch providers.
### Op/Administrator Players
+4
View File
@@ -29,3 +29,7 @@ A tool that is bundled with this image to provide complex, re-usable preparation
### [itzg/rcon](https://github.com/itzg/docker-rcon-web-admin)
An image that dockerizes [rcon-web-admin](https://github.com/rcon-web-admin/rcon-web-admin).
### [AutoStopper](https://github.com/Criseda/AutoStopper)
A Velocity plugin that stops idle backend servers and wakes them when players connect, with readiness-aware Docker lifecycle management.
+1 -1
View File
@@ -6,7 +6,7 @@ A specific file can be omitted from each reference to allow for auto-selecting t
!!! info "CurseForge API key usage"
A CurseForge API key is _now_ included by this image; however, you can always supply your own instead. A CurseForge API key can be allocated and set with `CF_API_KEY` (or `CF_API_KEY_FILE`) [as described here](../types-and-platforms/mod-platforms/auto-curseforge.md#api-key).
A CurseForge API key is _now_ included by this image on Java 17 and newer; however, you can always supply your own instead. A CurseForge API key can be allocated and set with `CF_API_KEY` (or `CF_API_KEY_FILE`) [as described here](../types-and-platforms/mod-platforms/auto-curseforge.md#api-key). The `java8` image (and other pre-Java 17 tags) does not include a baked-in key; set `CF_API_KEY` yourself.
## Project-file references
+10 -10
View File
@@ -1,25 +1,25 @@
click==8.4.2
click==8.5.0
colorama==0.4.6
deepmerge==2.1.0
deepmerge==3.0
ghp-import==2.1.0
griffe==2.1.0
griffe==2.2.0
Jinja2==3.1.6
Markdown==3.10.2
Markdown==3.10.3
MarkupSafe==3.0.3
mergedeep==1.3.4
mkdocs==1.6.1
mkdocs-autorefs==1.4.4
mkdocs-get-deps==0.2.2
mkdocstrings==1.0.6
mkdocstrings-python==2.0.5
packaging==26.2
mkdocstrings-python==2.0.7
packaging==26.3
pathspec==1.1.1
platformdirs==4.10.0
Pygments==2.20.0
pymdown-extensions==11.0.1
platformdirs==4.11.5
Pygments==2.21.0
pymdown-extensions==11.0.2
python-dateutil==2.9.0.post0
PyYAML==6.0.3
pyyaml_env_tag==1.1
six==1.17.0
watchdog==6.0.0
zensical==0.0.50
zensical==0.0.57
@@ -6,7 +6,9 @@ To manage a CurseForge modpack automatically with upgrade support, pinned or lat
!!! info "CurseForge API key usage"
A CurseForge API key is _now_ included by this image; however, you can always supply your own instead. Go to their [developer console](https://console.curseforge.com/), generate an API key, and set the environment variable `CF_API_KEY`.
A CurseForge API key is _now_ included by this image on Java 17 and newer; however, you can always supply your own instead. Go to their [developer console](https://console.curseforge.com/), generate an API key, and set the environment variable `CF_API_KEY`.
The `java8` image (and other pre-Java 17 tags) does **not** include that key. Set `CF_API_KEY` yourself, or install the pack on a Java 17+ image first. See [Java 8](../../versions/java.md#java-8).
When entering your API Key in a docker compose file you will need to escape any `$` character with a second `$`. Refer to [this compose file reference section](https://docs.docker.com/compose/compose-file/compose-file-v3/#variable-substitution) for more information.
@@ -109,7 +111,7 @@ The latest modpack file and its associated mod loader will be located and instal
- Use `CF_PAGE_URL`, but include the full URL to a specific file
- Set `CF_FILE_ID` to the numerical file ID
- Specify a substring to match the desired filename with `CF_FILENAME_MATCHER`
- Specify either a substring or a regex pattern surrounded with "/" to match the desired filename with `CF_FILENAME_MATCHER`
The following shows where to get the URL to the specific file and also shows where the file ID is located:
@@ -131,6 +133,21 @@ The following examples all refer to version 1.0.7 of ATM8:
CF_FILENAME_MATCHER: 1.0.7
```
To use a regular expression instead, surround the pattern with `/` characters:
```yaml
# Matches filenames containing a 1.0.7 version
CF_SLUG: all-the-mods-8
CF_FILENAME_MATCHER: '/1\.0\.7/'
```
Regular expressions can use `^` to anchor a match to the beginning of the filename and `$` to anchor it to the end. The following matches an ATM8 filename that starts with `all-the-mods-8` and ends with `1.0.7.zip`:
```yaml
CF_SLUG: all-the-mods-8
CF_FILENAME_MATCHER: '/^All the Mods 8-1\.0\.7\.zip$/'
```
Pinning modpack version also pins the mod loader (to the version specified by the modpack). Mod loader version cannot be pinned independently of the modpack.
### Custom modloader versions
@@ -12,7 +12,7 @@ Configuration options with defaults:
## Set Modpack version
As GTNH is a Minecraft 1.7.10 modpack, when using it your minecraft version is set to 1.7.10 by default. The [modpack version](https://www.gtnewhorizons.com/downloads/) can be selected by setting `GTNH_PACK_VERSION` to `latest`, `latest-dev` or any specific version number. `latest` will automatically select the latest full release version available and deploy the server with it (Note: this will also automatically update the server on startup). `latest-dev` does the same but selects the latest version marked as beta or RC (it won't select a full release version even if a newer exist). The third (and recommended) option is setting the server to a specific version like `2.8.1` to manage updates manually.
As GTNH is a Minecraft 1.7.10 modpack, when using it your minecraft version is set to 1.7.10 by default. The [modpack version](https://www.gtnewhorizons.com/downloads/) can be selected by setting `GTNH_PACK_VERSION` to `latest`, `latest-beta` (formerly `latest-dev`) or any specific version number. `latest` will automatically select the latest full release version available and deploy the server with it (Note: this will also automatically update the server on startup). `latest-beta` does the same but selects the latest version marked as beta or RC (it won't select a full release version even if a newer exist). The third (and recommended) option is setting the server to a specific version like `2.8.1` to manage updates manually.
> To actively prevent an update from happening you can set the environment variable `SKIP_GTNH_UPDATE_CHECK` to true this will prevent any update check from running, but will also prevent the server install from running, so just set it after the initial setup.
@@ -52,3 +52,11 @@ To deliver the intended GTNH by default, when running a GTNH server, the followi
With java 17+ the server starts with `-Dfml.readTimeout=180 @java9args.txt -jar lwjgl3ify-forgePatches.jar`.
With java 8 the server stars with `-XX:+UseStringDeduplication -XX:+UseCompressedOops -XX:+UseCodeCacheFlushing -Dfml.readTimeout=180 -jar forge-1.7.10-10.13.4.1614-1.7.10-universal.jar`
## Developer Versions
To run the nightly developer builds of GTNH, set the environment variable `GTNH_USE_DAILY_BUILD` to true and set `GTNH_PACK_VERSION` either to `latest` or a specific run ID of the build workflow. The run ID can be found in the [GTNH GitHub Actions](https://github.com/GTNewHorizons/DreamAssemblerXXL/actions) page of the DreamAssemblerXXL repository. The run ID is the number in the URL of the workflow run, for example `123456789`.
Since downloads require authentication, you will also need to set the environment variable `GH_TOKEN` to a valid GitHub Personal Access Token with `public_repo` scope. You can create a token in your [GitHub settings](https://github.com/settings/tokens) page. Be sure to keep your token secret and do not share it with anyone. The token is only used to download the developer builds and is not stored anywhere in the server (except in the environment variables).
Keep in mind that developer builds are not stable and may contain bugs or incomplete features. Use them at your own risk. It is recommended to use the latest stable release for production servers!
@@ -50,7 +50,7 @@ Some mods, such as [MCInstance Loader](https://modrinth.com/mod/mcinstance-loade
## Excluding files
To exclude client mods that are incorrectly declared by the modpack as server-compatible, set `MODRINTH_EXCLUDE_FILES` to a comma or newline delimited list of partial file names to exclude. You may need to set `MODRINTH_FORCE_SYNCHRONIZE` to "true" while iterating on a compatible set of mods to use.
To exclude client mods that are incorrectly declared by the modpack as server-compatible, set `MODRINTH_EXCLUDE_FILES` to a comma or newline delimited list of file name matchers. Each entry is a case-insensitive substring of the file path, or a regular expression if surrounded with `/` (same convention as [`CF_FILENAME_MATCHER`](auto-curseforge.md#pinning-modpack-and-mod-loader-versions)). You may need to set `MODRINTH_FORCE_SYNCHRONIZE` to "true" while iterating on a compatible set of mods to use.
!!! example
@@ -64,7 +64,7 @@ To exclude client mods that are incorrectly declared by the modpack as server-co
## Force-include files
To force include client mods, set `MODRINTH_FORCE_INCLUDE_FILES` to a comma or newline delimited list of partial file names. You may need to set `MODRINTH_FORCE_SYNCHRONIZE` to "true" while iterating on a compatible set of mods to use.
To force include client mods, set `MODRINTH_FORCE_INCLUDE_FILES` to a comma or newline delimited list of file name matchers using the same substring or `/regex/` rules as `MODRINTH_EXCLUDE_FILES`. You may need to set `MODRINTH_FORCE_SYNCHRONIZE` to "true" while iterating on a compatible set of mods to use.
!!! example
+7 -1
View File
@@ -204,6 +204,12 @@ alternatively, you can mount: <code>/etc/localtime:/etc/localtime:ro
<td><code>easy</code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>HARDCORE</code></td>
<td>Enable hardcore mode. Set to <code>true</code> or <code>false</code>. This maps to the Minecraft server property <code>hardcore</code>.</td>
<td><code>false</code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>ICON</code></td>
<td>The url or file path for the icon image to use for the server. It will be downloaded, scaled, and converted to the proper format.</td>
@@ -611,7 +617,7 @@ This image maps known server properties as described in [this section](configura
</tr>
<tr>
<td><code>CF_FILENAME_MATCHER</code></td>
<td>Specify a substring to match the desired filename</td>
<td>Specify either a substring or a regex pattern surrounded with "/" to match the desired filename</td>
<td><code></code></td>
<td>⬜️</td>
</tr>
+10 -2
View File
@@ -17,10 +17,13 @@ where `<tag>` refers to the first column of this table:
| java25 | 25 | Ubuntu | Hotspot | amd64, arm64, riscv64 | |
| java25-alpine | 25 | Alpine | Hotspot | amd64, arm64 | |
| java25-jdk | 25 | Ubuntu | Hotspot+JDK | amd64, arm64 | |
| java25-graalvm | 25 | Oracle | Oracle GraalVM | amd64, arm64 | (2)(3) |
| java21 | 21 | Ubuntu | Hotspot | amd64, arm64 | |
| java21-jdk | 21 | Ubuntu | Hotspot+JDK | amd64, arm64 | |
| java21-alpine | 21 | Alpine | Hotspot | amd64, arm64 | |
| java21-graalvm | 21 | Oracle | Oracle GraalVM | amd64, arm64 | (2)(3) |
| java17 | 17 | Ubuntu | Hotspot | amd64, arm64, armv7 | |
| java17-graalvm | 17 | Oracle | Oracle GraalVM | amd64, arm64 | (2)(3) |
| java16 | 16 | Ubuntu | Hotspot | amd64, arm64, armv7 | (1) |
| java11 | 11 | Ubuntu | Hotspot | amd64, arm64, armv7 | |
| java8 | 8 | Ubuntu | Hotspot | amd64, arm64, armv7 | |
@@ -28,6 +31,8 @@ where `<tag>` refers to the first column of this table:
Notes
1. This version of Java is [recommended for PaperMC 1.16.5](https://docs.papermc.io/paper/getting-started/#requirements)
2. Based on the [Oracle GraalVM images](https://blogs.oracle.com/java/post/new-oracle-graalvm-container-images), which as of JDK 17, are now under the [GraalVM Free License](https://blogs.oracle.com/java/post/graalvm-free-license) incorporating what used to be known as the GraalVM Enterprise.
3. Due to these images using Oracle Linux, (which is based on Red Hat Enterprise Linux) Forge Installer will not work due to its use of zlib-ng. Use other images for initial installation and Forge version upgrade.
!!! example "Example using java8"
@@ -106,7 +111,11 @@ Caused by: org.spongepowered.asm.mixin.throwables.ClassMetadataNotFoundException
#### Java 8
For Forge versions less than 1.18, you _must_ use the `java8-multiarch` (or other java8) image tag.
For Forge versions less than 1.18, you _must_ use the `java8` (or other java8) image tag.
!!! warning "Java 8 is in maintenance mode"
The `java8` / `java8-jdk` tags, and other pre-Java 17 tags (`java11`, `java16`), pin an older `mc-image-helper` that predates the baked-in CurseForge API key. `AUTO_CURSEFORGE` and `CURSEFORGE_FILES` on those images require you to set `CF_API_KEY` yourself. Java 17+ images include a key and do not need this.
In general, if you see the following line in a server startup failure, then it means you need to be using Java 8 instead of the latest image Java version:
@@ -121,7 +130,6 @@ Forge also doesn't support openj9 JVM implementation.
The following image tags have been deprecated and are no longer receiving updates:
- java25-graalvm, java21-graalvm, java17-graalvm
- adopt13
- adopt14
- adopt15
@@ -14,6 +14,9 @@ services:
# GTNH_DELETE_BACKUPS: true
# Use to prevent updates
# SKIP_GTNH_UPDATE_CHECK: true
# Enable and set Token for daily builds
# GTNH_USE_DAILY_BUILD: true
# GH_TOKEN: mytoken
MEMORY: 6G
# Bring in standard extra mods described at https://wiki.gtnewhorizons.com/wiki/Additional_Mods
# MODS: |
+2
View File
@@ -37,6 +37,8 @@ ln -s ${XDG_CONFIG_HOME}/containers/systemd/mc@.service ${XDG_CONFIG_HOME}/conta
If running rootless, be sure to enable lingering with `sudo loginctl enable-linger $USER`.
`GroupAdd=0` when rootless the equivalent of the user's group id, not the hosts root.
Also note that source IPs are currently lost due to how rootless podman handles custom networks.
This should be fixed in a future podman release.[^3]
@@ -6,6 +6,7 @@ Image=docker.io/itzg/mc-router
ContainerName=%N
AutoUpdate=registry
UserNS=host
GroupAdd=0
Volume=%t/podman/podman.sock:/var/run/docker.sock:ro
Network=minecraft.network
PublishPort=25565:25565
+3
View File
@@ -187,6 +187,9 @@
"create-arcane-engineering": {
"forceIncludes": ["just-enough-resources-jer"]
},
"fantasy-minecraft-fabric": {
"forceIncludes": ["simply-tooltips", "icon-leading-tooltip"]
},
"ftb-stoneblock-4": {
"forceIncludes": [
"particular-reforged",
+1 -2
View File
@@ -48,9 +48,8 @@
"fancymenu",
"fast-ip-ping",
"fastquit",
"FauxCustomEntityData",
"feytweaks",
"figura",
"/(^|/)figura-/",
"ForgeConfigScreens",
"GeckoLibIrisCompat",
"gpumemleakfix",
+12 -8
View File
@@ -1,12 +1,16 @@
{
"file": "/data/settings.yml",
"ops": [
"patches": [
{
"$set": {
"path": "$.bind.port",
"value": "${SERVER_PORT}",
"value-type": "int"
}
"file": "/data/settings.yml",
"ops": [
{
"$set": {
"path": "$.bind.port",
"value": "${SERVER_PORT}",
"value-type": "int"
}
}
]
}
]
}
}
+1 -1
View File
@@ -40,7 +40,7 @@ if ! mc-image-helper network-interfaces --check="$AUTOPAUSE_KNOCK_INTERFACE" ; t
autopause_error_loop
fi
knockdArgs=(-c /tmp/knockd-config.cfg -d -i "$AUTOPAUSE_KNOCK_INTERFACE")
knockdArgs=(-c /data/.knockd.cfg -d -i "$AUTOPAUSE_KNOCK_INTERFACE")
if isTrue "${DEBUG_AUTOPAUSE}"; then
knockdArgs+=(-D)
fi
+11 -5
View File
@@ -24,13 +24,13 @@ log "Autopause functionality enabled"
isDebugging && set -x
cp /image/knockd-config.cfg /tmp/knockd-config.cfg
cp /image/knockd-config.cfg /data/.knockd.cfg
function updatePort() {
regseq="^\s*sequence\s*=\s*$1\s*$"
linenum=$(grep -nm${2} sequence /tmp/knockd-config.cfg | cut -d : -f 1 | tail -n1)
if ! [[ $(awk "NR==$linenum" /tmp/knockd-config.cfg) =~ $regseq ]]; then
sed -i "${linenum}s/sequence.*/sequence = $1/" /tmp/knockd-config.cfg
linenum=$(grep -nm${2} sequence /data/.knockd.cfg | cut -d : -f 1 | tail -n1)
if ! [[ $(awk "NR==$linenum" /data/.knockd.cfg) =~ $regseq ]]; then
sed -i "${linenum}s/sequence.*/sequence = $1/" /data/.knockd.cfg
log "Updated $3 port in knockd config"
fi
}
@@ -67,6 +67,12 @@ fi
# seq_cooldown cannot be larger than AUTOPAUSE_TIMEOUT_KN, otherwise the server may
# become paused while knockd is still ignoring packets, preventing players from joining.
let COOLDOWN=$AUTOPAUSE_TIMEOUT_KN/2
sed -i "s/\(seq_cooldown *= *\).*/\1$COOLDOWN/" /tmp/knockd-config.cfg
sed -i "s/\(seq_cooldown *= *\).*/\1$COOLDOWN/" /data/.knockd.cfg
if isDebugging; then
echo "Autopause configuration: ======================================"
cat /data/.knockd.cfg
echo "==============================================================="
fi
"$(dirname "$0")/auto/autopause-daemon.sh" &
-11
View File
@@ -22,22 +22,11 @@ set -eu
: "${CF_DOWNLOADS_REPO=$([ -d /downloads ] && echo '/downloads' || echo '')}"
: "${CF_MODPACK_MANIFEST:=}"
: "${CF_API_CACHE_DEFAULT_TTL:=}" # as ISO-8601 duration, such as P2D or PT12H
: "${CF_API_KEY_FILE:=}" # Path to file containing CurseForge API key
: "${CF_MOD_LOADER_VERSION:=}" # Override mod loader version
: "${CF_USE_HTTP2:=false}" # CF downloads are faster with HTTP 1.1
resultsFile=/data/.install-curseforge.env
if [[ -n ${CF_API_KEY_FILE} ]]; then
if [[ -r "${CF_API_KEY_FILE}" ]]; then
CF_API_KEY="$(cat "${CF_API_KEY_FILE}")"
export CF_API_KEY
else
logError "CF_API_KEY_FILE is not readable: ${CF_API_KEY_FILE}"
exit 1
fi
fi
isDebugging && set -x
ensureRemoveAllModsOff "MODPACK_PLATFORM=AUTO_CURSEFORGE"
+1 -1
View File
@@ -43,7 +43,7 @@ function buildSpigotFromSource {
fi
logn ''
curl -sSL -o ${tempDir}/BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar && \
curl -fsSL -o "${tempDir}/BuildTools.jar" https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar && \
java $jvmOpts -jar ${tempDir}/BuildTools.jar --rev "$VERSION" 2>&1 |tee ${spigotBuildLog}| while read l; do echo -n .; done; log "done"
case ${TYPE^^} in
+2 -2
View File
@@ -127,7 +127,7 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
echo "${FTB_SERVER_MOD}" > $installMarker
fi
SERVER=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
SERVER=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
if [[ -z "${SERVER}" || ! -f "${SERVER}" ]]; then
logError "Unable to locate installed forge server jar"
isDebugging && find "${FTB_BASE_DIR}" -name "forge*.jar"
@@ -200,7 +200,7 @@ if [[ ! $startScript ]]; then
# no, then look for a forge jar to run
# Allow up to 2 levels since some modpacks have a top-level directory named for the modpack
forgeJar=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
forgeJar=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
if [[ "$forgeJar" ]]; then
FTB_BASE_DIR=$(dirname "${forgeJar}")
export FTB_BASE_DIR
+2 -2
View File
@@ -16,8 +16,8 @@ if isURL "${CUSTOM_SERVER}"; then
log "Using previously downloaded jar at ${SERVER}"
else
log "Downloading custom server jar from ${CUSTOM_SERVER} ..."
if ! curl -sSL -o "${SERVER}" "${CUSTOM_SERVER}"; then
log "Failed to download from ${CUSTOM_SERVER}"
if ! curl -fsSL -o "${SERVER}" "${CUSTOM_SERVER}"; then
logError "Failed to download from ${CUSTOM_SERVER}"
exit 2
fi
fi
+8 -5
View File
@@ -9,7 +9,7 @@ ftbInstallMarker=".ftb-installed"
# shellcheck source=start-utils
. "$(dirname "$0")/start-utils"
isDebugging && set -x
set -e
set -e -o pipefail
#
#{
@@ -93,7 +93,10 @@ if isTrue "$FTB_FORCE_REINSTALL" ||
log "Installing modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID}"
log "This could take a while..."
${ftbInstaller} -pack "${FTB_MODPACK_ID}" -version "${FTB_MODPACK_VERSION_ID}" -auto -force -no-java | tee ftb-installer.log
if ! ${ftbInstaller} -pack "${FTB_MODPACK_ID}" -version "${FTB_MODPACK_VERSION_ID}" -auto -force -no-java | tee ftb-installer.log; then
logError "FTB installer failed for modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID}"
exit 1
fi
rm -f forge*installer.jar
echo "${FTB_MODPACK_ID}=${FTB_MODPACK_VERSION_ID}" > ${ftbInstallMarker}
@@ -140,9 +143,9 @@ if [[ $SERVER = run.sh ]]; then
elif grep -q forge "$SERVER"; then
export FAMILY=FORGE
export TYPE=FORGE
elif grep -q fabric run.s; then
export FAMILY=FABRIC
export TYPE=FABRIC
elif grep -q fabric "$SERVER"; then
export FAMILY=FABRIC
export TYPE=FABRIC
else
logError "Unrecognized loader type in $SERVER"
cat "$SERVER"
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
: "${FORGE_VERSION:=${FORGEVERSION:-RECOMMENDED}}"
: "${FORGE_FORCE_REINSTALL:=false}}"
: "${FORGE_FORCE_REINSTALL:=false}"
# shellcheck source=start-utils
. "${SCRIPTS:-$(dirname "$0")}/start-utils"
+95 -29
View File
@@ -7,11 +7,13 @@
function getGTNHdownloadPath(){
gtnh_download_path=""
local release_object=""
local current_java_version=""
current_java_version=$(mc-image-helper java-release)
# Select release JSON object
if [ "$GTNH_PACK_VERSION" == "latest-dev" ]; then
# latest-dev will be removed in the future, but is still supported for now.
if [ "$GTNH_PACK_VERSION" == "latest-dev" ] || [ "$GTNH_PACK_VERSION" == "latest-beta" ]; then
if [ "$GTNH_PACK_VERSION" == "latest-dev" ]; then
logWarning "GTNH_PACK_VERSION=latest-dev is deprecated and will be removed in the future."
fi
if ! release_object="$(
curl -fsSL "https://downloads.gtnewhorizons.com/versions.json" \
| jq -r '(.versions // .)|to_entries|sort_by(.value.releaseDate)|map(select(.value.title=="Beta release"))|.[-1]'
@@ -46,23 +48,18 @@ function getGTNHdownloadPath(){
fi
# Select compatible server files for java version
if (( current_java_version == 8 )); then
if (( java_version == 8 )); then
gtnh_download_path=$(jq -r '.value.server.java8Url' <<< "$release_object")
log "Use GTNH Server Java 8 release."
elif (( current_java_version >= 17 )); then
if (( current_java_version > $(jq '.value.maxJavaVersion' <<< "$release_object") )); then
logError "Container Java version $current_java_version is not supported by GTNH. Try an older release."
elif (( java_version >= 17 )); then
if (( java_version > $(jq '.value.maxJavaVersion' <<< "$release_object") )); then
logError "Container Java version $java_version is not supported by GTNH. Try an older release."
exit 1
fi
gtnh_download_path=$(jq -r '.value.server.java17_2XUrl' <<< "$release_object")
log "Use GTNH Server Java 17+ release."
else
logError "Container Java version $current_java_version is not supported by GTNH."
exit 1
fi
if [[ -z $gtnh_download_path ]]; then
@@ -73,6 +70,56 @@ function getGTNHdownloadPath(){
}
function getGTNHdownloadOptions(){
# Used for GTNH daily build downloads, to pass additional options to the download command.
gtnh_download_options=()
# Used for dryrun check
gtnh_download_path=""
# Check if GH_TOKEN is set for daily builds
if [ -z "$GH_TOKEN" ]; then
logError "GH_TOKEN environment variable must be set to use daily builds."
exit 1
fi
gtnh_download_options+=( --output-filename )
# prepare download options as an array to safely append patterns
if [ "$GTNH_PACK_VERSION" == "latest" ] || [ "$GTNH_PACK_VERSION" == "latest-dev" ]; then
if [ "$GTNH_PACK_VERSION" == "latest-dev" ]; then
logWarning "GTNH_PACK_VERSION=latest-dev is deprecated and will be removed in the future."
fi
gtnh_download_options+=( --workflow=daily-modpack-build.yml )
log "Using latest daily build for GTNH server files."
elif [ "$GTNH_PACK_VERSION" == "latest-beta" ]; then
gtnh_download_options+=( --workflow=daily-modpack-build.yml )
logWarning "Using daily build instead of latest beta release for GTNH server files. If this is not intended, set GTNH_USE_DAILY_BUILD=false to use the latest beta release instead."
else
gtnh_download_options+=( --run-id="$GTNH_PACK_VERSION" )
log "Using specific daily build run ID $GTNH_PACK_VERSION for GTNH server files."
fi
# Select compatible server files for java version
if (( java_version == 8 )); then
log "Use GTNH Server Java 8 release."
gtnh_download_options+=( --artifact-pattern='GTNH-daily-\d{4}-\d{2}-\d{2}\+\d+-server-java8\.zip' )
elif (( java_version >= 17 )); then
log "Use GTNH Server Java 17+ release."
gtnh_download_options+=( --artifact-pattern='GTNH-daily-\d{4}-\d{2}-\d{2}\+\d+-server-java17-\d{2}\.zip' )
fi
debug "GTNH daily build download options: ${gtnh_download_options[*]}"
if ! gtnh_download_path=$(mc-image-helper github download-artifact --no-download "${gtnh_download_options[@]}" GTNewHorizons/DreamAssemblerXXL); then
logError "Failed to find a matching daily build for GTNH server files with the specified options."
exit 1
fi
debug "GTNH daily build download path: $gtnh_download_path"
}
function deleteGTNHbackup(){
log "Start deleting all config backups"
if ! find . -maxdepth 1 -type d -name 'gtnh-upgrade-*' -exec rm -rf {} + ; then
@@ -81,24 +128,33 @@ function deleteGTNHbackup(){
}
function downloadGTNH(){
local gtnh_download=""
gtnh_download=""
base_dir=/data/.tmp/gtnh_base
debug "Creating temporary /data/.tmp/packs folder for GTNH download"
mkdir -p /data/.tmp/packs
trap 'rm -rf /data/.tmp' EXIT
log "Downloading $gtnh_download_path."
if ! gtnh_download=$(mc-image-helper get -o /data/.tmp/packs --output-filename --skip-up-to-date "$gtnh_download_path"); then
logError "Failed to download $gtnh_download_path"
exit 1
fi
debug "Downloaded GTNH server files to $gtnh_download"
# Unpacking Server files into temporary directory
log "Unpacking Server Files into $base_dir"
mkdir -p "${base_dir}"
extract "${gtnh_download}" "${base_dir}"
if isTrue "$GTNH_USE_DAILY_BUILD"; then
log "Downloading Daily Build for GTNH server files."
# gtnh_download_options is injecting download parameters -> (--workflow or --run-id) and --artifact-pattern
if ! gtnh_download=$(mc-image-helper github download-artifact -o=$base_dir --unzip "${gtnh_download_options[@]}" GTNewHorizons/DreamAssemblerXXL); then
logError "Failed to download Daily Build for GTNH server files."
exit 1
fi
else
log "Downloading $gtnh_download_path."
if ! gtnh_download=$(mc-image-helper get -o /data/.tmp/packs --output-filename --skip-up-to-date "$gtnh_download_path"); then
logError "Failed to download $gtnh_download_path"
exit 1
fi
debug "Downloaded GTNH server files to $gtnh_download"
# Unpacking Server files into temporary directory
log "Unpacking Server Files into $base_dir"
extract "${gtnh_download}" "${base_dir}"
fi
# Remove any eula file since container manages it
debug "Removing eula.txt from $base_dir"
@@ -209,16 +265,23 @@ function handleGTNH() {
: "${GTNH_PACK_VERSION:=latest}"
: "${GTNH_DELETE_BACKUPS:=false}"
: "${SKIP_GTNH_UPDATE_CHECK:=false}"
debug "GTNH VAR CHECK: GTNH_DELETE_BACKUPS=$GTNH_DELETE_BACKUPS, GTNH_PACK_VERSION=$GTNH_PACK_VERSION, TYPE=$TYPE, SKIP_GTNH_UPDATE_CHECK=$SKIP_GTNH_UPDATE_CHECK"
: "${GTNH_USE_DAILY_BUILD:=false}"
debug "GTNH VAR CHECK: GTNH_DELETE_BACKUPS=$GTNH_DELETE_BACKUPS, GTNH_PACK_VERSION=$GTNH_PACK_VERSION, TYPE=$TYPE, SKIP_GTNH_UPDATE_CHECK=$SKIP_GTNH_UPDATE_CHECK, GTNH_USE_DAILY_BUILD=$GTNH_USE_DAILY_BUILD"
if isTrue "$GTNH_DELETE_BACKUPS"; then
deleteGTNHbackup
fi
if [[ -n "$GTNH_PACK_VERSION" ]] && isFalse "$SKIP_GTNH_UPDATE_CHECK" ; then
if [[ -n "$GTNH_PACK_VERSION" ]] && isFalse "$SKIP_GTNH_UPDATE_CHECK"; then
getGTNHdownloadPath
log "Server files located! Will proceed update $gtnh_download_path."
if isFalse "$GTNH_USE_DAILY_BUILD"; then
getGTNHdownloadPath
log "Server files located! Will proceed update $gtnh_download_path."
else
getGTNHdownloadOptions
log "Will proceed update with daily build options: ${gtnh_download_options[*]}."
fi
# Decide if update or install is needed or not.
@@ -239,7 +302,7 @@ function handleGTNH() {
fi
# Update .gtnh-version
basename "$gtnh_download_path" > /data/.gtnh-version
basename "$gtnh_download" > /data/.gtnh-version
# Cleaning up temporary files
rm -rf /data/.tmp
@@ -249,6 +312,9 @@ function handleGTNH() {
fi
else
log "SKIP_GTNH_UPDATE_CHECK=$SKIP_GTNH_UPDATE_CHECK ... Skipping GTNH Update/Install"
if [[ ! -f /data/.gtnh-version ]]; then
logWarning "No .gtnh-version file detected! There might not be a valid GTNH server installation in /data. Please ensure that the server files are present or set SKIP_GTNH_UPDATE_CHECK=false to allow the script to download and install the server files."
fi
fi
}
+2 -2
View File
@@ -158,10 +158,10 @@ traffic:
# Ignored if -1.0
maxPacketBytesRate: 2048.0
EOF
else
mc-image-helper patch --patch-env-prefix "" /image/nanolimbo-settings-patch.json
fi
mc-image-helper patch --patch-env-prefix "" /image/nanolimbo-settings-patch.json
export SERVER
export FAMILY=LIMBO
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
: "${NEOFORGE_VERSION:=latest}"
: "${NEOFORGE_FORCE_REINSTALL:=false}}"
: "${NEOFORGE_FORCE_REINSTALL:=false}"
: "${NEOFORGE_INSTALLER:=}"
# shellcheck source=start-utils
+14 -4
View File
@@ -22,18 +22,28 @@ case "$SPONGEBRANCH" in
esac
# If not SPONGEVERSION selected, detect last version on selected branch
if [ -z $SPONGEVERSION ]; then
if [ -z "$SPONGEVERSION" ]; then
log "Choosing Version for Sponge"
SPONGEVERSION=$(curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r --arg SPONGEBRANCH "$SPONGEBRANCH" '.buildTypes.$SPONGEBRANCH.latest.version')
if ! SPONGEVERSION=$(curl -fsSL "https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE" | jq -r --arg SPONGEBRANCH "$SPONGEBRANCH" '.buildTypes[$SPONGEBRANCH].latest.version'); then
logError "Failed to resolve latest SpongeVanilla version from the Sponge downloads API"
exit 1
fi
if [[ -z $SPONGEVERSION || $SPONGEVERSION == null ]]; then
logError "Sponge downloads API did not return a version for branch $SPONGEBRANCH"
exit 1
fi
fi
VERSION="$SPONGEVERSION"
export VERSION
export SERVER="spongevanilla-$SPONGEVERSION.jar"
if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
if [ ! -e "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD}"; then
log "Downloading $SERVER ..."
curl -sSL -o "$SERVER" "https://repo.spongepowered.org/maven/org/spongepowered/$TYPE/$SPONGEVERSION/$SERVER"
if ! curl -fsSL -o "$SERVER" "https://repo.spongepowered.org/maven/org/spongepowered/$TYPE/$SPONGEVERSION/$SERVER"; then
logError "Failed to download $SERVER"
exit 1
fi
fi
export FAMILY=SPONGE
+27 -9
View File
@@ -213,8 +213,11 @@ fi
: "${USE_MEOWICE_FLAGS:=false}"
: "${USE_MEOWICE_GRAALVM_FLAGS:=false}"
if isTrue "${USE_MEOWICE_FLAGS}"; then
if isTrue "${USE_MEOWICE_FLAGS}" || isTrue "${USE_MEOWICE_GRAALVM_FLAGS}"; then
java_major_version=$(mc-image-helper java-release)
fi
if isTrue "${USE_MEOWICE_FLAGS}"; then
if [[ $java_major_version -gt 16 ]]; then
log "Java version $java_major_version using MeowIce's flags for Java 17+"
else
@@ -344,6 +347,11 @@ if isTrue "${USE_MEOWICE_FLAGS}"; then
else
log "cpu not x86_64, disabling architecture specific flags"
fi
if [[ $java_major_version -gt 23 ]]; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseCompactObjectHeaders
"
fi
fi
if isTrue "${USE_MEOWICE_GRAALVM_FLAGS}"; then
@@ -483,7 +491,7 @@ if [[ ${STOP_SERVER_ANNOUNCE_DELAY} ]]; then
mcServerRunnerArgs+=(--stop-server-announce-delay "${STOP_SERVER_ANNOUNCE_DELAY}s")
fi
if [[ ${STOP_SERVER_DELAY_COMMAND} ]]; then
mcServerRunnerArgs+=(--stop-server-delay-command "${STOP_SERVER_DELAY_COMMAND}s")
mcServerRunnerArgs+=(--stop-server-delay-command "${STOP_SERVER_DELAY_COMMAND}")
fi
if isTrue "${ENABLE_SSH}"; then
mcServerRunnerArgs+=(--remote-console)
@@ -492,7 +500,10 @@ fi
if [[ ${TYPE} == "CURSEFORGE" && "${SERVER}" ]]; then
copyFilesForCurseForge
cd "${FTB_DIR}" || (logError "Can't go into ${FTB_DIR}"; exit 1)
if ! cd "${FTB_DIR}"; then
logError "Can't go into ${FTB_DIR}"
exit 1
fi
log "Starting CurseForge server in ${FTB_DIR}..."
if isTrue "${DEBUG_EXEC}"; then
set -x
@@ -505,11 +516,15 @@ elif [[ ${TYPE} == "CURSEFORGE" ]]; then
if isPercentage "$INIT_MEMORY" || isPercentage "$MAX_MEMORY"; then
# Convert to bytes
NORM_INIT_MEM=$(normalizeMemSize "$INIT_MEMORY")
NORM_MAX_MEM=$(normalizeMemSize "$MAX_MEMORY")
# Convert to MB
((NORM_INIT_MEM*=1048576))
((NORM_MAX_MEM*=1048576))
if ! NORM_INIT_MEM=$(normalizeMemSize "$INIT_MEMORY"); then
exit 1
fi
if ! NORM_MAX_MEM=$(normalizeMemSize "$MAX_MEMORY"); then
exit 1
fi
# Convert bytes to MB
((NORM_INIT_MEM/=1048576))
((NORM_MAX_MEM/=1048576))
cat > "${FTB_DIR}/settings-local.sh" <<EOF
export MIN_RAM="${NORM_INIT_MEM}M"
@@ -533,7 +548,10 @@ fi
fi
fi
cd "${FTB_DIR}" || (logError "Can't go into ${FTB_DIR}"; exit 1)
if ! cd "${FTB_DIR}"; then
logError "Can't go into ${FTB_DIR}"
exit 1
fi
log "Running FTB ${FTB_SERVER_START} in ${FTB_DIR} ..."
finalArgs="${FTB_SERVER_START}"
+3 -11
View File
@@ -9,23 +9,13 @@ set -e -o pipefail
: "${PLUGINS_FILE:=}"
: "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar,*-version.json}"
: "${CF_API_KEY_FILE:=}" # Path to file containing CurseForge API key
: "${CF_USE_HTTP2:=false}" # CF downloads are faster with HTTP 1.1
: "${MODRINTH_LOADER:=}"
# shellcheck source=start-utils
. "$(dirname "$0")/start-utils"
isDebugging && set -x
if [[ -n ${CF_API_KEY_FILE} ]]; then
if [[ -r "${CF_API_KEY_FILE}" ]]; then
CF_API_KEY="$(cat "${CF_API_KEY_FILE}")"
export CF_API_KEY
else
logError "CF_API_KEY_FILE is not readable: ${CF_API_KEY_FILE}"
exit 1
fi
fi
isDebugging && set -x
sum_file=/data/.generic_pack.sum
# Remove old mods/plugins
@@ -87,11 +77,13 @@ if [[ "$MODPACK" ]]; then
mkdir -p "$PLUGINS_OUT_DIR"
if ! unzip -o -d "$PLUGINS_OUT_DIR" /tmp/modpack.zip; then
logError "Failed to unzip the modpack from ${MODPACK}"
exit 2
fi
else
mkdir -p "$MODS_OUT_DIR"
if ! unzip -o -d "$MODS_OUT_DIR" /tmp/modpack.zip; then
logError "Failed to unzip the modpack from ${MODPACK}"
exit 2
fi
fi
rm -f /tmp/modpack.zip
+42 -11
View File
@@ -368,9 +368,22 @@ function logRcon() {
}
function normalizeMemSize() {
# Convert a JVM-style size (k/m/g) or a percentage of the container memory
# limit into bytes. Bash arithmetic is integer-only, so percentages cannot
# use a 0.01 scale factor.
local input=${1?}
local val=${input:0:-1}
local scale=1
local mem=1
case ${1,,} in
local mem
val=${val// /}
val=${val%%.*}
if ! [[ $val =~ ^[0-9]+$ ]]; then
logError "Unable to parse memory size '$input'"
return 1
fi
case ${input,,} in
*k)
scale=1024
;;
@@ -381,19 +394,25 @@ function normalizeMemSize() {
scale=1073741824
;;
*%)
# Get system memory
if [ -f "/sys/fs/cgroup/memory/memory.limit_in_bytes" ]; then
mem=$( cat /sys/fs/cgroup/memory/memory.limit_in_bytes )
elif [ -f "/sys/fs/cgroup/memory.max" ]; then
mem=$( cat /sys/fs/cgroup/memory.max )
if [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then
mem=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)
elif [ -f /sys/fs/cgroup/memory.max ]; then
mem=$(cat /sys/fs/cgroup/memory.max)
fi
# Scale is used to transform percentages into decimals (eg. 60 -> 0.6)
scale=0.01
# cgroup v2 unlimited is "max"; cgroup v1 uses a large sentinel (~2^63).
if [[ $mem == max || ! $mem =~ ^[0-9]+$ ]] || (( mem > 1 << 62 )); then
mem=$(awk '/MemTotal:/ { print $2 * 1024 }' /proc/meminfo)
fi
if ! [[ $mem =~ ^[0-9]+$ ]]; then
logError "Unable to determine memory limit for percentage value '$input'"
return 1
fi
echo $((val * mem / 100))
return 0
;;
esac
val=${1:0:-1}
echo $((val * scale * mem))
echo $((val * scale))
}
function compare_version() {
@@ -579,12 +598,24 @@ function extract() {
case "${type}" in
application/zip)
if unzip -Z1 "${src}" | grep -qE '(^/)|(^\.\./)|(/\.\./)|(/\.\.$)'; then
logError "Refusing to extract $src because it contains path traversal entries"
return 1
fi
unzip -o -q -d "${destDir}" "${src}" "$@"
;;
application/x-tar | application/gzip | application/x-gzip | application/x-bzip2)
if tar -tf "${src}" | grep -qE '(^/)|(^\.\./)|(/\.\./)|(/\.\.$)'; then
logError "Refusing to extract $src because it contains path traversal entries"
return 1
fi
tar -C "${destDir}" -xf "${src}" "$@"
;;
application/zstd | application/x-zstd)
if tar --use-compress-program=unzstd -tf "${src}" | grep -qE '(^/)|(^\.\./)|(/\.\./)|(/\.\.$)'; then
logError "Refusing to extract $src because it contains path traversal entries"
return 1
fi
tar -C "${destDir}" --use-compress-program=unzstd -xf "${src}" "$@"
;;
*)
@@ -0,0 +1,23 @@
services:
# copies seed/ into /data before mc starts, so the NanoLimbo setup takes its
# "settings.yml already exists" path instead of writing the template
seed:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
entrypoint: ["bash", "-c", "cp /seed/settings.yml /data/ && chown -R 1000:1000 /data"]
volumes:
- ./seed:/seed
- ./data:/data
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
depends_on:
seed:
condition: service_completed_successfully
environment:
EULA: "TRUE"
TYPE: NANOLIMBO
SERVER_PORT: "25599"
volumes:
- ./data:/data
@@ -0,0 +1,4 @@
bind:
ip: '0.0.0.0'
port: 25565
maxPlayers: 100
@@ -0,0 +1,4 @@
set -e
# SERVER_PORT must have been applied to the settings.yml that was already there
port=$(mc-image-helper yaml-path --file /data/settings.yml .bind.port)
[ "$port" = 25599 ] || { echo "expected bind.port 25599 but was '$port'"; exit 1; }