Compare commits

...

71 Commits

Author SHA1 Message Date
Geoff Bourne
cb3fb3c9e8 Allow image helper get to use user info 2022-09-17 10:33:08 -05:00
Ceci
d4692d2d07 fix(packwiz): provide side argument to packwiz (#1734) 2022-09-15 11:43:11 -05:00
Geoff Bourne
a1e4657e62 Fixed bug causing isTrue to fail (#1727) 2022-09-10 14:39:44 -05:00
Geoff Bourne
fabe14db49 Download and use packwiz from Maven repository (#1725)
Also
* Added github actions debug support
* added use of fileNotExists
2022-09-10 12:58:32 -05:00
Geoff Bourne
4d3464f3f1 Change versionLessThan to work in strict mode (#1723) 2022-09-08 20:23:34 -05:00
Geoff Bourne
d6de14123b Corrected Modrinth usage with TYPE=FORGE (#1719) 2022-09-05 18:21:11 -05:00
Geoff Bourne
247855c2cf Upgrade mc-image-helper to 1.22.4 (#1715) 2022-09-04 22:50:00 -05:00
Geoff Bourne
364f73c9d9 Adjusted mc-image-helper to use logback for java8 (#1713) 2022-09-04 18:14:33 -05:00
Geoff Bourne
7723cb0a41 Correctly parse modrinth dependencies declared as embedded (#1710) 2022-09-03 17:46:08 -05:00
Geoff Bourne
0e0bb09533 Show IP address that caused auto-pause to resume (#1709)
Also
* Refactored auto files, server.properties, and rcon-cmds
2022-09-03 16:48:14 -05:00
Geoff Bourne
417a65a3af Fixed issue with GENERIC_PACK where it exits after saving checksum (#1708) 2022-09-03 10:11:58 -05:00
Dov Alperin
3c131f853d Use pkill by default for autostop feature (#1707) 2022-09-02 18:14:10 -05:00
Geoff Bourne
cca9b3e21d docs: clarify placeholder usage with _FILE suffix (#1704) 2022-09-01 08:39:04 -05:00
J Thompson
e81cddd108 Added example for GENERIC_PACK TNP5 (#1698) 2022-08-28 17:43:57 -05:00
Geoff Bourne
1bc566c69a docs: Corrected versions required for FTBA (#1689) 2022-08-21 15:41:05 -05:00
Nolan Rosen
4f8104737e Updated GH_TOKEN usage (#1688) 2022-08-21 15:31:54 -05:00
Nolan Rosen
de43778eb9 Updates for GH_TOKEN addition for packwiz support (#1687) 2022-08-21 14:06:50 -05:00
Geoff Bourne
3310f0a069 Fix FORGEVERSION and FORGE_INSTALLER support (#1677) 2022-08-15 08:23:16 -05:00
Geoff Bourne
05b8899de6 Don't show server properties by default and obscure passwords (#1670) 2022-08-14 14:14:57 -05:00
Geoff Bourne
7a85cb5f39 Perform clean Forge version changes (#1669)
Switched to mc-image-helper
2022-08-14 13:34:08 -05:00
Gustave Abel Michel III
380ea202dc Updated LegacyJavaFixer Download URL (#1667) 2022-08-13 10:49:33 -05:00
dependabot[bot]
83d99f35f9 build(deps): bump docker/build-push-action from 3.1.0 to 3.1.1 (#1660)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3.1.0...v3.1.1)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-12 15:51:09 -05:00
Geoff Bourne
0f85646c69 Output expected files when FTBA prep fails (#1656) 2022-08-06 16:24:47 -05:00
Geoff Bourne
75afcc2fce build: corrected name of PR workflow 2022-08-05 21:45:18 -05:00
Geoff Bourne
94b2d8996d FTBA installer on Alpine fails gracefully (#1655) 2022-08-05 21:42:58 -05:00
Geoff Bourne
72b6eeba75 build: only login to DockerHub when credentials available (#1645) 2022-08-02 22:47:35 -05:00
Noa Himesaka
68a514e589 Install procps-ng on Oracle Linux-based images for autopause (#1644) 2022-08-02 22:04:13 -05:00
Geoff Bourne
2df678e96a Added debug options for autopause/stop (#1638) 2022-07-30 12:06:22 -05:00
Geoff Bourne
8dbfff1873 Allow for multiple patterns in REMOVE_OLD_MODS_INCLUDE/EXCLUDE (#1637) 2022-07-29 21:28:04 -05:00
dependabot[bot]
c83705157c build(deps): bump docker/build-push-action from 3.0.0 to 3.1.0 (#1629) 2022-07-25 06:18:12 -05:00
Geoff Bourne
c5d4e4d8ca Added top-level docker compose file (#1628) 2022-07-24 21:26:34 -05:00
Geoff Bourne
e70525b2ff Added jdk image tags to java versions table (#1626) 2022-07-24 09:07:35 -05:00
Khoo Hao Yit
c5e91ff823 fix typo in README.md (#1623) 2022-07-22 11:38:09 -05:00
Geoff Bourne
5cec41319d Download and use Magma server jar rather than installer (#1618) 2022-07-20 21:14:38 -05:00
Geoff Bourne
eb22d4cadc build: perform validation on all base images for PRs (#1610) 2022-07-20 20:24:05 -05:00
Jawa_Juice
a0a046f9f6 Remove Airplane as discontinued (#1615) 2022-07-19 08:23:01 -05:00
Cayce House
9210044b8d fix #1612 (#1614) 2022-07-19 07:28:58 -05:00
Noa Himesaka
df203d4b4b Fix GraalVM images error on AArch64 systems (#1609) 2022-07-17 10:06:33 -05:00
Cayce House
16a958d129 Choose shortest path for generic pack base (#1608)
Co-authored-by: Cayce House <cayce@house.email>
2022-07-16 17:05:44 -05:00
Noa Himesaka
76628e8ccc Fixing zstd uncompression for Oracle Linux (#1607) 2022-07-16 11:05:32 -05:00
Noa Himesaka
e8f3fd2d71 Add GraalVM CE support (#1601) 2022-07-16 10:11:11 -05:00
Geoff Bourne
fac72eac9d TYPE=CURSEFORGE also looks for start.sh (#1605) 2022-07-16 10:01:08 -05:00
Gabriel Simmer
f4eac20ff8 Default -> default in limbo world name (#1604)
See #994 - Limbo will pass along the world name verbatim, but Minecraft (doesn't appear to) allow uppercase letters in world names.
2022-07-16 09:33:18 -05:00
Geoff Bourne
e3a29180fd Handle packwiz bootstrap installer already being present (#1595) 2022-07-11 22:27:07 -05:00
Geoff Bourne
51f1a08f6e docs: Updated readiness and liveness probes in k8s example (#1592) 2022-07-09 17:30:08 -05:00
Geoff Bourne
5a507f800f VanillaTweaks uses mc-image-helper and auto-cleans old files (#1581) 2022-06-29 22:17:23 -05:00
Mikkel D
ab47b06ba9 Update Magma API to V2 (#1580) 2022-06-28 07:15:32 -05:00
Geoff Bourne
7001f2bcba Added support for downloading mods from Modrinth (#1577) 2022-06-27 09:08:21 -05:00
Geoff Bourne
8d7a5275a8 docs: Updated description of LEVEL_TYPE (#1575) 2022-06-22 13:04:27 -05:00
Geoff Bourne
30fa6d02c7 build: output time spent on each setuponly test (#1569) 2022-06-18 09:56:53 -05:00
Davide A
a18cf3348a packwiz manually download bootstrap and skip update when initial download fails 2022-06-17 09:21:41 -05:00
Mathéo CIMBARO
a84cdaf355 Added support for optimized SIMD operations (#1570) 2022-06-16 18:19:15 -05:00
Mathéo CIMBARO
23c8fc65a4 Added support for Pufferfish 1.19 (#1566)
* Added support for Pufferfish 1.19

* Update scripts/start-deployPufferfish

Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>

* Removed wrong negation

Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
2022-06-16 15:19:04 -05:00
Geoff Bourne
f8acb832f1 Ensure PURPUR_DOWNLOAD_URL has a default (#1568) 2022-06-16 08:39:25 -05:00
Bensuperpc
b6dbcbde02 Add custom download URL for Purpur (#1563) 2022-06-15 06:51:41 -05:00
Geoff Bourne
f5f09302b2 docs: added itzg/rcon to related projects 2022-06-12 08:39:46 -05:00
Caden Kriese
512fa7fbd4 Add 1.19 server properties (#1558) 2022-06-11 19:31:26 -05:00
Geoff Bourne
9458005b5b Resolve latest Paper version when no published builds (#1555) 2022-06-08 11:12:49 -05:00
Geoff Bourne
b1be888dd4 docs: Clarify the volume mounting example (#1549) 2022-06-05 16:05:57 -05:00
chblodg
4f9de809f8 updating forgeapi tests and adding is false (#1548)
Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
2022-06-05 15:16:12 -05:00
Geoff Bourne
1fb04c069c Place EULA file into subdir managed by ServerSetup (#1543) 2022-05-30 13:07:25 -05:00
Geoff Bourne
fd2431046c misc: Removed 88135 from spiget test (#1541) 2022-05-30 13:07:06 -05:00
Geoff Bourne
19ee3f58f8 build: alpine build needed sh not bash (#1540) 2022-05-30 12:10:14 -05:00
Geoff Bourne
8d0bdb60f0 For CurseForge, avoid conflicting start script error when run.sh present (#1539) 2022-05-30 08:41:21 -05:00
Geoff Bourne
0f23414198 Provide clearer log when minecraft server process fails (#1538) 2022-05-29 21:57:39 -05:00
Geoff Bourne
40ebddadff Pin base images to focal until netty epoll support is fixed (#1536) 2022-05-28 20:06:23 -05:00
Geoff Bourne
08556a63b8 CurseForge modpacks use run.sh when present (#1534)
* CurseForge modpacks use run.sh when present

* Added lbzip2
2022-05-26 22:02:26 -05:00
Bensuperpc
ea7046f93d Fixed older purpur versions not being removed (#1531) 2022-05-24 07:21:30 -05:00
Geoff Bourne
6768795594 docs: Corrected image tag in FTB example (#1530) 2022-05-22 15:25:44 -05:00
Skyler Spaeth
e7236212d8 Add jarfile options and custom worlds directory path (Multiverse) to docs (#1527) 2022-05-22 12:00:38 -05:00
Geoff Bourne
3e3abda71e Constrain GENERIC_PACK base detection depth (#1528) 2022-05-22 11:35:52 -05:00
91 changed files with 1398 additions and 1074 deletions

19
.gitattributes vendored
View File

@@ -1,17 +1,2 @@
# Auto detect text files and perform LF normalization # Auto detect text files and perform LF normalization
* text=auto * text=lf
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

3
.github/FUNDING.yml vendored
View File

@@ -1,5 +1,4 @@
github: itzg
#github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
custom: custom:
- https://www.buymeacoffee.com/itzg - https://www.buymeacoffee.com/itzg
- https://paypal.me/itzg - https://paypal.me/itzg

View File

@@ -1,4 +1,4 @@
name: Build and publish multiarch name: Test and Build multi-architecture
on: on:
push: push:
branches: branches:
@@ -18,10 +18,12 @@ jobs:
matrix: matrix:
variant: variant:
- java17 - java17
- java17-graalvm-ce
- java17-jdk - java17-jdk
- java17-openj9 - java17-openj9
- java17-alpine - java17-alpine
- java8 - java8
- java8-graalvm-ce
- java8-multiarch - java8-multiarch
- java8-openj9 - java8-openj9
- java8-jdk - java8-jdk
@@ -31,21 +33,26 @@ jobs:
include: include:
# JAVA 17: # JAVA 17:
- variant: java17 - variant: java17
baseImage: eclipse-temurin:17-jre # 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 platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: LATEST mcVersion: 1.18.2
- variant: java17-graalvm-ce
baseImage: ghcr.io/graalvm/graalvm-ce:ol8-java17
platforms: linux/amd64,linux/arm64
mcVersion: 1.18.2
- variant: java17-jdk - variant: java17-jdk
baseImage: eclipse-temurin:17 baseImage: eclipse-temurin:17-focal
platforms: linux/amd64,linux/arm/v7,linux/arm64 platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: LATEST mcVersion: 1.18.2
- variant: java17-openj9 - variant: java17-openj9
baseImage: ibm-semeru-runtimes:open-17-jre baseImage: ibm-semeru-runtimes:open-17-jre
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
mcVersion: LATEST mcVersion: 1.18.2
- variant: java17-alpine - variant: java17-alpine
baseImage: eclipse-temurin:17-jre-alpine baseImage: eclipse-temurin:17-jre-alpine
platforms: linux/amd64 platforms: linux/amd64
mcVersion: LATEST mcVersion: 1.18.2
# JAVA 11: # JAVA 11:
- variant: java11 - variant: java11
baseImage: adoptopenjdk:11-jre-hotspot baseImage: adoptopenjdk:11-jre-hotspot
@@ -64,12 +71,16 @@ jobs:
baseImage: openjdk:8-jre-alpine3.9 baseImage: openjdk:8-jre-alpine3.9
platforms: linux/amd64 platforms: linux/amd64
mcVersion: 1.12.2 mcVersion: 1.12.2
- variant: java8-graalvm-ce
baseImage: ghcr.io/graalvm/graalvm-ce:java8
platforms: linux/amd64
mcVersion: 1.12.2
- variant: java8-multiarch - variant: java8-multiarch
baseImage: eclipse-temurin:8u312-b07-jre baseImage: eclipse-temurin:8u312-b07-jre-focal
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
mcVersion: 1.12.2 mcVersion: 1.12.2
- variant: java8-jdk - variant: java8-jdk
baseImage: eclipse-temurin:8u312-b07-jdk baseImage: eclipse-temurin:8u312-b07-jdk-focal
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
mcVersion: 1.12.2 mcVersion: 1.12.2
- variant: java8-openj9 - variant: java8-openj9
@@ -78,6 +89,7 @@ jobs:
mcVersion: 1.12.2 mcVersion: 1.12.2
env: env:
IMAGE_TO_TEST: ${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }} IMAGE_TO_TEST: ${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}
HAS_IMAGE_REPO_ACCESS: ${{ secrets.DOCKER_USER != '' && secrets.DOCKER_PASSWORD != '' }}
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout - name: Checkout
@@ -109,14 +121,8 @@ jobs:
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v2.0.0 uses: docker/setup-qemu-action@v2.0.0
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test - name: Build for test
uses: docker/build-push-action@v3.0.0 uses: docker/build-push-action@v3.1.1
with: with:
platforms: linux/amd64 platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }} tags: ${{ env.IMAGE_TO_TEST }}
@@ -138,12 +144,27 @@ jobs:
run: | run: |
tests/test.sh tests/test.sh
- name: Login to DockerHub
uses: docker/login-action@v2
if: env.HAS_IMAGE_REPO_ACCESS
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push - name: Build and push
id: docker_build uses: docker/build-push-action@v3.1.1
uses: docker/build-push-action@v3.0.0 if: github.actor == github.repository_owner
with: with:
platforms: ${{ matrix.platforms }} platforms: ${{ matrix.platforms }}
push: ${{ github.ref_type == 'tag' || github.ref_name == 'master' }} push: >
${{
github.ref_type == 'tag'
|| github.ref_name == 'master'
|| ( 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 }} tags: ${{ steps.meta.outputs.tags }}
# ensure latest base image is used # ensure latest base image is used
pull: true pull: true

View File

@@ -1,43 +0,0 @@
name: ContinuousIntegration
on:
push:
branches:
- 'dev*'
- '!master'
- '!java*'
- '!multi*'
paths-ignore:
- "*.md"
- "docs/**"
- "examples/**"
env:
IMAGE_TO_TEST: ${{ secrets.IMAGE_ORG }}/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
jobs:
test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build
uses: docker/build-push-action@v3.0.0
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
load: true
cache-from: type=gha
- name: Run Setup Only Tests
run: bash tests/setuponlytests/test.sh
# - name: Run Full Minecraft Service Tests
# run: |
# tests/fulltests/test.sh

View File

@@ -1,66 +0,0 @@
name: PullRequest
on:
pull_request:
branches: [ master ]
types: [assigned, opened, synchronize, labeled]
paths-ignore:
- "*.md"
- "docs/**"
- "examples/**"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
jobs:
test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build
uses: docker/build-push-action@v3.0.0
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
load: true
cache-from: type=gha
- name: Run tests
env:
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
MINECRAFT_VERSION: LATEST
run: |
tests/test.sh
- name: Gather Docker metadata
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
id: meta
uses: docker/metadata-action@v4
with:
images: |
itzg/minecraft-server
- name: Login to DockerHub
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
uses: docker/build-push-action@v3.0.0
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
pull: true
push: true
cache-from: type=gha
labels: ${{ steps.meta.outputs.labels }}

69
.github/workflows/verify-pr.yml vendored Normal file
View File

@@ -0,0 +1,69 @@
name: Verify PR
on:
pull_request:
branches: [ master ]
types: [assigned, opened, synchronize, labeled]
paths-ignore:
- "*.md"
- "docs/**"
- "examples/**"
jobs:
build:
strategy:
fail-fast: false
matrix:
variant:
- java17
- java17-alpine
- java8-multiarch
include:
# 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
mcVersion: 1.18.2
- variant: java17-alpine
baseImage: eclipse-temurin:17-jre-alpine
platforms: linux/amd64
mcVersion: 1.18.2
- variant: java8-multiarch
baseImage: eclipse-temurin:8u312-b07-jre-focal
platforms: linux/amd64
mcVersion: 1.12.2
env:
IMAGE_TO_TEST: ${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3
with:
# for build-files step
fetch-depth: 0
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build for test
uses: docker/build-push-action@v3.1.1
with:
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
# ensure latest base image is used
pull: true
# load into daemon for test usage in next step
load: true
push: false
build-args: |
BASE_IMAGE=${{ matrix.baseImage }}
cache-from: type=gha,scope=${{ matrix.variant }}
- name: Run tests
env:
MINECRAFT_VERSION: ${{ matrix.mcVersion }}
VARIANT: ${{ matrix.variant }}
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
DEBUG: ${{ runner.debug }}
run: |
tests/test.sh

View File

@@ -78,7 +78,7 @@ In the cloned copy of [`mc-image-helper`](https://github.com/itzg/mc-image-helpe
Assuming [http-server](https://www.npmjs.com/package/http-server) is installed globally, start a static web server using: Assuming [http-server](https://www.npmjs.com/package/http-server) is installed globally, start a static web server using:
```shell ```shell
http-server ./build/distributions -p 0 http-server ./build/distributions -p 8080
``` ```
Note the port that was selected by http-server and pass the build arguments, such as: Note the port that was selected by http-server and pass the build arguments, such as:
@@ -88,7 +88,7 @@ Note the port that was selected by http-server and pass the build arguments, suc
--build-arg MC_HELPER_BASE_URL=http://host.docker.internal:8080 --build-arg MC_HELPER_BASE_URL=http://host.docker.internal:8080
``` ```
Now the image can be built like normal and it will install mc-image-helper from the locally built copy. Now the image can be built like normal, and it will install mc-image-helper from the locally built copy.
## Generating release notes ## Generating release notes

View File

@@ -1,75 +1,73 @@
# syntax = docker/dockerfile:1.3 # syntax = docker/dockerfile:1.3
ARG BASE_IMAGE=eclipse-temurin:17-jdk ARG BASE_IMAGE=eclipse-temurin:17-jre-focal
FROM ${BASE_IMAGE} FROM ${BASE_IMAGE}
# CI system should set this to a hash or git revision of the build directory and it's contents to # CI system should set this to a hash or git revision of the build directory and it's contents to
# ensure consistent cache updates. # ensure consistent cache updates.
ARG BUILD_FILES_REV=1 ARG BUILD_FILES_REV=1
RUN --mount=target=/build,source=build \ RUN --mount=target=/build,source=build \
REV=${BUILD_FILES_REV} /build/run.sh install-packages REV=${BUILD_FILES_REV} /build/run.sh install-packages
RUN --mount=target=/build,source=build \ RUN --mount=target=/build,source=build \
REV=${BUILD_FILES_REV} /build/run.sh setup-user REV=${BUILD_FILES_REV} /build/run.sh setup-user
COPY --chmod=644 files/sudoers* /etc/sudoers.d COPY --chmod=644 files/sudoers* /etc/sudoers.d
EXPOSE 25565 25575 EXPOSE 25565 25575
# hook into docker BuildKit --platform support # hook into docker BuildKit --platform support
# see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope # see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
ARG TARGETOS ARG TARGETOS
ARG TARGETARCH ARG TARGETARCH
ARG TARGETVARIANT ARG TARGETVARIANT
ARG EASY_ADD_VER=0.7.1 ARG EASY_ADD_VER=0.7.1
ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
RUN chmod +x /usr/bin/easy-add RUN chmod +x /usr/bin/easy-add
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.2.0 --var app=restify --file {{.app}} \ --var version=1.2.0 --var app=restify --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.6.0 --var app=rcon-cli --file {{.app}} \ --var version=1.6.0 --var app=rcon-cli --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=0.10.3 --var app=mc-monitor --file {{.app}} \ --var version=0.10.3 --var app=mc-monitor --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.8.0 --var app=mc-server-runner --file {{.app}} \ --var version=1.8.1 --var app=mc-server-runner --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \ --var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
ARG MC_HELPER_VERSION=1.16.11 ARG MC_HELPER_VERSION=1.22.7
ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/v${MC_HELPER_VERSION} ARG MC_HELPER_RELEASE=v${MC_HELPER_VERSION}
RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \ ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/${MC_HELPER_RELEASE}
| tar -C /usr/share -zxf - \ RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \
&& ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin | tar -C /usr/share -zxf - \
&& ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin
VOLUME ["/data"]
WORKDIR /data VOLUME ["/data"]
WORKDIR /data
STOPSIGNAL SIGTERM
STOPSIGNAL SIGTERM
# End user MUST set EULA and change RCON_PASSWORD
ENV TYPE=VANILLA VERSION=LATEST EULA="" UID=1000 GID=1000 RCON_PASSWORD=minecraft # End user MUST set EULA and change RCON_PASSWORD
ENV TYPE=VANILLA VERSION=LATEST EULA="" UID=1000 GID=1000 RCON_PASSWORD=minecraft
COPY --chmod=755 scripts/start* /
COPY --chmod=755 bin/ /usr/local/bin/ COPY --chmod=755 scripts/start* /
COPY --chmod=755 bin/mc-health /health.sh COPY --chmod=755 bin/ /usr/local/bin/
COPY --chmod=644 files/server.properties /tmp/server.properties COPY --chmod=755 bin/mc-health /health.sh
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml COPY --chmod=644 files/log4j2.xml /image/log4j2.xml
COPY --chmod=755 files/autopause /autopause COPY --chmod=755 files/auto /auto
COPY --chmod=755 files/autostop /autostop
COPY --chmod=755 files/rconcmds /rconcmds RUN dos2unix /start* /auto/*
RUN dos2unix /start* /autopause/* /autostop/* /rconcmds/* ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m --interval=5s --retries=24 CMD mc-health
ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m CMD mc-health

239
README.md
View File

@@ -86,9 +86,14 @@ Everything the container manages is located under the **container's** `/data` pa
### Attaching data directory to host filesystem ### Attaching data directory to host filesystem
In most cases the easier way to persist and work with the minecraft data files is to use the `-v` argument to map a directory on your host machine to the container's `/data` directory, such as the following where `/home/user/minecraft-data` would be a directory of your choosing on your host machine: In most cases the easiest way to persist and work with the minecraft data files is to use the [volume mounting](https://docs.docker.com/storage/volumes/) `-v` argument to map a directory on your host machine to the container's `/data` directory. In the following example, the path `/home/user/minecraft-data` **must be** a directory on your host machine:
docker run -d -v /home/user/minecraft-data:/data ... -v /home/user/minecraft-data:/data
------------------------- -----
| |
| +-- must always be /data
|
+-- replace with a directory on your host machine
When attached in this way you can stop the server, edit the configuration under your attached directory and start the server again to pick up the new configuration. When attached in this way you can stop the server, edit the configuration under your attached directory and start the server again to pick up the new configuration.
@@ -160,19 +165,24 @@ the server jar remain in the `/data` directory. It is safe to remove those._
## Running Minecraft server on different Java version ## Running Minecraft server on different Java version
When using the image `itzg:/minecraft-server` without a tag, the `latest` image tag is implied from the table below. To use a different version of Java, please use an alternate tag to run your Minecraft server container. When using the image `itzg/minecraft-server` without a tag, the `latest` image tag is implied from the table below. To use a different version of Java, please use an alternate tag to run your Minecraft server container.
| Tag name | Java version | Linux | JVM Type | Architecture | | Tag name | Java version | Linux | JVM Type | Architecture |
|-----------------|-------------|--------|----------|-------------------| |-------------------|--------------|--------|-------------|-------------------|
| latest | 17 | Debian | Hotspot | amd64,arm64,armv7 | | latest | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java8 | 8 | Alpine | Hotspot | amd64 | | java8 | 8 | Alpine | Hotspot | amd64 |
| java8-multiarch | 8 | Debian | Hotspot | amd64,arm64,armv7 | | java8-jdk | 8 | Ubuntu | Hotspot+JDK | amd64 |
| java8-openj9 | 8 | Debian | OpenJ9 | amd64 | | java8-multiarch | 8 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 | | java8-openj9 | 8 | Debian | OpenJ9 | amd64 |
| java11-openj9 | 11 | Debian | OpenJ9 | amd64 | | java8-graalvm-ce | 8 | Oracle | GraalVM CE | amd64 |
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 | | java11 | 11 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 | | java11-jdk | 11 | Ubuntu | Hotspot+JDK | amd64,arm64,armv7 |
| java17-alpine | 17 | Alpine | Hotspot | amd64 | | java11-openj9 | 11 | Debian | OpenJ9 | amd64 |
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java17-jdk | 17 | Ubuntu | Hotspot+JDK | amd64,arm64,armv7 |
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 |
| java17-graalvm-ce | 17 | Oracle | GraalVM CE | amd64,arm64 |
| java17-alpine | 17 | Alpine | Hotspot | amd64 |
For example, to use Java version 8 on any supported architecture: For example, to use Java version 8 on any supported architecture:
@@ -222,11 +232,13 @@ A tool that is bundled with this image that provides health checks and metrics r
A tool that is bundled with this image to provide complex, re-usable preparation operations. A tool that is bundled with this image to provide complex, re-usable preparation operations.
### [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).
## Healthcheck ## Healthcheck
This image contains [mc-monitor](https://github.com/itzg/mc-monitor) and uses This image contains [mc-monitor](https://github.com/itzg/mc-monitor) and uses its `status` command to continually check on the container's. That can be observed from the `STATUS` column of `docker ps`
its `status` command to continually check on the container's. That can be observed
from the `STATUS` column of `docker ps`
``` ```
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
@@ -240,6 +252,16 @@ You can also query the container's health in a script friendly way:
healthy healthy
``` ```
There's actually a wrapper script called `mc-health` that takes care of calling `mc-monitor status` with the correct arguments. If needing to customize the health checks parameters, such as in a compose file, then use something like the following in the service declaration:
```yaml
healthcheck:
test: mc-health
start_period: 1m
interval: 5s
retries: 20
```
Some orchestration systems, such as Portainer, don't allow for disabling the default `HEALTHCHECK` declared by this image. In those cases you can approximate the disabling of healthchecks by setting the environment variable `DISABLE_HEALTHCHECK` to `true`. Some orchestration systems, such as Portainer, don't allow for disabling the default `HEALTHCHECK` declared by this image. In those cases you can approximate the disabling of healthchecks by setting the environment variable `DISABLE_HEALTHCHECK` to `true`.
## Deployment Templates and Examples ## Deployment Templates and Examples
@@ -414,18 +436,6 @@ If you have attached a host directory to the `/data` volume, then you can instal
[You can also auto-download plugins using `SPIGET_RESOURCES`.](#auto-downloading-spigotmcbukkitpapermc-plugins) [You can also auto-download plugins using `SPIGET_RESOURCES`.](#auto-downloading-spigotmcbukkitpapermc-plugins)
### Running an Airplane server
An [Airplane](https://airplane.gg) server, which is "a stable, optimized, well supported 1.17 Paper fork."
-e TYPE=AIRPLANE
> NOTE: The `VERSION` variable is used to select an Airplane type to download. The available options are "LATEST" and "PURPUR", both 1.17.1. Airplane does not support 1.18 -- use Paper/Pufferfish/Purpur.
Extra variables:
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
### Running a Pufferfish server ### Running a Pufferfish server
A [Pufferfish](https://github.com/pufferfish-gg/Pufferfish) server, which is "a highly optimized Paper fork designed for large servers requiring both maximum performance, stability, and "enterprise" features." A [Pufferfish](https://github.com/pufferfish-gg/Pufferfish) server, which is "a highly optimized Paper fork designed for large servers requiring both maximum performance, stability, and "enterprise" features."
@@ -441,7 +451,7 @@ Extra variables:
### Running a Purpur server ### Running a Purpur server
A [Purpur](https://purpur.pl3x.net/) server, which is "drop-in replacement for Paper servers designed for configurability, new fun and exciting gameplay features, and performance built on top of Airplane." A [Purpur](https://purpurmc.org/) server, which is "a drop-in replacement for Paper servers designed for configurability and new, fun, exciting gameplay features."
-e TYPE=PURPUR -e TYPE=PURPUR
@@ -451,6 +461,7 @@ Extra variables:
- `PURPUR_BUILD=LATEST` : set a specific Purpur build to use - `PURPUR_BUILD=LATEST` : set a specific Purpur build to use
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded - `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler - `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
- `PURPUR_DOWNLOAD_URL=<url>` : set URL to download Purpur from custom URL.
### Running a Magma server ### Running a Magma server
@@ -458,8 +469,6 @@ A [Magma](https://magmafoundation.org/) server, which is a combination of Forge
-e TYPE=MAGMA -e TYPE=MAGMA
By default, the "stable" channel is used, but you can set `MAGMA_CHANNEL` to "dev" to access dev channel versions.
> **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2", "1.16.5", etc. > **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2", "1.16.5", etc.
@@ -535,7 +544,10 @@ Configuration options with defaults:
- `FORCE_REDOWNLOAD`=false - `FORCE_REDOWNLOAD`=false
- `LIMBO_SCHEMA_FILENAME`=default.schem - `LIMBO_SCHEMA_FILENAME`=default.schem
- `LEVEL`="Default;${LIMBO_SCHEMA_FILENAME}" - `LEVEL`="Default;${LIMBO_SCHEMA
NAME}"
> NOTE: instead of using format codes in the MOTD, Limbo requires [JSON chat content](https://minecraft.fandom.com/wiki/Raw_JSON_text_format#Java_Edition). If a plain string is provided, which is the default, then it gets converted into the required JSON structure. > NOTE: instead of using format codes in the MOTD, Limbo requires [JSON chat content](https://minecraft.fandom.com/wiki/Raw_JSON_text_format#Java_Edition). If a plain string is provided, which is the default, then it gets converted into the required JSON structure.
@@ -551,7 +563,7 @@ Crucible is only available for 1.7.10, so be sure to set `VERSION=1.7.10`.
## Running a server with a Feed the Beast modpack ## Running a server with a Feed the Beast modpack
> **NOTE** requires one of the Debian based images listed in [the Java versions section](#running-minecraft-server-on-different-java-version). > **NOTE** requires one of the Ubuntu with Hotspot images listed in [the Java versions section](#running-minecraft-server-on-different-java-version).
[Feed the Beast application](https://www.feed-the-beast.com/) modpacks are supported by using `-e TYPE=FTBA` (**note** the "A" at the end of the type). This server type will automatically take care of downloading and installing the modpack and appropriate version of Forge, so the `VERSION` does not need to be specified. [Feed the Beast application](https://www.feed-the-beast.com/) modpacks are supported by using `-e TYPE=FTBA` (**note** the "A" at the end of the type). This server type will automatically take care of downloading and installing the modpack and appropriate version of Forge, so the `VERSION` does not need to be specified.
@@ -571,7 +583,7 @@ The following example runs the latest version of [FTB Presents Direwolf20 1.12](
docker run -d --name mc-ftb -e EULA=TRUE \ docker run -d --name mc-ftb -e EULA=TRUE \
-e TYPE=FTBA -e FTB_MODPACK_ID=31 \ -e TYPE=FTBA -e FTB_MODPACK_ID=31 \
-p 25565:25565 \ -p 25565:25565 \
itzg/minecraft-server:multiarch itzg/minecraft-server:java8-multiarch
``` ```
> Normally you will also add `-v` volume for `/data` since the mods and config are installed there along with world data. > Normally you will also add `-v` volume for `/data` since the mods and config are installed there along with world data.
@@ -634,6 +646,40 @@ packwiz modpack defitions are processed before other mod definitions (`MODPACK`,
> packwiz is pre-configured to only download server mods. If client-side mods are downloaded and cause issues, check your pack.toml configuration, and make sure any client-only mods are not set to `"both"`, but rather `"client"` for the side configuration item. > packwiz is pre-configured to only download server mods. If client-side mods are downloaded and cause issues, check your pack.toml configuration, and make sure any client-only mods are not set to `"both"`, but rather `"client"` for the side configuration item.
### Known Issues: Curl 403 on Startup
If the container enters a crash-loop or is otherwise rate-limited by Github, you
will see an error similar to, `curl: (22) The requested URL returned error: 403`.
Packwiz is primarily distributed through Github releases. In order to check if
there are any new releases, this container must call Githubs API. All of the
data that we need to check is public, but trouble happens when Github has reason
to think these calls are a bad-actor. Like if the container gets stuck in a loop
restarting and calls the API too fast or too many times. Simply, this container uses
personal access tokens to tells Github that this system is built by a friendly
human.
[Manage Your Github's Personal Access Tokens](https://github.com/settings/tokens)
Create a new personal access token for this container to use. This token will
be used everytime the container is started or restarted so choose an expiration
date that will last for as long as you plan to be operating this container
instance. **The token cannot have any scopes.** This script doesn't need any
scopes what-so-ever to Github and is only being used to signal to Github that
a friendly human is requesting some data. **Do NOT give this token scopes. This
container will refuse to use any token with scopes.**
To configure server mods using a packwiz modpack and a github token, set the
`PACKWIZ_URL` environment variable to the location of your `pack.toml` modpack
definition and the `GH_TOKEN` to your token's secret value:
docker run -d -v /path/on/host:/data \
-p 25565:25565 \
-e TYPE=FORGE \
-e "PACKWIZ_URL=https://example.com/modpack/pack.toml" \
-e "GH_TOKEN"=ghp_chaosofrandomdigitsandletters \
itzg/minecraft-server
## Working with mods and plugins ## Working with mods and plugins
### Optional plugins, mods, and config attach points ### Optional plugins, mods, and config attach points
@@ -651,7 +697,9 @@ There are optional volume paths that can be attached to supply content to be cop
By default, the [environment variable processing](#replacing-variables-inside-configs) is performed on synchronized files that match the expected suffixes in `REPLACE_ENV_SUFFIXES` (by default "yml,yaml,txt,cfg,conf,properties,hjson,json,tml,toml") and are not excluded by `REPLACE_ENV_VARIABLES_EXCLUDES` and `REPLACE_ENV_VARIABLES_EXCLUDE_PATHS`. This processing can be disabled by setting `REPLACE_ENV_DURING_SYNC` to `false`. By default, the [environment variable processing](#replacing-variables-inside-configs) is performed on synchronized files that match the expected suffixes in `REPLACE_ENV_SUFFIXES` (by default "yml,yaml,txt,cfg,conf,properties,hjson,json,tml,toml") and are not excluded by `REPLACE_ENV_VARIABLES_EXCLUDES` and `REPLACE_ENV_VARIABLES_EXCLUDE_PATHS`. This processing can be disabled by setting `REPLACE_ENV_DURING_SYNC` to `false`.
If you want old mods/plugins to be removed before the content is brought over from those attach points, then add `-e REMOVE_OLD_MODS=TRUE`. You can fine tune the removal process by specifying the `REMOVE_OLD_MODS_INCLUDE` and `REMOVE_OLD_MODS_EXCLUDE` variables. By default, everything will be removed. You can also specify the `REMOVE_OLD_MODS_DEPTH` (default is 16) variable to only delete files up to a certain level. If you want old mods/plugins to be removed before the content is brought over from those attach points, then add `-e REMOVE_OLD_MODS=TRUE`. You can fine tune the removal process by specifying the `REMOVE_OLD_MODS_INCLUDE` and `REMOVE_OLD_MODS_EXCLUDE` variables, which are comma separated lists of file glob patterns. If a directory is excluded, then it and all of its contents are excluded. By default, only jars are removed.
You can also specify the `REMOVE_OLD_MODS_DEPTH` (default is 16) variable to only delete files up to a certain level.
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. 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.
@@ -674,6 +722,20 @@ For example, the following will auto-download the [EssentialsX](https://www.spig
-e SPIGET_RESOURCES=9089,34315 -e SPIGET_RESOURCES=9089,34315
### Auto-download mods from Modrinth
[Modrinth](https://modrinth.com/) is an open source modding platform with a clean, easy to use website for finding [Fabric and Forge mods](https://modrinth.com/mods). At startup, the container will automatically locate and download the newest versions of mod files that correspond to the `TYPE` and `VERSION` in use. Older file versions downloaded previously will automatically be cleaned up.
- **MODRINTH_PROJECTS** : comma separated list of project slugs (short name) or IDs. The project ID can be located in the "Technical information" section. The slug is the part of the page URL that follows `/mod/`:
```
https://modrinth.com/mod/fabric-api
----------
|
+-- project slug
```
- **MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES**=true : required dependencies of the project will _always_ be downloaded and optional dependencies can also be downloaded by setting this to `true`
- **MODRINTH_ALLOWED_VERSION_TYPE**=release : the version type is used to determine the newest version to use from each project. The allowed values are `release`, `beta`, `alpha`.
### Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers ### Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers
Like the `WORLD` option above, you can specify the URL or path of a "mod pack" Like the `WORLD` option above, you can specify the URL or path of a "mod pack"
@@ -834,6 +896,14 @@ The following diagram shows how this option can be used in a compose deployment
### Overwrite world on start ### Overwrite world on start
The world will only be downloaded or copied if it doesn't exist already. Set `FORCE_WORLD_COPY=TRUE` to force overwrite the world on every server start. The world will only be downloaded or copied if it doesn't exist already. Set `FORCE_WORLD_COPY=TRUE` to force overwrite the world on every server start.
### Custom worlds directory path
To set a custom worlds directory for the Multiverse plugin on a baremetal server, you'd pass the `--world-dir` argument after the jar file.
In order to accomplish the same in a containerized server, set the `EXTRA_ARGS` environment variable in your command line or docker compose yaml to the same argument string. For example:
```
docker run -d -e EXTRA_ARGS='--world-dir ./worlds/'
```
`--world-container`, `-W`, and `--universe` are aliases to `--world-dir` and can also be used.
### Datapacks ### Datapacks
Datapacks can be installed in a similar manner to mods/plugins. There are many environment variables which function in the same way they do for [mods](#working-with-mods-and-plugins): Datapacks can be installed in a similar manner to mods/plugins. There are many environment variables which function in the same way they do for [mods](#working-with-mods-and-plugins):
* `DATAPACKS` * `DATAPACKS`
@@ -846,28 +916,30 @@ Datapacks will be placed in `/data/$LEVEL/datapacks`
### VanillaTweaks ### VanillaTweaks
VanillaTweaks datapacks can be installed with a share code from the website UI **OR** a json file to specify packs to download and install. [VanillaTweaks](https://vanillatweaks.net/) datapacks, crafting tweaks, and resource packs can be installed with a share code from the website **OR** a json file to specify packs to download and install. Datapacks and crafting tweaks will be installed into the current world directory specified by `$LEVEL`. As new versions of the packs are retrieved the previous versions will automatically be cleaned up.
Datapacks will be placed in `/data/$LEVEL/datapacks` The share code is the part following the hash sign, as shown here:
Resourcepacks will be placed in `/data/resourcepacks`
```
https://vanillatweaks.net/share/#MGr52E
------
|
+- share code MGr52E
```
Accepted Parameters: Accepted Parameters:
- `VANILLATWEAKS_FILE` - `VANILLATWEAKS_FILE`: comma separated list of JSON VanillaTweak pack files accessible within the container
- `VANILLATWEAKS_SHARECODE` - `VANILLATWEAKS_SHARECODE`: comma separated list of share codes
- `REMOVE_OLD_VANILLATWEAKS`
- `REMOVE_OLD_VANILLATWEAKS_DEPTH`
- `REMOVE_OLD_VANILLATWEAKS_INCLUDE`
- `REMOVE_OLD_VANILLATWEAKS_EXCLUDE`
Example of expected Vanillatweaks sharecode: Example of expected VanillaTweaks share codes:
**Note**: ResourcePacks, DataPacks, and CraftingTweaks all have separate sharecodes **Note**: ResourcePacks, DataPacks, and CraftingTweaks all have separate sharecodes
```yaml ```yaml
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT
``` ```
Example of expected Vanillatweaks file format: Example of expected VanillaTweaks files:
```yaml ```yaml
VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
@@ -881,7 +953,7 @@ Datapacks Json:
"packs": { "packs": {
"survival": [ "survival": [
"graves", "graves",
"multiplayer sleep", "multiplayer sleep"
], ],
"items": ["armored elytra"] "items": ["armored elytra"]
} }
@@ -895,8 +967,7 @@ Resourcepacks Json:
"version": "1.18", "version": "1.18",
"packs": { "packs": {
"aesthetic": ["CherryPicking", "BlackNetherBricks", "AlternateBlockDestruction"] "aesthetic": ["CherryPicking", "BlackNetherBricks", "AlternateBlockDestruction"]
}, }
"result": "ok"
} }
``` ```
@@ -911,8 +982,7 @@ CraftingTweaks Json:
"double slabs", "double slabs",
"back to blocks" "back to blocks"
] ]
}, }
"result": "ok"
} }
``` ```
@@ -1161,30 +1231,9 @@ environment variable set to `false`, such as
### Level Type and Generator Settings ### Level Type and Generator Settings
By default, a standard world is generated with hills, valleys, water, etc. A different level type can By default, a standard world is generated with hills, valleys, water, etc. A different level type can
be configured by setting `LEVEL_TYPE` to an expected type, for example be configured by setting `LEVEL_TYPE` to [an expected type listed here](https://minecraft.fandom.com/wiki/Server.properties#level-type).
- DEFAULT For some of the level types, `GENERATOR_SETTINGS` can be used to further customize the world generation [as described here](https://minecraft.fandom.com/wiki/Server.properties#generator-settings).
- FLAT
- LARGEBIOMES
- AMPLIFIED
- CUSTOMIZED
- BUFFET
- BIOMESOP (Biomes O' Plenty for 1.12 and older)
- BIOMESOPLENTY (Biomes O' Plenty for 1.15 and above)
Descriptions are available at the [gamepedia](http://minecraft.gamepedia.com/Server.properties).
When using a level type of `FLAT`, `CUSTOMIZED`, and `BUFFET`, you can further configure the world generator
by passing [custom generator settings](http://minecraft.gamepedia.com/Superflat).
**Since generator settings usually have ;'s in them, surround the -e value with a single quote, like below.**
For example (just the `-e` bits):
-e LEVEL_TYPE=flat -e 'GENERATOR_SETTINGS=3;minecraft:bedrock,3*minecraft:stone,52*minecraft:sandstone;2;'
In Minecraft 1.13+ you need to pass json ([generator site](https://misode.github.io/world/)) like this (details see [here](https://github.com/itzg/docker-minecraft-server/issues/999#issuecomment-907849644)):
-e LEVEL_TYPE=flat -e 'GENERATOR_SETTINGS={"biome":"minecraft:the_void","layers":[{"block":"minecraft:bedrock","height":1},{"block":"minecraft:stone","height":10},{"block":"minecraft:dirt","height":1}],"structures":{"structures":{}}}'
### Custom Server Resource Pack ### Custom Server Resource Pack
@@ -1273,7 +1322,27 @@ Variables that you want to replace need to be declared inside curly brackets and
You can also change `REPLACE_ENV_VARIABLE_PREFIX`, which defaults to "CFG_", to limit which environment variables are allowed to be used. For example, with "CFG_" as the prefix, the variable `${CFG_DB_HOST}` would be subsituted, but not `${DB_HOST}`. You can also change `REPLACE_ENV_VARIABLE_PREFIX`, which defaults to "CFG_", to limit which environment variables are allowed to be used. For example, with "CFG_" as the prefix, the variable `${CFG_DB_HOST}` would be subsituted, but not `${DB_HOST}`.
If you want to use a file for value (like when use secrets) you can add suffix `_FILE` to your variable name. If you want to use a file's content for value, such as when using secrets mounted as files, declare the placeholder named like normal in the file and declare an environment variable named the same but with the suffix `_FILE`.
For example, a `my.cnf` file could contain:
```
[client]
password = ${CFG_DB_PASSWORD}
```
...a secret declared in the compose file with:
```yaml
secrets:
db_password:
external: true
```
...and finally the environment variable would be named with a `_FILE` suffix and point to the mounted secret:
```yaml
environment:
CFG_DB_PASSWORD_FILE: /run/secrets/db_password
```
Variables will be replaced in files with the following extensions: Variables will be replaced in files with the following extensions:
`.yml`, `.yaml`, `.txt`, `.cfg`, `.conf`, `.properties`. `.yml`, `.yaml`, `.txt`, `.cfg`, `.conf`, `.properties`.
@@ -1438,6 +1507,10 @@ environment variable. The JVM requires `-XX` options to precede `-X` options, so
For some cases, if e.g. after removing mods, it could be necessary to startup minecraft with an additional `-D` parameter like `-Dfml.queryResult=confirm`. To address this you can use the environment variable `JVM_DD_OPTS`, which builds the params from a given list of values separated by space, but without the `-D` prefix. To make things running under systems (e.g. Plesk), which doesn't allow `=` inside values, a `:` (colon) could be used instead. The upper example would look like this: For some cases, if e.g. after removing mods, it could be necessary to startup minecraft with an additional `-D` parameter like `-Dfml.queryResult=confirm`. To address this you can use the environment variable `JVM_DD_OPTS`, which builds the params from a given list of values separated by space, but without the `-D` prefix. To make things running under systems (e.g. Plesk), which doesn't allow `=` inside values, a `:` (colon) could be used instead. The upper example would look like this:
`JVM_DD_OPTS=fml.queryResult:confirm`, and will be converted to `-Dfml.queryResult=confirm`. `JVM_DD_OPTS=fml.queryResult:confirm`, and will be converted to `-Dfml.queryResult=confirm`.
### Jarfile Options
Options that would usually be passed to the jar file (those which are written after the filename) can be passed via the `EXTRA_ARGS` environment variable.
See [Custom worlds directory path](#custom-worlds-directory-path) for an example.
### Interactive and Color Console ### Interactive and Color Console
If you would like to `docker attach` to the Minecraft server console with color and interactive capabilities, then add If you would like to `docker attach` to the Minecraft server console with color and interactive capabilities, then add
@@ -1546,7 +1619,15 @@ To enable the JVM flags required to fully support the [Flare profiling suite](ht
-e USE_FLARE_FLAGS=true -e USE_FLARE_FLAGS=true
Flare is built-in to Airplane/Pufferfish/Purpur, and is available in [plugin form](https://github.com/TECHNOVE/FlarePlugin) for other server types. Flare is built-in to Pufferfish/Purpur, and is available in [plugin form](https://github.com/TECHNOVE/FlarePlugin) for other server types.
### Enable support for optimized SIMD operations
To enable support for optimized SIMD operations, the JVM flag can be set with the following variable:
-e USE_SIMD_FLAGS=true
SIMD optimized operations are supported by Pufferfish and Purpur.
### Enable timestamps in init logs ### Enable timestamps in init logs
@@ -1675,6 +1756,8 @@ The following environment variables define the behaviour of auto-pausing:
* `AUTOPAUSE_KNOCK_INTERFACE`, default `eth0` * `AUTOPAUSE_KNOCK_INTERFACE`, default `eth0`
<br>Describes the interface passed to the `knockd` daemon. If the default interface does not work, run the `ifconfig` command inside the container and derive the interface receiving the incoming connection from its output. The passed interface must exist inside the container. Using the loopback interface (`lo`) does likely not yield the desired results. <br>Describes the interface passed to the `knockd` daemon. If the default interface does not work, run the `ifconfig` command inside the container and derive the interface receiving the incoming connection from its output. The passed interface must exist inside the container. Using the loopback interface (`lo`) does likely not yield the desired results.
> To troubleshoot, add `DEBUG_AUTOPAUSE=true` to see additional output
## Autostop ## Autostop
An option to stop the server after a specified time has been added for niche applications (e.g. billing saving on AWS Fargate). The function is incompatible with the Autopause functionality, as they basically cancel out each other. An option to stop the server after a specified time has been added for niche applications (e.g. billing saving on AWS Fargate). The function is incompatible with the Autopause functionality, as they basically cancel out each other.
@@ -1697,6 +1780,8 @@ The following environment variables define the behaviour of auto-stopping:
* `AUTOSTOP_PERIOD`, default `10` (seconds) * `AUTOSTOP_PERIOD`, default `10` (seconds)
describes period of the daemonized state machine, that handles the stopping of the server describes period of the daemonized state machine, that handles the stopping of the server
> To troubleshoot, add `DEBUG_AUTOSTOP=true` to see additional output
## Running on RaspberryPi ## Running on RaspberryPi
To run this image on a RaspberryPi 3 B+, 4, or newer, use any of the image tags [list in the Java version section](#running-minecraft-server-on-different-java-version) that specify `armv7` for the architecture, which includes `itzg/minecraft-server:latest`. To run this image on a RaspberryPi 3 B+, 4, or newer, use any of the image tags [list in the Java version section](#running-minecraft-server-on-different-java-version) that specify `armv7` for the architecture, which includes `itzg/minecraft-server:latest`.

View File

@@ -8,8 +8,8 @@
: "${RCON_CMDS_PERIOD:=10}" : "${RCON_CMDS_PERIOD:=10}"
# needed for the clients connected function residing in autopause # needed for the clients connected function residing in autopause
# shellcheck source=/autopause/autopause-fcns.sh # shellcheck source=../auto/autopause-fcns.sh
. /autopause/autopause-fcns.sh . /auto/autopause-fcns.sh
# shellcheck source=start-utils # shellcheck source=start-utils
. ${SCRIPTS:-/}start-utils . ${SCRIPTS:-/}start-utils

12
build/ol/install-gosu.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
if [[ $(uname -m) == "aarch64" ]]; then
curl -sL -o /bin/gosu https://github.com/tianon/gosu/releases/download/1.14/gosu-arm64
chmod +x /bin/gosu
elif [[ $(uname -m) == "x86_64" ]]; then
curl -sL -o /bin/gosu https://github.com/tianon/gosu/releases/download/1.14/gosu-amd64
chmod +x /bin/gosu
else
echo "Not supported!"
exit 1
fi

38
build/ol/install-packages.sh Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
set -e
microdnf install dnf -y
dnf install 'dnf-command(config-manager)' -y
dnf config-manager --set-enabled ol8_codeready_builder
tee /etc/yum.repos.d/ol8-epel.repo<<EOF
[ol8_developer_EPEL]
name= Oracle Linux \$releasever EPEL (\$basearch)
baseurl=https://yum.oracle.com/repo/OracleLinux/OL8/developer/EPEL/\$basearch/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
gpgcheck=1
enabled=1
EOF
dnf update -y
dnf install -y ImageMagick \
file \
sudo \
net-tools \
iputils \
curl \
git \
jq \
dos2unix \
mysql \
procps-ng \
tzdata \
rsync \
nano \
unzip \
zstd \
lbzip2 \
knock
bash /build/ol/install-gosu.sh

2
build/ol/setup-user.sh Executable file
View File

@@ -0,0 +1,2 @@
groupadd --gid 1000 minecraft
useradd --system --shell /bin/false --uid 1000 -g minecraft --home /data minecraft

View File

@@ -22,6 +22,7 @@ apt-get install -y \
nano \ nano \
unzip \ unzip \
zstd \ zstd \
lbzip2 \
knockd knockd
apt-get clean apt-get clean

16
docker-compose.yml Normal file
View File

@@ -0,0 +1,16 @@
version: "3.8"
services:
mc:
image: itzg/minecraft-server
environment:
EULA: "true"
ports:
- "25565:25565"
volumes:
- data:/data
stdin_open: true
tty: true
restart: unless-stopped
volumes:
data: {}

3
examples/.gitignore vendored
View File

@@ -1 +1,2 @@
/data/ /data/
modpacks/

View File

@@ -9,7 +9,9 @@ services:
environment: environment:
EULA: "true" EULA: "true"
TYPE: CURSEFORGE TYPE: CURSEFORGE
CF_SERVER_MOD: https://media.forgecdn.net/files/3482/169/Valhelsia+3-3.4.4-SERVER.zip CF_SERVER_MOD: /modpacks/SIMPLE-SERVER-FILES-0.3.20.zip
# CF_SERVER_MOD: /modpacks/createlive3serverfiles+1.4.2.zip
# CF_SERVER_MOD: /modpacks/Valhelsia+3-3.5.1-SERVER.zip
# CF_SERVER_MOD: https://media.forgecdn.net/files/3012/800/SkyFactory-4_Server_4.2.2.zip # CF_SERVER_MOD: https://media.forgecdn.net/files/3012/800/SkyFactory-4_Server_4.2.2.zip
# CF_SERVER_MOD: /modpacks/${MODPACK:-SkyFactory_4_Server_4.1.0.zip} # CF_SERVER_MOD: /modpacks/${MODPACK:-SkyFactory_4_Server_4.1.0.zip}
ports: ports:

View File

@@ -0,0 +1,19 @@
version: '3.8'
services:
mc:
image: itzg/minecraft-server
volumes:
- ./data:/data
- ./modpacks:/modpacks:ro
environment:
EULA: "true"
MEMORY: 2G
TYPE: FORGE
VERSION: 1.18.2
FORGEVERSION: 40.1.30
# Need to download Server-Files-0.4.13.zip and
# put it in modpacks directory next to this compose file
GENERIC_PACK: /modpacks/Server-Files-0.4.13.zip
ports:
- "25565:25565"

View File

@@ -0,0 +1,160 @@
version: '3.8'
####################################################################
# FORGE GENERIC_PACK #
# #
# Date: 20220828 #
# #
# Mod: TNP Limitless 5 v2.19.0 #
# #
# Notes: Verify that there is no EULA file in the modpack.zip #
# if you do not delete it the EULA flag below will be #
# overwritten when the modpack is copied and the server #
# will not start. #
# #
####################################################################
services:
####################################################################
# Service Name #
# #
# Define Service Name here. If using RCON this name will be #
# referenced again as RWA_RCON_HOST below. #
# #
# Example: 'name:' or 'mc_atm6:' #
####################################################################
mc_tnp5:
####################################################################
# Image & Container Name #
# #
# Specify Image Name and Java Version. The 'image' will always be #
# 'itzg/minecraft-server' however the tag added to the end is #
# where you can specify the java version or container architecture.#
# See readme.md for a full list. #
# #
# 'container_name:' This can be anything you like. This is the name#
# that will show when you run 'docker ps' commands. #
####################################################################
image: itzg/minecraft-server
container_name: mc_tnp5
####################################################################
# Server Ports #
# #
# Specify external port. #
####################################################################
ports:
- 25565:25565
####################################################################
# Automatic Server Restart #
# #
# Define a restart policy here. #
# - 'no' = Do not restart. #
# - 'on-failure' = Restart if container exits because an error. #
# - 'always' = Regardless of stop reason. #
# - 'unless-stopped' = Similar to always except if stopped. #
####################################################################
restart: unless-stopped
####################################################################
# Volume and Folder Access #
# #
# This section defines what folders and volumes you want to give #
# this container access to. It is recommended to leaves these set #
# to the default values unless you know what you are doing. #
# #
# Place your mod zip file in a folder called 'modpacks' in the #
# same directory you place this docker-compose file. #
# #
# Specify the data volume name or directory here as well. #
# In this example the volume name is 'data'. When docker creates #
# the volume it will add what ever name you give it here to the #
# end of the container name specified above. In this example it #
# would be named 'mc_atm6_data'. If you change this be sure to #
# update the volume name at the bottom of this config. #
####################################################################
volumes:
- ./modpacks:/modpacks:ro
- data:/data
####################################################################
# EULA #
# #
# Accept EULA by setting to "true" #
####################################################################
environment:
EULA: "true"
####################################################################
# FORGE INSTALL #
# #
# Sets install type to FORGE and specifys the zip folder name #
# and location of your mod pack. #
# #
# TYPE: Defines the install type as FORGE #
# #
# VERSION: Defines the version of MC the modpack is based on. #
# #
# FORGEVERSION: Defines the version of FORGE the modpack uses. #
# This can usually be found in the modpack.zip as #
# installer.jar #
# #
# GENERIC_PACK: Define where the modpack.zip is located. #
# #
# Place your mod zip file in a folder called 'modpacks' in the #
# same directory you place this docker-compose file. #
####################################################################
TYPE: FORGE
VERSION: 1.18.2
FORGEVERSION: 40.1.73
GENERIC_PACK: /modpacks/tnp5.zip
####################################################################
# Server Memory #
# #
# Set Maximum amount of memory allowed for your server. #
####################################################################
MEMORY: "8G"
####################################################################
# Logging Options #
# #
# Set to "true" to delete old logs #
####################################################################
ENABLE_ROLLING_LOGS: "true"
####################################################################
# Server Timezone #
# #
# Specify server Timezone #
####################################################################
TZ: "America/New_York"
####################################################################
# Minecraft Game Options #
# #
# List any game options you want to define here. A full list can #
# be found on the readme.md page on github. #
####################################################################
OVERRIDE_SERVER_PROPERTIES: "true"
DIFFICULTY: "easy"
MAX_TICK_TIME: "-1"
VIEW_DISTANCE: "6"
ALLOW_FLIGHT: "true"
OPS: ""
VIEW_DISTANCE: 10
MAX_PLAYERS: 10
PVP: "false"
LEVEL_TYPE: "biomesoplenty"
MOTD: "Welcome Home"
####################################################################
# Volumes #
# #
# Define data volume name here. You should leave this set to the #
# default. #
####################################################################
volumes:
data:

View File

@@ -0,0 +1,17 @@
version: "3.8"
services:
mc:
image: itzg/minecraft-server:java8
tty: true
stdin_open: true
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: MAGMA
VERSION: 1.16.5
volumes:
- data:/data
volumes:
data: {}

View File

@@ -0,0 +1,18 @@
version: "3.8"
services:
mc:
image: itzg/minecraft-server
tty: true
stdin_open: true
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: FABRIC
MODRINTH_PROJECTS: fallingtree
volumes:
- data:/data
volumes:
data: {}

View File

@@ -0,0 +1,21 @@
version: '3.8'
services:
minecraft:
image: itzg/minecraft-server
volumes:
- data:/data
- ./mods:/mods
ports:
- "25565:25565"
environment:
EULA: "true"
TYPE: "FORGE"
VERSION: "1.19.2"
DEBUG: "true"
SETUP_ONLY: "true"
tty: True
stdin_open: True
volumes:
data: {}

View File

@@ -1,27 +1,27 @@
version: '3.8' version: '3.8'
services: services:
rlcraft: mc:
image: itzg/minecraft-server:java8 image: itzg/minecraft-server:java8
container_name: rlcraft
volumes: volumes:
- rlcraft-modpack:/modpacks:ro - data:/data
- rlcraft-data:/data - ./modpacks:/modpacks:ro
environment: environment:
EULA: "true" EULA: "true"
TYPE: "FORGE" TYPE: "FORGE"
VERSION: "1.12.2" VERSION: "1.12.2"
FORGEVERSION: "14.23.5.2855" FORGEVERSION: "14.23.5.2860"
OVERRIDE_SERVER_PROPERTIES: "true"
DIFFICULTY: "hard" DIFFICULTY: "hard"
MAX_TICK_TIME: "-1" MAX_TICK_TIME: "-1"
VIEW_DISTANCE: "6"
ALLOW_FLIGHT: "true" ALLOW_FLIGHT: "true"
ENABLE_COMMAND_BLOCK: "true"
VIEW_DISTANCE: "10"
MEMORY: "4G" MEMORY: "4G"
GENERIC_PACK: "/modpacks/RLCraft_Server_Pack_1.12.2_Beta_v2.8.2.zip" # Download from https://www.curseforge.com/minecraft/modpacks/rlcraft and place in modpacks subdir
GENERIC_PACK: "/modpacks/RLCraft+Server+Pack+1.12.2+-+Release+v2.9.1c.zip"
ports: ports:
- 25565:25565 - 25565:25565
restart: unless-stopped
volumes: volumes:
rlcraft-data: data:
rlcraft-modpack:

View File

@@ -3,13 +3,16 @@ version: "3"
services: services:
mc: mc:
# Only using IMAGE variable to allow for local testing # Only using IMAGE variable to allow for local testing
image: ${IMAGE:-itzg/minecraft-server} image: itzg/minecraft-server
# image: ${IMAGE:-itzg/minecraft-server}
ports: ports:
- "25565:25565" - "25565:25565"
environment: environment:
EULA: "TRUE" EULA: "TRUE"
TYPE: SPIGOT TYPE: SPIGOT
SPIGET_RESOURCES: 34315,3836 # SPIGET_RESOURCES: 34315,3836
SPIGET_RESOURCES: ""
REMOVE_OLD_MODS: "true"
volumes: volumes:
- data:/data - data:/data

View File

@@ -35,20 +35,17 @@ spec:
name: main name: main
readinessProbe: readinessProbe:
exec: exec:
command: command: [ "/usr/local/bin/mc-monitor", "status", "--host", "localhost" ]
- mcstatus # Give it i + p * f seconds to be ready, so 120 seconds
- localhost initialDelaySeconds: 20
- ping
initialDelaySeconds: 5
periodSeconds: 5 periodSeconds: 5
failureThreshold: 20
# Monitor ongoing liveness
livenessProbe: livenessProbe:
exec: exec:
command: command: ["/usr/local/bin/mc-monitor", "status", "--host", "localhost"]
- mcstatus initialDelaySeconds: 120
- localhost periodSeconds: 60
- ping
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts: volumeMounts:
- name: mc-data - name: mc-data
mountPath: /data mountPath: /data

View File

@@ -0,0 +1,21 @@
version: '3.8'
services:
mc:
image: itzg/minecraft-server:java8-multiarch
volumes:
- data:/data
- ./modpacks:/modpacks:ro
environment:
EULA: "true"
TYPE: FORGE
VERSION: "1.15.2"
GENERIC_PACK: /modpacks/Valhelsia_2-2.3.4-SERVER.zip
MEMORY: "2G"
ports:
- "25565:25565"
healthcheck:
test: NONE
volumes:
data: {}

View File

@@ -1,9 +1,12 @@
#!/bin/bash #!/bin/bash
. /autopause/autopause-fcns.sh . /auto/autopause-fcns.sh
. ${SCRIPTS:-/}start-utils
# shellcheck source=../../scripts/start-utils
. "${SCRIPTS:-/}start-utils"
if isTrue "${DEBUG_AUTOPAUSE}"; then
set -x
fi
autopause_error_loop() { autopause_error_loop() {
logAutopause "Available interfaces within the docker container:" logAutopause "Available interfaces within the docker container:"
@@ -39,7 +42,12 @@ if ! [[ -d "/sys/class/net/$AUTOPAUSE_KNOCK_INTERFACE" ]] ; then
autopause_error_loop autopause_error_loop
fi fi
sudo /usr/sbin/knockd -c /tmp/knockd-config.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
sudo /usr/sbin/knockd "${knockdArgs[@]}"
if [ $? -ne 0 ] ; then if [ $? -ne 0 ] ; then
logAutopause "Failed to start knockd daemon." logAutopause "Failed to start knockd daemon."
logAutopause "Probable cause: Unable to attach to interface \"$AUTOPAUSE_KNOCK_INTERFACE\"." logAutopause "Probable cause: Unable to attach to interface \"$AUTOPAUSE_KNOCK_INTERFACE\"."
@@ -50,12 +58,13 @@ STATE=INIT
while : while :
do do
isTrue "${DEBUG_AUTOPAUSE}" && log "DEBUG: autopause state = $STATE"
case X$STATE in case X$STATE in
XINIT) XINIT)
# Server startup # Server startup
if mc_server_listening ; then if mc_server_listening ; then
TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_INIT)) TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_INIT))
logAutopause "MC Server listening for connections - stopping in $AUTOPAUSE_TIMEOUT_INIT seconds" logAutopause "MC Server listening for connections - pausing in $AUTOPAUSE_TIMEOUT_INIT seconds"
STATE=K STATE=K
fi fi
;; ;;
@@ -66,8 +75,8 @@ do
STATE=E STATE=E
else else
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
logAutopause "No client connected since startup / knocked - stopping" logAutopause "No client connected since startup / knocked - pausing"
/autopause/pause.sh /auto/pause.sh
STATE=S STATE=S
fi fi
fi fi
@@ -76,7 +85,7 @@ do
# Established # Established
if ! java_clients_connected ; then if ! java_clients_connected ; then
TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_EST)) TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_EST))
logAutopause "All clients disconnected - stopping in $AUTOPAUSE_TIMEOUT_EST seconds" logAutopause "All clients disconnected - pausing in $AUTOPAUSE_TIMEOUT_EST seconds"
STATE=I STATE=I
fi fi
;; ;;
@@ -87,8 +96,8 @@ do
STATE=E STATE=E
else else
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
logAutopause "No client reconnected - stopping" logAutopause "No client reconnected - pausing"
/autopause/pause.sh /auto/pause.sh
STATE=S STATE=S
fi fi
fi fi
@@ -96,7 +105,7 @@ do
XS) XS)
# Stopped # Stopped
if rcon_client_exists ; then if rcon_client_exists ; then
/autopause/resume.sh /auto/resume.sh
fi fi
if java_running ; then if java_running ; then
if java_clients_connected ; then if java_clients_connected ; then
@@ -104,7 +113,11 @@ do
STATE=E STATE=E
else else
TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_KN)) TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_KN))
logAutopause "Server was knocked - waiting for clients or timeout" from=unknown
if [ -e /var/log/knocked-source ]; then
from=$(cat /var/log/knocked-source)
fi
logAutopause "Server was knocked from $from - waiting for clients or timeout"
STATE=K STATE=K
fi fi
fi fi
@@ -115,8 +128,8 @@ do
esac esac
if [[ "$STATE" == "S" ]] ; then if [[ "$STATE" == "S" ]] ; then
# before rcon times out # before rcon times out
sleep 2 sleep 5
else else
sleep $AUTOPAUSE_PERIOD sleep "$AUTOPAUSE_PERIOD"
fi fi
done done

View File

View File

@@ -1,9 +1,13 @@
#!/bin/bash #!/bin/bash
# needed for the clients connected function residing in autopause # needed for the clients connected function residing in autopause
. /autopause/autopause-fcns.sh . /auto/autopause-fcns.sh
. ${SCRIPTS:-/}start-utils # shellcheck source=../../scripts/start-utils
. "${SCRIPTS:-/}start-utils"
if isTrue "${DEBUG_AUTOSTOP}"; then
set -x
fi
# wait for java process to be started # wait for java process to be started
while : while :
@@ -18,11 +22,12 @@ STATE=INIT
while : while :
do do
isTrue "${DEBUG_AUTOSTOP}" && log "DEBUG: autostop state = $STATE"
case X$STATE in case X$STATE in
XINIT) XINIT)
# Server startup # Server startup
if mc_server_listening ; then if mc_server_listening ; then
TIME_THRESH=$(($(current_uptime)+$AUTOSTOP_TIMEOUT_INIT)) TIME_THRESH=$(($(current_uptime)+AUTOSTOP_TIMEOUT_INIT))
logAutostop "MC Server listening for connections - stopping in $AUTOSTOP_TIMEOUT_INIT seconds" logAutostop "MC Server listening for connections - stopping in $AUTOSTOP_TIMEOUT_INIT seconds"
STATE=II STATE=II
fi fi
@@ -35,7 +40,7 @@ do
else else
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
logAutostop "No client connected since startup - stopping server" logAutostop "No client connected since startup - stopping server"
/autostop/stop.sh /auto/stop.sh
exit 0 exit 0
fi fi
fi fi
@@ -56,7 +61,7 @@ do
else else
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
logAutostop "No client reconnected - stopping" logAutostop "No client reconnected - stopping"
/autostop/stop.sh /auto/stop.sh
exit 0 exit 0
fi fi
fi fi

View File

@@ -3,13 +3,13 @@
[unpauseMCServer-server] [unpauseMCServer-server]
sequence = 25565 sequence = 25565
seq_timeout = 1 seq_timeout = 1
command = /autopause/resume.sh command = /auto/resume.sh %IP%
tcpflags = syn tcpflags = syn
[unpauseMCServer-rcon] [unpauseMCServer-rcon]
sequence = 25575 sequence = 25575
seq_timeout = 1 seq_timeout = 1
command = /autopause/resume.sh command = /auto/resume.sh %IP%
tcpflags = syn tcpflags = syn
[unpauseMCServer-bedrock] [unpauseMCServer-bedrock]
sequence = 19132:udp sequence = 19132:udp
command = /autopause/resume.sh command = /auto/resume.sh %IP%

3
files/autopause/pause.sh → files/auto/pause.sh Executable file → Normal file
View File

@@ -1,6 +1,9 @@
#!/bin/bash #!/bin/bash
. /start-utils . /start-utils
if isTrue "${DEBUG_AUTOPAUSE}"; then
set -x
fi
if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then
# save world # save world

12
files/auto/resume.sh Normal file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
. /start-utils
if isTrue "${DEBUG_AUTOPAUSE}"; then
set -x
fi
if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then
logAutopauseAction "Knocked from $1, resuming Java process"
echo "$1" > /var/log/knocked-source
pkill -CONT java
fi

13
files/auto/stop.sh Normal file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
. /start-utils
if isTrue "${DEBUG_AUTOSTOP}"; then
set -x
fi
logAutostopAction "Stopping Java process"
if isTrue "${AUTOSTOP_PKILL_USE_SUDO:-false}"; then
sudo pkill -f --signal SIGTERM mc-server-runner
else
pkill -f --signal SIGTERM mc-server-runner
fi

View File

@@ -1,8 +0,0 @@
#!/bin/bash
. /start-utils
if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then
logAutopauseAction "Knocked, resuming Java process"
pkill -CONT java
fi

View File

@@ -1,6 +0,0 @@
#!/bin/bash
. /start-utils
logAutostopAction "Stopping Java process"
kill -SIGTERM 1

View File

@@ -10,6 +10,7 @@
: "${AUTOPAUSE_TIMEOUT_INIT:=600}" : "${AUTOPAUSE_TIMEOUT_INIT:=600}"
: "${AUTOPAUSE_PERIOD:=10}" : "${AUTOPAUSE_PERIOD:=10}"
: "${AUTOPAUSE_KNOCK_INTERFACE:=eth0}" : "${AUTOPAUSE_KNOCK_INTERFACE:=eth0}"
: "${DEBUG_AUTOPAUSE:=false}"
export SERVER_PORT export SERVER_PORT
export ENABLE_AUTOPAUSE export ENABLE_AUTOPAUSE
export AUTOPAUSE_TIMEOUT_EST export AUTOPAUSE_TIMEOUT_EST
@@ -17,12 +18,13 @@ export AUTOPAUSE_TIMEOUT_KN
export AUTOPAUSE_TIMEOUT_INIT export AUTOPAUSE_TIMEOUT_INIT
export AUTOPAUSE_PERIOD export AUTOPAUSE_PERIOD
export AUTOPAUSE_KNOCK_INTERFACE export AUTOPAUSE_KNOCK_INTERFACE
export DEBUG_AUTOPAUSE
log "Autopause functionality enabled" log "Autopause functionality enabled"
isDebugging && set -x isDebugging && set -x
cp /autopause/knockd-config.cfg /tmp/knockd-config.cfg cp /auto/knockd-config.cfg /tmp/knockd-config.cfg
# update server port to listen to # update server port to listen to
regseq="^\s*sequence\s*=\s*$SERVER_PORT\s*$" regseq="^\s*sequence\s*=\s*$SERVER_PORT\s*$"
@@ -82,4 +84,4 @@ elif [[ -z "$MAX_TICK_TIME" ]] ; then
export MAX_TICK_TIME export MAX_TICK_TIME
fi fi
/autopause/autopause-daemon.sh & /auto/autopause-daemon.sh &

View File

@@ -8,11 +8,13 @@
: "${AUTOSTOP_TIMEOUT_EST:=3600}" : "${AUTOSTOP_TIMEOUT_EST:=3600}"
: "${AUTOSTOP_TIMEOUT_INIT:=1800}" : "${AUTOSTOP_TIMEOUT_INIT:=1800}"
: "${AUTOSTOP_PERIOD:=10}" : "${AUTOSTOP_PERIOD:=10}"
: "${DEBUG_AUTOSTOP:=false}"
export SERVER_PORT export SERVER_PORT
export ENABLE_AUTOSTOP export ENABLE_AUTOSTOP
export AUTOSTOP_TIMEOUT_EST export AUTOSTOP_TIMEOUT_EST
export AUTOSTOP_TIMEOUT_INIT export AUTOSTOP_TIMEOUT_INIT
export AUTOSTOP_PERIOD export AUTOSTOP_PERIOD
export DEBUG_AUTOSTOP
log "Autostop functionality enabled" log "Autostop functionality enabled"
@@ -39,4 +41,4 @@ if ! [[ $AUTOSTOP_TIMEOUT_INIT =~ ^[0-9]+$ ]] ; then
log "Warning: AUTOSTOP_TIMEOUT_INIT is not numeric, set to 1800 (seconds)" log "Warning: AUTOSTOP_TIMEOUT_INIT is not numeric, set to 1800 (seconds)"
fi fi
/autostop/autostop-daemon.sh & /auto/autostop-daemon.sh &

View File

@@ -227,10 +227,6 @@ case "${TYPE^^}" in
exec "${SCRIPTS:-/}start-deployPurpur" "$@" exec "${SCRIPTS:-/}start-deployPurpur" "$@"
;; ;;
AIRPLANE)
exec "${SCRIPTS:-/}start-deployAirplane" "$@"
;;
PUFFERFISH) PUFFERFISH)
exec "${SCRIPTS:-/}start-deployPufferfish" "$@" exec "${SCRIPTS:-/}start-deployPufferfish" "$@"
;; ;;

View File

@@ -1,46 +0,0 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
set -euo pipefail
isDebugging && set -x
IFS=$'\n\t'
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "PURPUR" ] ; then
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=PURPUR."
exit 1
fi
: ${AIRPLANE_TYPE:=airplane}
if [ "${VERSION}" = "LATEST" ] ; then
AIRPLANE_TYPE="airplane"
fi
if [ "${VERSION}" = "PURPUR" ]; then
AIRPLANE_TYPE="airplanepurpur"
fi
log "Using ${AIRPLANE_TYPE} 1.17.1 (1.18 unsupported - use Paper/Pufferfish/Purpur for newer versions)"
export SERVER=${AIRPLANE_TYPE}-1.17.1.jar
log "Removing old Airplane versions ..."
shopt -s nullglob
for f in airplane*.jar; do
[[ $f != $SERVER ]] && rm $f
done
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
downloadUrl="https://airplane.gg/dl/launcher-${AIRPLANE_TYPE}1.17.1.jar"
log "Downloading Airplane from $downloadUrl ..."
if ! get -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
# Normalize on Spigot for later operations
export FAMILY=SPIGOT
exec "${SCRIPTS:-/}start-spiget" "$@"

View File

@@ -27,13 +27,16 @@ isDebugging && set -x
: "${FTB_BASE_DIR:=${CF_BASE_DIR:-/data/FeedTheBeast}}" : "${FTB_BASE_DIR:=${CF_BASE_DIR:-/data/FeedTheBeast}}"
export FTB_BASE_DIR export FTB_BASE_DIR
legacyJavaFixerUrl=https://ftb.forgecdn.net/FTB2/maven/net/minecraftforge/lex/legacyjavafixer/1.0/legacyjavafixer-1.0.jar legacyJavaFixerUrl=https://files.minecraftforge.net/maven/net/minecraftforge/lex/legacyjavafixer/1.0/legacyjavafixer-1.0.jar
export TYPE=CURSEFORGE export TYPE=CURSEFORGE
FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD} FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD}
log "Looking for Feed-The-Beast / CurseForge server modpack." log "Looking for Feed-The-Beast / CurseForge server modpack."
requireVar FTB_SERVER_MOD if [[ ! $FTB_SERVER_MOD ]]; then
log "ERROR: CF_SERVER_MOD or FTB_SERVER_MOD is required to be set"
exit 1
fi
downloadModpack() { downloadModpack() {
srv_modpack=${FTB_SERVER_MOD} srv_modpack=${FTB_SERVER_MOD}
@@ -133,31 +136,32 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
exec "${SCRIPTS:-/}start-setupWorld" "$@" exec "${SCRIPTS:-/}start-setupWorld" "$@"
fi fi
entryScriptExpr="
-name ServerStart.sh
-o -name serverstart.sh
-o -name ServerStartLinux.sh
-o -name LaunchServer.sh
-o -name server-start.sh
-o -name start-server.sh
-o -name startserver.sh
-o -name StartServer.sh
"
if [[ -d ${FTB_BASE_DIR} ]]; then findStartScript() {
startScriptCount=$(find "${FTB_BASE_DIR}" $entryScriptExpr |wc -l) entryScriptExpr=(
if (( startScriptCount > 1 )); then -name ServerStart.sh
log "Conflicting FTB/CurseForge packages have been installed. Please cleanup ${FTB_BASE_DIR}" -o -name serverstart.sh
exit 2 -o -name ServerStartLinux.sh
-o -name LaunchServer.sh
-o -name server-start.sh
-o -name start-server.sh
-o -name startserver.sh
-o -name StartServer.sh
-o -name run.sh
-o -name start.sh
)
if [ -d "${FTB_BASE_DIR}" ]; then
find "${FTB_BASE_DIR}" \( "${entryScriptExpr[@]}" \) -print -quit
fi fi
else }
startScriptCount=0
fi startScript=$(findStartScript)
# only download and install if a mod pack isn't already installed # only download and install if a mod pack isn't already installed
# also check for the start script rather than just the folder # also check for the start script rather than just the folder
# this allows saving just the world separate from the rest of the data directory # this allows saving just the world separate from the rest of the data directory
if [[ $startScriptCount = 0 ]]; then if [[ ! $startScript ]]; then
downloadModpack downloadModpack
srv_modpack=${FTB_SERVER_MOD} srv_modpack=${FTB_SERVER_MOD}
@@ -165,49 +169,61 @@ if [[ $startScriptCount = 0 ]]; then
mkdir -p "${FTB_BASE_DIR}" mkdir -p "${FTB_BASE_DIR}"
unzip -o "${srv_modpack}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}' unzip -o "${srv_modpack}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}'
installScript=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f -name install.sh) installScriptExpr=(
-name install.sh
-o -name FTBInstall.sh
-o -name Install.sh
)
installScript=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( "${installScriptExpr[@]}" \) -print -quit)
if [[ "$installScript" ]]; then if [[ "$installScript" ]]; then
( (
cd "$(dirname "${installScript}")" cd "$(dirname "${installScript}")"
chmod +x ./install.sh chmod +x "${installScript}"
log "Running included install.sh" log "Running included $(basename "${installScript}"). This might take a minute or two..."
./install.sh "${installScript}" > install.log
) )
fi fi
startScript=$(findStartScript)
fi fi
if [[ $(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l) = 0 ]]; then # start script provided by unzipped+installed modpack?
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 # Allow up to 2 levels since some modpacks have a top-level directory named for the modpack
# 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 log "No entry script found, so building one for ${forgeJar}"
log "No entry script found, so building one for ${forgeJar}" cat > "${FTB_BASE_DIR}/ServerStart.sh" <<EOF
cat > "${FTB_BASE_DIR}/ServerStart.sh" <<EOF
#!/bin/sh #!/bin/sh
. ./settings-local.sh . ./settings-local.sh
java \${JAVA_PARAMETERS} -Xmx\${MAX_RAM} -jar $(basename "${forgeJar}") nogui java \${JAVA_PARAMETERS} -Xmx\${MAX_RAM} -jar $(basename "${forgeJar}") nogui
EOF EOF
chmod +x "${FTB_BASE_DIR}/ServerStart.sh" startScript="${FTB_BASE_DIR}/ServerStart.sh"
else chmod +x "$startScript"
log "Please make sure you are using the server version of the FTB modpack!" else
exit 2 log "ERROR: Modpack missing start script and unable to find Forge jar to generate one"
fi exit 2
fi
fi fi
scriptCount=$(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l) # Modpacks that use https://github.com/BloodyMods/ServerStarter will sometimes specify an
if [[ $scriptCount = 0 ]]; then # extra subpath where all the server files get installed. Need to transplant EULA file there.
log "Please make sure you are using the server version of the FTB modpack!" serverSetupConfig=$(find "${FTB_BASE_DIR}" -type f -name server-setup-config.yaml)
exit 2 if [[ $serverSetupConfig && $serverSetupConfig != "~" ]]; then
elif (( scriptCount > 1 )); then if baseInstallPath=$(mc-image-helper yaml-path --file "$serverSetupConfig" ".install.baseInstallPath"); then
log "Ambiguous startup scripts in FTB modpack! Found:" resolvedBaseInstallPath="$(dirname "$serverSetupConfig")/${baseInstallPath}"
find "${FTB_BASE_DIR}" $entryScriptExpr mkdir -p "$resolvedBaseInstallPath"
exit 2
cp -n /data/eula.txt "${resolvedBaseInstallPath}/eula.txt"
fi
fi fi
FTB_SERVER_START=$(find "${FTB_BASE_DIR}" $entryScriptExpr) FTB_SERVER_START="$startScript"
export FTB_SERVER_START export FTB_SERVER_START
FTB_DIR=$(dirname "${FTB_SERVER_START}") FTB_DIR=$(dirname "${FTB_SERVER_START}")
@@ -226,15 +242,5 @@ if isTrue "${FTB_LEGACYJAVAFIXER}" && [ ! -e "${legacyJavaFixerPath}" ]; then
fi fi
fi fi
if [ -e "${FTB_DIR}/FTBInstall.sh" ]; then
pushd "${FTB_DIR}"
sh FTBInstall.sh
popd
elif [ -e "${FTB_DIR}/Install.sh" ]; then
pushd "${FTB_DIR}"
sh Install.sh
popd
fi
export FAMILY=FORGE export FAMILY=FORGE
exec "${SCRIPTS:-/}start-setupWorld" "$@" exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -7,6 +7,11 @@ ftbInstallMarker=".ftb-installed"
isDebugging && set -x isDebugging && set -x
set -e set -e
if [[ $(getDistro) = alpine ]]; then
log "ERROR: the FTBA installer is not supported on Alpine. Use the java8-multiarch image tag instead."
exit 1
fi
if ! [[ -v FTB_MODPACK_ID ]]; then if ! [[ -v FTB_MODPACK_ID ]]; then
log "ERROR FTB_MODPACK_ID is required with TYPE=FTB" log "ERROR FTB_MODPACK_ID is required with TYPE=FTB"
exit 1 exit 1
@@ -27,7 +32,7 @@ elif ! [[ ${FTB_MODPACK_VERSION_ID} =~ [0-9]+ ]]; then
exit 1 exit 1
fi fi
if ! [ -f "${ftbInstallMarker}" ] || [ $(cat "${ftbInstallMarker}") != "${FTB_MODPACK_ID}=${FTB_MODPACK_VERSION_ID}" ]; then if ! [ -f "${ftbInstallMarker}" ] || [ "$(cat "${ftbInstallMarker}")" != "${FTB_MODPACK_ID}=${FTB_MODPACK_VERSION_ID}" ]; then
ftbInstaller=/data/ftb-installer ftbInstaller=/data/ftb-installer
if ! [[ -f "${ftbInstaller}" ]]; then if ! [[ -f "${ftbInstaller}" ]]; then
log "Downloading FTB installer" log "Downloading FTB installer"
@@ -63,10 +68,10 @@ fabricVersion=$(jq -r '.targets|unique[] | select(.name == "fabric") | .version'
mcVersion=$(jq -r '.targets|unique[] | select(.name == "minecraft") | .version' version.json) mcVersion=$(jq -r '.targets|unique[] | select(.name == "minecraft") | .version' version.json)
variants=( variants=(
forge-${mcVersion}-${forgeVersion}.jar "forge-${mcVersion}-${forgeVersion}.jar"
forge-${mcVersion}-${forgeVersion}-universal.jar "forge-${mcVersion}-${forgeVersion}-universal.jar"
forge-${mcVersion}-${forgeVersion}-${mcVersion}-universal.jar "forge-${mcVersion}-${forgeVersion}-${mcVersion}-universal.jar"
fabric-${mcVersion}-${fabricVersion}-server-launch.jar "fabric-${mcVersion}-${fabricVersion}-server-launch.jar"
run.sh run.sh
) )
for f in "${variants[@]}"; do for f in "${variants[@]}"; do
@@ -77,10 +82,10 @@ for f in "${variants[@]}"; do
done done
if ! [ -v SERVER ]; then if ! [ -v SERVER ]; then
log "ERROR unable to locate the installed FTB server jar" log "ERROR unable to locate the installed FTB server jar"
ls *.jar log " Tried looking for ${variants[*]}"
exit 2 exit 2
fi fi
export FAMILY=FORGE export FAMILY=FORGE
exec ${SCRIPTS:-/}start-setupWorld $@ exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -6,155 +6,21 @@
. "${SCRIPTS:-$(dirname "$0")}/start-utils" . "${SCRIPTS:-$(dirname "$0")}/start-utils"
isDebugging && set -x isDebugging && set -x
get_installer() { if ! mc-image-helper install-forge \
if [[ -z $FORGE_INSTALLER_URL ]]; then --output-directory=/data \
log "Downloading $normForgeVersion" --results-file=/data/.run-forge.env \
--minecraft-version="${VANILLA_VERSION}" \
forgeFileNames=" --forge-version="${FORGEVERSION}" \
$shortForgeVersion/forge-$shortForgeVersion-installer.jar --force-reinstall="${FORCE_REINSTALL:-false}"; then
$normForgeVersion/forge-$normForgeVersion-installer.jar log "ERROR failed to install forge"
" exit 1
for fn in $forgeFileNames; do
downloadUrl=https://maven.minecraftforge.net/net/minecraftforge/forge/$fn
log "...trying $downloadUrl"
if get -o "$FORGE_INSTALLER" "$downloadUrl"; then
return
fi
done
log "Unable to locate usable URL for $normForgeVersion"
exit 2
else
log "Downloading $FORGE_INSTALLER_URL ..."
if ! get -o "$FORGE_INSTALLER" "$FORGE_INSTALLER_URL"; then
log "Failed to download from given location $FORGE_INSTALLER_URL"
exit 2
fi
fi
}
install() {
if [ ! -e "$FORGE_INSTALLER" ]; then
get_installer "$normForgeVersion" "$shortForgeVersion"
fi
# reference issue #1459
rm -f run.sh
log "Installing Forge $shortForgeVersion. This might take a minute or two..."
mkdir -p mods
tries=3
while true; do
if ! java -jar "$FORGE_INSTALLER" --installServer &> forge-installer.log; then
if ((--tries <= 0)); then
cat forge-installer.log
log "
ERROR Forge failed to install after several tries.
"
exit 1
fi
log "Install failed. Trying again..."
else
break # out of this loop
fi
done
# NOTE $shortForgeVersion will be empty if installer location was given to us
log "Finding installed server jar..."
unset -v latest
# 1.17+ ?
if [ -f /data/run.sh ]; then
latest=/data/run.sh
# else pre 1.17
else
for file in *forge*.jar; do
if ! [[ $file =~ installer ]]; then
if [[ -z $latest ]] || [[ $file -nt $latest ]]; then
latest=$file
fi
fi
done
fi
if [[ -z $latest ]]; then
log "Unable to derive server jar for Forge"
exit 2
fi
export SERVER=$latest
log "Using server $SERVER"
debug "Writing install marker at $installMarker"
echo "$SERVER" > "$installMarker"
}
resolve_versions() {
if [[ -z $FORGE_INSTALLER && -z $FORGE_INSTALLER_URL ]]; then
norm=$VANILLA_VERSION
case $VANILLA_VERSION in
*.*.*)
norm=$VANILLA_VERSION ;;
*.*)
norm=${VANILLA_VERSION}.0 ;;
esac
#################################################################################
promosUrl=http://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json
log "Checking Forge version information."
case $FORGEVERSION in
LATEST)
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" --json-value-when-missing "" "$promosUrl"); then
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
log " Refer to http://files.minecraftforge.net/ for supported versions"
exit 2
fi
;;
RECOMMENDED)
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-recommended']" --json-value-when-missing "" "$promosUrl"); then
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" --json-value-when-missing "" "$promosUrl"); then
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
log " Refer to http://files.minecraftforge.net/ for supported versions"
exit 2
fi
fi
;;
*)
FORGE_VERSION=$FORGEVERSION
;;
esac
normForgeVersion=$VANILLA_VERSION-$FORGE_VERSION-$norm
shortForgeVersion=$VANILLA_VERSION-$FORGE_VERSION
FORGE_INSTALLER="/tmp/forge-$shortForgeVersion-installer.jar"
elif [[ -z $FORGE_INSTALLER ]]; then
FORGE_INSTALLER="/tmp/forge-installer.jar"
elif [[ ! -e $FORGE_INSTALLER ]]; then
log "ERROR: the given Forge installer doesn't exist : $FORGE_INSTALLER"
exit 2
else
shortForgeVersion=$VANILLA_VERSION-${FORGE_INSTALLER_CUSTOM_VERSION:-custom}
fi
}
### main
resolve_versions
installMarker="/data/.forge-installed-$shortForgeVersion"
if [ ! -e "$installMarker" ] || isTrue "${FORCE_REINSTALL:-false}"; then
install
else
SERVER=$(cat "$installMarker")
export SERVER
if [ ! -e "$SERVER" ]; then
rm "$installMarker"
install
fi
fi fi
# grab SERVER and export it
set -a
source /data/.run-forge.env
set +a
export FAMILY=FORGE export FAMILY=FORGE
exec "${SCRIPTS:-/}start-setupWorld" "$@" exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -8,7 +8,7 @@ isDebugging && set -x
: ${LIMBO_BUILD:=LATEST} : ${LIMBO_BUILD:=LATEST}
: ${FORCE_REDOWNLOAD:=false} : ${FORCE_REDOWNLOAD:=false}
: ${LIMBO_SCHEMA_FILENAME:=default.schem} : ${LIMBO_SCHEMA_FILENAME:=default.schem}
: ${LEVEL:=Default;${LIMBO_SCHEMA_FILENAME}} : ${LEVEL:=default;${LIMBO_SCHEMA_FILENAME}}
# defaults to localhost, if this is not set # defaults to localhost, if this is not set
: ${SERVER_IP:=0.0.0.0} : ${SERVER_IP:=0.0.0.0}

View File

@@ -5,89 +5,18 @@
isDebugging && set -x isDebugging && set -x
: "${VANILLA_VERSION?}" : "${VANILLA_VERSION?}"
# stable, dev
: "${MAGMA_CHANNEL:=stable}"
if ! downloadUrl=$(get --json-path '$.link' "https://api.magmafoundation.org/api/v2/${VANILLA_VERSION}/latest"); then
magmaDownloadServer() { log "ERROR failed to locate latest Magma download for ${VANILLA_VERSION}. Is that version supported?"
url=${1?}
tagName=${2?}
markerFile=${3?}
export SERVER="/data/magma-server-${VANILLA_VERSION}.jar"
log "Downloading Magma server file for ${VANILLA_VERSION} @ ${tagName}"
if ! curl -o /data/magma-server-${VANILLA_VERSION}.jar -fsSL "$url"; then
log "ERROR failed to download Magma server from $url (status=$?)"
exit 1
fi
echo -n "$SERVER" > "$markerFile"
}
magmaHandleInstaller() {
url=${1?}
tagName=${2?}
markerFile=${3?}
installerFile="magma-installer-${VANILLA_VERSION}-${tagName}.jar"
log "Downloading Magma installer file for ${VANILLA_VERSION} @ ${tagName}"
if ! curl -o "$installerFile" -fsSL "$url"; then
log "ERROR failed to download Magma installer from $url (status=$?)"
exit 1
fi
echo "forge" > "$markerFile"
export FORGE_INSTALLER="$installerFile"
export FORGE_INSTALLER_CUSTOM_VERSION="$tagName"
# now hand off the rest to forge
exec ${SCRIPTS:-/}start-deployForge "$@"
}
latestMeta=$(curl -fsSL https://api.magmafoundation.org/api/resources/Magma/${VANILLA_VERSION}/${MAGMA_CHANNEL}/latest || exit $?)
if [ $? != 0 ]; then
log "ERROR failed to locate latest Magma info for ${VANILLA_VERSION} in channel ${MAGMA_CHANNEL} (error=$?)"
exit 1 exit 1
fi fi
tagName=$(echo "${latestMeta}" | jq -r '.tag_name') if ! SERVER=$(get --output-filename --skip-up-to-date --output /data "$downloadUrl"); then
markerFile=".magma-installed-${VANILLA_VERSION}-${tagName}" log "ERROR: failed to download Magma server jar from $downloadUrl"
if [ -f "${markerFile}" ]; then exit 1
installedTagName=$(cat "${markerFile}")
fi
if [ ! -f "${markerFile}" ]; then
if versionLessThan 1.16; then
assetType=server
else
assetType=installer
fi
assetUrl=$(echo "${latestMeta}" | jq -r ".assets | .[].browser_download_url | select(test(\"${assetType}\"))")
if [ $? != 0 ] || [ -z "$assetUrl" ]; then
log "ERROR failed to extract ${assetType} asset type for ${VANILLA_VERSION} in channel ${MAGMA_CHANNEL}"
exit 1
fi
if [[ ${assetType} = server ]]; then
magmaDownloadServer "$assetUrl" "$tagName" "$markerFile"
else
magmaHandleInstaller "$assetUrl" "$tagName" "$markerFile"
fi
else
export SERVER=$(cat "${markerFile}")
if [[ $SERVER == "forge" ]]; then
export FORGE_INSTALLER="magma-installer-${VANILLA_VERSION}-${tagName}.jar"
export FORGE_INSTALLER_CUSTOM_VERSION="$tagName"
# now hand off the rest to forge
exec ${SCRIPTS:-/}start-deployForge "$@"
fi
fi fi
export SERVER
export FAMILY=HYBRID export FAMILY=HYBRID
exec "${SCRIPTS:-/}start-setupWorld" "$@" exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -1,10 +1,39 @@
#!/bin/bash #!/bin/bash
. ${SCRIPTS:-/}start-utils # shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
set -o pipefail set -o pipefail
isDebugging && set -x handleDebugMode
if [[ $PAPER_DOWNLOAD_URL ]]; then : "${PAPER_CUSTOM_JAR:=}"
ourScript="$0"
ourArgs=("$@")
function handleMissingVersion() {
expectedVersion=${VANILLA_VERSION}
versions=$(curl -fsSL "https://papermc.io/api/v2/projects/paper" -H "accept: application/json")
if [[ $VERSION = LATEST ]]; then
tries=0
while ((tries++ < 5)); do
VANILLA_VERSION=$(echo "$versions" | jq -r ".versions[$((- tries))]")
if [[ $(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}" -H "accept: application/json" \
| jq '.builds[-1]') != null ]]; then
log "WARN: using ${VANILLA_VERSION} since that's the latest provided by PaperMC"
# re-execute the current script with the newly computed version
exec "$ourScript" "${ourArgs[@]}"
fi
done
fi
log "ERROR: ${expectedVersion} is not published by PaperMC"
log " Set VERSION to one of the following: "
log " $(echo "$versions" | jq -r '.versions | join(", ")')"
exit 1
}
if [[ $PAPER_CUSTOM_JAR ]]; then
export SERVER="$PAPER_CUSTOM_JAR"
elif [[ $PAPER_DOWNLOAD_URL ]]; then
export SERVER=$(getFilenameFromUrl "${PAPER_DOWNLOAD_URL}") export SERVER=$(getFilenameFromUrl "${PAPER_DOWNLOAD_URL}")
if [ -f "$SERVER" ]; then if [ -f "$SERVER" ]; then
@@ -23,26 +52,16 @@ else
0) 0)
;; ;;
22) 22)
versions=$(curl -fsSL "https://papermc.io/api/v2/projects/paper" -H "accept: application/json") handleMissingVersion
if [[ $VERSION = LATEST ]]; then
VANILLA_VERSION=$(echo "$versions" | jq -r '.versions[-1]')
log "WARN: using ${VANILLA_VERSION} since that's the latest provided by PaperMC"
# re-execute the current script with the newly computed version
exec "$0" "$@"
fi
log "ERROR: ${VANILLA_VERSION} is not published by PaperMC"
log " Set VERSION to one of the following: "
log " $(echo "$versions" | jq -r '.versions | join(", ")')"
exit 1
;; ;;
*) *)
echo "ERROR: unknown error while looking up PaperMC version=${VANILLA_VERSION}" echo "ERROR: unknown error while looking up PaperMC version=${VANILLA_VERSION}"
exit 1 exit 1
;; ;;
esac esac
if [ $? != 0 ]; then
echo "ERROR: failed to lookup PaperMC build from version ${VANILLA_VERSION}" if [[ $build = null ]]; then
exit 1 handleMissingVersion
fi fi
export SERVER=$(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}/builds/${build}" -H "accept: application/json" \ export SERVER=$(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}/builds/${build}" -H "accept: application/json" \

View File

@@ -8,8 +8,8 @@ isDebugging && set -x
IFS=$'\n\t' IFS=$'\n\t'
if [[ "${MAJOR_VANILLA_VERSION}" != "1.18" ]] && [[ "${MAJOR_VANILLA_VERSION}" != "1.17" ]]; then if versionLessThan 1.17; then
log "ERROR: Pufferfish server type only supports versions 1.18 or 1.17, use PUFFERFISH_BUILD to select the the correct build 47 => 1.18.1, 50 => 1.18.2 etc" log "ERROR: Pufferfish server type only supports versions 1.17, 1.18 or 1.19, use PUFFERFISH_BUILD to select the the correct build 47 => 1.18.1, 50 => 1.18.2 etc"
exit 1 exit 1
fi fi

View File

@@ -2,31 +2,51 @@
set -euo pipefail set -euo pipefail
IFS=$'\n\t' IFS=$'\n\t'
: "${PURPUR_DOWNLOAD_URL:=}"
# shellcheck source=start-utils # shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils" . "${SCRIPTS:-/}start-utils"
isDebugging && set -x isDebugging && set -x
: "${VANILLA_VERSION:?}" if [[ $PURPUR_DOWNLOAD_URL ]]; then
: "${PURPUR_BUILD:=LATEST}" export SERVER=$(getFilenameFromUrl "${PURPUR_DOWNLOAD_URL}")
: "${FORCE_REDOWNLOAD:=false}"
if [[ ${PURPUR_BUILD} == LATEST ]]; then if [ -f "$SERVER" ]; then
if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then zarg=(-z "$SERVER")
log "ERROR: Failed to locate a Purpur build for ${VANILLA_VERSION}."
log " Please check if a download is available at https://purpur.pl3x.net/downloads/"
exit 1
fi fi
fi
export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar" echo "Preparing custom Purpur jar from $PURPUR_DOWNLOAD_URL"
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then curl -fsSL -o "$SERVER" "${zarg[@]}" "${PURPUR_DOWNLOAD_URL}"
downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download" else
log "Downloading Purpur from $downloadUrl ..." : "${VANILLA_VERSION:?}"
if ! get -o "$SERVER" "$downloadUrl"; then : "${PURPUR_BUILD:=LATEST}"
log "ERROR: failed to download from $downloadUrl (status=$?)" : "${FORCE_REDOWNLOAD:=false}"
exit 3
if [[ ${PURPUR_BUILD} == LATEST ]]; then
if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then
log "ERROR: Failed to locate a Purpur build for ${VANILLA_VERSION}."
log " Please check if a download is available at https://purpur.pl3x.net/downloads/"
exit 1
fi fi
fi
export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar"
log "Removing old Purpur versions ..."
shopt -s nullglob
for f in purpur-*.jar; do
[[ $f != "$SERVER" ]] && rm "$f"
done
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
log "Downloading Purpur from $downloadUrl ..."
if ! get -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
fi fi
# Normalize on Spigot for later operations # Normalize on Spigot for later operations

View File

@@ -1,5 +1,8 @@
#!/bin/bash #!/bin/bash
: "${DEBUG_EXEC:=false}"
: "${SETUP_ONLY:=false}"
# shellcheck source=start-utils # shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils" . "${SCRIPTS:-/}start-utils"
isDebugging && set -x isDebugging && set -x
@@ -83,7 +86,7 @@ if isTrue ${ENABLE_ROLLING_LOGS:-false}; then
LOGFILE="/data/log4j2.xml" LOGFILE="/data/log4j2.xml"
if [ ! -e "$LOGFILE" ]; then if [ ! -e "$LOGFILE" ]; then
log "Creating log4j2.xml in ${LOGFILE}" log "Creating log4j2.xml in ${LOGFILE}"
cp /tmp/log4j2.xml "$LOGFILE" cp /image/log4j2.xml "$LOGFILE"
else else
log "log4j2.xml already created, skipping" log "log4j2.xml already created, skipping"
fi fi
@@ -122,8 +125,8 @@ if [ -n "$JVM_DD_OPTS" ]; then
done done
fi fi
if isTrue ${ENABLE_JMX}; then if isTrue "${ENABLE_JMX}"; then
: ${JMX_PORT:=7091} : "${JMX_PORT:=7091}"
JVM_OPTS="${JVM_OPTS} JVM_OPTS="${JVM_OPTS}
-Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.port=${JMX_PORT} -Dcom.sun.management.jmxremote.port=${JMX_PORT}
@@ -186,6 +189,12 @@ if isTrue "${USE_FLARE_FLAGS}"; then
" "
fi fi
if isTrue "${USE_SIMD_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
--add-modules=jdk.incubator.vector
"
fi
if isTrue "${DEBUG_MEMORY}"; then if isTrue "${DEBUG_MEMORY}"; then
log "Memory usage and availability (in MB)" log "Memory usage and availability (in MB)"
uname -a uname -a
@@ -208,7 +217,7 @@ function copyFilesForCurseForge() {
[ -f /data/ops.txt ] && cp -f /data/ops.txt "${FTB_DIR}/" [ -f /data/ops.txt ] && cp -f /data/ops.txt "${FTB_DIR}/"
[ -f /data/white-list.txt ] && cp -f /data/white-list.txt "${FTB_DIR}/" [ -f /data/white-list.txt ] && cp -f /data/white-list.txt "${FTB_DIR}/"
if [ ! -e "${FTB_DIR}/server-icon.png" -a -e /data/server-icon.png ]; then if [ ! -e "${FTB_DIR}/server-icon.png" ] && [ -e /data/server-icon.png ]; then
cp -f /data/server-icon.png "${FTB_DIR}/" cp -f /data/server-icon.png "${FTB_DIR}/"
fi fi
@@ -228,10 +237,10 @@ if [[ ${TYPE} == "CURSEFORGE" && "${SERVER}" ]]; then
cd "${FTB_DIR}" || (log "ERROR: can't go into ${FTB_DIR}"; exit 1) cd "${FTB_DIR}" || (log "ERROR: can't go into ${FTB_DIR}"; exit 1)
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
fi fi
exec mc-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 elif [[ ${TYPE} == "CURSEFORGE" ]]; then
mcServerRunnerArgs+=(--shell bash) mcServerRunnerArgs+=(--shell bash)
@@ -253,15 +262,15 @@ EOF
finalArgs="${FTB_SERVER_START}" finalArgs="${FTB_SERVER_START}"
if isTrue "${SETUP_ONLY:=false}"; then if isTrue "${SETUP_ONLY}"; then
echo "SETUP_ONLY: ${finalArgs}" echo "SETUP_ONLY: ${finalArgs}"
exit exit
fi fi
if isTrue ${DEBUG_EXEC}; then if isTrue "${DEBUG_EXEC}"; then
set -x set -x
fi fi
if isTrue ${EXEC_DIRECTLY:-false}; then if isTrue "${EXEC_DIRECTLY:-false}"; then
"${finalArgs[@]}" "${finalArgs[@]}"
else else
exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}" exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}"
@@ -269,7 +278,7 @@ EOF
elif [[ $SERVER =~ run.sh ]]; then elif [[ $SERVER =~ run.sh ]]; then
log "Using Forge supplied run.sh script..." log "Using Forge supplied run.sh script..."
echo $JVM_XX_OPTS $JVM_OPTS $expandedDOpts > user_jvm_args.txt echo $JVM_XX_OPTS $JVM_OPTS $expandedDOpts > user_jvm_args.txt
if isTrue ${SETUP_ONLY:=false}; then if isTrue ${SETUP_ONLY}; then
echo "SETUP_ONLY: bash ${SERVER}" echo "SETUP_ONLY: bash ${SERVER}"
exit exit
fi fi
@@ -290,7 +299,7 @@ else
"$@" $EXTRA_ARGS "$@" $EXTRA_ARGS
) )
if isTrue ${SETUP_ONLY:=false}; then if isTrue ${SETUP_ONLY}; then
echo "SETUP_ONLY: java ${finalArgs[*]}" echo "SETUP_ONLY: java ${finalArgs[*]}"
exit exit
fi fi

View File

@@ -33,4 +33,4 @@ if [ "$RCON_CMDS_PERIOD" -eq "0" ] ; then
log "Warning: RCON_CMDS_PERIOD must not be 0, set to 10 (seconds)" log "Warning: RCON_CMDS_PERIOD must not be 0, set to 10 (seconds)"
fi fi
/rconcmds/rcon-cmds-daemon.sh & /usr/local/bin/rcon-cmds-daemon.sh &

View File

@@ -17,7 +17,7 @@ set -e
if isTrue "${REPLACE_ENV_IN_PLACE}"; then if isTrue "${REPLACE_ENV_IN_PLACE}"; then
log "Replacing env variables in ${REPLACE_ENV_PATHS} that match the prefix $REPLACE_ENV_VARIABLE_PREFIX ..." log "Replacing env variables in ${REPLACE_ENV_PATHS} that match the prefix $REPLACE_ENV_VARIABLE_PREFIX ..."
mc-image-helper --debug=${DEBUG} interpolate \ mc-image-helper interpolate \
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \ --replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \ --replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \ --replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
@@ -27,7 +27,7 @@ fi
if [[ ${PATCH_DEFINITIONS} ]]; then if [[ ${PATCH_DEFINITIONS} ]]; then
log "Applying patch definitions from ${PATCH_DEFINITIONS}" log "Applying patch definitions from ${PATCH_DEFINITIONS}"
mc-image-helper --debug=${DEBUG} patch \ mc-image-helper patch \
--patch-env-prefix="${REPLACE_ENV_VARIABLE_PREFIX}" \ --patch-env-prefix="${REPLACE_ENV_VARIABLE_PREFIX}" \
"${PATCH_DEFINITIONS}" "${PATCH_DEFINITIONS}"
fi fi

View File

@@ -10,7 +10,7 @@ set -e -o pipefail
: "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES:=false}" : "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES:=false}"
: "${MODS_FORGEAPI_IGNORE_GAMETYPE:=false}" : "${MODS_FORGEAPI_IGNORE_GAMETYPE:=false}"
: "${REMOVE_OLD_MODS_DEPTH:=1} " : "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar}" : "${REMOVE_OLD_MODS_INCLUDE:=*.jar,*-version.json}"
# FORGEAPI_BASE_URL used in manifest downloads below # FORGEAPI_BASE_URL used in manifest downloads below
FORGEAPI_BASE_URL=${FORGEAPI_BASE_URL:-https://api.curseforge.com/v1} FORGEAPI_BASE_URL=${FORGEAPI_BASE_URL:-https://api.curseforge.com/v1}
@@ -118,7 +118,7 @@ modFileByProjectID(){
# Looks for file by name # Looks for file by name
current_project_file=$(jq -n "$project_files" | jq --arg FILE_NAME "$project_id_file_name" -jc ' current_project_file=$(jq -n "$project_files" | jq --arg FILE_NAME "$project_id_file_name" -jc '
.data | map(select(.fileName<=($FILE_NAME))) | .[0] // empty') .data | map(select(.fileName<=($FILE_NAME))) | .[0] // empty')
elif $( ! isTrue "$MODS_FORGEAPI_IGNORE_GAMETYPE" ) && $FILTER_BY_FAMILY ; then elif isFalse "${MODS_FORGEAPI_IGNORE_GAMETYPE}" && $FILTER_BY_FAMILY ; then
# Looks for file by version and server type in lowercase # Looks for file by version and server type in lowercase
current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" --arg GAME_TYPE "${FAMILY,,}" --arg VERSION "$VANILLA_VERSION" -jc ' current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" --arg GAME_TYPE "${FAMILY,,}" --arg VERSION "$VANILLA_VERSION" -jc '
.data | sort_by(.id) | reverse | map(select(.gameVersions[] | ascii_downcase | contains ($GAME_TYPE))) | map(select(.gameVersions[] | contains ($VERSION))) | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0] // empty') .data | sort_by(.id) | reverse | map(select(.gameVersions[] | ascii_downcase | contains ($GAME_TYPE))) | map(select(.gameVersions[] | contains ($VERSION))) | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0] // empty')
@@ -160,7 +160,7 @@ downloadModPackfromModFile() {
fi fi
# trys to make the output directory incase it doesnt exist. # trys to make the output directory incase it doesnt exist.
mkdir -p "$out_dir" mkdir -p "$out_dir"
debug "DEBUG: PROJECT_FILE: ${PROJECT_FILE}"
# grabs needed values from our json return # grabs needed values from our json return
file_name=$(jq -n "$PROJECT_FILE" | jq -jc '.fileName // empty' ) file_name=$(jq -n "$PROJECT_FILE" | jq -jc '.fileName // empty' )
download_url=$(jq -n "$PROJECT_FILE" | jq -jc '.downloadUrl // empty' ) download_url=$(jq -n "$PROJECT_FILE" | jq -jc '.downloadUrl // empty' )
@@ -204,9 +204,10 @@ if [ "$MODS_FORGEAPI_FILE" ] && [ -z "$MODS_FORGEAPI_PROJECTIDS" ]; then
log "ERROR: given MODS_FORGEAPI_FILE file does not exist" log "ERROR: given MODS_FORGEAPI_FILE file does not exist"
exit 2 exit 2
fi fi
debug "DEBUG: MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_FILE}"
# Needs loop here to look up release types befor calling download. # Needs loop here to look up release types befor calling download.
while read -r current_project; do while read -r current_project; do
debug "DEBUG: current_project: ${current_project}"
# Per stack overflow we can use //empty to return empty string that works with -z # Per stack overflow we can use //empty to return empty string that works with -z
project_id=$(jq -n "$current_project" | jq -r '.projectId // empty' ) project_id=$(jq -n "$current_project" | jq -r '.projectId // empty' )
current_release_type=$(jq -n "$current_project" | jq -r '.releaseType // empty' ) current_release_type=$(jq -n "$current_project" | jq -r '.releaseType // empty' )

View File

@@ -5,7 +5,7 @@ set -e -o pipefail
: "${REMOVE_OLD_MODS:=false}" : "${REMOVE_OLD_MODS:=false}"
: "${MODS_FILE:=}" : "${MODS_FILE:=}"
: "${REMOVE_OLD_MODS_DEPTH:=1} " : "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar}" : "${REMOVE_OLD_MODS_INCLUDE:=*.jar,*-version.json}"
sum_file=/data/.generic_pack.sum sum_file=/data/.generic_pack.sum
# shellcheck source=start-utils # shellcheck source=start-utils
@@ -22,31 +22,26 @@ if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
rm -f "$sum_file" rm -f "$sum_file"
fi fi
# If packwiz url passed, bootstrap packwiz and update mods before other modpack processing function handlePackwiz() {
if [[ "${PACKWIZ_URL}" ]]; then # If packwiz url passed, bootstrap packwiz and update mods before other modpack processing
# Ensure we have the latest packwiz bootstrap installer if [[ "${PACKWIZ_URL:-}" ]]; then
latestPackwiz=$(curl -fsSL https://api.github.com/repos/packwiz/packwiz-installer-bootstrap/releases/latest) if ! packwizInstaller=$(mc-image-helper maven-download \
if [[ -z "${latestPackwiz}" ]]; then --maven-repo=https://maven.packwiz.infra.link/repository/release/ \
log "WARNING: Could not retrieve Packwiz bootstrap installer release information" --group=link.infra.packwiz --artifact=packwiz-installer --classifier=dist \
else --skip-existing); then
isDebugging && log "Latest packwiz ${latestPackwiz}" log "ERROR: failed to get packwiz installer"
latestPackwizVer=$(echo ${latestPackwiz} | jq --raw-output '.tag_name') exit 1
latestPackwizUrl=$(echo ${latestPackwiz} | jq --raw-output '.assets[] | select(.name | match("packwiz-installer-bootstrap.jar")) | .url') fi
: "${PACKWIZ_JAR:=packwiz-installer-bootstrap_${latestPackwizVer}.jar}"
if [[ ! -e $PACKWIZ_JAR ]]; then log "Running packwiz installer against URL: ${PACKWIZ_URL}"
log "Downloading Packwiz ${latestPackwizVer}" if ! java -cp "${packwizInstaller}" link.infra.packwiz.installer.Main -s server "${PACKWIZ_URL}"; then
curl -H "Accept:application/octet-stream" -o "$PACKWIZ_JAR" -fsSL ${latestPackwizUrl} log "ERROR failed to run packwiz installer"
ln -sf "${PACKWIZ_JAR}" packwiz-installer-bootstrap.jar exit 1
fi fi
fi fi
if [[ ! -e packwiz-installer-bootstrap.jar ]]; then }
log "ERROR: Packwiz not available or could not be downloaded from Github!"
exit 1
fi
log "Running packwiz against URL: ${PACKWIZ_URL}"
java -jar packwiz-installer-bootstrap.jar -g -s server "${PACKWIZ_URL}"
fi
function handleModpackListOrFile() {
# If supplied with a URL for a modpack (simple zip of jars), download it and unpack # If supplied with a URL for a modpack (simple zip of jars), download it and unpack
if [[ "$MODPACK" ]]; then if [[ "$MODPACK" ]]; then
if isURL "${MODPACK}"; then if isURL "${MODPACK}"; then
@@ -141,13 +136,15 @@ elif [[ "$MODS_FILE" ]]; then
exit 1 exit 1
fi fi
fi fi
}
function handleCurseForgeManifest() {
if [[ "$MANIFEST" ]]; then if [[ "$MANIFEST" ]]; then
if [[ -e "$MANIFEST" ]]; then if [[ -e "$MANIFEST" ]]; then
EFFECTIVE_MANIFEST_FILE=$MANIFEST EFFECTIVE_MANIFEST_FILE=$MANIFEST
elif isURL "$MANIFEST"; then elif isURL "$MANIFEST"; then
EFFECTIVE_MANIFEST_FILE=/tmp/manifest.json EFFECTIVE_MANIFEST_FILE=/tmp/manifest.json
EFFECTIVE_MANIFEST_URL=$(curl -Ls -o /dev/null -w %{effective_url} $MANIFEST) EFFECTIVE_MANIFEST_URL=$(curl -Ls -o /dev/null -w "%{effective_url}" "$MANIFEST")
curl -Ls -o $EFFECTIVE_MANIFEST_FILE "$EFFECTIVE_MANIFEST_URL" curl -Ls -o $EFFECTIVE_MANIFEST_FILE "$EFFECTIVE_MANIFEST_URL"
else else
log "MANIFEST='$MANIFEST' is not a valid manifest url or location" log "MANIFEST='$MANIFEST' is not a valid manifest url or location"
@@ -164,11 +161,11 @@ case "X$EFFECTIVE_MANIFEST_FILE" in
mkdir -p "$MOD_DIR" mkdir -p "$MOD_DIR"
fi fi
log "Starting manifest download..." log "Starting manifest download..."
cat "${EFFECTIVE_MANIFEST_FILE}" | jq -r '.files[] | (.projectID|tostring) + " " + (.fileID|tostring)'| while read -r p f jq -r '.files[] | (.projectID|tostring) + " " + (.fileID|tostring)' "${EFFECTIVE_MANIFEST_FILE}" | while read -r p f
do do
if [ ! -f $MOD_DIR/${p}_${f}.jar ] if [ ! -f $MOD_DIR/${p}_${f}.jar ]
then then
redirect_url="$(curl -Ls -o /dev/null -w %{effective_url} ${CURSE_URL_BASE}/${p})" redirect_url="$(curl -Ls -o /dev/null -w "%{effective_url}" "${CURSE_URL_BASE}/${p}")"
url="$redirect_url/download/${f}/file" url="$redirect_url/download/${f}/file"
log Downloading curseforge mod $url log Downloading curseforge mod $url
# Manifest usually doesn't have mod names. Using id should be fine, tho # Manifest usually doesn't have mod names. Using id should be fine, tho
@@ -184,74 +181,114 @@ case "X$EFFECTIVE_MANIFEST_FILE" in
;; ;;
esac esac
fi fi
}
: "${GENERIC_PACKS:=${GENERIC_PACK}}" function genericPacks() {
: "${GENERIC_PACKS_PREFIX:=}" : "${GENERIC_PACKS:=${GENERIC_PACK}}"
: "${GENERIC_PACKS_SUFFIX:=}" : "${GENERIC_PACKS_PREFIX:=}"
: "${GENERIC_PACKS_SUFFIX:=}"
if [[ "${GENERIC_PACKS}" ]]; then if [[ "${GENERIC_PACKS}" ]]; then
IFS=',' read -ra packs <<< "${GENERIC_PACKS}" IFS=',' read -ra packs <<< "${GENERIC_PACKS}"
packFiles=() packFiles=()
for packEntry in "${packs[@]}"; do for packEntry in "${packs[@]}"; do
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}" pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
if isURL "${pack}"; then if isURL "${pack}"; then
mkdir -p /data/packs mkdir -p /data/packs
log "Downloading generic pack from $pack" log "Downloading generic pack from $pack"
if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
log "ERROR: failed to download $pack" log "ERROR: failed to download $pack"
exit 2 exit 2
fi
packFiles+=("$outfile")
else
packFiles+=("$pack")
fi fi
packFiles+=("$outfile")
else
packFiles+=("$pack")
fi
done
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
log "Checking if generic packs are up to date"
if isTrue "${SKIP_GENERIC_PACK_UPDATE_CHECK:-false}" && [ -f "$sum_file" ]; then
log "Skipping generic pack update check"
elif isTrue "${FORCE_GENERIC_PACK_UPDATE}" || ! checkSum "${sum_file}"; then
log "Generic pack(s) are out of date. Re-applying..."
base_dir=/tmp/generic_pack_base
mkdir -p ${base_dir}
for pack in "${packFiles[@]}"; do
isDebugging && ls -l "${pack}"
extract "${pack}" "${base_dir}"
done done
# recalculate the actual base directory of content isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
base_dir=$(find "$base_dir" -type d \( -name mods -o -name plugins -o -name config \) -printf '%h' -quit)
if [[ ! $base_dir ]]; then log "Checking if generic packs are up to date"
log "ERROR: Unable to find content base of generic packs ${GENERIC_PACKS}. Directories:" if isTrue "${SKIP_GENERIC_PACK_UPDATE_CHECK:-false}" && [ -f "$sum_file" ]; then
find /tmp/generic_pack_base -type d -printf ' - %P\n' log "Skipping generic pack update check"
exit 1 elif isTrue "${FORCE_GENERIC_PACK_UPDATE}" || ! checkSum "${sum_file}"; then
log "Generic pack(s) are out of date. Re-applying..."
original_base_dir=/data/.tmp/generic_pack_base
base_dir=$original_base_dir
rm -rf "${base_dir}"
mkdir -p "${base_dir}"
for pack in "${packFiles[@]}"; do
isDebugging && ls -l "${pack}"
extract "${pack}" "${base_dir}"
done
# recalculate the actual base directory of content
if ! base_dir=$(mc-image-helper find \
--max-depth=3 --type=directory --name=mods,plugins,config \
--only-shallowest --fail-no-matches --format '%h' \
"$base_dir"); then
log "ERROR: Unable to find content base of generic packs ${GENERIC_PACKS}. Directories:"
mc-image-helper find --name=* --max-depth=3 --type=directory --format '- %P' "$original_base_dir"
exit 1
fi
if [ -f /data/manifest.txt ]; then
log "Manifest exists from older generic pack, cleaning up ..."
while read -r f; do
rm -rf "/data/${f}"
done < /data/manifest.txt
# prune empty dirs
find /data -mindepth 1 -depth -type d -empty -delete
rm -f /data/manifest.txt
fi
log "Writing generic pack manifest ... "
find "${base_dir}" -type f -printf "%P\n" > /data/manifest.txt
log "Applying generic pack ..."
cp -R -f "${base_dir}"/* /data
rm -rf $original_base_dir
log "Saving generic pack(s) checksum"
sha1sum "${packFiles[@]}" > "${sum_file}"
if isDebugging; then
cat "$sum_file"
fi
fi fi
if [ -f /data/manifest.txt ]; then
log "Manifest exists from older generic pack, cleaning up ..."
while read -r f; do
rm -rf "/data/${f}"
done < /data/manifest.txt
# prune empty dirs
find /data -mindepth 1 -depth -type d -empty -delete
rm -f /data/manifest.txt
fi
log "Writing generic pack manifest ... "
find "${base_dir}" -type f -printf "%P\n" > /data/manifest.txt
log "Applying generic pack ..."
cp -R -f "${base_dir}"/* /data
rm -rf /tmp/generic_pack_base
log "Saving generic pack(s) checksum"
sha1sum "${packFiles[@]}" > "${sum_file}"
isDebugging && cat "$sum_file"
fi fi
fi }
function modrinthProjects() {
: "${MODRINTH_PROJECTS:=}"
: "${MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES:=true}"
: "${MODRINTH_ALLOWED_VERSION_TYPE:=release}"
if [[ $MODRINTH_PROJECTS ]] && isFamily HYBRID FORGE FABRIC; then
if isFamily HYBRID FORGE; then
loader=forge
else
loader="${FAMILY,,}"
fi
mc-image-helper modrinth \
--output-directory=/data \
--projects="${MODRINTH_PROJECTS}" \
--game-version="${VANILLA_VERSION}" \
--loader="$loader" \
--download-optional-dependencies="$MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES" \
--allowed-version-type="$MODRINTH_ALLOWED_VERSION_TYPE"
fi
}
handlePackwiz
handleModpackListOrFile
handleCurseForgeManifest
genericPacks
modrinthProjects
exec "${SCRIPTS:-/}start-setupModconfig" "$@" exec "${SCRIPTS:-/}start-setupModconfig" "$@"

View File

@@ -30,7 +30,7 @@ if [ -d /plugins ]; then
mkdir -p /data/plugins mkdir -p /data/plugins
log "Copying plugins over..." log "Copying plugins over..."
mc-image-helper \ mc-image-helper \
--debug=${DEBUG} ${subcommand} $updateArg \ ${subcommand} $updateArg \
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \ --replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \ --replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \ --replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
@@ -46,7 +46,7 @@ fi
if [ -d /mods ]; then if [ -d /mods ]; then
log "Copying any mods over..." log "Copying any mods over..."
mc-image-helper \ mc-image-helper \
--debug=${DEBUG} ${subcommand} $updateArg \ ${subcommand} $updateArg \
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \ --replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \ --replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \ --replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
@@ -59,7 +59,7 @@ fi
if [ -d /config ]; then if [ -d /config ]; then
log "Copying any configs from /config to ${COPY_CONFIG_DEST}" log "Copying any configs from /config to ${COPY_CONFIG_DEST}"
mc-image-helper \ mc-image-helper \
--debug=${DEBUG} ${subcommand} $updateArg \ ${subcommand} $updateArg \
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \ --replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \ --replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \ --replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \

View File

@@ -15,11 +15,16 @@ function setServerPropValue {
TRUE|FALSE) TRUE|FALSE)
value=${value,,} ;; value=${value,,} ;;
esac esac
if grep "${prop}" "$SERVER_PROPERTIES" > /dev/null; then if [[ $prop =~ password ]]; then
log "Setting ${prop} to '${value}' in ${SERVER_PROPERTIES}" showValue="*****"
else
showValue="$value"
fi
if [ -f "$SERVER_PROPERTIES" ] && grep "${prop}" "$SERVER_PROPERTIES" > /dev/null; then
debug "Setting ${prop} to '${showValue}' in ${SERVER_PROPERTIES}"
sed -i "/^${prop}\s*=/ c ${prop}=${value//\\/\\\\}" "$SERVER_PROPERTIES" sed -i "/^${prop}\s*=/ c ${prop}=${value//\\/\\\\}" "$SERVER_PROPERTIES"
else else
log "Adding ${prop} with '${value}' in ${SERVER_PROPERTIES}" debug "Adding ${prop} with '${showValue}' in ${SERVER_PROPERTIES}"
echo "${prop}=${value}" >> "$SERVER_PROPERTIES" echo "${prop}=${value}" >> "$SERVER_PROPERTIES"
fi fi
} }
@@ -38,13 +43,11 @@ function customizeServerProps {
if [ -n "$WHITELIST" ] || [ -n "$WHITELIST_FILE" ] || isTrue "${ENABLE_WHITELIST:-false}"; then if [ -n "$WHITELIST" ] || [ -n "$WHITELIST_FILE" ] || isTrue "${ENABLE_WHITELIST:-false}"; then
log "Enabling whitelist functionality" log "Enabling whitelist functionality"
setServerPropValue "white-list" "true" setServerPropValue "white-list" "true"
setServerPropValue "enforce-whitelist" "true"
else else
log "Disabling whitelist functionality" log "Disabling whitelist functionality"
setServerPropValue "white-list" "false" setServerPropValue "white-list" "false"
fi setServerProp "enforce-whitelist" ENFORCE_WHITELIST
setServerProp "enforce-whitelist" ENFORCE_WHITELIST
if [[ $(grep "enforce-whitelist" $SERVER_PROPERTIES) != *true ]]; then
log "WARNING: whitelist enabled but not enforced. Set ENFORCE_WHITELIST=TRUE or update 'enforce-whitelist' in server.properties to enforce the whitelist."
fi fi
# If not provided, generate a reasonable default message-of-the-day, # If not provided, generate a reasonable default message-of-the-day,
@@ -116,6 +119,8 @@ function customizeServerProps {
setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS
setServerProp "use-native-transport" USE_NATIVE_TRANSPORT setServerProp "use-native-transport" USE_NATIVE_TRANSPORT
setServerProp "simulation-distance" SIMULATION_DISTANCE setServerProp "simulation-distance" SIMULATION_DISTANCE
setServerProp "previews-chat" PREVIEWS_CHAT
setServerProp "enforce-secure-profile" ENFORCE_SECURE_PROFILE
setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)" setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)"
[[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}" [[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}"
@@ -205,12 +210,12 @@ fi
if ! isTrue "${SKIP_SERVER_PROPERTIES:-false}"; then if ! isTrue "${SKIP_SERVER_PROPERTIES:-false}"; then
if [ ! -e "$SERVER_PROPERTIES" ]; then if [ ! -e "$SERVER_PROPERTIES" ]; then
log "Creating server.properties in ${SERVER_PROPERTIES}" log "Creating server properties in ${SERVER_PROPERTIES}"
cp /tmp/server.properties "$SERVER_PROPERTIES"
customizeServerProps customizeServerProps
elif [ -n "${OVERRIDE_SERVER_PROPERTIES}" ]; then elif [ -n "${OVERRIDE_SERVER_PROPERTIES}" ]; then
case ${OVERRIDE_SERVER_PROPERTIES^^} in case ${OVERRIDE_SERVER_PROPERTIES^^} in
TRUE|1) TRUE|1)
log "Updating server properties in ${SERVER_PROPERTIES}"
customizeServerProps customizeServerProps
;; ;;
*) *)
@@ -225,15 +230,17 @@ else
fi fi
if isTrue "${ENABLE_AUTOPAUSE}"; then if isTrue "${ENABLE_AUTOPAUSE}"; then
current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' ) if [ -f "$SERVER_PROPERTIES" ]; then
if (( current_max_tick > 0 && current_max_tick < 86400000 )); then current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' )
log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled." if (( current_max_tick > 0 && current_max_tick < 86400000 )); then
log "Warning (cont): Autopause functionality resuming the process might trigger the Watchdog and restart the server completely." log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled."
log "Warning (cont): Set the max-tick-time property to a high value (or disable the Watchdog with value -1 for versions 1.8.1+)." log " Autopause functionality resuming the process might trigger the Watchdog and restart the server completely."
log " Set the MAX_TICK_TIME env variable (or max-tick-time property) to a high value (or disable the Watchdog with value -1 for versions 1.8.1+)."
fi
fi fi
fi fi
if isDebugging && [ -f "${SERVER_PROPERTIES}" ]; then if isTrue "${DUMP_SERVER_PROPERTIES:-false}"; then
log "DEBUG Dumping server.properties" log "DEBUG Dumping server.properties"
cat "${SERVER_PROPERTIES}" cat "${SERVER_PROPERTIES}"
fi fi

View File

@@ -2,125 +2,18 @@
set -e -o pipefail set -e -o pipefail
: "${REMOVE_OLD_VANILLATWEAKS:=false}"
: "${VANILLATWEAKS_FILE:=}" : "${VANILLATWEAKS_FILE:=}"
: "${VANILLATWEAKS_SHARECODE:=}" : "${VANILLATWEAKS_SHARECODE:=}"
: "${REMOVE_OLD_VANILLATWEAKS_DEPTH:=1} "
: "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:=*.zip}"
# shellcheck source=start-utils # shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils" . "${SCRIPTS:-/}start-utils"
isDebugging && set -x
VT_VERSION="" if [[ ${VANILLATWEAKS_FILE} || ${VANILLATWEAKS_SHARECODE} ]]; then
DATAPACKS_DIR="/data/${LEVEL:-world}/datapacks" mc-image-helper vanillatweaks \
RESOURCEPACKS_DIR="/data/resourcepacks" --output-directory="/data" \
--world-subdir="${LEVEL:-world}" \
# Remove old VANILLATWEAKS --share-codes="$VANILLATWEAKS_SHARECODE" \
if isTrue "${REMOVE_OLD_VANILLATWEAKS}"; then --pack-files="$VANILLATWEAKS_FILE"
# NOTE: datapacks include crafting tweaks.
if [ -d "$DATAPACKS_DIR" ]; then
find "$DATAPACKS_DIR" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
fi
if [ -d "$RESOURCEPACKS_DIR" ]; then
find "$RESOURCEPACKS_DIR" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
fi
fi
# Gets the download url and downloads the actual files.
getUrlAndDownload(){
VT_FILE=$1
URL_SUFFIX=$2
OUTPUT_FILE=$3
PACKS=$(jq -jc '.packs // empty' $VT_FILE)
if [ ! "$PACKS" ]; then
log "ERROR: unable to retrieve ${URL_SUFFIX} from ${VT_FILE}"
exit 2
fi
ZIPDATA_URL="https://vanillatweaks.net/assets/server/zip${URL_SUFFIX}.php"
DOWNLOAD_URL=$(curl -X POST -F "packs=${PACKS}" -F "version=${VT_VERSION}" $ZIPDATA_URL | jq -r '.link // empty')
if [ ! "$DOWNLOAD_URL" ]; then
log "ERROR: unable to retrieve ${URL_SUFFIX} packs from vanillatweaks.net!"
exit 2
fi
if ! get -o $OUTPUT_FILE "https://vanillatweaks.net${DOWNLOAD_URL}"; then
log "ERROR: failed to download ${URL_SUFFIX} from ${DOWNLOAD_URL}"
exit 2
fi
}
# Datapacks Handler
downloadDatapacks(){
VT_FILE=$1
URL_SUFFIX="datapacks"
OUTPUT_FILE="/tmp/vanillatweaks.zip"
getUrlAndDownload $VT_FILE $URL_SUFFIX $OUTPUT_FILE
mkdir -p "$DATAPACKS_DIR"
if ! unzip -o -d "$DATAPACKS_DIR" $OUTPUT_FILE; then
log "ERROR: failed to unzip the datapacks ${DATAPACKS} from ${OUTPUT_FILE}"
fi
rm -f $OUTPUT_FILE
}
# Crafting Tweaks Handler
downloadCraftingtweaks(){
VT_FILE=$1
mkdir -p "$DATAPACKS_DIR"
getUrlAndDownload $VT_FILE "craftingtweaks" "${DATAPACKS_DIR}/craftingtweaks.zip"
}
# Resourcepacks Handler
downloadResourcepacks(){
VT_FILE=$1
mkdir -p "$RESOURCEPACKS_DIR"
getUrlAndDownload $VT_FILE "resourcepacks" "${RESOURCEPACKS_DIR}/resourcepacks.zip"
}
# Example: VANILLATWEAKS_SHARECODE=MGr52E
# Code generated from the UI website, typically a alphanumeric 6 digit code.
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
VANILLATWEAKS_FILE=()
for SHARECODE in ${VANILLATWEAKS_SHARECODE//,/ }; do
TMP_FILE="/tmp/${SHARECODE}.json"
SHARECODE_LOOKUP_URL="https://vanillatweaks.net/assets/server/sharecode.php?code=${SHARECODE}"
if ! get -o "$TMP_FILE" "$SHARECODE_LOOKUP_URL"; then
log "ERROR: Unable to use ${SHARECODE} share code provided to retrieve vanillatweaks file"
exit 2
fi
VANILLATWEAKS_FILE+="${TMP_FILE},"
done
fi
# Use vanillatweaks file to specify VT and datapacks and crafting tweaks
if [[ "$VANILLATWEAKS_FILE" ]]; then
for VT_FILE in ${VANILLATWEAKS_FILE//,/ }; do
if [ ! -f "$VT_FILE" ]; then
log "ERROR: given VANILLATWEAKS_FILE file does not exist"
exit 2
fi
VT_VERSION=$(jq -jc '.version // empty' $VT_FILE)
if [ ! "$VT_VERSION" ]; then
log "ERROR: unable to retrieve version from $VT_FILE"
exit 2
fi
TYPE=$(jq -jc '.type // empty' $VT_FILE)
if [[ "$TYPE" = "datapacks" ]]; then
downloadDatapacks $VT_FILE
elif [[ "$TYPE" = "craftingtweaks" ]]; then
downloadCraftingtweaks $VT_FILE
elif [[ "$TYPE" = "resourcepacks" ]]; then
downloadResourcepacks $VT_FILE
fi
# cleans up temp vanilla tweaks file download to get stored packs
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
rm -f $VT_FILE
fi
done
fi fi
exec "${SCRIPTS:-/}start-setupDatapack" "$@" exec "${SCRIPTS:-/}start-setupDatapack" "$@"

View File

@@ -8,6 +8,7 @@ handleDebugMode
: "${SPIGET_RESOURCES:=}" : "${SPIGET_RESOURCES:=}"
: "${SPIGET_DOWNLOAD_TOLERANCE:=5}" # in minutes : "${SPIGET_DOWNLOAD_TOLERANCE:=5}" # in minutes
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar,*-version.json}"
acceptArgs=(--accept application/zip --accept application/java-archive --accept application/octet-stream) acceptArgs=(--accept application/zip --accept application/java-archive --accept application/octet-stream)

View File

@@ -1,5 +1,23 @@
#!/bin/bash #!/bin/bash
function get_from_gh() {
if [[ "${GH_TOKEN:-}" ]]; then
# User has provided a Personal Access Token to mitigate rate-limiting issues
if [[ -z "${oAuthScopes}" ]]; then
oAuthScopes=$(curl -s -H "Authorization: token $GH_TOKEN" https://api.github.com/users/codertocat -I | grep x-oauth-scopes)
fi
if [[ ! "$oAuthScopes" =~ ^x-oauth-scopes:[[:space:]]*$ ]]; then
# Don't use what you don't have to...
log "ERROR: GH_TOKEN has permissions it doesn't need. Recreate or update this personal access token and disable ALL scopes."
exit 1
else
curl -fsSL -H "Authorization: token $GH_TOKEN" "${@:2}" "$1"
fi
else
curl -fsSL "${@:2}" "$1"
fi
}
function join_by() { function join_by() {
local d=$1 local d=$1
shift shift
@@ -32,7 +50,7 @@ function isValidFileURL() {
function resolveEffectiveUrl() { function resolveEffectiveUrl() {
url="${1:?Missing required url argument}" url="${1:?Missing required url argument}"
if ! curl -Ls -o /dev/null -w %{url_effective} "$url"; then if ! curl -Ls -o /dev/null -w "%{url_effective}" "$url"; then
log "ERROR failed to resolve effective URL from $url" log "ERROR failed to resolve effective URL from $url"
exit 2 exit 2
fi fi
@@ -45,25 +63,25 @@ function getFilenameFromUrl() {
} }
function isTrue() { function isTrue() {
local oldState case "${1,,}" in
oldState=$(shopt -po xtrace) true | on | 1)
shopt -u -o xtrace return 0
local value=${1,,}
result=
case ${value} in
true | on)
result=0
;; ;;
*) *)
result=1 return 1
;; ;;
esac esac
}
eval "$oldState" function isFalse() {
return ${result} case "${1,,}" in
false | off | 0)
return 0
;;
*)
return 1
;;
esac
} }
function isDebugging() { function isDebugging() {
@@ -77,7 +95,6 @@ function isDebugging() {
function handleDebugMode() { function handleDebugMode() {
if isDebugging; then if isDebugging; then
set -x set -x
extraCurlArgs=(-v)
fi fi
} }
@@ -145,11 +162,16 @@ function normalizeMemSize() {
} }
function versionLessThan() { function versionLessThan() {
mc-image-helper compare-versions "${VANILLA_VERSION}" lt "${1?}" # Use if-else since strict mode might be enabled
if mc-image-helper compare-versions "${VANILLA_VERSION}" lt "${1?}"; then
return 0
else
return 1
fi
} }
requireVar() { requireVar() {
if [ ! -v $1 ]; then if [ ! -v "$1" ]; then
log "ERROR: $1 is required to be set" log "ERROR: $1 is required to be set"
exit 1 exit 1
fi fi
@@ -163,8 +185,8 @@ requireEnum() {
var=${1?} var=${1?}
shift shift
for allowed in $*; do for allowed in "$@"; do
if [[ ${!var} = $allowed ]]; then if [[ ${!var} = "$allowed" ]]; then
return 0 return 0
fi fi
done done
@@ -185,16 +207,20 @@ eula=${EULA,,}
function removeOldMods { function removeOldMods {
if [ -d "$1" ]; then if [ -d "$1" ]; then
find "$1" -mindepth 1 -maxdepth ${REMOVE_OLD_MODS_DEPTH:-16} -wholename "${REMOVE_OLD_MODS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_MODS_EXCLUDE:-}" -delete log "Removing old mods including:${REMOVE_OLD_MODS_INCLUDE} excluding:${REMOVE_OLD_MODS_EXCLUDE}"
mc-image-helper find \
--delete \
--type file,directory \
--min-depth=1 --max-depth "${REMOVE_OLD_MODS_DEPTH:-16}" \
--name "${REMOVE_OLD_MODS_INCLUDE:-*}" \
--exclude-name "${REMOVE_OLD_MODS_EXCLUDE:-}" \
--quiet \
"$1"
fi fi
} }
function get() { function get() {
local flags=() mc-image-helper get "$@"
if isTrue "${DEBUG_GET:-false}"; then
flags+=("--debug")
fi
mc-image-helper "${flags[@]}" get "$@"
} }
function get_silent() { function get_silent() {
@@ -244,9 +270,12 @@ function extract() {
application/zip) application/zip)
unzip -o -q -d "${destDir}" "${src}" unzip -o -q -d "${destDir}" "${src}"
;; ;;
application/x-tar|application/gzip|application/x-gzip|application/x-bzip2|application/zstd|application/x-zstd) application/x-tar|application/gzip|application/x-gzip|application/x-bzip2)
tar -C "${destDir}" -xf "${src}" tar -C "${destDir}" -xf "${src}"
;; ;;
application/zstd|application/x-zstd)
tar -C "${destDir}" --use-compress-program=unzstd -xf "${src}"
;;
*) *)
log "ERROR: unsupported archive type: $type" log "ERROR: unsupported archive type: $type"
return 1 return 1
@@ -255,7 +284,7 @@ function extract() {
} }
function getDistro() { function getDistro() {
cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | sed -e 's/"//g' grep -E "^ID=" /etc/os-release | cut -d= -f2 | sed -e 's/"//g'
} }
function checkSum() { function checkSum() {
@@ -263,13 +292,15 @@ function checkSum() {
# Get distro # Get distro
distro=$(getDistro) distro=$(getDistro)
if [ "${distro}" == "debian" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then if [ "${distro}" == "debian" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
return 0 return 0
elif [ "${distro}" == "ubuntu" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then elif [ "${distro}" == "ubuntu" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
return 0 return 0
elif [ "${distro}" == "alpine" ] && sha1sum -c "${sum_file}" -s 2> /dev/null; then elif [ "${distro}" == "alpine" ] && sha1sum -c "${sum_file}" -s 2> /dev/null; then
return 0 return 0
elif [ "${distro}" == "ol" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
return 0
else else
return 1 return 1
fi fi

View File

@@ -5,7 +5,7 @@ services:
depends_on: depends_on:
- mc - mc
image: itzg/mc-monitor:${MC_MONITOR_VERSION:-0.10.4} image: itzg/mc-monitor:${MC_MONITOR_VERSION:-0.10.4}
command: status --host mc --retry-interval 1s --timeout 1s --retry-limit 240 command: status --host mc --retry-interval 1s --timeout 1s --retry-limit 300
mc: mc:
restart: "no" restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server} image: ${IMAGE_TO_TEST:-itzg/minecraft-server}

View File

@@ -1,5 +1,7 @@
mc-image-helper assert fileExists world/level.dat && \ mc-image-helper assert fileExists \
mc-image-helper assert fileExists world_nether/DIM-1/some_spigot_nether_file && \ world/level.dat \
mc-image-helper assert fileExists world_the_end/DIM1/some_spigot_end_file && \ world_nether/DIM-1/some_spigot_nether_file \
! mc-image-helper assert fileExists world_nether/DIM-1/some_vanilla_nether_file && \ world_the_end/DIM1/some_spigot_end_file
! mc-image-helper assert fileExists world_the_end/DIM1/some_vanilla_end_file mc-image-helper assert fileNotExists \
world_nether/DIM-1/some_vanilla_nether_file \
world_the_end/DIM1/some_vanilla_end_file

View File

@@ -7,8 +7,13 @@ services:
environment: environment:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
WORLD: /worlds/world-for-testing.zip WORLD: /worlds/world-for-testing.zip
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes: volumes:
- ./worlds:/worlds:ro - ./worlds:/worlds:ro
- ./data:/data - ./data:/data
# the following are only used to speed up test execution
- ./verify.sh:/servers/fake.jar

View File

@@ -7,14 +7,15 @@ services:
environment: environment:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
DEBUG: "FALSE"
# Using custom to bypass Fabric setup # Using custom to bypass Fabric setup
TYPE: CUSTOM TYPE: CUSTOM
# Using family to test FORGEAPI Family filter. # Using family to test FORGEAPI Family filter.
FAMILY: FABRIC FAMILY: FABRIC
CUSTOM_SERVER: /servers/fake.jar CUSTOM_SERVER: /servers/fake.jar
VERSION: ${MINECRAFT_VERSION:-LATEST} VERSION: 1.18.2
MODS_FORGEAPI_FILE: /config/forgeapi_mods.json MODS_FORGEAPI_FILE: /config/forgeapi_mods.json
# Key is defined in .github/workflows/pr.yml and ci.yml # Key is passed by Github Workflow
# This should be coming from github secrets. # This should be coming from github secrets.
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY} MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
REMOVE_OLD_FORGEAPI_MODS: "TRUE" REMOVE_OLD_FORGEAPI_MODS: "TRUE"

View File

@@ -1,11 +1,11 @@
[{ [
"name": "On A Stick [FABRIC]", {
"projectId": "550544", "name": "Flan (Land Claim Tool)",
"releaseType": "release" "projectId": "404578"
}, },
{ {
"name": "Fabric Voice Mod", "name": "Fabric Voice Mod",
"projectId": "416089", "projectId": "416089",
"releaseType": "beta" "releaseType": "beta"
} }
] ]

View File

@@ -1,5 +1,5 @@
# Validates specific beta call out for specific mod: # Validates specific beta call out for specific mod:
mc-image-helper assert fileExists "/data/mods/voicechat-fabric*" mc-image-helper assert fileExists "/data/mods/voicechat-fabric*"
mc-image-helper assert fileExists "/data/mods/onastick-fabric*" mc-image-helper assert fileExists "/data/mods/flan*"
# Dependent of on a stick: # Dependent of flan:
mc-image-helper assert fileExists "/data/mods/fabric-api*" mc-image-helper assert fileExists "/data/mods/fabric-api*"

View File

@@ -7,23 +7,24 @@ services:
environment: environment:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
DEBUG: "FALSE"
# Using custom to bypass Fabric setup # Using custom to bypass Fabric setup
TYPE: CUSTOM TYPE: CUSTOM
# Using family to test FORGEAPI Family filter. # Using family to test FORGEAPI Family filter.
FAMILY: FABRIC FAMILY: FABRIC
CUSTOM_SERVER: /servers/fake.jar CUSTOM_SERVER: /servers/fake.jar
VERSION: ${MINECRAFT_VERSION:-LATEST} VERSION: 1.18.2
# Validate Skip Gametype Filter: # Validate Skip Gametype Filter:
MODS_FORGEAPI_IGNORE_GAMETYPE: "TRUE" MODS_FORGEAPI_IGNORE_GAMETYPE: "TRUE"
# Validates that Biomes does not download terrablender # Validates that Biomes does not download terrablender
# Using default false for testing: # Using default false for testing:
# MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "FALSE" MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "FALSE"
# Contains mix of Forge and Fabric mods # Contains mix of Forge and Fabric mods
MODS_FORGEAPI_PROJECTIDS: 306612,416089,220318 MODS_FORGEAPI_PROJECTIDS: 416089,493246
# Allows for Beta releases of 416089 the Fabric Voice Mod # Allows for Beta releases of 416089 the Fabric Voice Mod
MODS_FORGEAPI_RELEASES: BETA MODS_FORGEAPI_RELEASES: BETA
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY} MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
REMOVE_OLD_FORGEAPI_MODS: "FALSE" REMOVE_OLD_FORGEAPI_MODS: "TRUE"
volumes: volumes:
- ./data:/data - ./data:/data
- ./fake.jar:/servers/fake.jar - ./fake.jar:/servers/fake.jar

View File

@@ -1,5 +1,5 @@
mc-image-helper assert fileExists "/data/mods/BiomesOPlenty*"
# testing dependencies don't get downloaded when download dependencies is set to false. # testing dependencies don't get downloaded when download dependencies is set to false.
! mc-image-helper assert fileExists "/data/mods/TerraBlender*"
mc-image-helper assert fileExists "/data/mods/voicechat-fabric*" mc-image-helper assert fileExists "/data/mods/voicechat-fabric*"
mc-image-helper assert fileExists "/data/mods/fabric-api*" mc-image-helper assert fileExists "/data/mods/flan*"
# Dependent of flan, but dependencies are set to false:
! mc-image-helper assert fileExists "/data/mods/fabric-api*"

View File

@@ -13,7 +13,7 @@ services:
# - Currently we do not support filtering on vanilla. # - Currently we do not support filtering on vanilla.
FAMILY: VANILLA FAMILY: VANILLA
CUSTOM_SERVER: /servers/fake.jar CUSTOM_SERVER: /servers/fake.jar
VERSION: ${MINECRAFT_VERSION:-LATEST} VERSION: 1.18.2
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE" MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE"
# Contains mix of Forge and Fabric mods # Contains mix of Forge and Fabric mods
MODS_FORGEAPI_PROJECTIDS: 416089,419697 MODS_FORGEAPI_PROJECTIDS: 416089,419697

View File

@@ -9,6 +9,13 @@ services:
GENERIC_PACKS: testing GENERIC_PACKS: testing
GENERIC_PACKS_PREFIX: /packs/ GENERIC_PACKS_PREFIX: /packs/
GENERIC_PACKS_SUFFIX: .zip GENERIC_PACKS_SUFFIX: .zip
DEBUG: "true"
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes: volumes:
- ./packs:/packs - ./packs:/packs
- ./data:/data - ./data:/data
# the following are only used to speed up test execution
- ./verify.sh:/servers/fake.jar

View File

@@ -18,6 +18,7 @@ services:
TYPE: CUSTOM TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1 VERSION: 1.18.1
DEBUG: "true"
volumes: volumes:
- ./packs:/packs - ./packs:/packs
- ./data:/data - ./data:/data

View File

@@ -0,0 +1,16 @@
version: "3"
services:
mc:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
TYPE: FABRIC
FABRIC_LAUNCHER: /servers/fake.jar
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.19.1
MODRINTH_PROJECTS: fabric-api,cloth-config
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

View File

@@ -0,0 +1 @@
mc-image-helper assert fileExists "mods/cloth-config-*.jar" "mods/fabric-api-*.jar"

View File

@@ -7,7 +7,12 @@ services:
environment: environment:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
OPS: itzg OPS: itzg
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes: volumes:
- ./data:/data - ./data:/data
# the following are only used to speed up test execution
- ./verify.sh:/servers/fake.jar

View File

@@ -0,0 +1,21 @@
version: "3"
services:
web:
image: nginx
volumes:
- ./web:/usr/share/nginx/html
mc:
depends_on:
- web
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
PACKWIZ_URL: http://web/pack.toml
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.19
DEBUG_HELPER: "true"
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

View File

@@ -0,0 +1 @@
mc-image-helper assert fileExists mods/architectury-5.7.28-fabric.jar

View File

@@ -0,0 +1,6 @@
hash-format = "sha256"
[[files]]
file = "mods/architectury-api.pw.toml"
hash = "c20179449fff711afb96ba0eadd3328fbf1aae639082d25d77c9080837685b79"
metafile = true

View File

@@ -0,0 +1,13 @@
name = "Architectury API"
filename = "architectury-5.7.28-fabric.jar"
side = "both"
[download]
url = "https://cdn.modrinth.com/data/lhGA9TYQ/versions/5.7.28+fabric/architectury-5.7.28-fabric.jar"
hash-format = "sha1"
hash = "aa38ae9cc2e978e4ec87ff891f7b02ea0c0ee1b8"
[update]
[update.modrinth]
mod-id = "lhGA9TYQ"
version = "Hf0Bau1j"

View File

@@ -0,0 +1,13 @@
name = "Vanillia Server"
author = "itzg"
version = "2.0.0"
pack-format = "packwiz:1.1.0"
[index]
file = "index.toml"
hash-format = "sha256"
hash = "1a27b406c3fb6d35167fe659384ab528a6b3f8a66e6c05d593058e646aec591f"
[versions]
fabric = "0.14.8"
minecraft = "1.19"

View File

@@ -8,6 +8,8 @@ services:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
TYPE: PAPER TYPE: PAPER
SPIGET_RESOURCES: "34315,3836,6245,2124,88135" # jar doesn't need to exist for setuponly tests
PAPER_CUSTOM_JAR: /servers/fake.jar
SPIGET_RESOURCES: "34315,3836,6245,2124"
volumes: volumes:
- ./data:/data - ./data:/data

View File

@@ -1,5 +1,4 @@
mc-image-helper assert fileExists plugins/3836.jar mc-image-helper assert fileExists plugins/3836.jar
mc-image-helper assert fileExists plugins/34315.jar mc-image-helper assert fileExists plugins/34315.jar
mc-image-helper assert fileExists plugins/6245.jar mc-image-helper assert fileExists plugins/6245.jar
mc-image-helper assert fileExists plugins/88135.jar
mc-image-helper assert fileExists plugins/SkinsRestorer.jar mc-image-helper assert fileExists plugins/SkinsRestorer.jar

View File

@@ -7,9 +7,11 @@ services:
environment: environment:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
TYPE: "PAPER" TYPE: "PAPER"
WORLD: /worlds/world-for-testing.zip WORLD: /worlds/world-for-testing.zip
# the following are only used to speed up test execution
VERSION: 1.18.1
PAPER_CUSTOM_JAR: /servers/fake.jar
volumes: volumes:
- ./worlds:/worlds:ro - ./worlds:/worlds:ro
- ./data:/data - ./data:/data

View File

@@ -7,8 +7,13 @@ services:
environment: environment:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
WORLD: /worlds/world-for-testing.zip WORLD: /worlds/world-for-testing.zip
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes: volumes:
- ./worlds:/worlds:ro - ./worlds:/worlds:ro
- ./data:/data - ./data:/data
# the following are only used to speed up test execution
- ./verify.sh:/servers/fake.jar

View File

@@ -15,6 +15,13 @@ $logs
" "
} }
delta() {
startTime=${1?}
endTime=$(date +%s)
echo "$(( endTime - startTime )) seconds"
}
# tests that only run the setup files for things like downloads and configuration. # tests that only run the setup files for things like downloads and configuration.
setupOnlyMinecraftTest(){ setupOnlyMinecraftTest(){
folder=$1 folder=$1
@@ -32,22 +39,27 @@ setupOnlyMinecraftTest(){
fi fi
fi fi
if ! logs=$(docker-compose run mc 2>&1); then # false positive since it's used in delta calculations below
# shellcheck disable=SC2034
start=$(date +%s)
if ! logs=$(docker compose run --rm -e SETUP_ONLY=true -e DEBUG="${DEBUG:-false}" mc 2>&1); then
outputContainerLog "$logs" outputContainerLog "$logs"
result=1 result=1
elif [ -f verify.sh ]; then elif [ -f verify.sh ]; then
if ! docker run --rm --entrypoint bash -v "${PWD}/data":/data -v "${PWD}/verify.sh":/verify "${IMAGE_TO_TEST:-itzg/minecraft-server}" -e /verify; then if ! docker run --rm --entrypoint bash -v "${PWD}/data":/data -v "${PWD}/verify.sh":/verify "${IMAGE_TO_TEST:-itzg/minecraft-server}" -e /verify; then
echo "Verify ${folder} FAILED" endTime=$(date +%s)
echo "${folder} FAILED verify in $(delta start)"
outputContainerLog "$logs" outputContainerLog "$logs"
result=1 result=1
else else
echo "Verify ${folder} PASS" endTime=$(date +%s)
echo "${folder} PASSED verify in $(delta start)"
fi fi
else else
echo "${folder} PASS" echo "${folder} PASSED in $(delta start)"
fi fi
docker-compose down -v --remove-orphans > /dev/null docker compose down -v --remove-orphans >& /dev/null
cd .. cd ..
return $result return $result

View File

@@ -7,9 +7,11 @@ services:
environment: environment:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
TYPE: "PAPER" TYPE: "PAPER"
WORLD: /worlds/world-for-testing.zip WORLD: /worlds/world-for-testing.zip
# the following are only used to speed up test execution
VERSION: 1.18.1
PAPER_CUSTOM_JAR: /servers/fake.jar
volumes: volumes:
- ./worlds:/worlds:ro - ./worlds:/worlds:ro
- ./data:/data - ./data:/data

View File

@@ -7,8 +7,13 @@ services:
environment: environment:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
WORLD: /worlds/world-for-testing.zip WORLD: /worlds/world-for-testing.zip
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes: volumes:
- ./worlds:/worlds:ro - ./worlds:/worlds:ro
- ./data:/data - ./data:/data
# the following are only used to speed up test execution
- ./verify.sh:/servers/fake.jar

View File

@@ -1,17 +1,21 @@
version: "3" version: "3"
services: services:
mc: mc:
restart: "no" restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server} image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment: environment:
EULA: "TRUE" VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
SETUP_ONLY: "TRUE" EULA: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST} SETUP_ONLY: "TRUE"
VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json # the following are only used to speed up test execution
REMOVE_OLD_VANILLATWEAKS: "FALSE" TYPE: CUSTOM
volumes: CUSTOM_SERVER: /servers/fake.jar
- ./data:/data VERSION: 1.18.1
- ./vt-datapacks.json:/config/vt-datapacks.json:ro volumes:
- ./vt-craftingtweaks.json:/config/vt-craftingtweaks.json:ro - ./data:/data
- ./vt-resourcepacks.json:/config/vt-resourcepacks.json:ro - ./vt-datapacks.json:/config/vt-datapacks.json:ro
- ./vt-craftingtweaks.json:/config/vt-craftingtweaks.json:ro
- ./vt-resourcepacks.json:/config/vt-resourcepacks.json:ro
# the following are only used to speed up test execution
- ./verify.sh:/servers/fake.jar

View File

@@ -1,4 +1,4 @@
mc-image-helper assert fileExists "/data/world/datapacks/afk*" mc-image-helper assert fileExists "/data/world/datapacks/afk*"
mc-image-helper assert fileExists "/data/world/datapacks/graves*" mc-image-helper assert fileExists "/data/world/datapacks/graves*"
mc-image-helper assert fileExists "/data/world/datapacks/craftingtweaks*" mc-image-helper assert fileExists "/data/world/datapacks/VanillaTweaks_*"
mc-image-helper assert fileExists "/data/resourcepacks/resourcepacks*" mc-image-helper assert fileExists "/data/resourcepacks/VanillaTweaks_*"

View File

@@ -5,10 +5,14 @@ services:
restart: "no" restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server} image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment: environment:
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST} # the following are only used to speed up test execution
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT TYPE: CUSTOM
REMOVE_OLD_VANILLATWEAKS: "FALSE" CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes: volumes:
- ./data:/data - ./data:/data
# the following are only used to speed up test execution
- ./verify.sh:/servers/fake.jar

View File

@@ -1,4 +1,4 @@
mc-image-helper assert fileExists "/data/world/datapacks/afk*" mc-image-helper assert fileExists "/data/world/datapacks/afk*"
mc-image-helper assert fileExists "/data/world/datapacks/graves*" mc-image-helper assert fileExists "/data/world/datapacks/graves*"
mc-image-helper assert fileExists "/data/world/datapacks/craftingtweaks*" mc-image-helper assert fileExists "/data/world/datapacks/VanillaTweaks_488158f.zip"
mc-image-helper assert fileExists "/data/resourcepacks/resourcepacks*" mc-image-helper assert fileExists "/data/resourcepacks/VanillaTweaks_d1d810f.zip"

View File

@@ -7,9 +7,14 @@ services:
environment: environment:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
WHITELIST: itzg WHITELIST: itzg
ENFORCE_WHITELIST: "true" ENFORCE_WHITELIST: "true"
OVERRIDE_SERVER_PROPERTIES: "true" OVERRIDE_SERVER_PROPERTIES: "true"
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes: volumes:
- ./data:/data - ./data:/data
# the following are only used to speed up test execution
- ./verify.sh:/servers/fake.jar

View File

@@ -7,8 +7,13 @@ services:
environment: environment:
EULA: "TRUE" EULA: "TRUE"
SETUP_ONLY: "TRUE" SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
WORLD: /worlds/world-for-testing.tar WORLD: /worlds/world-for-testing.tar
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes: volumes:
- ./worlds:/worlds:ro - ./worlds:/worlds:ro
- ./data:/data - ./data:/data
# the following are only used to speed up test execution
- ./verify.sh:/servers/fake.jar