mirror of
https://github.com/itzg/docker-minecraft-server.git
synced 2026-08-17 20:53:17 +00:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4cbdf520c8 | ||
|
|
a3bb7bff34 | ||
|
|
1e77b81b32 | ||
|
|
479973c950 | ||
|
|
2a246ee805 | ||
|
|
3c4c94e1ad | ||
|
|
cd2c5628f2 | ||
|
|
0a445cd8db | ||
|
|
537a3e43fe | ||
|
|
17d7f01267 | ||
|
|
591f37bfa5 |
@@ -6,11 +6,15 @@ on:
|
||||
jobs:
|
||||
auto-release:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# allow for creating releases/tags
|
||||
contents: write
|
||||
# If forked, changed to your username to enable auto-releases
|
||||
if: github.repository_owner == 'itzg'
|
||||
steps:
|
||||
- uses: zenengeo/github-auto-release-action@main
|
||||
with:
|
||||
stable-duration: 3d
|
||||
force-duration: 14d
|
||||
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 }}'
|
||||
|
||||
|
||||
+24
-29
@@ -18,6 +18,7 @@ on:
|
||||
- "zensical.toml"
|
||||
- ".readthedocs.yaml"
|
||||
- "renovate.json5"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -45,12 +46,12 @@ jobs:
|
||||
baseImage: eclipse-temurin:25-jre-noble
|
||||
platforms: linux/amd64,linux/arm64,linux/riscv64
|
||||
mcVersion: latest
|
||||
# forked build that include riscv64
|
||||
knockdRepoOrg: Opvolger/knock
|
||||
- variant: java25-alpine
|
||||
baseImage: eclipse-temurin:25-jre-alpine
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: latest
|
||||
# For GLIBC_2.34 support (and Alpine)
|
||||
knockdRepoOrg: Metalcape/knock
|
||||
- variant: java25-jdk
|
||||
baseImage: eclipse-temurin:25
|
||||
platforms: linux/amd64,linux/arm64
|
||||
@@ -68,55 +69,47 @@ jobs:
|
||||
baseImage: eclipse-temurin:21-jre-alpine
|
||||
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
|
||||
# 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.3-java8
|
||||
mcHelperVersion: 1.51.4-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.3-java8
|
||||
mcHelperVersion: 1.51.4-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.3-java8
|
||||
mcHelperVersion: 1.51.4-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.3-java8
|
||||
mcHelperVersion: 1.51.4-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 }}"
|
||||
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
|
||||
@@ -129,10 +122,8 @@ 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: |
|
||||
${{ github.repository_owner }}/minecraft-server
|
||||
${{ env.DOCKER_HUB_ORG }}/minecraft-server
|
||||
ghcr.io/${{ github.repository_owner }}/minecraft-server
|
||||
tags: |
|
||||
# Apply the variant as a moving tag for most recent commit per variant
|
||||
@@ -154,7 +145,7 @@ jobs:
|
||||
flavor: |
|
||||
latest=${{ matrix.variant == env.MAIN_VARIANT && github.ref_name == github.event.repository.default_branch }}
|
||||
labels: |
|
||||
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>
|
||||
org.opencontainers.image.authors=${{ env.IMAGE_AUTHOR }}
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
@@ -210,13 +201,16 @@ jobs:
|
||||
platforms: ${{ matrix.platforms }}
|
||||
push: >
|
||||
${{
|
||||
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')
|
||||
)
|
||||
env.PUSH &&
|
||||
(
|
||||
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
|
||||
@@ -233,5 +227,6 @@ 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 }}
|
||||
|
||||
@@ -16,6 +16,7 @@ jobs:
|
||||
discord:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
if: github.repository_owner == 'itzg'
|
||||
steps:
|
||||
- name: on-publish
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
|
||||
@@ -13,6 +13,7 @@ on:
|
||||
- labeled
|
||||
jobs:
|
||||
notify:
|
||||
if: github.repository_owner == 'itzg'
|
||||
uses: itzg/github-workflows/.github/workflows/issues-notify-discord.yml@main
|
||||
with:
|
||||
triageLabel: 'status/needs triage'
|
||||
@@ -7,6 +7,7 @@ on:
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-22.04
|
||||
if: github.repository_owner == 'itzg'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
@@ -47,6 +47,7 @@ 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
|
||||
@@ -54,7 +55,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.3-java8
|
||||
mcHelperVersion: 1.51.4-java8
|
||||
env:
|
||||
IMAGE_TO_TEST: ${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ ARG EXTRA_DNF_PACKAGES=""
|
||||
ARG EXTRA_ALPINE_PACKAGES=""
|
||||
ARG FORCE_INSTALL_PACKAGES=1
|
||||
ARG KNOCKD_VERSION=0.8.1
|
||||
ARG KNOCKD_REPO_ORG=Opvolger/knock
|
||||
ARG KNOCKD_REPO_ORG=Metalcape/knock
|
||||
RUN --mount=target=/build,source=build \
|
||||
TARGET=${TARGETARCH}${TARGETVARIANT} \
|
||||
/build/run.sh install-packages
|
||||
@@ -57,7 +57,7 @@ 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/mc-image-helper versioning=loose
|
||||
ARG MC_HELPER_VERSION=1.61.4
|
||||
ARG MC_HELPER_VERSION=1.62.1
|
||||
ARG MC_HELPER_BASE_URL=${GITHUB_BASEURL}/itzg/mc-image-helper/releases/download/${MC_HELPER_VERSION}
|
||||
# used for cache busting local copy of mc-image-helper
|
||||
ARG MC_HELPER_REV=1
|
||||
|
||||
@@ -35,6 +35,7 @@ apk add --no-cache -U \
|
||||
libcap \
|
||||
numactl \
|
||||
jattach \
|
||||
gcompat \
|
||||
${EXTRA_ALPINE_PACKAGES}
|
||||
|
||||
# Download and install patched knockd
|
||||
|
||||
@@ -179,6 +179,10 @@ 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`.
|
||||
@@ -198,6 +202,13 @@ 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.
|
||||
|
||||
## 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:
|
||||
|
||||
@@ -6,7 +6,7 @@ A specific file can be omitted from each reference to allow for auto-selecting t
|
||||
|
||||
!!! info "CurseForge API key usage"
|
||||
|
||||
A CurseForge API key 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).
|
||||
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).
|
||||
|
||||
## Project-file references
|
||||
|
||||
|
||||
@@ -151,6 +151,26 @@ 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".
|
||||
|
||||
@@ -79,13 +79,11 @@ 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 CF_API_KEY=${CF_API_KEY} -e TYPE=AUTO_CURSEFORGE -e CF_PAGE_URL=https://www.curseforge.com/minecraft/modpacks/all-the-mods-8
|
||||
docker run -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,13 +96,11 @@ 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 CF_API_KEY=${CF_API_KEY} -e TYPE=AUTO_CURSEFORGE -e CF_SLUG=all-the-mods-8
|
||||
docker run -e TYPE=AUTO_CURSEFORGE -e CF_SLUG=all-the-mods-8
|
||||
```
|
||||
|
||||
### Pinning modpack and mod loader versions
|
||||
@@ -148,7 +144,6 @@ 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"
|
||||
```
|
||||
@@ -197,8 +192,6 @@ 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:
|
||||
|
||||
@@ -7,6 +7,7 @@ IFS=$'\n\t'
|
||||
|
||||
: "${EULA:=}"
|
||||
: "${PROXY:=}"
|
||||
: "${PREFER_IPV6:=false}"
|
||||
: "${ENABLE_AUTOPAUSE:=false}"
|
||||
: "${ENABLE_AUTOSTOP:=false}"
|
||||
: "${RCON_CMDS_STARTUP:=}"
|
||||
@@ -28,11 +29,22 @@ 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 (( $(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)'"
|
||||
|
||||
+16
-40
@@ -5,52 +5,28 @@
|
||||
isDebugging && set -x
|
||||
set -o pipefail
|
||||
|
||||
resolveVersion
|
||||
export SERVER="minecraft_server.${VERSION// /_}.jar"
|
||||
resultsFile=/data/.install-vanilla.env
|
||||
|
||||
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"
|
||||
args=(
|
||||
--output-directory=/data
|
||||
--results-file="${resultsFile}"
|
||||
--version="${VERSION}"
|
||||
)
|
||||
|
||||
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
|
||||
if isTrue "${FORCE_REDOWNLOAD}"; then
|
||||
log "Forcing re-install of Minecraft"
|
||||
args+=(--force-reinstall)
|
||||
fi
|
||||
minecraftServerJarPath=/data/minecraft_server.jar
|
||||
|
||||
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
|
||||
if ! mc-image-helper install-vanilla "${args[@]}"; then
|
||||
logError "Failed to install vanilla Minecraft version $VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
applyResultsFile "${resultsFile}"
|
||||
|
||||
log "Successfully setup vanilla Minecraft version $VERSION"
|
||||
|
||||
isDebugging && ls -l
|
||||
export FAMILY=VANILLA
|
||||
exec "$(dirname "$0")/start-setupWorld" "$@"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
: "${DEBUG_EXEC:=false}"
|
||||
: "${SETUP_ONLY:=false}"
|
||||
: "${CUSTOM_JAR_EXEC:=}"
|
||||
: "${SERVER_RUNNER:=mc-server-runner}"
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "$(dirname "$0")/start-utils"
|
||||
@@ -96,7 +97,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}"
|
||||
@@ -496,7 +497,7 @@ if [[ ${TYPE} == "CURSEFORGE" && "${SERVER}" ]]; then
|
||||
if isTrue "${DEBUG_EXEC}"; then
|
||||
set -x
|
||||
fi
|
||||
exec mc-server-runner ${bootstrapArgs} "${mcServerRunnerArgs[@]}" java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar "$(basename "${SERVER}")" "$@" $EXTRA_ARGS
|
||||
exec ${SERVER_RUNNER} ${bootstrapArgs} "${mcServerRunnerArgs[@]}" -- java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar "$(basename "${SERVER}")" "$@" $EXTRA_ARGS
|
||||
elif [[ ${TYPE} == "CURSEFORGE" ]]; then
|
||||
mcServerRunnerArgs+=(--shell bash)
|
||||
|
||||
@@ -550,18 +551,18 @@ fi
|
||||
JVM_ARGS=${JVM_ARGS//$'\n'/}
|
||||
sed -i "s~JAVA_ARGS=.*~JAVA_ARGS=\"${JVM_ARGS}\"~" "${FTB_DIR}/variables.txt"
|
||||
fi
|
||||
exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}"
|
||||
exec ${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
|
||||
if isTrue "${DEBUG_EXEC}"; then
|
||||
set -x
|
||||
fi
|
||||
exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash "${SERVER}" $EXTRA_ARGS
|
||||
exec ${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
|
||||
@@ -590,7 +591,7 @@ else
|
||||
"$@" $EXTRA_ARGS
|
||||
)
|
||||
|
||||
if isTrue ${SETUP_ONLY}; then
|
||||
if isTrue "${SETUP_ONLY}"; then
|
||||
echo "SETUP_ONLY: java ${finalArgs[*]}"
|
||||
exit
|
||||
fi
|
||||
@@ -599,5 +600,5 @@ else
|
||||
set -x
|
||||
fi
|
||||
|
||||
exec mc-server-runner ${bootstrapArgs} "${mcServerRunnerArgs[@]}" java "${finalArgs[@]}"
|
||||
exec ${SERVER_RUNNER} ${bootstrapArgs} "${mcServerRunnerArgs[@]}" -- java "${finalArgs[@]}"
|
||||
fi
|
||||
|
||||
@@ -181,7 +181,38 @@ function handleGenericPacks() {
|
||||
packFiles=()
|
||||
for packEntry in "${packs[@]}"; do
|
||||
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
|
||||
if isURL "${pack}"; then
|
||||
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
|
||||
mkdir -p /data/packs
|
||||
log "Downloading generic pack from $pack"
|
||||
if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
|
||||
|
||||
@@ -173,6 +173,12 @@ 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}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
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
|
||||
@@ -0,0 +1 @@
|
||||
[[ $EXTENDED_TESTS ]] || exit 1
|
||||
@@ -0,0 +1,7 @@
|
||||
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
|
||||
Reference in New Issue
Block a user