Compare commits

..
1 Commits
Author SHA1 Message Date
renovate[bot] fbd2ab30b7 Update dependency itzg/mc-image-helper to v1.61.4 2026-07-16 05:01:10 +00:00
85 changed files with 396 additions and 816 deletions
+4 -8
View File
@@ -6,15 +6,11 @@ on:
jobs:
auto-release:
runs-on: ubuntu-latest
# If forked, changed to your username to enable auto-releases
if: github.repository_owner == 'itzg'
permissions:
# allow for creating releases/tags
contents: write
steps:
- uses: zenengeo/github-auto-release-action@main
with:
stable-duration: 3d
force-duration: 14d
# It is important to use a token other than the workflow allocated GITHUB_TOKEN,
# since actions prevent loops by disallowing recursive workflow triggers with that token.
# In this case, the created tag needs to trigger the "Build and Publish" workflow.
token: '${{ secrets.GH_TOKEN }}'
force-duration: 14d
+34 -44
View File
@@ -18,7 +18,6 @@ on:
- "zensical.toml"
- ".readthedocs.yaml"
- "renovate.json5"
workflow_dispatch:
jobs:
build:
@@ -30,13 +29,10 @@ jobs:
- java25
- java25-alpine
- java25-jdk
- java25-graalvm
- java21
- java21-alpine
- java21-graalvm
- java21-jdk
- java17
- java17-graalvm
- java16
- java11
- java8
@@ -53,14 +49,12 @@ jobs:
baseImage: eclipse-temurin:25-jre-alpine
platforms: linux/amd64,linux/arm64
mcVersion: latest
# For GLIBC_2.34 support (and Alpine)
knockdRepoOrg: Metalcape/knock
- variant: java25-jdk
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
@@ -74,57 +68,55 @@ 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
# For GLIBC_2.34 support (and Alpine)
knockdRepoOrg: Metalcape/knock
# 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
# For GLIBC_2.34 support (and Alpine)
knockdRepoOrg: Metalcape/knock
# JAVA 16
- variant: java16
baseImage: adoptopenjdk:16-jre-hotspot
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.16.5
# For GLIBC_2.34 support
knockdRepoOrg: Metalcape/knock
# Pin version for pre-Java 17
mcHelperVersion: 1.51.4-java8
mcHelperVersion: 1.51.3-java8
# JAVA 11
- variant: java11
baseImage: adoptopenjdk:11-jre-hotspot
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.16.4
# For GLIBC_2.34 support
knockdRepoOrg: Metalcape/knock
# Pin version for pre-Java 17
mcHelperVersion: 1.51.4-java8
mcHelperVersion: 1.51.3-java8
# JAVA 8: NOTE: Unable to go past 8u312 because of Forge dependencies
- variant: java8
baseImage: eclipse-temurin:8u312-b07-jre-focal
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.12.2
# For GLIBC_2.34 support
knockdRepoOrg: Metalcape/knock
# Pin version for Java 8, also be sure to set in verify-pr.yml
mcHelperVersion: 1.51.4-java8
mcHelperVersion: 1.51.3-java8
- variant: java8-jdk
baseImage: eclipse-temurin:8u312-b07-jdk-focal
platforms: linux/amd64,linux/arm64
mcVersion: 1.12.2
# For GLIBC_2.34 support
knockdRepoOrg: Metalcape/knock
# Pin version for Java 8, also be sure to set in verify-pr.yml
mcHelperVersion: 1.51.4-java8
mcHelperVersion: 1.51.3-java8
env:
# 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' }}
IMAGE_AUTHOR: "Geoff Bourne <itzgeoff@gmail.com>"
runs-on: ubuntu-22.04
steps:
- name: Checkout
@@ -137,8 +129,10 @@ jobs:
id: meta
uses: docker/metadata-action@v6.2.0
with:
# NOTE for forks: if your Docker Hub organization doesn't match your Github repo's,
# then the use of ${{ github.repository_owner }} will need to be replaced.
images: |
${{ env.DOCKER_HUB_ORG }}/minecraft-server
${{ github.repository_owner }}/minecraft-server
ghcr.io/${{ github.repository_owner }}/minecraft-server
tags: |
# Apply the variant as a moving tag for most recent commit per variant
@@ -160,13 +154,13 @@ jobs:
flavor: |
latest=${{ matrix.variant == env.MAIN_VARIANT && github.ref_name == github.event.repository.default_branch }}
labels: |
org.opencontainers.image.authors=${{ env.IMAGE_AUTHOR }}
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v4.4.0
uses: docker/setup-qemu-action@v4.2.0
- name: Build for test
uses: docker/build-push-action@v7
@@ -195,15 +189,15 @@ jobs:
tests/test.sh
- name: Login to DockerHub
uses: docker/login-action@v4.6.0
if: env.HAS_IMAGE_REPO_ACCESS == 'true'
uses: docker/login-action@v4.4.0
if: env.HAS_IMAGE_REPO_ACCESS
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v4.6.0
if: env.HAS_IMAGE_REPO_ACCESS == 'true'
uses: docker/login-action@v4.4.0
if: env.HAS_IMAGE_REPO_ACCESS
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -216,16 +210,13 @@ jobs:
platforms: ${{ matrix.platforms }}
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 == 'true'
&& contains(github.event.pull_request.labels.*.name, 'ci/push-image')
)
)
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
&& contains(github.event.pull_request.labels.*.name, 'ci/push-image')
)
}}
tags: ${{ steps.meta.outputs.tags }}
# ensure latest base image is used
@@ -242,6 +233,5 @@ jobs:
REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
${{ matrix.mcHelperVersion && format('MC_HELPER_VERSION={0}', matrix.mcHelperVersion) }}
${{ matrix.knockdRepoOrg && format('KNOCKD_REPO_ORG={0}', matrix.knockdRepoOrg) }}
IMAGE_AUTHOR=${{ env.IMAGE_AUTHOR }}
cache-from: type=gha,scope=${{ matrix.variant }}
cache-to: type=gha,mode=max,scope=${{ matrix.variant }}
+42
View File
@@ -0,0 +1,42 @@
name: Discord notifications
on:
release:
types:
- published
workflow_run:
workflows: ["Build and Publish"]
types:
- completed
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
jobs:
discord:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: on-publish
if: github.event_name == 'release' && github.event.action == 'published'
uses: SethCohen/github-releases-to-discord@v1.20.0
with:
webhook_url: ${{ secrets.DISCORD_WEBHOOK }}
- name: on-success
if: github.event.workflow_run.conclusion == 'success'
uses: Ilshidur/action-discord@master
with:
args: |
Github repo: ${{ github.repository }}
- Branch: ${{ github.event.workflow_run.head_branch }}
- [Link: to Actions](<${{ github.event.workflow_run.html_url }}>)
- Status: 🎉 ${{ github.event.workflow_run.conclusion }} 🍏
- name: on-failure
if: github.event.workflow_run.conclusion == 'failure'
uses: Ilshidur/action-discord@master
with:
args: |
Github repo: ${{ github.repository }}
- Branch: ${{ github.event.workflow_run.head_branch }}
- [Link: to Actions](<${{ github.event.workflow_run.html_url }}>)
- Status: 🤔 ${{ github.event.workflow_run.conclusion }} 💣💥
@@ -7,13 +7,9 @@ on:
- labeled
- unlabeled
- closed
pull_request_target:
types:
- closed
- labeled
jobs:
notify:
if: github.repository_owner == 'itzg'
uses: itzg/github-workflows/.github/workflows/issues-notify-discord.yml@main
with:
triageLabel: 'status/needs triage'
+1 -2
View File
@@ -7,13 +7,12 @@ on:
jobs:
check:
runs-on: ubuntu-22.04
if: github.repository_owner == 'itzg'
permissions:
issues: write
pull-requests: write
steps:
- name: Process Stale Issues
uses: actions/stale@v11
uses: actions/stale@v10
with:
stale-issue-label: status/stale
stale-pr-label: status/stale
+1 -11
View File
@@ -24,7 +24,6 @@ jobs:
variant:
- java25
- java25-alpine
- java25-graalvm
- java17
- java8
include:
@@ -40,11 +39,6 @@ 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
@@ -53,7 +47,6 @@ jobs:
mcVersion: 1.20.4
# For GLIBC_2.34 support
knockdRepoOrg: Metalcape/knock
# JAVA 8:
- variant: java8
baseImage: eclipse-temurin:8u312-b07-jre-focal
platforms: linux/amd64
@@ -61,7 +54,7 @@ jobs:
# For GLIBC_2.34 support
knockdRepoOrg: Metalcape/knock
# Pin version for Java 8, be sure to also set in build.yml
mcHelperVersion: 1.51.4-java8
mcHelperVersion: 1.51.3-java8
env:
IMAGE_TO_TEST: ${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}
runs-on: ubuntu-22.04
@@ -75,9 +68,6 @@ jobs:
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v4.4.0
- name: Confirm multi-arch build
uses: docker/build-push-action@v7
with:
+7 -7
View File
@@ -13,11 +13,11 @@ ARG EXTRA_DNF_PACKAGES=""
ARG EXTRA_ALPINE_PACKAGES=""
ARG FORCE_INSTALL_PACKAGES=1
ARG KNOCKD_VERSION=0.8.1
ARG KNOCKD_REPO_ORG=Metalcape/knock
ARG KNOCKD_REPO_ORG=Opvolger/knock
RUN --mount=target=/build,source=build \
TARGET=${TARGETARCH}${TARGETVARIANT} \
/build/run.sh install-packages
COPY --from=tianon/gosu:1.19 /gosu /usr/local/bin/
COPY --from=tianon/gosu /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.17
ARG EASY_ADD_VERSION=0.8.15
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.7
ARG RCON_CLI_VERSION=1.7.6
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=1.18.2
ARG MC_MONITOR_VERSION=0.16.11
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.16.0
ARG MC_SERVER_RUNNER_VERSION=1.15.1
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.70.2
ARG MC_HELPER_VERSION=1.61.4
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
+1 -8
View File
@@ -6,10 +6,9 @@
[![](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/)
@@ -37,12 +36,6 @@ 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
@@ -1,39 +0,0 @@
# 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.
+5 -18
View File
@@ -3,13 +3,6 @@
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 \
@@ -42,19 +35,13 @@ apk add --no-cache -U \
libcap \
numactl \
jattach \
gcompat \
"$knockPkg" \
${EXTRA_ALPINE_PACKAGES}
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
# 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
# Set Git credentials globally
cat <<EOF >> /etc/gitconfig
+10 -6
View File
@@ -66,12 +66,16 @@ fi
# Clean up DNF when done
dnf clean all
# 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
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
# Set git credentials globally
cat <<EOF >> /etc/gitconfig
-4
View File
@@ -1,6 +1,2 @@
#!/bin/sh
set -e
groupadd --gid 1000 minecraft
useradd --system --shell /bin/false --uid 1000 -g minecraft --home /data minecraft
+1 -6
View File
@@ -37,13 +37,8 @@ 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
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"
curl -fsSL -o /tmp/knock.tar.gz "https://github.com/${KNOCKD_REPO_ORG}/releases/download/${KNOCKD_VERSION}/knock-${KNOCKD_VERSION}-$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
setcap cap_net_raw=ep /usr/local/sbin/knockd
-27
View File
@@ -179,10 +179,6 @@ such as:
You may configure the use of an HTTP/HTTPS proxy by passing the proxy's "host:port" via the environment variable `PROXY`. In [the example compose file](https://github.com/itzg/docker-minecraft-server/blob/master/examples/proxied/compose.yml) it references a Squid proxy. The host and port can be separately passed via the environment variables `PROXY_HOST` and `PROXY_PORT`. A `|` delimited list of hosts to exclude from proxying can be passed via `PROXY_NON_PROXY_HOSTS`.
## Prefer IPv6 Addresses and Stack
The image can be configured to prefer IPv6 addresses and stack by setting the environment variable `PREFER_IPV6` to "true". This will ensure the Java properties `java.net.preferIPv6Addresses` and `java.net.preferIPv6Stack` are set accordingly for mc-image-helper and the Minecraft server process.
## Using "noconsole" option
Some older versions (pre-1.14) of Spigot required `--noconsole` to be passed when detaching stdin, which can be done by setting `-e CONSOLE=FALSE`.
@@ -202,29 +198,6 @@ Be sure to also increase the shutdown timeout described [here for docker compose
If you are using a host-attached data directory, then you can have the image setup the Minecraft server files and stop prior to launching the server process by setting `SETUP_ONLY` to `true`.
## Custom server runner
By default, the image finishes startup by exec'ing [mc-server-runner](https://github.com/itzg/mc-server-runner) to run the Minecraft server itself. This can be replaced by setting the environment variable `SERVER_RUNNER`. The arguments passed will start with ones specific to mc-server-runner, followed by `--`, and then the actual `java -jar` arguments or equivalent server entry script, such as `run.sh` for Forge.
> [!TIP]
> The `SERVER_RUNNER` variable is expanded when passed to `exec` so that `mc-server-runner` can be wrapped by another executable that is mounted into the container.
## Pre-start script
To run something of your own after the image has finished setting up the server files and just before it starts the server, set `PRE_START_SCRIPT` to the path of an executable file that you have mounted into the container. The image runs it directly (not through a shell) and waits for it to finish. It runs as the user the server runs as, from the server's working directory, with the same environment the server gets. If it exits with a non-zero status, the container exits without starting the server.
For example, a script that waits for plugin jars that another process is still downloading:
```yaml
environment:
PRE_START_SCRIPT: /hooks/wait-for-plugins
volumes:
- ./hooks:/hooks:ro
```
> [!WARNING]
> The image does not guarantee that any particular command is available to the script, and it may change between image versions. Keeping the script working is up to you.
## Enable Flare Flags
To enable the JVM flags required to fully support the [Flare profiling suite](https://blog.airplane.gg/flare), set the following variable:
+1 -3
View File
@@ -168,9 +168,7 @@ To [enforce the whitelist changes immediately](https://minecraft.wiki/w/Server.p
!!! tip "Changing user API provider"
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.
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.
### Op/Administrator Players
+1 -1
View File
@@ -19,7 +19,7 @@
### Using the MASH playbook
[The MASH Playbook](https://github.com/mother-of-all-self-hosting/mash-playbook) is a premade playbook with the option to deploy a [wide variety of open-source services](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md) to your server(s), including [docker-minecraft-server](https://github.com/mother-of-all-self-hosting/ansible-role-minecraft), making it a good option if you want all the bells and whistles alongside your Minecraft server.
[The MASH Playbook](https://github.com/mother-of-all-self-hosting/mash-playbook) is a premade playbook with the option to deploy a [wide variety of open-source services](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md) to your server(s), including [docker-minecraft-server](https://github.com/XHawk87/ansible-role-minecraft), making it a good option if you want all the bells and whistles alongside your Minecraft server.
- Check out the [Installation Guide](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/README.md) for the MASH playbook to get started.
- You can then enable [Minecraft](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/minecraft.md) in your vars.yml.
- Enable any supporting services that you might find useful, such as [user authentication](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/authelia.md), [remote backups](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/backup-borg.md), [email relay](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/exim-relay.md), [cron monitoring](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/healthchecks.md), [audio and video conferencing](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/jitsi.md), databases ([MariaDB](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/mariadb.md), [PostgresSQL](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/postgres.md)), [push notifications](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/ntfy.md), [uptime monitoring](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/uptime-kuma.md), [a website](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/wordpress.md), as well as installing any [extra files, folders, applications, services and running commands](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/auxiliary.md) automatically on deployment.
-8
View File
@@ -29,11 +29,3 @@ 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.
### [Kobblestone](https://github.com/kobblestoneio/kobblestone)
A Kubernetes operator for Minecraft that supports custom resource types to manage servers, routers, backups and more.
+2 -2
View File
@@ -4,9 +4,9 @@ Mods and plugins can be auto-downloaded and upgraded from CurseForge by setting
A specific file can be omitted from each reference to allow for auto-selecting the newest version of the selected mod/plugin. The resolved `VERSION` and `TYPE` will be taken into consideration for selecting the appropriate file.
!!! info "CurseForge API key usage"
!!! warning "CurseForge API key usage"
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.
A CurseForge API key must 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).
## Project-file references
-22
View File
@@ -66,8 +66,6 @@ You can also specify the `REMOVE_OLD_MODS_DEPTH` (default is 16) variable to onl
For example: `-e REMOVE_OLD_MODS=TRUE -e REMOVE_OLD_MODS_INCLUDE="*.jar" -e REMOVE_OLD_MODS_DEPTH=1` will remove all old jar files that are directly inside the `plugins/` or `mods/` directory.
To remove all files in the `/data/config` directory before a modpack is downloaded and unpacked, set `REMOVE_OLD_CONFIGS=TRUE`. This is useful when a modpack update would otherwise override locally customized configuration files. The removal process can be fine tuned with `REMOVE_OLD_CONFIGS_INCLUDE` and `REMOVE_OLD_CONFIGS_EXCLUDE` (comma separated lists of file glob patterns, defaults to `*` so everything is removed) and `REMOVE_OLD_CONFIGS_DEPTH` (default 16). The target directory can be changed with `CONFIG_OUT_DIR` (default `/data/config`).
These paths work well if you want to have a common set of modules in a separate location, but still have multiple worlds with different server requirements in either persistent volumes or a downloadable archive.
!!! information "Multiple source directories"
@@ -153,26 +151,6 @@ GENERIC_PACKS_SUFFIX=.zip
would expand to `https://cdn.example.org/configs-v9.0.1.zip,https://cdn.example.org/mods-v4.3.6.zip`.
### Generic packs from an OCI registry
An entry can also reference a pack stored as an [OCI](https://opencontainers.org/) artifact in a container registry by prefixing it with `oci://`. The reference may use a tag or an immutable `@sha256:` digest:
```
GENERIC_PACKS=oci://ghcr.io/itzg/oci-modpack-template/tech:latest,oci://ghcr.io/itzg/oci-modpack-template/magic:latest
```
OCI, URL, and local-path entries can be mixed in the same list and are applied in the order given. Each artifact's layers are pulled into a content-addressed cache under `/data/packs/oci`, so a digest already on disk (for example a base layer shared between packs) is not downloaded again. `GENERIC_PACKS_PREFIX`/`GENERIC_PACKS_SUFFIX`, `GENERIC_PACKS_DISABLE_MODS`, and the update/checksum behaviour below all apply to OCI entries exactly as they do to URLs.
The artifact must be a Minecraft modpack artifact (artifact type `application/vnd.itzg.minecraft.modpack.v1+json` with `…modpack.layer.v1.tar+gzip` layers); any other reference is rejected before its contents touch `/data`. Validation and registry authentication are handled by `mc-image-helper`.
For a private registry, point `GENERIC_PACKS_OCI_AUTH_FILE` at a registry login file (the `auth.json`/`config.json` produced by `docker login`, `podman login`, etc.):
```
GENERIC_PACKS_OCI_AUTH_FILE=/run/secrets/registry-auth.json
```
When it is unset, a credentials file at `~/.config/containers/auth.json` or `~/.docker/config.json` is used if present, otherwise the pull is anonymous.
If applying large generic packs, the update can be time-consuming. To skip the update set `SKIP_GENERIC_PACK_UPDATE_CHECK` to "true". Conversely, the generic pack(s) can be forced to be applied by setting `FORCE_GENERIC_PACK_UPDATE` to "true".
The most time-consuming portion of the generic pack update is generating and comparing the SHA1 checksum. To skip the checksum generation, set `SKIP_GENERIC_PACK_CHECKSUM` to "true".
+10 -10
View File
@@ -1,25 +1,25 @@
click==8.5.0
click==8.4.2
colorama==0.4.6
deepmerge==3.0.1
deepmerge==2.1.0
ghp-import==2.1.0
griffe==2.3.0
griffe==2.1.0
Jinja2==3.1.6
Markdown==3.11
Markdown==3.10.2
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.9
packaging==26.3
mkdocstrings-python==2.0.5
packaging==26.2
pathspec==1.1.1
platformdirs==4.12.0
Pygments==2.21.0
pymdown-extensions==12.1
platformdirs==4.10.0
Pygments==2.20.0
pymdown-extensions==11.0.1
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.65
zensical==0.0.50
@@ -4,11 +4,9 @@ To manage a CurseForge modpack automatically with upgrade support, pinned or lat
## API Key
!!! info "CurseForge API key usage"
!!! warning "CurseForge API key usage"
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).
A CurseForge API key is **required** to use this feature. Go to their [developer console](https://console.curseforge.com/), generate an API key, and set the environment variable `CF_API_KEY`.
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.
@@ -81,11 +79,13 @@ Pass a page URL to the modpack or a specific file with `CF_PAGE_URL` such as the
environment:
# ...
MODPACK_PLATFORM: AUTO_CURSEFORGE
# allocate from https://console.curseforge.com/ and set in .env file
CF_API_KEY: ${CF_API_KEY}
CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/all-the-mods-8
```
```title="Using docker run"
docker run -e TYPE=AUTO_CURSEFORGE -e CF_PAGE_URL=https://www.curseforge.com/minecraft/modpacks/all-the-mods-8
docker run -e CF_API_KEY=${CF_API_KEY} -e TYPE=AUTO_CURSEFORGE -e CF_PAGE_URL=https://www.curseforge.com/minecraft/modpacks/all-the-mods-8
```
Instead of a URL, the modpack slug can be provided as `CF_SLUG`. The slug is the short identifier visible in the URL after "/modpacks/", such as
@@ -98,11 +98,13 @@ Instead of a URL, the modpack slug can be provided as `CF_SLUG`. The slug is the
environment:
# ...
MODPACK_PLATFORM: AUTO_CURSEFORGE
# allocate from https://console.curseforge.com/ and set in .env file
CF_API_KEY: ${CF_API_KEY}
CF_SLUG: all-the-mods-8
```
```title="Using docker run"
docker run -e TYPE=AUTO_CURSEFORGE -e CF_SLUG=all-the-mods-8
docker run -e CF_API_KEY=${CF_API_KEY} -e TYPE=AUTO_CURSEFORGE -e CF_SLUG=all-the-mods-8
```
### Pinning modpack and mod loader versions
@@ -111,7 +113,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 either a substring or a regex pattern surrounded with "/" to match the desired filename with `CF_FILENAME_MATCHER`
- Specify a substring 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:
@@ -133,21 +135,6 @@ 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
@@ -161,6 +148,7 @@ By default, AUTO_CURSEFORGE will use the exact modloader version declared by the
```yaml
environment:
MODPACK_PLATFORM: AUTO_CURSEFORGE
CF_API_KEY: ${CF_API_KEY}
CF_SLUG: all-the-mods-8
CF_MOD_LOADER_VERSION: "43.4.22"
```
@@ -209,6 +197,8 @@ If you wish to use an unpublished modpack zip, set the container path to the fil
environment:
EULA: true
MODPACK_PLATFORM: AUTO_CURSEFORGE
# allocate from https://console.curseforge.com/ and set in .env file
CF_API_KEY: ${CF_API_KEY}
CF_MODPACK_MANIFEST: /manifests/manifest.json
CF_SLUG: "custom"
volumes:
@@ -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-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.
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.
> 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,11 +52,3 @@ 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 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.
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.
!!! 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 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.
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.
!!! example
+1 -13
View File
@@ -204,12 +204,6 @@ 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>
@@ -288,12 +282,6 @@ alternatively, you can mount: <code>/etc/localtime:/etc/localtime:ro
<td><code>false</code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>PRE_START_SCRIPT</code></td>
<td>Path to an executable run after setup and just before the server starts. The server is not started if it exits non-zero. See <a href="../configuration/misc-options/#pre-start-script">Pre-start script</a></td>
<td><code></code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>USE_FLARE_FLAGS</code></td>
<td>To enable the JVM flags required to fully support the <a href="https://blog.airplane.gg/flare">Flare profiling suite</a>.</td>
@@ -623,7 +611,7 @@ This image maps known server properties as described in [this section](configura
</tr>
<tr>
<td><code>CF_FILENAME_MATCHER</code></td>
<td>Specify either a substring or a regex pattern surrounded with "/" to match the desired filename</td>
<td>Specify a substring to match the desired filename</td>
<td><code></code></td>
<td>⬜️</td>
</tr>
+2 -10
View File
@@ -17,13 +17,10 @@ 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 | |
@@ -31,8 +28,6 @@ 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"
@@ -111,11 +106,7 @@ Caused by: org.spongepowered.asm.mixin.throwables.ClassMetadataNotFoundException
#### Java 8
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.
For Forge versions less than 1.18, you _must_ use the `java8-multiarch` (or other java8) image tag.
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:
@@ -130,6 +121,7 @@ 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
@@ -4,6 +4,11 @@ services:
environment:
EULA: true
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/all-of-fabric-7
# CF_FILENAME_MATCHER: 1.2.2
CF_OVERRIDES_EXCLUSIONS: |
@@ -1 +0,0 @@
cf-api-key*
@@ -1,34 +0,0 @@
name: atm10-with-secret-file
secrets:
cf-api-key:
file: ./cf-api-key.txt
services:
mc:
image: itzg/minecraft-server
tty: true
stdin_open: true
ports:
- "25565:25565"
environment:
EULA: true
MOD_PLATFORM: AUTO_CURSEFORGE
CF_SLUG: all-the-mods-10
# Optional: select a specific version/file
# CF_FILENAME_MATCHER: "1.17"
CF_API_KEY_FILE: /run/secrets/cf-api-key
DEBUG: true
MEMORY: 4G
CF_OVERRIDES_EXCLUSIONS: |
# Not applicable for server side
shaderpacks/**
secrets:
- cf-api-key
volumes:
# Use managed volume by default, but can change to a relative path like
# ./data:/data
# to use a host directory
- mc-data:/data
volumes:
mc-data:
@@ -8,13 +8,15 @@ services:
environment:
EULA: true
MOD_PLATFORM: AUTO_CURSEFORGE
# Verified up to ATM10 8.1
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_SLUG: all-the-mods-10
# Optional: select a specific version/file
# CF_FILENAME_MATCHER: "1.17"
MEMORY: 4G
CF_IGNORE_MISSING_FILES: |
config/ftbquests/quests/reward_tables/*.snbt
CF_OVERRIDES_EXCLUSIONS: |
# Not applicable for server side
shaderpacks/**
@@ -6,6 +6,11 @@ services:
environment:
EULA: "true"
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/all-the-mods-8
# CF_FILENAME_MATCHER: "1.1.0"
MEMORY: 4G
@@ -6,6 +6,11 @@ services:
environment:
EULA: "true"
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/all-the-mods-9
# Optional: select a specific version/file
#CF_FILENAME_MATCHER: "0.2.34"
@@ -9,6 +9,7 @@ services:
EULA: true
ALLOW_FLIGHT: true
MOD_PLATFORM: AUTO_CURSEFORGE
CF_API_KEY: ${CF_API_KEY}
CF_SLUG: craftoria
MOTD: |
A %TYPE% server on %VERSION%
@@ -4,6 +4,8 @@ services:
environment:
EULA: "TRUE"
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
CF_API_KEY: ${CF_API_KEY}
# Example of overriding modloader version for a Fabric modpack
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_SLUG: "cobblemon-fabric"
@@ -9,6 +9,11 @@ services:
environment:
EULA: "TRUE"
TYPE: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/ftb-evolution
# This modpack includes an override client-side only mod that will prevent the server from starting.
# For more information on override exclusions see:
@@ -4,6 +4,11 @@ services:
environment:
EULA: true
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_MODPACK_MANIFEST: /manifests/manifest.json
CF_SLUG: "custom"
MEMORY: 2G
@@ -6,6 +6,11 @@ services:
environment:
EULA: "true"
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_SLUG: one-block-modded
# Modpack client zip must be manually downloaded from
# https://www.curseforge.com/minecraft/modpacks/one-block-modded
@@ -6,6 +6,11 @@ services:
environment:
EULA: "true"
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_SLUG: the-pixelmon-modpack
CF_FILENAME_MATCHER: "9.1.2"
MEMORY: 4G
@@ -6,6 +6,11 @@ services:
environment:
EULA: "true"
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/prominence-2-rpg
CF_FILENAME_MATCHER: "2.8.7"
MEMORY: 4G
@@ -7,6 +7,11 @@ services:
environment:
EULA: "true"
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/roguelike-adventures-and-dungeons-2
# Optional: select a specific version/file
#CF_FILENAME_MATCHER: "0.2.34"
@@ -6,6 +6,7 @@ services:
MODPACK_PLATFORM: AUTO_CURSEFORGE
CF_SLUG: skyfactory-4
CF_FILENAME_MATCHER: 4.2.4
CF_API_KEY: ${CF_API_KEY}
MEMORY: 3G
ports:
- "25565:25565"
@@ -10,6 +10,11 @@ services:
# Comment out the following to get the latest version or pick a version from
# https://www.curseforge.com/minecraft/modpacks/skyfactory-5/files/all?page=1&pageSize=20
CF_FILENAME_MATCHER: 5.0.8
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
MEMORY: 4G
ports:
- "25565:25565"
@@ -6,6 +6,11 @@ services:
environment:
EULA: "true"
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/minecraft-eternal/files/4102634
MEMORY: 4G
volumes:
@@ -6,6 +6,11 @@ services:
environment:
EULA: "true"
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_FORCE_SYNCHRONIZE: "true"
CF_PAGE_URL: https://www.curseforge.com/minecraft/modpacks/valhelsia-5/files/4429560
MEMORY: 4G
@@ -6,6 +6,11 @@ services:
environment:
EULA: "true"
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_SLUG: vault-hunters-1-18-2
MOTD: "§4----- §2 Vault Hunters: 1.18.2 §4 -----§r\\n §4------ §e vaulthunters.gg §4------"
MEMORY: 6G # 4G for base server + 2G per player
+5
View File
@@ -4,6 +4,11 @@ services:
environment:
EULA: true
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_SLUG: better-mc-fabric-bmc1
# CF_FILENAME_MATCHER: v18.5
MEMORY: 4G
@@ -4,6 +4,11 @@ services:
environment:
EULA: true
TYPE: FORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
VERSION: 1.19.2
CURSEFORGE_FILES: |
geckolib # some comment
+6 -2
View File
@@ -1,7 +1,6 @@
name: mc-rconcmd
services:
minecraft:
image: itzg/minecraft-server
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
ports:
- "25565:25565"
volumes:
@@ -13,6 +12,11 @@ services:
CURSEFORGE_FILES: |
fabric-api
chunky-pregenerator
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
# YAML Heredoc, be sure to use '|-' this will remove the first newline and final new line.
# This is versus '|' that will leaving with two empty strings at top and bottom.
RCON_CMDS_STARTUP: |-
@@ -14,9 +14,6 @@ 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: |
+5
View File
@@ -5,6 +5,11 @@ services:
EULA: true
TYPE: KETTING
VERSION: 1.20.1
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: "${CF_API_KEY}"
CURSEFORGE_FILES: https://www.curseforge.com/minecraft/mc-mods/aquaculture
ports:
- "25565:25565"
-2
View File
@@ -37,8 +37,6 @@ 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,7 +6,6 @@ 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
+5
View File
@@ -4,6 +4,11 @@ services:
environment:
EULA: true
MODPACK_PLATFORM: AUTO_CURSEFORGE
# Allocate API key from https://console.curseforge.com/
# and set in .env file making sure to double up dollar signs, such as
# CF_API_KEY=$$2a$$10$$....
# Refer to https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/auto-curseforge/#api-key
CF_API_KEY: ${CF_API_KEY}
CF_SLUG: rlcraft
CF_FILENAME_MATCHER: 2.9.3
CF_FORCE_SYNCHRONIZE: true
-4
View File
@@ -177,7 +177,6 @@
"yungs-menu-tweaks",
"zume"
],
"globalForceIncludes": ["simply-tooltips"],
"modpacks": {
"all-of-fabric-6": {
"forceIncludes": ["revelationary"]
@@ -188,9 +187,6 @@
"create-arcane-engineering": {
"forceIncludes": ["just-enough-resources-jer"]
},
"fantasy-minecraft-fabric": {
"forceIncludes": ["icon-leading-tooltip"]
},
"ftb-stoneblock-4": {
"forceIncludes": [
"particular-reforged",
+3 -2
View File
@@ -48,8 +48,9 @@
"fancymenu",
"fast-ip-ping",
"fastquit",
"FauxCustomEntityData",
"feytweaks",
"/(^|/)figura-/",
"figura",
"ForgeConfigScreens",
"GeckoLibIrisCompat",
"gpumemleakfix",
@@ -105,7 +106,7 @@
"Zoomify",
"zume"
],
"globalForceIncludes": ["/(^|/)simplytooltips-/", "/(^|/)s-lib-/"],
"globalForceIncludes": [],
"modpacks": {
"cobbleverse": {
"excludes": [
+8 -12
View File
@@ -1,16 +1,12 @@
{
"patches": [
"file": "/data/settings.yml",
"ops": [
{
"file": "/data/settings.yml",
"ops": [
{
"$set": {
"path": "$.bind.port",
"value": "${SERVER_PORT}",
"value-type": "int"
}
}
]
"$set": {
"path": "$.bind.port",
"value": "${SERVER_PORT}",
"value-type": "int"
}
}
]
}
}
-10
View File
@@ -10,16 +10,6 @@
"matchStrings": [
"# renovate: datasource=(?<datasource>[a-z-]+?)(?: packageName=(?<packageName>.+?))?(?: versioning=(?<versioning>[a-z-]+))?\\s(?:ENV|ARG) .+?_VERSION=(?<currentValue>.+?)\\s"
]
},
{
"customType": "regex",
"description": "Update versioned images used by Dockerfile COPY --from instructions",
"managerFilePatterns": ["/^Dockerfile$/"],
"matchStrings": [
"COPY --from=(?<depName>[^:\\s]+):(?<currentValue>[^\\s]+)\\s"
],
"datasourceTemplate": "docker",
"versioningTemplate": "docker"
}
],
"labels": ["dependencies"]
+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 /data/.knockd.cfg -d -i "$AUTOPAUSE_KNOCK_INTERFACE")
knockdArgs=(-c /tmp/knockd-config.cfg -d -i "$AUTOPAUSE_KNOCK_INTERFACE")
if isTrue "${DEBUG_AUTOPAUSE}"; then
knockdArgs+=(-D)
fi
+5 -11
View File
@@ -24,13 +24,13 @@ log "Autopause functionality enabled"
isDebugging && set -x
cp /image/knockd-config.cfg /data/.knockd.cfg
cp /image/knockd-config.cfg /tmp/knockd-config.cfg
function updatePort() {
regseq="^\s*sequence\s*=\s*$1\s*$"
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
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
log "Updated $3 port in knockd config"
fi
}
@@ -67,12 +67,6 @@ 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/" /data/.knockd.cfg
if isDebugging; then
echo "Autopause configuration: ======================================"
cat /data/.knockd.cfg
echo "==============================================================="
fi
sed -i "s/\(seq_cooldown *= *\).*/\1$COOLDOWN/" /tmp/knockd-config.cfg
"$(dirname "$0")/auto/autopause-daemon.sh" &
+1 -13
View File
@@ -7,7 +7,6 @@ IFS=$'\n\t'
: "${EULA:=}"
: "${PROXY:=}"
: "${PREFER_IPV6:=false}"
: "${ENABLE_AUTOPAUSE:=false}"
: "${ENABLE_AUTOSTOP:=false}"
: "${RCON_CMDS_STARTUP:=}"
@@ -29,22 +28,11 @@ shopt -s nullglob
isDebugging && set -x
if isTrue "$PREFER_IPV6"; then
MC_IMAGE_HELPER_OPTS+="-Djava.net.preferIPv6Addresses=true -Djava.net.preferIPv6Stack=true"
export MC_IMAGE_HELPER_OPTS
JVM_DD_OPTS+="java.net.preferIPv6Addresses=true java.net.preferIPv6Stack=true"
export JVM_DD_OPTS
fi
if (( $(getJavaRelease) >= 17 )); then
if (( $(mc-image-helper java-release) >= 17 )); then
MC_IMAGE_HELPER_OPTS+=" --enable-native-access=ALL-UNNAMED"
export MC_IMAGE_HELPER_OPTS
fi
if [[ $(getDistro) == alpine ]]; then
export LD_PRELOAD=/lib/libgcompat.so.0
fi
export HOME=/data
log "Running as uid=$(id -u) gid=$(id -g) with /data as '$(ls -lnd /data)'"
+11
View File
@@ -22,11 +22,22 @@ 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 -fsSL -o "${tempDir}/BuildTools.jar" https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar && \
curl -sSL -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 -fsSL -o "${SERVER}" "${CUSTOM_SERVER}"; then
logError "Failed to download from ${CUSTOM_SERVER}"
if ! curl -sSL -o "${SERVER}" "${CUSTOM_SERVER}"; then
log "Failed to download from ${CUSTOM_SERVER}"
exit 2
fi
fi
+5 -8
View File
@@ -9,7 +9,7 @@ ftbInstallMarker=".ftb-installed"
# shellcheck source=start-utils
. "$(dirname "$0")/start-utils"
isDebugging && set -x
set -e -o pipefail
set -e
#
#{
@@ -93,10 +93,7 @@ if isTrue "$FTB_FORCE_REINSTALL" ||
log "Installing modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID}"
log "This could take a while..."
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
${ftbInstaller} -pack "${FTB_MODPACK_ID}" -version "${FTB_MODPACK_VERSION_ID}" -auto -force -no-java | tee ftb-installer.log
rm -f forge*installer.jar
echo "${FTB_MODPACK_ID}=${FTB_MODPACK_VERSION_ID}" > ${ftbInstallMarker}
@@ -143,9 +140,9 @@ if [[ $SERVER = run.sh ]]; then
elif grep -q forge "$SERVER"; then
export FAMILY=FORGE
export TYPE=FORGE
elif grep -q fabric "$SERVER"; then
export FAMILY=FABRIC
export TYPE=FABRIC
elif grep -q fabric run.s; 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"
+31 -97
View File
@@ -7,20 +7,18 @@
function getGTNHdownloadPath(){
gtnh_download_path=""
local release_object=""
local current_java_version=""
current_java_version=$(mc-image-helper java-release)
# Select release JSON object
# 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 [ "$GTNH_PACK_VERSION" == "latest-dev" ]; then
if ! release_object="$(
curl -fsSL "https://downloads.gtnewhorizons.com/versions.json" \
| jq -r '(.versions // .)|to_entries|sort_by(.value.releaseDate,(.key | ascii_downcase | if test("rc") then 2 elif test("beta") then 1 else 0 end))|map(select(.value.title=="Beta release"))|.[-1]'
| jq -r '(.versions // .)|to_entries|sort_by(.value.releaseDate)|map(select(.value.title=="Beta release"))|.[-1]'
)"; then logError "Failed to retrieve release from https://downloads.gtnewhorizons.com/versions.json"
exit 1
fi
log "Selected $(jq '.key' <<< "$release_object") as latest beta version for download."
log "Selected $(jq '.key' <<< "$release_object") as latest dev version for download."
elif [ "$GTNH_PACK_VERSION" == "latest" ]; then
if ! release_object="$(
@@ -34,7 +32,7 @@ function getGTNHdownloadPath(){
else
if ! release_object="$(
curl -fsSL "https://downloads.gtnewhorizons.com/versions.json" \
| jq -r --arg USRIN "$GTNH_PACK_VERSION" '($USRIN | ascii_downcase) as $in|(.versions // .)|to_entries|sort_by(.value.releaseDate)|map(select((.key | ascii_downcase)==$in))|.[]'
| jq -r --arg USRIN "$GTNH_PACK_VERSION" '(.versions // .)|to_entries|sort_by(.value.releaseDate)|map(select(.key==$USRIN))|.[]'
)"; then logError "Failed to retrieve release from https://downloads.gtnewhorizons.com/versions.json"
exit 1
fi
@@ -48,18 +46,23 @@ function getGTNHdownloadPath(){
fi
# Select compatible server files for java version
if (( java_version == 8 )); then
if (( current_java_version == 8 )); then
gtnh_download_path=$(jq -r '.value.server.java8Url' <<< "$release_object")
log "Use GTNH Server Java 8 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."
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."
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
@@ -70,56 +73,6 @@ 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
@@ -128,33 +81,24 @@ function deleteGTNHbackup(){
}
function downloadGTNH(){
gtnh_download=""
local 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
mkdir -p "${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}"
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}"
# Remove any eula file since container manages it
debug "Removing eula.txt from $base_dir"
@@ -265,23 +209,16 @@ function handleGTNH() {
: "${GTNH_PACK_VERSION:=latest}"
: "${GTNH_DELETE_BACKUPS:=false}"
: "${SKIP_GTNH_UPDATE_CHECK:=false}"
: "${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"
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"
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
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
getGTNHdownloadPath
log "Server files located! Will proceed update $gtnh_download_path."
# Decide if update or install is needed or not.
@@ -302,7 +239,7 @@ function handleGTNH() {
fi
# Update .gtnh-version
basename "$gtnh_download" > /data/.gtnh-version
basename "$gtnh_download_path" > /data/.gtnh-version
# Cleaning up temporary files
rm -rf /data/.tmp
@@ -312,9 +249,6 @@ 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
+4 -14
View File
@@ -22,28 +22,18 @@ 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"
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
SPONGEVERSION=$(curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r --arg SPONGEBRANCH "$SPONGEBRANCH" '.buildTypes.$SPONGEBRANCH.latest.version')
fi
VERSION="$SPONGEVERSION"
export VERSION
export SERVER="spongevanilla-$SPONGEVERSION.jar"
if [ ! -e "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD}"; then
if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
log "Downloading $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
curl -sSL -o "$SERVER" "https://repo.spongepowered.org/maven/org/spongepowered/$TYPE/$SPONGEVERSION/$SERVER"
fi
export FAMILY=SPONGE
+40 -16
View File
@@ -5,28 +5,52 @@
isDebugging && set -x
set -o pipefail
resultsFile=/data/.install-vanilla.env
resolveVersion
export SERVER="minecraft_server.${VERSION// /_}.jar"
args=(
--output-directory=/data
--results-file="${resultsFile}"
--version="${VERSION}"
)
if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
debug "Finding version manifest for $VERSION"
versionManifestUrl=$(get 'https://launchermeta.mojang.com/mc/game/version_manifest.json' | jq --arg VERSION "$VERSION" --raw-output '[.versions[]|select(.id == $VERSION)][0].url')
result=$?
if [ $result != 0 ]; then
logError "Failed to obtain version manifest URL ($result)"
exit 1
fi
if [ "$versionManifestUrl" = "null" ]; then
logError "Couldn't find a matching manifest entry for $VERSION"
exit 1
fi
debug "Found version manifest at $versionManifestUrl"
if isTrue "${FORCE_REDOWNLOAD}"; then
log "Forcing re-install of Minecraft"
args+=(--force-reinstall)
if ! serverDownloadUrl=$(get --json-path '$.downloads.server.url' "${versionManifestUrl}"); then
logError "Failed to obtain version manifest from $versionManifestUrl ($result)"
exit 1
elif [ "$serverDownloadUrl" = "null" ]; then
logError "There is not a server download for version $VERSION"
exit 1
fi
log "Downloading $VERSION server..."
debug "Downloading server from $serverDownloadUrl"
get -o "$SERVER" "$serverDownloadUrl"
result=$?
if [ $result != 0 ]; then
logError "Failed to download server from $serverDownloadUrl ($result)"
exit 1
fi
fi
minecraftServerJarPath=/data/minecraft_server.jar
if ! mc-image-helper install-vanilla "${args[@]}"; then
logError "Failed to install vanilla Minecraft version $VERSION"
exit 1
if versionLessThan 1.6; then
if ! [[ -L $minecraftServerJarPath && $minecraftServerJarPath -ef "/data/$SERVER" ]]; then
rm -f $minecraftServerJarPath
ln -s "/data/$SERVER" $minecraftServerJarPath
fi
SERVER=minecraft_server.jar
elif [[ -L $minecraftServerJarPath ]]; then
rm -f $minecraftServerJarPath
fi
applyResultsFile "${resultsFile}"
log "Successfully setup vanilla Minecraft version $VERSION"
isDebugging && ls -l
export FAMILY=VANILLA
exec "$(dirname "$0")/start-setupWorld" "$@"
+16 -56
View File
@@ -3,28 +3,10 @@
: "${DEBUG_EXEC:=false}"
: "${SETUP_ONLY:=false}"
: "${CUSTOM_JAR_EXEC:=}"
: "${SERVER_RUNNER:=mc-server-runner}"
: "${PRE_START_SCRIPT:=}"
# shellcheck source=start-utils
. "$(dirname "$0")/start-utils"
isDebugging && set -x
function runPreStartScript() {
if [[ ! $PRE_START_SCRIPT ]]; then
return
fi
if [[ ! -x $PRE_START_SCRIPT ]]; then
logError "PRE_START_SCRIPT $PRE_START_SCRIPT is not an executable file"
exit 1
fi
log "Running pre-start script $PRE_START_SCRIPT..."
if ! "$PRE_START_SCRIPT"; then
logError "Pre-start script $PRE_START_SCRIPT failed, so the server will not be started"
exit 1
fi
}
baseDataDir=/data
tmpServerIconPath=/tmp/icon.img
serverIconPath=${baseDataDir}/server-icon.png
@@ -114,7 +96,7 @@ fi
if versionLessThan 1.7; then
: # No patch required here.
elif versionLessThan 1.18.1; then
if isTrue "${SKIP_LOG4J_PATCHER:-false}"; then
if isTrue ${SKIP_LOG4J_PATCHER:-false}; then
log "Skipping Log4jPatcher, make sure you are not affected"
else
JVM_OPTS="-javaagent:/image/Log4jPatcher.jar ${JVM_OPTS}"
@@ -230,11 +212,8 @@ fi
: "${USE_MEOWICE_FLAGS:=false}"
: "${USE_MEOWICE_GRAALVM_FLAGS:=false}"
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
java_major_version=$(mc-image-helper java-release)
if [[ $java_major_version -gt 16 ]]; then
log "Java version $java_major_version using MeowIce's flags for Java 17+"
else
@@ -364,11 +343,6 @@ 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
@@ -508,7 +482,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}")
mcServerRunnerArgs+=(--stop-server-delay-command "${STOP_SERVER_DELAY_COMMAND}s")
fi
if isTrue "${ENABLE_SSH}"; then
mcServerRunnerArgs+=(--remote-console)
@@ -517,16 +491,12 @@ fi
if [[ ${TYPE} == "CURSEFORGE" && "${SERVER}" ]]; then
copyFilesForCurseForge
if ! cd "${FTB_DIR}"; then
logError "Can't go into ${FTB_DIR}"
exit 1
fi
cd "${FTB_DIR}" || (logError "Can't go into ${FTB_DIR}"; exit 1)
log "Starting CurseForge server in ${FTB_DIR}..."
runPreStartScript
if isTrue "${DEBUG_EXEC}"; then
set -x
fi
exec ${SERVER_RUNNER} ${bootstrapArgs} "${mcServerRunnerArgs[@]}" -- java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar "$(basename "${SERVER}")" "$@" $EXTRA_ARGS
exec mc-server-runner ${bootstrapArgs} "${mcServerRunnerArgs[@]}" java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar "$(basename "${SERVER}")" "$@" $EXTRA_ARGS
elif [[ ${TYPE} == "CURSEFORGE" ]]; then
mcServerRunnerArgs+=(--shell bash)
@@ -534,15 +504,11 @@ elif [[ ${TYPE} == "CURSEFORGE" ]]; then
if isPercentage "$INIT_MEMORY" || isPercentage "$MAX_MEMORY"; then
# Convert to bytes
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))
NORM_INIT_MEM=$(normalizeMemSize "$INIT_MEMORY")
NORM_MAX_MEM=$(normalizeMemSize "$MAX_MEMORY")
# Convert to MB
((NORM_INIT_MEM*=1048576))
((NORM_MAX_MEM*=1048576))
cat > "${FTB_DIR}/settings-local.sh" <<EOF
export MIN_RAM="${NORM_INIT_MEM}M"
@@ -566,10 +532,7 @@ fi
fi
fi
if ! cd "${FTB_DIR}"; then
logError "Can't go into ${FTB_DIR}"
exit 1
fi
cd "${FTB_DIR}" || (logError "Can't go into ${FTB_DIR}"; exit 1)
log "Running FTB ${FTB_SERVER_START} in ${FTB_DIR} ..."
finalArgs="${FTB_SERVER_START}"
@@ -587,20 +550,18 @@ fi
JVM_ARGS=${JVM_ARGS//$'\n'/}
sed -i "s~JAVA_ARGS=.*~JAVA_ARGS=\"${JVM_ARGS}\"~" "${FTB_DIR}/variables.txt"
fi
runPreStartScript
exec ${SERVER_RUNNER} "${mcServerRunnerArgs[@]}" -- "${finalArgs[@]}"
exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}"
elif [[ $SERVER =~ run.sh ]]; then
log "Using Forge supplied run.sh script..."
echo $JVM_XX_OPTS $JVM_OPTS $expandedDOpts > user_jvm_args.txt
if isTrue "${SETUP_ONLY}"; then
if isTrue ${SETUP_ONLY}; then
echo "SETUP_ONLY: bash ${SERVER}"
exit
fi
runPreStartScript
if isTrue "${DEBUG_EXEC}"; then
set -x
fi
exec ${SERVER_RUNNER} "${mcServerRunnerArgs[@]}" --shell bash -- "${SERVER}" $EXTRA_ARGS
exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash "${SERVER}" $EXTRA_ARGS
else
# If we have a bootstrap.txt file... feed that in to the server stdin
if [ -f $bootstrapPath ]; then
@@ -629,15 +590,14 @@ else
"$@" $EXTRA_ARGS
)
if isTrue "${SETUP_ONLY}"; then
if isTrue ${SETUP_ONLY}; then
echo "SETUP_ONLY: java ${finalArgs[*]}"
exit
fi
runPreStartScript
if isTrue "${DEBUG_EXEC}"; then
set -x
fi
exec ${SERVER_RUNNER} ${bootstrapArgs} "${mcServerRunnerArgs[@]}" -- java "${finalArgs[@]}"
exec mc-server-runner ${bootstrapArgs} "${mcServerRunnerArgs[@]}" java "${finalArgs[@]}"
fi
+12 -44
View File
@@ -9,19 +9,24 @@ set -e -o pipefail
: "${PLUGINS_FILE:=}"
: "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar,*-version.json}"
: "${REMOVE_OLD_CONFIGS:=false}"
: "${CONFIG_OUT_DIR:=/data/config}"
: "${REMOVE_OLD_CONFIGS_DEPTH:=16}"
: "${REMOVE_OLD_CONFIGS_INCLUDE:=*}"
: "${REMOVE_OLD_CONFIGS_EXCLUDE:=}"
: "${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
sum_file=/data/.generic_pack.sum
# Remove old mods/plugins
if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
@@ -30,10 +35,6 @@ if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
rm -f "$sum_file"
fi
if isTrue "${REMOVE_OLD_CONFIGS}"; then
removeOldConfigs "$CONFIG_OUT_DIR"
fi
function handlePackwiz() {
# If packwiz url passed, bootstrap packwiz and update mods before other modpack processing
if [[ "${PACKWIZ_URL:-}" ]]; then
@@ -86,13 +87,11 @@ 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
@@ -182,38 +181,7 @@ function handleGenericPacks() {
packFiles=()
for packEntry in "${packs[@]}"; do
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
if isOCIRef "${pack}"; then
# All OCI refs share one staging dir so layers common to multiple
# sibling artifacts (the point of layered distribution) are pulled
# exactly once across all of GENERIC_PACKS.
mkdir -p /data/packs/oci /data/.tmp
log "Pulling OCI generic pack from $pack"
# A list file is used rather than stdout because mc-image-helper INFO
# logs share that stream; it holds one absolute layer path per line in
# apply order.
layerListFile=$(mktemp -p /data/.tmp)
ociArgs=(install-oci-pack
--ref "$pack"
--output-directory /data/packs/oci
--filename-strategy digest
--layer-list-file "$layerListFile")
if [[ "${GENERIC_PACKS_OCI_AUTH_FILE:-}" ]]; then
ociArgs+=(--auth-file "${GENERIC_PACKS_OCI_AUTH_FILE}")
fi
if ! mc-image-helper "${ociArgs[@]}"; then
logError "Failed to pull OCI generic pack $pack"
logError "(OCI generic packs require mc-image-helper with install-oci-pack support)"
rm -f "$layerListFile"
exit 2
fi
mapfile -t ociLayers < "$layerListFile"
rm -f "$layerListFile"
if [ ${#ociLayers[@]} -eq 0 ]; then
logError "OCI generic pack $pack resolved to zero layers"
exit 2
fi
packFiles+=("${ociLayers[@]}")
elif isURL "${pack}"; then
if isURL "${pack}"; then
mkdir -p /data/packs
log "Downloading generic pack from $pack"
if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
+11 -82
View File
@@ -173,12 +173,6 @@ function isURL() {
[[ $value =~ ^(https?|ftp):// ]]
}
function isOCIRef() {
local value=$1
[[ $value =~ ^oci:// ]]
}
function isValidFileURL() {
suffix=${1:?Missing required suffix arg}
url=${2:?Missing required url arg}
@@ -368,22 +362,9 @@ 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
val=${val// /}
val=${val%%.*}
if ! [[ $val =~ ^[0-9]+$ ]]; then
logError "Unable to parse memory size '$input'"
return 1
fi
case ${input,,} in
local mem=1
case ${1,,} in
*k)
scale=1024
;;
@@ -394,25 +375,19 @@ function normalizeMemSize() {
scale=1073741824
;;
*%)
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)
# 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 )
fi
# 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
# Scale is used to transform percentages into decimals (eg. 60 -> 0.6)
scale=0.01
;;
esac
echo $((val * scale))
val=${1:0:-1}
echo $((val * scale * mem))
}
function compare_version() {
@@ -547,23 +522,6 @@ function removeOldMods {
fi
}
function removeOldConfigs {
if [ -d "$1" ]; then
log "Removing old configs including='${REMOVE_OLD_CONFIGS_INCLUDE}' excluding='${REMOVE_OLD_CONFIGS_EXCLUDE}' up to depth=${REMOVE_OLD_CONFIGS_DEPTH}"
args=(
--delete
--type file
--min-depth=1 --max-depth "${REMOVE_OLD_CONFIGS_DEPTH}"
--name "${REMOVE_OLD_CONFIGS_INCLUDE}"
--exclude-name "${REMOVE_OLD_CONFIGS_EXCLUDE}"
)
if ! isDebugging; then
args+=(--quiet)
fi
mc-image-helper find "${args[@]}" "$1"
fi
}
function get() {
mc-image-helper get "$@"
}
@@ -615,24 +573,12 @@ 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}" "$@"
;;
*)
@@ -646,23 +592,6 @@ function getDistro() {
grep -E "^ID=" /etc/os-release | cut -d= -f2 | sed -e 's/"//g'
}
function getJavaRelease() {
# Read the major version from the JDK's release file so no JVM has to start;
# the helper is the fallback when the file is missing.
local version
if [[ ${JAVA_HOME:-} && -f "$JAVA_HOME/release" ]]; then
version=$(sed -n -e 's/^JAVA_VERSION="\(.*\)"$/\1/p' "$JAVA_HOME/release")
# Java 8 and earlier report 1.8.0_312 and so on
version=${version#1.}
version=${version%%[._-]*}
fi
if isNumeric "${version:-}"; then
echo "$version"
else
mc-image-helper java-release
fi
}
function checkSum() {
local sum_file=${1?}
@@ -1,18 +0,0 @@
services:
mc:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
# two OCI packs that share a common base layer; the shared blob is
# pulled into /data/packs/oci once and reused for the second pack
GENERIC_PACKS: oci://ghcr.io/itzg/oci-modpack-template/tech:latest,oci://ghcr.io/itzg/oci-modpack-template/magic:latest
LOG_TIMESTAMP: "true"
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
DEBUG: "true"
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar
@@ -1 +0,0 @@
[[ $EXTENDED_TESTS ]] || exit 1
@@ -1,7 +0,0 @@
set -e
# OCI layers were cached
[ -d /data/packs/oci ]
compgen -G "/data/packs/oci/sha256:*" > /dev/null
# pack content was extracted and applied to /data
[ -d /data/mods ]
compgen -G "/data/mods/*" > /dev/null
@@ -1,23 +0,0 @@
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
@@ -1,4 +0,0 @@
bind:
ip: '0.0.0.0'
port: 25565
maxPlayers: 100
@@ -1,4 +0,0 @@
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; }
Binary file not shown.
@@ -1,43 +0,0 @@
services:
# copies an existing config into /data before mc starts, so REMOVE_OLD_CONFIGS
# has an old config to remove once the modpack config is installed
seed:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
entrypoint: ["bash", "-c", "mkdir -p /data/config && cp /seed/config/stale.txt /data/config/ && chown -R 1000:1000 /data"]
volumes:
- ./seed:/seed
- ./data:/data
web:
image: nginx
volumes:
- ./configs.zip:/usr/share/nginx/html/configs.zip:ro
healthcheck:
test: ["CMD", "curl", "--fail", "http://localhost/configs.zip"]
interval: 3s
timeout: 5s
retries: 3
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
depends_on:
seed:
condition: service_completed_successfully
web:
condition: service_healthy
environment:
EULA: "true"
SETUP_ONLY: "true"
GENERIC_PACKS: http://web/configs.zip
REMOVE_OLD_CONFIGS: "true"
LOG_TIMESTAMP: "true"
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
DEBUG: "true"
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar
@@ -1 +0,0 @@
old
@@ -1,3 +0,0 @@
# verify that the old config was removed and the new one from the pack was installed
mc-image-helper assert fileNotExists config/stale.txt
mc-image-helper assert fileExists config/opt.yml