Compare commits

..
39 Commits
Author SHA1 Message Date
dependabot[bot] 13fff11fcf build(deps): bump the patches group in /docs with 2 updates (#4265) 2026-09-02 07:15:30 -05:00
82d89ee4eb Honor cd failure when starting a CurseForge pack (#4257)
Co-authored-by: LCB <me@lbellows.com>
Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
2026-09-01 20:40:27 -05:00
LBandLCB b0fbd35f7d Resolve SpongeVanilla latest version and fail closed on download (#4255)
Co-authored-by: LCB <me@lbellows.com>
2026-09-01 19:58:33 -05:00
LBandLCB 99f3a841f4 Do not mark an FTB App pack installed after a failed installer (#4251)
Co-authored-by: LCB <me@lbellows.com>
2026-09-01 17:16:40 -05:00
LBandLCB 3eaa1be6fb Stop startup when a MODPACK zip cannot be extracted (#4254)
Co-authored-by: LCB <me@lbellows.com>
2026-09-01 16:59:22 -05:00
LBandLCB f4fc9382ca Prune CurseForge libraries/mods using relative find paths (#4259)
Co-authored-by: LCB <me@lbellows.com>
2026-09-01 16:58:25 -05:00
Alexey Potsetsuev f7f115182b Fix Fantasy MC Fabric failing to start due to excluded server-required mods (#4264) 2026-09-01 07:11:16 -05:00
LBandLCB 9100b32093 Fail closed when CUSTOM_SERVER download returns an HTTP error (#4258)
Co-authored-by: LCB <me@lbellows.com>
2026-08-31 21:28:45 -05:00
LBandLCB bbc31603e2 Compute percentage memory sizes with integer arithmetic (#4252)
Co-authored-by: LCB <me@lbellows.com>
2026-08-31 21:21:42 -05:00
LBandLCB 430805da64 Detect Fabric FTB App packs from run.sh (#4250)
Co-authored-by: LCB <me@lbellows.com>
2026-08-31 21:10:13 -05:00
LBandLCB dd7644daf5 fix: drop extra brace in Forge/NeoForge FORCE_REINSTALL defaults (#4249)
Co-authored-by: LCB <me@lbellows.com>
2026-08-31 20:38:44 -05:00
renovate[bot] 235be828d8 Update dependency itzg/mc-image-helper to v1.67.1 (#4243)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-30 16:34:29 -05:00
LB 3f7737bc05 Note java8 CurseForge installs need CF_API_KEY (#4262) 2026-08-28 22:39:41 -05:00
LB 319582ae22 Stop figura exclude from matching configurable jars (#4261) 2026-08-28 22:34:50 -05:00
Echo Nar 8df827ed27 fix quadlet example socket access (#4260) 2026-08-28 07:25:50 -05:00
renovate[bot] 9f8248206c Update dependency itzg/mc-server-runner to v1.15.2 (#4237)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-27 14:55:06 -05:00
LCB 6d6c99ff6b pin gosu, fail closed on BuildTools download, reject zip slip (#4247) 2026-08-27 12:38:41 -05:00
dependabot[bot] 6417a93920 build(deps): bump deepmerge from 2.1.0 to 3.0 in /docs (#4246) 2026-08-26 16:37:38 -05:00
dependabot[bot] 2a0a0e651f build(deps): bump the patches group in /docs with 5 updates (#4245) 2026-08-26 07:18:53 -05:00
Harrison Black f61f72196b Fixed extra appended "s" in STOP_SERVER_DELAY_COMMAND (#4242) 2026-08-19 19:40:50 -05:00
dependabot[bot] 9d6aefc153 build(deps): bump the patches group in /docs with 2 updates (#4240) 2026-08-19 08:14:00 -05:00
Eirik H d62afadb5d Add missing HARDCORE environment variable to variables docs (#4239) 2026-08-18 15:03:14 -05:00
renovate[bot] f5d94230e8 Update dependency itzg/easy-add to v0.8.17 (#4235) 2026-08-16 16:34:22 -05:00
renovate[bot] cfceb23ae4 Update dependency itzg/rcon-cli to v1.7.7 (#4238) 2026-08-16 16:12:38 -05:00
renovate[bot] f0e8df639d Update dependency itzg/mc-image-helper to v1.66.1 (#4228) 2026-08-16 13:15:17 -05:00
renovate[bot] d8e2c90d5c Update dependency itzg/mc-monitor to v0.17.1 (#4236) 2026-08-16 12:26:15 -05:00
Alexey Potsetsuev 68d99f434d Fix two Modrinth packs that fail to start due to excluded server-required mods (#4232) 2026-08-14 12:41:45 -05:00
Criseda f93230f6a8 docs: add AutoStopper to related projects (#4231) 2026-08-13 20:52:05 -05:00
Leon Kampwerth 2826f51f5f Add warning for missing .gtnh-version file when using SKIP_GTNH_UPDATE_CHECK (#4230) 2026-08-13 14:48:48 -05:00
dependabot[bot] 218826cba0 build(deps): bump the patches group in /docs with 3 updates (#4224) 2026-08-12 12:44:46 -05:00
Columbus Labs 91b98bcc7b Document Java profile names for user management (#4225) 2026-08-12 08:41:03 -05:00
Harrison Black 21b134fd2b docs: Add docs for CurseForge regex filename matcher (#4223) 2026-08-09 08:09:24 -05:00
renovate[bot] 9b12eb6a6c Update dependency itzg/mc-image-helper to v1.66.0 (#4222) 2026-08-08 16:55:21 -05:00
renovate[bot] 14c83f1015 Update dependency itzg/easy-add to v0.8.16 (#4219) 2026-08-08 12:56:31 -05:00
Andrew Barnes 7ba5a858b9 Remove redundant CF_API_KEY_FILE handling (#4220) 2026-08-07 07:26:34 -05:00
dependabot[bot] 8bf8a7bc8d build(deps): bump the patches group in /docs with 2 updates (#4217)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-05 22:04:30 -05:00
renovate[bot] bbb8f7ffec Update dependency itzg/mc-image-helper to v1.65.0 (#4215) 2026-08-05 12:25:01 -05:00
dependabot[bot] 4657c5f8f3 build(deps): bump docker/login-action from 4.5.2 to 4.6.0 in the updates group (#4216) 2026-08-05 07:01:48 -05:00
renovate[bot] 4fc54b9e43 Update dependency itzg/mc-image-helper to v1.64.2 (#4214) 2026-08-04 10:31:27 -05:00
26 changed files with 160 additions and 85 deletions
+2 -2
View File
@@ -195,14 +195,14 @@ jobs:
tests/test.sh tests/test.sh
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@v4.5.2 uses: docker/login-action@v4.6.0
if: env.HAS_IMAGE_REPO_ACCESS == 'true' if: env.HAS_IMAGE_REPO_ACCESS == 'true'
with: with:
username: ${{ secrets.DOCKER_USER }} username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR - name: Login to GHCR
uses: docker/login-action@v4.5.2 uses: docker/login-action@v4.6.0
if: env.HAS_IMAGE_REPO_ACCESS == 'true' if: env.HAS_IMAGE_REPO_ACCESS == 'true'
with: with:
registry: ghcr.io registry: ghcr.io
+6 -6
View File
@@ -17,7 +17,7 @@ ARG KNOCKD_REPO_ORG=Metalcape/knock
RUN --mount=target=/build,source=build \ RUN --mount=target=/build,source=build \
TARGET=${TARGETARCH}${TARGETVARIANT} \ TARGET=${TARGETARCH}${TARGETVARIANT} \
/build/run.sh install-packages /build/run.sh install-packages
COPY --from=tianon/gosu /gosu /usr/local/bin/ COPY --from=tianon/gosu:1.19 /gosu /usr/local/bin/
RUN --mount=target=/build,source=build \ RUN --mount=target=/build,source=build \
/build/run.sh setup-user /build/run.sh setup-user
@@ -28,7 +28,7 @@ ARG APPS_REV=1
ARG GITHUB_BASEURL=https://github.com ARG GITHUB_BASEURL=https://github.com
# renovate: datasource=github-releases packageName=itzg/easy-add # renovate: datasource=github-releases packageName=itzg/easy-add
ARG EASY_ADD_VERSION=0.8.15 ARG EASY_ADD_VERSION=0.8.17
ADD ${GITHUB_BASEURL}/itzg/easy-add/releases/download/${EASY_ADD_VERSION}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add 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 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 --from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
# renovate: datasource=github-releases packageName=itzg/rcon-cli # renovate: datasource=github-releases packageName=itzg/rcon-cli
ARG RCON_CLI_VERSION=1.7.6 ARG RCON_CLI_VERSION=1.7.7
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=${RCON_CLI_VERSION} --var app=rcon-cli --file {{.app}} \ --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 --from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
# renovate: datasource=github-releases packageName=itzg/mc-monitor # renovate: datasource=github-releases packageName=itzg/mc-monitor
ARG MC_MONITOR_VERSION=0.17.0 ARG MC_MONITOR_VERSION=0.17.1
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=${MC_MONITOR_VERSION} --var app=mc-monitor --file {{.app}} \ --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 --from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
# renovate: datasource=github-releases packageName=itzg/mc-server-runner # renovate: datasource=github-releases packageName=itzg/mc-server-runner
ARG MC_SERVER_RUNNER_VERSION=1.15.1 ARG MC_SERVER_RUNNER_VERSION=1.15.2
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=${MC_SERVER_RUNNER_VERSION} --var app=mc-server-runner --file {{.app}} \ --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 --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 # renovate: datasource=github-releases packageName=itzg/mc-image-helper versioning=loose
ARG MC_HELPER_VERSION=1.64.1 ARG MC_HELPER_VERSION=1.67.1
ARG MC_HELPER_BASE_URL=${GITHUB_BASEURL}/itzg/mc-image-helper/releases/download/${MC_HELPER_VERSION} 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 # used for cache busting local copy of mc-image-helper
ARG MC_HELPER_REV=1 ARG MC_HELPER_REV=1
+3 -1
View File
@@ -168,7 +168,9 @@ To [enforce the whitelist changes immediately](https://minecraft.wiki/w/Server.p
!!! tip "Changing user API provider" !!! tip "Changing user API provider"
The usernames provided for whitelist and ops processing are resolved using either [PlayerDB](https://playerdb.co/) or [Mojang's API](https://wiki.vg/Mojang_API#Username_to_UUID). The default uses PlayerDB, but can be changed by setting the environment variable `USER_API_PROVIDER` to "mojang". Sometimes one or the other service can become overloaded, which is why there is the ability to switch providers. When specifying usernames for whitelist and ops processing, use Minecraft: Java Edition profile names, not Xbox gamertags. They can differ even when they belong to the same Microsoft account. A player can review or change their Java profile name on the [Minecraft profile page](https://www.minecraft.net/en-us/msaprofile/mygames/editprofile).
Usernames are resolved using either [PlayerDB](https://playerdb.co/) or [Mojang's API](https://wiki.vg/Mojang_API#Username_to_UUID). The default uses PlayerDB, but can be changed by setting the environment variable `USER_API_PROVIDER` to "mojang". Sometimes one or the other service can become overloaded, which is why there is the ability to switch providers.
### Op/Administrator Players ### Op/Administrator Players
+4
View File
@@ -29,3 +29,7 @@ A tool that is bundled with this image to provide complex, re-usable preparation
### [itzg/rcon](https://github.com/itzg/docker-rcon-web-admin) ### [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). An image that dockerizes [rcon-web-admin](https://github.com/rcon-web-admin/rcon-web-admin).
### [AutoStopper](https://github.com/Criseda/AutoStopper)
A Velocity plugin that stops idle backend servers and wakes them when players connect, with readiness-aware Docker lifecycle management.
+1 -1
View File
@@ -6,7 +6,7 @@ A specific file can be omitted from each reference to allow for auto-selecting t
!!! info "CurseForge API key usage" !!! info "CurseForge API key usage"
A CurseForge API key is _now_ included by this image; however, you can always supply your own instead. A CurseForge API key can be allocated and set with `CF_API_KEY` (or `CF_API_KEY_FILE`) [as described here](../types-and-platforms/mod-platforms/auto-curseforge.md#api-key). A CurseForge API key is _now_ included by this image on Java 17 and newer; however, you can always supply your own instead. A CurseForge API key can be allocated and set with `CF_API_KEY` (or `CF_API_KEY_FILE`) [as described here](../types-and-platforms/mod-platforms/auto-curseforge.md#api-key). The `java8` image (and other pre-Java 17 tags) does not include a baked-in key; set `CF_API_KEY` yourself.
## Project-file references ## Project-file references
+10 -10
View File
@@ -1,25 +1,25 @@
click==8.4.2 click==8.5.0
colorama==0.4.6 colorama==0.4.6
deepmerge==2.1.0 deepmerge==3.0
ghp-import==2.1.0 ghp-import==2.1.0
griffe==2.1.0 griffe==2.2.0
Jinja2==3.1.6 Jinja2==3.1.6
Markdown==3.10.2 Markdown==3.10.3
MarkupSafe==3.0.3 MarkupSafe==3.0.3
mergedeep==1.3.4 mergedeep==1.3.4
mkdocs==1.6.1 mkdocs==1.6.1
mkdocs-autorefs==1.4.4 mkdocs-autorefs==1.4.4
mkdocs-get-deps==0.2.2 mkdocs-get-deps==0.2.2
mkdocstrings==1.0.6 mkdocstrings==1.0.6
mkdocstrings-python==2.0.5 mkdocstrings-python==2.0.7
packaging==26.2 packaging==26.3
pathspec==1.1.1 pathspec==1.1.1
platformdirs==4.11.0 platformdirs==4.11.5
Pygments==2.20.0 Pygments==2.21.0
pymdown-extensions==11.0.1 pymdown-extensions==11.0.2
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
PyYAML==6.0.3 PyYAML==6.0.3
pyyaml_env_tag==1.1 pyyaml_env_tag==1.1
six==1.17.0 six==1.17.0
watchdog==6.0.0 watchdog==6.0.0
zensical==0.0.51 zensical==0.0.57
@@ -6,7 +6,9 @@ To manage a CurseForge modpack automatically with upgrade support, pinned or lat
!!! info "CurseForge API key usage" !!! info "CurseForge API key usage"
A CurseForge API key is _now_ included by this image; however, you can always supply your own instead. Go to their [developer console](https://console.curseforge.com/), generate an API key, and set the environment variable `CF_API_KEY`. A CurseForge API key is _now_ included by this image on Java 17 and newer; however, you can always supply your own instead. Go to their [developer console](https://console.curseforge.com/), generate an API key, and set the environment variable `CF_API_KEY`.
The `java8` image (and other pre-Java 17 tags) does **not** include that key. Set `CF_API_KEY` yourself, or install the pack on a Java 17+ image first. See [Java 8](../../versions/java.md#java-8).
When entering your API Key in a docker compose file you will need to escape any `$` character with a second `$`. Refer to [this compose file reference section](https://docs.docker.com/compose/compose-file/compose-file-v3/#variable-substitution) for more information. When entering your API Key in a docker compose file you will need to escape any `$` character with a second `$`. Refer to [this compose file reference section](https://docs.docker.com/compose/compose-file/compose-file-v3/#variable-substitution) for more information.
@@ -109,7 +111,7 @@ The latest modpack file and its associated mod loader will be located and instal
- Use `CF_PAGE_URL`, but include the full URL to a specific file - Use `CF_PAGE_URL`, but include the full URL to a specific file
- Set `CF_FILE_ID` to the numerical file ID - Set `CF_FILE_ID` to the numerical file ID
- Specify a substring to match the desired filename with `CF_FILENAME_MATCHER` - Specify either a substring or a regex pattern surrounded with "/" to match the desired filename with `CF_FILENAME_MATCHER`
The following shows where to get the URL to the specific file and also shows where the file ID is located: The following shows where to get the URL to the specific file and also shows where the file ID is located:
@@ -131,6 +133,21 @@ The following examples all refer to version 1.0.7 of ATM8:
CF_FILENAME_MATCHER: 1.0.7 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. 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 ### Custom modloader versions
@@ -50,7 +50,7 @@ Some mods, such as [MCInstance Loader](https://modrinth.com/mod/mcinstance-loade
## Excluding files ## Excluding files
To exclude client mods that are incorrectly declared by the modpack as server-compatible, set `MODRINTH_EXCLUDE_FILES` to a comma or newline delimited list of partial file names to exclude. You may need to set `MODRINTH_FORCE_SYNCHRONIZE` to "true" while iterating on a compatible set of mods to use. To exclude client mods that are incorrectly declared by the modpack as server-compatible, set `MODRINTH_EXCLUDE_FILES` to a comma or newline delimited list of file name matchers. Each entry is a case-insensitive substring of the file path, or a regular expression if surrounded with `/` (same convention as [`CF_FILENAME_MATCHER`](auto-curseforge.md#pinning-modpack-and-mod-loader-versions)). You may need to set `MODRINTH_FORCE_SYNCHRONIZE` to "true" while iterating on a compatible set of mods to use.
!!! example !!! example
@@ -64,7 +64,7 @@ To exclude client mods that are incorrectly declared by the modpack as server-co
## Force-include files ## Force-include files
To force include client mods, set `MODRINTH_FORCE_INCLUDE_FILES` to a comma or newline delimited list of partial file names. You may need to set `MODRINTH_FORCE_SYNCHRONIZE` to "true" while iterating on a compatible set of mods to use. To force include client mods, set `MODRINTH_FORCE_INCLUDE_FILES` to a comma or newline delimited list of file name matchers using the same substring or `/regex/` rules as `MODRINTH_EXCLUDE_FILES`. You may need to set `MODRINTH_FORCE_SYNCHRONIZE` to "true" while iterating on a compatible set of mods to use.
!!! example !!! example
+7 -1
View File
@@ -204,6 +204,12 @@ alternatively, you can mount: <code>/etc/localtime:/etc/localtime:ro
<td><code>easy</code></td> <td><code>easy</code></td>
<td>⬜️</td> <td>⬜️</td>
</tr> </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> <tr>
<td><code>ICON</code></td> <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> <td>The url or file path for the icon image to use for the server. It will be downloaded, scaled, and converted to the proper format.</td>
@@ -611,7 +617,7 @@ This image maps known server properties as described in [this section](configura
</tr> </tr>
<tr> <tr>
<td><code>CF_FILENAME_MATCHER</code></td> <td><code>CF_FILENAME_MATCHER</code></td>
<td>Specify a substring to match the desired filename</td> <td>Specify either a substring or a regex pattern surrounded with "/" to match the desired filename</td>
<td><code></code></td> <td><code></code></td>
<td>⬜️</td> <td>⬜️</td>
</tr> </tr>
+5 -1
View File
@@ -111,7 +111,11 @@ Caused by: org.spongepowered.asm.mixin.throwables.ClassMetadataNotFoundException
#### Java 8 #### Java 8
For Forge versions less than 1.18, you _must_ use the `java8-multiarch` (or other java8) image tag. For Forge versions less than 1.18, you _must_ use the `java8` (or other java8) image tag.
!!! warning "Java 8 is in maintenance mode"
The `java8` / `java8-jdk` tags, and other pre-Java 17 tags (`java11`, `java16`), pin an older `mc-image-helper` that predates the baked-in CurseForge API key. `AUTO_CURSEFORGE` and `CURSEFORGE_FILES` on those images require you to set `CF_API_KEY` yourself. Java 17+ images include a key and do not need this.
In general, if you see the following line in a server startup failure, then it means you need to be using Java 8 instead of the latest image Java version: 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:
+2
View File
@@ -37,6 +37,8 @@ ln -s ${XDG_CONFIG_HOME}/containers/systemd/mc@.service ${XDG_CONFIG_HOME}/conta
If running rootless, be sure to enable lingering with `sudo loginctl enable-linger $USER`. 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. 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] This should be fixed in a future podman release.[^3]
@@ -6,6 +6,7 @@ Image=docker.io/itzg/mc-router
ContainerName=%N ContainerName=%N
AutoUpdate=registry AutoUpdate=registry
UserNS=host UserNS=host
GroupAdd=0
Volume=%t/podman/podman.sock:/var/run/docker.sock:ro Volume=%t/podman/podman.sock:/var/run/docker.sock:ro
Network=minecraft.network Network=minecraft.network
PublishPort=25565:25565 PublishPort=25565:25565
+3
View File
@@ -187,6 +187,9 @@
"create-arcane-engineering": { "create-arcane-engineering": {
"forceIncludes": ["just-enough-resources-jer"] "forceIncludes": ["just-enough-resources-jer"]
}, },
"fantasy-minecraft-fabric": {
"forceIncludes": ["simply-tooltips", "icon-leading-tooltip"]
},
"ftb-stoneblock-4": { "ftb-stoneblock-4": {
"forceIncludes": [ "forceIncludes": [
"particular-reforged", "particular-reforged",
+1 -2
View File
@@ -48,9 +48,8 @@
"fancymenu", "fancymenu",
"fast-ip-ping", "fast-ip-ping",
"fastquit", "fastquit",
"FauxCustomEntityData",
"feytweaks", "feytweaks",
"figura", "/(^|/)figura-/",
"ForgeConfigScreens", "ForgeConfigScreens",
"GeckoLibIrisCompat", "GeckoLibIrisCompat",
"gpumemleakfix", "gpumemleakfix",
-11
View File
@@ -22,22 +22,11 @@ set -eu
: "${CF_DOWNLOADS_REPO=$([ -d /downloads ] && echo '/downloads' || echo '')}" : "${CF_DOWNLOADS_REPO=$([ -d /downloads ] && echo '/downloads' || echo '')}"
: "${CF_MODPACK_MANIFEST:=}" : "${CF_MODPACK_MANIFEST:=}"
: "${CF_API_CACHE_DEFAULT_TTL:=}" # as ISO-8601 duration, such as P2D or PT12H : "${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_MOD_LOADER_VERSION:=}" # Override mod loader version
: "${CF_USE_HTTP2:=false}" # CF downloads are faster with HTTP 1.1 : "${CF_USE_HTTP2:=false}" # CF downloads are faster with HTTP 1.1
resultsFile=/data/.install-curseforge.env 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 isDebugging && set -x
ensureRemoveAllModsOff "MODPACK_PLATFORM=AUTO_CURSEFORGE" ensureRemoveAllModsOff "MODPACK_PLATFORM=AUTO_CURSEFORGE"
+1 -1
View File
@@ -43,7 +43,7 @@ function buildSpigotFromSource {
fi fi
logn '' logn ''
curl -sSL -o ${tempDir}/BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar && \ curl -fsSL -o "${tempDir}/BuildTools.jar" https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar && \
java $jvmOpts -jar ${tempDir}/BuildTools.jar --rev "$VERSION" 2>&1 |tee ${spigotBuildLog}| while read l; do echo -n .; done; log "done" java $jvmOpts -jar ${tempDir}/BuildTools.jar --rev "$VERSION" 2>&1 |tee ${spigotBuildLog}| while read l; do echo -n .; done; log "done"
case ${TYPE^^} in case ${TYPE^^} in
+2 -2
View File
@@ -127,7 +127,7 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
echo "${FTB_SERVER_MOD}" > $installMarker echo "${FTB_SERVER_MOD}" > $installMarker
fi 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 if [[ -z "${SERVER}" || ! -f "${SERVER}" ]]; then
logError "Unable to locate installed forge server jar" logError "Unable to locate installed forge server jar"
isDebugging && find "${FTB_BASE_DIR}" -name "forge*.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 # 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 # 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 if [[ "$forgeJar" ]]; then
FTB_BASE_DIR=$(dirname "${forgeJar}") FTB_BASE_DIR=$(dirname "${forgeJar}")
export FTB_BASE_DIR export FTB_BASE_DIR
+2 -2
View File
@@ -16,8 +16,8 @@ if isURL "${CUSTOM_SERVER}"; then
log "Using previously downloaded jar at ${SERVER}" log "Using previously downloaded jar at ${SERVER}"
else else
log "Downloading custom server jar from ${CUSTOM_SERVER} ..." log "Downloading custom server jar from ${CUSTOM_SERVER} ..."
if ! curl -sSL -o "${SERVER}" "${CUSTOM_SERVER}"; then if ! curl -fsSL -o "${SERVER}" "${CUSTOM_SERVER}"; then
log "Failed to download from ${CUSTOM_SERVER}" logError "Failed to download from ${CUSTOM_SERVER}"
exit 2 exit 2
fi fi
fi fi
+6 -3
View File
@@ -9,7 +9,7 @@ ftbInstallMarker=".ftb-installed"
# shellcheck source=start-utils # shellcheck source=start-utils
. "$(dirname "$0")/start-utils" . "$(dirname "$0")/start-utils"
isDebugging && set -x isDebugging && set -x
set -e set -e -o pipefail
# #
#{ #{
@@ -93,7 +93,10 @@ if isTrue "$FTB_FORCE_REINSTALL" ||
log "Installing modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID}" log "Installing modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID}"
log "This could take a while..." log "This could take a while..."
${ftbInstaller} -pack "${FTB_MODPACK_ID}" -version "${FTB_MODPACK_VERSION_ID}" -auto -force -no-java | tee ftb-installer.log if ! ${ftbInstaller} -pack "${FTB_MODPACK_ID}" -version "${FTB_MODPACK_VERSION_ID}" -auto -force -no-java | tee ftb-installer.log; then
logError "FTB installer failed for modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID}"
exit 1
fi
rm -f forge*installer.jar rm -f forge*installer.jar
echo "${FTB_MODPACK_ID}=${FTB_MODPACK_VERSION_ID}" > ${ftbInstallMarker} echo "${FTB_MODPACK_ID}=${FTB_MODPACK_VERSION_ID}" > ${ftbInstallMarker}
@@ -140,7 +143,7 @@ if [[ $SERVER = run.sh ]]; then
elif grep -q forge "$SERVER"; then elif grep -q forge "$SERVER"; then
export FAMILY=FORGE export FAMILY=FORGE
export TYPE=FORGE export TYPE=FORGE
elif grep -q fabric run.s; then elif grep -q fabric "$SERVER"; then
export FAMILY=FABRIC export FAMILY=FABRIC
export TYPE=FABRIC export TYPE=FABRIC
else else
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
: "${FORGE_VERSION:=${FORGEVERSION:-RECOMMENDED}}" : "${FORGE_VERSION:=${FORGEVERSION:-RECOMMENDED}}"
: "${FORGE_FORCE_REINSTALL:=false}}" : "${FORGE_FORCE_REINSTALL:=false}"
# shellcheck source=start-utils # shellcheck source=start-utils
. "${SCRIPTS:-$(dirname "$0")}/start-utils" . "${SCRIPTS:-$(dirname "$0")}/start-utils"
+3
View File
@@ -312,6 +312,9 @@ function handleGTNH() {
fi fi
else else
log "SKIP_GTNH_UPDATE_CHECK=$SKIP_GTNH_UPDATE_CHECK ... Skipping GTNH Update/Install" 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 fi
} }
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
: "${NEOFORGE_VERSION:=latest}" : "${NEOFORGE_VERSION:=latest}"
: "${NEOFORGE_FORCE_REINSTALL:=false}}" : "${NEOFORGE_FORCE_REINSTALL:=false}"
: "${NEOFORGE_INSTALLER:=}" : "${NEOFORGE_INSTALLER:=}"
# shellcheck source=start-utils # shellcheck source=start-utils
+14 -4
View File
@@ -22,18 +22,28 @@ case "$SPONGEBRANCH" in
esac esac
# If not SPONGEVERSION selected, detect last version on selected branch # If not SPONGEVERSION selected, detect last version on selected branch
if [ -z $SPONGEVERSION ]; then if [ -z "$SPONGEVERSION" ]; then
log "Choosing Version for Sponge" log "Choosing Version for Sponge"
SPONGEVERSION=$(curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r --arg SPONGEBRANCH "$SPONGEBRANCH" '.buildTypes.$SPONGEBRANCH.latest.version') if ! SPONGEVERSION=$(curl -fsSL "https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE" | jq -r --arg SPONGEBRANCH "$SPONGEBRANCH" '.buildTypes[$SPONGEBRANCH].latest.version'); then
logError "Failed to resolve latest SpongeVanilla version from the Sponge downloads API"
exit 1
fi
if [[ -z $SPONGEVERSION || $SPONGEVERSION == null ]]; then
logError "Sponge downloads API did not return a version for branch $SPONGEBRANCH"
exit 1
fi
fi fi
VERSION="$SPONGEVERSION" VERSION="$SPONGEVERSION"
export VERSION export VERSION
export SERVER="spongevanilla-$SPONGEVERSION.jar" export SERVER="spongevanilla-$SPONGEVERSION.jar"
if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then if [ ! -e "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD}"; then
log "Downloading $SERVER ..." log "Downloading $SERVER ..."
curl -sSL -o "$SERVER" "https://repo.spongepowered.org/maven/org/spongepowered/$TYPE/$SPONGEVERSION/$SERVER" if ! curl -fsSL -o "$SERVER" "https://repo.spongepowered.org/maven/org/spongepowered/$TYPE/$SPONGEVERSION/$SERVER"; then
logError "Failed to download $SERVER"
exit 1
fi
fi fi
export FAMILY=SPONGE export FAMILY=SPONGE
+18 -8
View File
@@ -491,7 +491,7 @@ if [[ ${STOP_SERVER_ANNOUNCE_DELAY} ]]; then
mcServerRunnerArgs+=(--stop-server-announce-delay "${STOP_SERVER_ANNOUNCE_DELAY}s") mcServerRunnerArgs+=(--stop-server-announce-delay "${STOP_SERVER_ANNOUNCE_DELAY}s")
fi fi
if [[ ${STOP_SERVER_DELAY_COMMAND} ]]; then if [[ ${STOP_SERVER_DELAY_COMMAND} ]]; then
mcServerRunnerArgs+=(--stop-server-delay-command "${STOP_SERVER_DELAY_COMMAND}s") mcServerRunnerArgs+=(--stop-server-delay-command "${STOP_SERVER_DELAY_COMMAND}")
fi fi
if isTrue "${ENABLE_SSH}"; then if isTrue "${ENABLE_SSH}"; then
mcServerRunnerArgs+=(--remote-console) mcServerRunnerArgs+=(--remote-console)
@@ -500,7 +500,10 @@ fi
if [[ ${TYPE} == "CURSEFORGE" && "${SERVER}" ]]; then if [[ ${TYPE} == "CURSEFORGE" && "${SERVER}" ]]; then
copyFilesForCurseForge copyFilesForCurseForge
cd "${FTB_DIR}" || (logError "Can't go into ${FTB_DIR}"; exit 1) if ! cd "${FTB_DIR}"; then
logError "Can't go into ${FTB_DIR}"
exit 1
fi
log "Starting CurseForge server in ${FTB_DIR}..." log "Starting CurseForge server in ${FTB_DIR}..."
if isTrue "${DEBUG_EXEC}"; then if isTrue "${DEBUG_EXEC}"; then
set -x set -x
@@ -513,11 +516,15 @@ elif [[ ${TYPE} == "CURSEFORGE" ]]; then
if isPercentage "$INIT_MEMORY" || isPercentage "$MAX_MEMORY"; then if isPercentage "$INIT_MEMORY" || isPercentage "$MAX_MEMORY"; then
# Convert to bytes # Convert to bytes
NORM_INIT_MEM=$(normalizeMemSize "$INIT_MEMORY") if ! NORM_INIT_MEM=$(normalizeMemSize "$INIT_MEMORY"); then
NORM_MAX_MEM=$(normalizeMemSize "$MAX_MEMORY") exit 1
# Convert to MB fi
((NORM_INIT_MEM*=1048576)) if ! NORM_MAX_MEM=$(normalizeMemSize "$MAX_MEMORY"); then
((NORM_MAX_MEM*=1048576)) exit 1
fi
# Convert bytes to MB
((NORM_INIT_MEM/=1048576))
((NORM_MAX_MEM/=1048576))
cat > "${FTB_DIR}/settings-local.sh" <<EOF cat > "${FTB_DIR}/settings-local.sh" <<EOF
export MIN_RAM="${NORM_INIT_MEM}M" export MIN_RAM="${NORM_INIT_MEM}M"
@@ -541,7 +548,10 @@ fi
fi fi
fi fi
cd "${FTB_DIR}" || (logError "Can't go into ${FTB_DIR}"; exit 1) if ! cd "${FTB_DIR}"; then
logError "Can't go into ${FTB_DIR}"
exit 1
fi
log "Running FTB ${FTB_SERVER_START} in ${FTB_DIR} ..." log "Running FTB ${FTB_SERVER_START} in ${FTB_DIR} ..."
finalArgs="${FTB_SERVER_START}" finalArgs="${FTB_SERVER_START}"
+2 -11
View File
@@ -9,23 +9,12 @@ set -e -o pipefail
: "${PLUGINS_FILE:=}" : "${PLUGINS_FILE:=}"
: "${REMOVE_OLD_MODS_DEPTH:=1} " : "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar,*-version.json}" : "${REMOVE_OLD_MODS_INCLUDE:=*.jar,*-version.json}"
: "${CF_API_KEY_FILE:=}" # Path to file containing CurseForge API key
: "${CF_USE_HTTP2:=false}" # CF downloads are faster with HTTP 1.1 : "${CF_USE_HTTP2:=false}" # CF downloads are faster with HTTP 1.1
: "${MODRINTH_LOADER:=}" : "${MODRINTH_LOADER:=}"
# shellcheck source=start-utils # shellcheck source=start-utils
. "$(dirname "$0")/start-utils" . "$(dirname "$0")/start-utils"
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 isDebugging && set -x
sum_file=/data/.generic_pack.sum sum_file=/data/.generic_pack.sum
@@ -88,11 +77,13 @@ if [[ "$MODPACK" ]]; then
mkdir -p "$PLUGINS_OUT_DIR" mkdir -p "$PLUGINS_OUT_DIR"
if ! unzip -o -d "$PLUGINS_OUT_DIR" /tmp/modpack.zip; then if ! unzip -o -d "$PLUGINS_OUT_DIR" /tmp/modpack.zip; then
logError "Failed to unzip the modpack from ${MODPACK}" logError "Failed to unzip the modpack from ${MODPACK}"
exit 2
fi fi
else else
mkdir -p "$MODS_OUT_DIR" mkdir -p "$MODS_OUT_DIR"
if ! unzip -o -d "$MODS_OUT_DIR" /tmp/modpack.zip; then if ! unzip -o -d "$MODS_OUT_DIR" /tmp/modpack.zip; then
logError "Failed to unzip the modpack from ${MODPACK}" logError "Failed to unzip the modpack from ${MODPACK}"
exit 2
fi fi
fi fi
rm -f /tmp/modpack.zip rm -f /tmp/modpack.zip
+40 -9
View File
@@ -368,9 +368,22 @@ function logRcon() {
} }
function normalizeMemSize() { 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 scale=1
local mem=1 local mem
case ${1,,} in
val=${val// /}
val=${val%%.*}
if ! [[ $val =~ ^[0-9]+$ ]]; then
logError "Unable to parse memory size '$input'"
return 1
fi
case ${input,,} in
*k) *k)
scale=1024 scale=1024
;; ;;
@@ -381,19 +394,25 @@ function normalizeMemSize() {
scale=1073741824 scale=1073741824
;; ;;
*%) *%)
# Get system memory if [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then
if [ -f "/sys/fs/cgroup/memory/memory.limit_in_bytes" ]; then
mem=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) mem=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)
elif [ -f "/sys/fs/cgroup/memory.max" ]; then elif [ -f /sys/fs/cgroup/memory.max ]; then
mem=$(cat /sys/fs/cgroup/memory.max) mem=$(cat /sys/fs/cgroup/memory.max)
fi fi
# Scale is used to transform percentages into decimals (eg. 60 -> 0.6) # cgroup v2 unlimited is "max"; cgroup v1 uses a large sentinel (~2^63).
scale=0.01 if [[ $mem == max || ! $mem =~ ^[0-9]+$ ]] || (( mem > 1 << 62 )); then
mem=$(awk '/MemTotal:/ { print $2 * 1024 }' /proc/meminfo)
fi
if ! [[ $mem =~ ^[0-9]+$ ]]; then
logError "Unable to determine memory limit for percentage value '$input'"
return 1
fi
echo $((val * mem / 100))
return 0
;; ;;
esac esac
val=${1:0:-1} echo $((val * scale))
echo $((val * scale * mem))
} }
function compare_version() { function compare_version() {
@@ -579,12 +598,24 @@ function extract() {
case "${type}" in case "${type}" in
application/zip) 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}" "$@" unzip -o -q -d "${destDir}" "${src}" "$@"
;; ;;
application/x-tar | application/gzip | application/x-gzip | application/x-bzip2) 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}" "$@" tar -C "${destDir}" -xf "${src}" "$@"
;; ;;
application/zstd | application/x-zstd) 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}" "$@" tar -C "${destDir}" --use-compress-program=unzstd -xf "${src}" "$@"
;; ;;
*) *)