Compare commits

..

90 Commits

Author SHA1 Message Date
Geoff Bourne
be20c79d92 Auto-merging via docker-versions-create 2022-01-23 22:24:06 -06:00
Geoff Bourne
153623382a Auto-merging via docker-versions-create 2022-01-23 11:00:51 -06:00
Geoff Bourne
331a055170 Auto-merging via docker-versions-create 2022-01-20 23:10:40 +00:00
Geoff Bourne
cfd3f412f5 Auto-merging via docker-versions-create 2022-01-17 13:25:30 -06:00
Geoff Bourne
40186eb0cf Auto-merging via docker-versions-create 2022-01-10 06:58:08 -06:00
Geoff Bourne
30bd043b46 Auto-merging via docker-versions-create 2022-01-08 15:22:43 -06:00
Geoff Bourne
b686587ac9 Auto-merging via docker-versions-create 2022-01-06 22:16:03 -06:00
Geoff Bourne
cf33fbc081 Auto-merging via docker-versions-create 2021-12-23 16:08:56 -06:00
Geoff Bourne
885d5a36eb Auto-merging via docker-versions-create 2021-12-13 21:28:54 -06:00
Geoff Bourne
15a4569dc5 Auto-merging via docker-versions-create 2021-12-12 19:52:07 -06:00
Geoff Bourne
6729ba462e Merge branch 'master' of github.com:itzg/docker-minecraft-server 2021-12-12 15:35:14 -06:00
Geoff Bourne
4b28d5e472 fix: qualify Fabric server jar by installer version
Fixes #1191
2021-12-12 15:28:30 -06:00
Geoff Bourne
9b5bd3787f Merging latest from master 2021-12-12 09:16:19 -06:00
Geoff Bourne
a1665bc874 Auto-merging via docker-versions-create 2021-12-11 16:24:47 -06:00
Geoff Bourne
3f2022da40 Merge branch 'master' of github.com:itzg/docker-minecraft-server 2021-12-11 16:23:25 -06:00
Geoff Bourne
0f7464403c build: added github release creation step to docker-versions-create.sh 2021-12-11 16:09:15 -06:00
Geoff Bourne
b77586a10a Auto-merging via docker-versions-create 2021-12-10 21:04:47 -06:00
Geoff Bourne
9a3f3fc33f Auto-merging via docker-versions-create 2021-12-10 10:42:32 -06:00
Geoff Bourne
a88c046d59 Auto-merging via docker-versions-create 2021-12-10 07:57:43 -06:00
Geoff Bourne
871d54f44e Merge latest from master 2021-12-06 22:06:03 -06:00
Geoff Bourne
cd59602d40 Auto merge branch with master 2021-12-04 10:00:25 -06:00
Geoff Bourne
793bedcd14 Auto-merging via docker-versions-create 2021-12-04 10:00:24 -06:00
Geoff Bourne
0f94d0aece Auto-merging via docker-versions-create 2021-12-02 19:47:07 -06:00
Geoff Bourne
6ee44b3409 Auto-merging via docker-versions-create 2021-11-24 15:57:54 -06:00
Geoff Bourne
faa7553e54 Auto-merging via docker-versions-create 2021-11-24 14:34:41 -06:00
Geoff Bourne
0d85d672ef Track latest from master 2021-11-16 19:02:35 -06:00
Geoff Bourne
0e6c85f25a Auto-merging via docker-versions-create 2021-11-16 18:52:12 -06:00
Geoff Bourne
484417c7a3 Auto-merging via docker-versions-create 2021-11-15 20:48:43 -06:00
Geoff Bourne
dc44c328d4 Auto-merging via docker-versions-create 2021-11-13 19:18:11 -06:00
Geoff Bourne
7a4e308e8c Auto-merging via docker-versions-create 2021-11-13 18:52:44 -06:00
Geoff Bourne
b267afc0bc Auto-merging via docker-versions-create 2021-11-12 21:24:34 -06:00
Geoff Bourne
13a6b2c44e Auto-merging via docker-versions-create 2021-11-06 21:38:46 -05:00
Geoff Bourne
1db04946df Auto-merging via docker-versions-create 2021-11-04 21:05:23 -05:00
Geoff Bourne
c682e4ebf6 Auto-merging via docker-versions-create 2021-10-31 09:46:50 -05:00
Geoff Bourne
5132a662e7 Switched base image to JDK
#1064
2021-10-27 21:26:20 -05:00
Geoff Bourne
79d169cb9a Merge branch 'master' into java11 2021-10-27 21:25:57 -05:00
Geoff Bourne
6950c05ea0 Auto-merging via docker-versions-create 2021-10-25 19:24:29 -05:00
Geoff Bourne
71dc5af9a9 Auto-merging via docker-versions-create 2021-10-24 20:29:00 -05:00
Geoff Bourne
098ba9554e Auto-merging via docker-versions-create 2021-10-23 09:44:17 -05:00
Geoff Bourne
c6925eb316 Auto-merging via docker-versions-create 2021-10-22 15:54:57 -05:00
Geoff Bourne
82963e7474 Auto-merging via docker-versions-create 2021-10-18 22:15:02 -05:00
Geoff Bourne
59fde19e3f Auto-merging via docker-versions-create 2021-10-17 14:53:37 -05:00
Geoff Bourne
63c5acfe49 Auto-merging via docker-versions-create 2021-10-15 18:58:11 -05:00
Geoff Bourne
1f1fa02031 Auto-merging via docker-versions-create 2021-10-15 18:48:40 -05:00
Geoff Bourne
250ce7849b Auto-merging via docker-versions-create 2021-10-10 09:57:18 -05:00
Geoff Bourne
c6587a115c Auto-merging via docker-versions-create 2021-10-09 15:26:23 -05:00
Geoff Bourne
a2ce3a7437 Auto-merging via docker-versions-create 2021-10-09 12:05:03 -05:00
Geoff Bourne
80cad3572d Auto-merging via docker-versions-create 2021-10-02 19:23:05 -05:00
Geoff Bourne
9a2eb0042f Auto-merging via docker-versions-create 2021-09-29 10:26:59 -05:00
Geoff Bourne
559745dd80 Auto-merging via docker-versions-create 2021-09-27 20:41:53 -05:00
Geoff Bourne
a3972d83bb Auto-merging via docker-versions-create 2021-09-20 12:31:17 -05:00
Geoff Bourne
baf7cdd7e2 Auto-merging via docker-versions-create 2021-09-15 21:31:47 -05:00
Geoff Bourne
f24096e584 Auto-merging via docker-versions-create 2021-09-15 21:07:40 -05:00
Geoff Bourne
d39f3b0afc Auto-merging via docker-versions-create 2021-09-15 20:37:38 -05:00
Geoff Bourne
add67113ff Auto-merging via docker-versions-create 2021-08-30 21:38:08 -05:00
Geoff Bourne
fe67ee5c79 Auto-merging via docker-versions-create 2021-08-10 12:56:42 -05:00
Geoff Bourne
5b777eff5b Auto-merging via docker-versions-create 2021-08-01 12:13:34 -05:00
Geoff Bourne
f36dd34f72 Auto-merging via docker-versions-create 2021-07-31 09:28:04 -05:00
Geoff Bourne
c4fa657c61 Auto-merging via docker-versions-create 2021-07-26 19:36:01 -05:00
Geoff Bourne
bfb0d19372 Merge branch 'master' into java11 2021-07-25 18:20:51 -05:00
Geoff Bourne
bef6e7b432 Auto-merging via docker-versions-create 2021-07-25 09:37:18 -05:00
Geoff Bourne
3263a23140 Auto-merging via docker-versions-create 2021-07-23 21:28:09 -05:00
Geoff Bourne
8163e266fe Auto-merging via docker-versions-create 2021-07-17 21:15:14 -05:00
Geoff Bourne
349f27f345 Auto-merging via docker-versions-create 2021-07-17 20:57:59 -05:00
Geoff Bourne
9b6b813fe8 Auto-merging via docker-versions-create 2021-07-17 18:04:38 -05:00
Geoff Bourne
1f39283fd0 Auto-merging via docker-versions-create 2021-07-14 18:43:19 -05:00
Geoff Bourne
2086562d03 Auto-merging via docker-versions-create 2021-07-12 19:10:15 -05:00
Geoff Bourne
67404c017a Auto-merging via docker-versions-create 2021-07-09 19:58:58 -05:00
Geoff Bourne
41e97454a9 Auto-merging via docker-versions-create 2021-07-08 18:00:07 -05:00
Geoff Bourne
31d082574d Auto-merging via docker-versions-create 2021-07-08 08:04:19 -05:00
itzg
0f59ec97b7 Auto-merging via docker-versions-create 2021-07-08 12:56:03 +00:00
Geoff Bourne
a1ce1b5a24 Auto-merging via docker-versions-create 2021-07-08 07:39:17 -05:00
itzg
fb3504ec1a Auto-merging via docker-versions-create 2021-07-04 19:54:04 +00:00
Geoff Bourne
b75f83cbf1 Auto-merging via docker-versions-create 2021-07-03 14:24:32 -05:00
Geoff Bourne
dc5192e2e7 ci: auto-merge from master 2021-07-02 15:59:12 -05:00
itzg
76b5ec75cc Auto-merging via docker-versions-create 2021-07-02 16:55:58 +00:00
itzg
4663723b84 Auto-merging via docker-versions-create 2021-06-28 12:14:08 +00:00
itzg
2acb45dc62 Auto-merging via docker-versions-create 2021-06-27 13:13:14 +00:00
itzg
de42f62031 Auto-merging via docker-versions-create 2021-06-24 12:47:08 +00:00
Geoff Bourne
7e690849b6 Auto-merging via docker-versions-create 2021-06-23 22:34:21 -05:00
Geoff Bourne
0a1c00f701 Auto-merging via docker-versions-create 2021-06-20 12:49:10 -05:00
Geoff Bourne
dc8c9e5d1a Auto-merging via docker-versions-create 2021-06-05 17:52:23 -05:00
Geoff Bourne
9577c84d6a Auto-merging via docker-versions-create 2021-05-24 20:51:26 -05:00
Geoff Bourne
575197a109 Merge branch 'master' into java11 2021-05-23 12:27:03 -05:00
Geoff Bourne
2b621b8236 Merge from master 2021-05-22 13:45:56 -05:00
Geoff Bourne
14d3446f52 Auto-merging via docker-versions-create 2021-05-21 23:02:26 -05:00
Geoff Bourne
83a7481027 Auto-merging via docker-versions-create 2021-05-21 22:50:35 -05:00
Geoff Bourne
4c3a329e31 ci: adjusted CACHE_NAME 2021-05-21 17:34:05 -05:00
Geoff Bourne
6c94e49732 ci: updated java11 Dockerfile 2021-05-21 17:33:26 -05:00
Geoff Bourne
af77b29509 ci: add java11 to build/merge 2021-05-21 17:32:38 -05:00
214 changed files with 1960 additions and 4634 deletions

17
.gitattributes vendored
View File

@@ -1,2 +1,17 @@
# Auto detect text files and perform LF normalization # Auto detect text files and perform LF normalization
* text=lf * text=auto
# 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,4 +1,5 @@
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

13
.github/release.yml vendored
View File

@@ -2,16 +2,3 @@ changelog:
exclude: exclude:
authors: authors:
- dependabot - dependabot
categories:
- title: Enhancements
labels:
- enhancement
- title: Bug Fixes
labels:
- bug
- title: Documentation
labels:
- documentation
- title: Other Changes
labels:
- "*"

View File

@@ -1,176 +1,93 @@
name: Test and Build multi-architecture name: Build and publish multiarch
on: on:
push: push:
branches: branches:
- master - master
- java8-multiarch
- java8-openj9
- java11*
- java16*
- java17*
- test/** - test/**
tags: tags:
- "[0-9]+.[0-9]+.[0-9]+" - "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+-java8-multiarch"
- "[0-9]+.[0-9]+.[0-9]+-java8-openj9"
- "[0-9]+.[0-9]+.[0-9]+-java11*"
- "[0-9]+.[0-9]+.[0-9]+-java16*"
paths-ignore: paths-ignore:
- "*.md" - "*.md"
- "docs/**" - "docs/**"
- "examples/**" - "examples/**"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
jobs: jobs:
build: build:
strategy: if: github.repository == 'itzg/docker-minecraft-server'
fail-fast: false
matrix:
variant:
- java17
- java17-graalvm-ce
- java17-jdk
- java17-openj9
- java17-alpine
- java8
- java8-graalvm-ce
- java8-multiarch
- java8-openj9
- java8-jdk
- java11
- java11-openj9
- java11-jdk
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,linux/arm/v7,linux/arm64
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
baseImage: eclipse-temurin:17-focal
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.18.2
- variant: java17-openj9
baseImage: ibm-semeru-runtimes:open-17-jre
platforms: linux/amd64,linux/arm64
mcVersion: 1.18.2
- variant: java17-alpine
baseImage: eclipse-temurin:17-jre-alpine
platforms: linux/amd64
mcVersion: 1.18.2
# JAVA 11:
- variant: java11
baseImage: adoptopenjdk:11-jre-hotspot
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.16.5
- variant: java11-jdk
baseImage: adoptopenjdk:11-jdk-hotspot
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.16.5
- variant: java11-openj9
baseImage: ibm-semeru-runtimes:open-11-jre
platforms: linux/amd64,linux/arm64
mcVersion: 1.16.5
# JAVA 8: NOTE: Unable to go past 8u312 because of Forge dependencies
- variant: java8
baseImage: openjdk:8-jre-alpine3.9
platforms: linux/amd64
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
baseImage: eclipse-temurin:8u312-b07-jre-focal
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.12.2
- variant: java8-jdk
baseImage: eclipse-temurin:8u312-b07-jdk-focal
platforms: linux/amd64,linux/arm64
mcVersion: 1.12.2
- variant: java8-openj9
baseImage: ibm-semeru-runtimes:open-8u312-b07-jre
platforms: linux/amd64,linux/arm64
mcVersion: 1.12.2
env:
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
uses: actions/checkout@v3 uses: actions/checkout@v2.4.0
with:
# for build-files step
fetch-depth: 0
- name: Docker meta - name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v4 uses: docker/metadata-action@v3
with: with:
# NOTE for forks: if your Docker Hub organization doesn't match your Github repo's,
# then the use of ${{ github.repository_owner }} will need to be replaced.
images: | images: |
${{ github.repository_owner }}/minecraft-server itzg/minecraft-server
tags: | tags: |
type=ref,event=tag,enable=${{ matrix.variant == 'java17' }} type=ref,event=branch
type=ref,event=tag,suffix=-${{ matrix.variant }} type=ref,event=tag
type=raw,value=${{ matrix.variant }}
flavor: | flavor: |
latest=${{ matrix.variant == 'java17' }} latest=${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
labels: |
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>
- name: Setup Docker Buildx - name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v1
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v2.1.0 uses: docker/setup-qemu-action@v1.2.0
- name: Build for test
uses: docker/build-push-action@v3.2.0
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 }}
# no cache-to to avoid cross-cache update from next build step
- name: Run tests
env:
MINECRAFT_VERSION: ${{ matrix.mcVersion }}
VARIANT: ${{ matrix.variant }}
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
run: |
tests/test.sh
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@v2 uses: docker/login-action@v1
if: env.HAS_IMAGE_REPO_ACCESS
with: with:
username: ${{ secrets.DOCKER_USER }} username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push - name: Build for test
uses: docker/build-push-action@v3.2.0 uses: docker/build-push-action@v2.7.0
if: github.actor == github.repository_owner if: github.ref_name == 'master' || startsWith(github.ref_name, 'test/')
with: with:
platforms: ${{ matrix.platforms }} context: .
push: > platforms: linux/amd64
${{ tags: ${{ env.IMAGE_TO_TEST }}
github.ref_type == 'tag' # ensure latest base image is used
|| github.ref_name == 'master' pull: true
|| ( github.event_name == 'pull_request' load: true
&& env.HAS_IMAGE_REPO_ACCESS push: false
&& contains(github.event.pull_request.labels.*.name, 'ci/push-image') cache-from: type=gha
) # no cache-to to avoid cross-cache update from next build step
}}
- name: Run tests
# It is assumed that image variants are merged from master and tested there
if: github.ref_name == 'master' || startsWith(github.ref_name, 'test/')
run: |
tests/test.sh
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2.7.0
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: true
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
cache-from: type=gha
cache-to: type=gha,mode=max
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
build-args: |
BASE_IMAGE=${{ matrix.baseImage }} - name: Image digest
BUILD_FILES_REV=${{ steps.build-files-rev.outputs.REV }} run: echo ${{ steps.docker_build.outputs.digest }}
cache-from: type=gha,scope=${{ matrix.variant }}
cache-to: type=gha,mode=max,scope=${{ matrix.variant }}

43
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
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@v2.4.0
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build
uses: docker/build-push-action@v2.7.0
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
load: true
cache-from: type=gha
- name: Run Setup Only Tests
run: sh tests/setuponlytests/test.sh
# - name: Run Full Minecraft Service Tests
# run: |
# tests/fulltests/test.sh

View File

@@ -1,4 +1,4 @@
name: Discord notifications name: discord
on: on:
workflow_run: workflow_run:

21
.github/workflows/generate-toc.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Generate README table of contents
on:
push:
branches:
- master
paths:
- README.md
jobs:
generate:
if: github.repository == 'itzg/docker-minecraft-server'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v2.4.0
- run: |
curl https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc -o gh-md-toc
chmod a+x gh-md-toc
./gh-md-toc --insert --no-backup README.md
- uses: stefanzweifel/git-auto-commit-action@v4.13.1
with:
commit_message: "docs: Auto update markdown TOC"

View File

@@ -1,33 +1,17 @@
name: Issue labels
on: on:
issues: issues:
types: [labeled, reopened, closed, deleted] types: [labeled]
env: env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_ISSUES_WEBHOOK }} DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
jobs: jobs:
labelNotify: labelNotify:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5 timeout-minutes: 5
steps: steps:
- name: notify on label - name: notify
if: > if: github.event.label.name == 'enhancement' || github.event.label.name == 'bug'
github.event.label.name == 'enhancement'
|| github.event.label.name == 'bug'
|| github.event.label.name == 'help wanted'
|| github.event.label.name == 'priority/high'
|| github.event.label.name == 'question'
|| github.event.label.name == 'status/waiting on upstream'
uses: Ilshidur/action-discord@master uses: Ilshidur/action-discord@master
with: with:
args: "[${{ github.event.issue.title }} (#${{ github.event.issue.number }})](<${{ github.event.issue.html_url }}>) added `${{ github.event.label.name }}` label" args: "[${{ github.event.issue.title }}](<${{ github.event.issue.html_url }}>) added `${{ github.event.label.name }}` label"
- name: notify on action change
if: >
github.event.action == 'closed'
|| github.event.action == 'reopened'
|| github.event.action == 'deleted'
uses: Ilshidur/action-discord@master
with:
args: "[${{ github.event.issue.title }} (#${{ github.event.issue.number }})](<${{ github.event.issue.html_url }}>) has been `${{ github.event.action }}` by `${{ github.event.sender.login }}`"

97
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,97 @@
name: Build and Publish
on:
push:
branches:
- java8
- openj9
- openj9-11
- adopt11
- test/alpine/*
tags:
- "[0-9]+.[0-9]+.[0-9]+-java8"
- "[0-9]+.[0-9]+.[0-9]+-openj9"
- "[0-9]+.[0-9]+.[0-9]+-openj9-11"
- "[0-9]+.[0-9]+.[0-9]+-openj9-nightly"
- "[0-9]+.[0-9]+.[0-9]+-adopt11"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
jobs:
build:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2.4.0
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=itzg/minecraft-server
VERSION=edge
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
fi
if [[ $GITHUB_REF == refs/heads/* ]]; then
VERSION=${GITHUB_REF#refs/heads/}
if [[ $VERSION == master ]]; then
VERSION=latest
fi
fi
TAGS="${DOCKER_IMAGE}:${VERSION//\//-}"
echo ::set-output name=tags::${TAGS}
echo ::set-output name=version::${VERSION//\//-}
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test
uses: docker/build-push-action@v2.7.0
if: github.ref_name == 'java8'
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
# ensure latest base image is used
pull: true
load: true
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Run tests
if: github.ref_name == 'java8'
run: |
tests/test.sh
env:
MINECRAFT_VERSION: 1.12.2
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2.7.0
with:
context: .
file: ./Dockerfile
# ensure latest base image is used
pull: true
# publish
push: true
# tags determined by prep step
tags: ${{ steps.prep.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
labels: |
org.opencontainers.image.documentation=https://github.com/itzg/docker-minecraft-server
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
org.opencontainers.image.source=https://github.com/itzg/docker-minecraft-server
org.opencontainers.image.revision=${{ github.sha }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

64
.github/workflows/pr.yml vendored Normal file
View File

@@ -0,0 +1,64 @@
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 }}
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
jobs:
test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2.4.0
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build
uses: docker/build-push-action@v2.7.0
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
load: true
cache-from: type=gha
- name: Run tests
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@v3
with:
images: |
itzg/minecraft-server
- name: Login to DockerHub
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
uses: docker/login-action@v1
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@v2.7.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 }}

View File

@@ -12,7 +12,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: Process Stale Issues - name: Process Stale Issues
uses: actions/stale@v6 uses: actions/stale@v4.1.0
with: with:
stale-issue-label: status/stale stale-issue-label: status/stale
stale-pr-label: status/stale stale-pr-label: status/stale

View File

@@ -1,69 +0,0 @@
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.2.0
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

1
.gitignore vendored
View File

@@ -3,4 +3,3 @@
/.idea/ /.idea/
*.iml *.iml
/gh-md-toc /gh-md-toc
personal-build-and-develop.*

View File

@@ -15,35 +15,8 @@ Individual scripts can be iteratively developed, debugged, and tested using the
First, build a baseline of the image to include the packages needed by existing or new scripts: First, build a baseline of the image to include the packages needed by existing or new scripts:
PowerShell: (Example of building and testing ForgeAPI) ```shell script
```powershell docker build -t mc-dev .
$env:MODS_FORGEAPI_KEY='$2a$...'
$env:FOLDER_TO_TEST="forgeapimods_projectids"
$env:IMAGE_TO_TEST="mc-dev"
docker build -t $env:IMAGE_TO_TEST .
pushd "tests/setuponlytests/$env:FOLDER_TO_TEST/"
docker-compose run mc
docker-compose down -v --remove-orphans
popd
```
PowerShell: Building different images of Java for testing
```powershell
$env:BASE_IMAGE='eclipse-temurin:8u312-b07-jre'
$env:IMAGE_TO_TEST="mc-dev"
docker build --build-arg BASE_IMAGE=$env:BASE_IMAGE -t $env:IMAGE_TO_TEST .
```
Bash: (Example of building and testing ForgeAPI)
```bash
export MODS_FORGEAPI_KEY='$2a$...'
export FOLDER_TO_TEST="forgeapimods_file"
export IMAGE_TO_TEST="mc-dev"
docker build -t $IMAGE_TO_TEST .
pushd tests/setuponlytests/$FOLDER_TO_TEST/
docker-compose run mc
docker-compose down -v --remove-orphans
popd
``` ```
Using the baseline image, an interactive container can be started to iteratively run the scripts to be developed. By attaching the current workspace directory, you can use the local editor of your choice to iteratively modify scripts while using the container to run them. Using the baseline image, an interactive container can be started to iteratively run the scripts to be developed. By attaching the current workspace directory, you can use the local editor of your choice to iteratively modify scripts while using the container to run them.
@@ -78,7 +51,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 8080 http-server ./build/distributions -p 0
``` ```
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 +61,32 @@ 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.
## Multi-base-image variants
Several base-image variants are maintained in order to offer choices in JDK provider and version. The variants are maintained in their respective branches:
- openj9
- openj9-nightly
- adopt11
- adopt13
- multiarch
The [docker-versions-create.sh](docker-versions-create.sh) script is configured with the branches to maintain and is used to merge changes from the master branch into the mulit-base variant branches. The script also manages git tagging the master branch along with the merged branches. So a typical use of the script would be like:
```shell script
./docker-versions-create.sh -s -t 1.2.0
```
> Most often the major version will be bumped unless a bug or hotfix needs to be published in which case the patch version should be incremented.
> The build and publishing of those branches and their tags is currently performed within Docker Hub.
## multiarch support
The [multiarch branch](https://github.com/itzg/docker-minecraft-server/tree/multiarch) supports running the image on amd64, arm64, and armv7 (aka RaspberryPi). Unlike the mainline branches, it is based on Ubuntu 18.04 since the openjdk package provided by Ubuntu includes full JIT support on all of the processor types.
The multiarch images are built and published by [a Github action](https://github.com/itzg/docker-minecraft-server/actions?query=workflow%3A%22Build+and+publish+multiarch%22), which [is configured in that branch](https://github.com/itzg/docker-minecraft-server/blob/multiarch/.github/workflows/build-multiarch.yml).
## Generating release notes ## Generating release notes
@@ -97,3 +95,25 @@ The following git command can be used to provide the bulk of release notes conte
```shell script ```shell script
git log --invert-grep --grep "^ci:" --grep "^misc:" --grep "^docs:" --pretty="* %s" 1.1.0..1.2.0 git log --invert-grep --grep "^ci:" --grep "^misc:" --grep "^docs:" --pretty="* %s" 1.1.0..1.2.0
``` ```
## Tracking changes from master without content
The following script uses the [ours](https://git-scm.com/docs/merge-strategies#Documentation/merge-strategies.txt-ours) merging strategy to track the history from master into the other branches without actually bringing the changes over. It is useful when a change is specific to master only, such as bumping the base Java version for the `latest` image tag.
```shell
branches=(
java8
java8-multiarch
java8-openj9
java11
java11-openj9
java16
java16-openj9
java17
)
for b in "${branches[@]}"; do
git checkout "$b"
git merge -s ours -m "Track latest from master" master
git push origin
done
```

View File

@@ -1,16 +1,31 @@
# syntax = docker/dockerfile:1.3 FROM adoptopenjdk:11-jdk
ARG BASE_IMAGE=eclipse-temurin:17-jre-focal LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
FROM ${BASE_IMAGE}
# CI system should set this to a hash or git revision of the build directory and it's contents to RUN apt-get update \
# ensure consistent cache updates. && DEBIAN_FRONTEND=noninteractive \
ARG BUILD_FILES_REV=1 apt-get install -y \
RUN --mount=target=/build,source=build \ imagemagick \
REV=${BUILD_FILES_REV} /build/run.sh install-packages file \
gosu \
sudo \
net-tools \
iputils-ping \
curl \
git \
jq \
dos2unix \
mysql-client \
tzdata \
rsync \
nano \
unzip \
knockd \
ttf-dejavu \
&& apt-get clean
RUN --mount=target=/build,source=build \ RUN addgroup --gid 1000 minecraft \
REV=${BUILD_FILES_REV} /build/run.sh setup-user && adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft
COPY --chmod=644 files/sudoers* /etc/sudoers.d COPY --chmod=644 files/sudoers* /etc/sudoers.d
@@ -31,23 +46,23 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--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.5.1 --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.11.0 --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.2 --var app=mc-server-runner --file {{.app}} \ --var version=1.8.0 --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.22.12 ARG MC_HELPER_VERSION=1.16.0
ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/${MC_HELPER_VERSION} ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/v${MC_HELPER_VERSION}
RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \ RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \
| tar -C /usr/share -zxf - \ | tar -C /usr/share -zxf - \
&& ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin && ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin
@@ -57,16 +72,23 @@ WORKDIR /data
STOPSIGNAL SIGTERM STOPSIGNAL SIGTERM
# End user MUST set EULA and change RCON_PASSWORD ENV UID=1000 GID=1000 \
ENV TYPE=VANILLA VERSION=LATEST EULA="" UID=1000 GID=1000 RCON_PASSWORD=minecraft MEMORY="1G" \
TYPE=VANILLA VERSION=LATEST \
ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \
ENABLE_AUTOPAUSE=false AUTOPAUSE_TIMEOUT_EST=3600 AUTOPAUSE_TIMEOUT_KN=120 AUTOPAUSE_TIMEOUT_INIT=600 \
AUTOPAUSE_PERIOD=10 AUTOPAUSE_KNOCK_INTERFACE=eth0 \
ENABLE_AUTOSTOP=false AUTOSTOP_TIMEOUT_EST=3600 AUTOSTOP_TIMEOUT_INIT=1800 AUTOSTOP_PERIOD=10
COPY --chmod=755 scripts/start* / COPY --chmod=755 scripts/start* /
COPY --chmod=755 bin/ /usr/local/bin/ COPY --chmod=755 bin/ /usr/local/bin/
COPY --chmod=755 bin/mc-health /health.sh COPY --chmod=755 bin/mc-health /health.sh
COPY --chmod=644 files/log4j2.xml /image/log4j2.xml COPY --chmod=644 files/server.properties /tmp/server.properties
COPY --chmod=755 files/auto /auto COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml
COPY --chmod=755 files/autopause /autopause
COPY --chmod=755 files/autostop /autostop
RUN dos2unix /start* /auto/* RUN dos2unix /start* /autopause/* /autostop/*
ENTRYPOINT [ "/start" ] ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m --interval=5s --retries=24 CMD mc-health HEALTHCHECK --start-period=1m CMD mc-health

664
README.md
View File

@@ -21,6 +21,130 @@ where, in this case, the standard server port 25565, will be exposed on your hos
By default, the container will download the latest version of the "vanilla" [Minecraft: Java Edition server](https://www.minecraft.net/en-us/download/server) provided by Mojang. The [`VERSION`](#versions) and the [`TYPE`](#server-types) can be configured to create many variations of desired Minecraft server. By default, the container will download the latest version of the "vanilla" [Minecraft: Java Edition server](https://www.minecraft.net/en-us/download/server) provided by Mojang. The [`VERSION`](#versions) and the [`TYPE`](#server-types) can be configured to create many variations of desired Minecraft server.
**TABLE OF CONTENTS**
<!--ts-->
* [Mitigated Log4jShell Vulnerability](#mitigated-log4jshell-vulnerability)
* [Looking for a Bedrock Dedicated Server](#looking-for-a-bedrock-dedicated-server)
* [Interacting with the server](#interacting-with-the-server)
* [Data Directory](#data-directory)
* [Attaching data directory to host filesystem](#attaching-data-directory-to-host-filesystem)
* [Converting anonymous /data volume to named volume](#converting-anonymous-data-volume-to-named-volume)
* [Versions](#versions)
* [Running Minecraft server on different Java version](#running-minecraft-server-on-different-java-version)
* [Deprecated Image Tags](#deprecated-image-tags)
* [Healthcheck](#healthcheck)
* [Deployment Templates and Examples](#deployment-templates-and-examples)
* [Helm Charts](#helm-charts)
* [Examples](#examples)
* [Amazon Web Services (AWS) Deployment](#amazon-web-services-aws-deployment)
* [Using Docker Compose](#using-docker-compose)
* [Troubleshooting](#troubleshooting)
* [Server types](#server-types)
* [Running a Forge Server](#running-a-forge-server)
* [Running a Fabric Server](#running-a-fabric-server)
* [Running a Bukkit/Spigot server](#running-a-bukkitspigot-server)
* [Running a Paper server](#running-a-paper-server)
* [Running an Airplane server](#running-an-airplane-server)
* [Running a Pufferfish server](#running-a-pufferfish-server)
* [Running a Purpur server](#running-a-purpur-server)
* [Running a Magma server](#running-a-magma-server)
* [Running a Mohist server](#running-a-mohist-server)
* [Running a Catserver type server](#running-a-catserver-type-server)
* [Running a Canyon server](#running-a-canyon-server)
* [Running a SpongeVanilla server](#running-a-spongevanilla-server)
* [Running a Limbo server](#running-a-limbo-server)
* [Running a Crucible server](#running-a-crucible-server)
* [Running a server with a Feed the Beast modpack](#running-a-server-with-a-feed-the-beast-modpack)
* [Environment Variables:](#environment-variables)
* [Upgrading](#upgrading)
* [Example](#example)
* [Running a server with a CurseForge modpack](#running-a-server-with-a-curseforge-modpack)
* [Modpack data directory](#modpack-data-directory)
* [Buggy start scripts](#buggy-start-scripts)
* [Fixing "unable to launch forgemodloader"](#fixing-unable-to-launch-forgemodloader)
* [Running a server with a packwiz modpack](#running-a-server-with-a-packwiz-modpack)
* [Working with mods and plugins](#working-with-mods-and-plugins)
* [Optional plugins, mods, and config attach points](#optional-plugins-mods-and-config-attach-points)
* [Auto-downloading SpigotMC/Bukkit/PaperMC plugins](#auto-downloading-spigotmcbukkitpapermc-plugins)
* [Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers](#downloadable-modplugin-pack-for-forge-fabric-and-bukkit-like-servers)
* [<strong>ForgeAPI</strong> usage to use non-version specific projects](#forgeapi-usage-to-use-non-version-specific-projects)
* [Generic pack file](#generic-pack-file)
* [Mod/Plugin URL Listing File](#modplugin-url-listing-file)
* [Remove old mods/plugins](#remove-old-modsplugins)
* [Working with world data](#working-with-world-data)
* [Downloadable world](#downloadable-world)
* [Cloning world from a container path](#cloning-world-from-a-container-path)
* [Overwrite world on start](#overwrite-world-on-start)
* [Datapacks](#datapacks)
* [VanillaTweaks](#vanillatweaks)
* [Server configuration](#server-configuration)
* [Message of the Day](#message-of-the-day)
* [Difficulty](#difficulty)
* [Whitelist Players](#whitelist-players)
* [Op/Administrator Players](#opadministrator-players)
* [Server icon](#server-icon)
* [Rcon](#rcon)
* [Query](#query)
* [Max players](#max-players)
* [Max world size](#max-world-size)
* [Allow Nether](#allow-nether)
* [Announce Player Achievements](#announce-player-achievements)
* [Enable Command Block](#enable-command-block)
* [Force Gamemode](#force-gamemode)
* [Generate Structures](#generate-structures)
* [Hardcore](#hardcore)
* [Snooper](#snooper)
* [Max Build Height](#max-build-height)
* [Max Tick Time](#max-tick-time)
* [Spawn Animals](#spawn-animals)
* [Spawn Monsters](#spawn-monsters)
* [Spawn NPCs](#spawn-npcs)
* [Set spawn protection](#set-spawn-protection)
* [View Distance](#view-distance)
* [Level Seed](#level-seed)
* [Game Mode](#game-mode)
* [PVP Mode](#pvp-mode)
* [Level Type and Generator Settings](#level-type-and-generator-settings)
* [Custom Server Resource Pack](#custom-server-resource-pack)
* [Level / World Save Name](#level--world-save-name)
* [Online mode](#online-mode)
* [Allow flight](#allow-flight)
* [Server name](#server-name)
* [Server port](#server-port)
* [Other server property mappings](#other-server-property-mappings)
* [Miscellaneous Options](#miscellaneous-options)
* [Replacing variables inside configs](#replacing-variables-inside-configs)
* [Patching existing files](#patching-existing-files)
* [Running with a custom server JAR](#running-with-a-custom-server-jar)
* [Force re-download of the server file](#force-re-download-of-the-server-file)
* [Running as alternate user/group ID](#running-as-alternate-usergroup-id)
* [Memory Limit](#memory-limit)
* [JVM Options](#jvm-options)
* [Interactive and Color Console](#interactive-and-color-console)
* [Server Shutdown Options](#server-shutdown-options)
* [OpenJ9 Specific Options](#openj9-specific-options)
* [Enabling rolling logs](#enabling-rolling-logs)
* [Timezone Configuration](#timezone-configuration)
* [Enable Remote JMX for Profiling](#enable-remote-jmx-for-profiling)
* [Enable Aikar's Flags](#enable-aikars-flags)
* [HTTP Proxy](#http-proxy)
* [Using "noconsole" option](#using-noconsole-option)
* [Explicitly disable GUI](#explicitly-disable-gui)
* [Stop Duration](#stop-duration)
* [Setup only](#setup-only)
* [Enable Flare Flags](#enable-flare-flags)
* [Autopause](#autopause)
* [Description](#description)
* [Enabling Autopause](#enabling-autopause)
* [Autostop](#autostop)
* [Running on RaspberryPi](#running-on-raspberrypi)
* [Contributing](#contributing)
<!-- Added by: runner, at: Mon Jan 24 04:19:37 UTC 2022 -->
<!--te-->
## Mitigated Log4jShell Vulnerability ## Mitigated Log4jShell Vulnerability
**Please ensure you have pulled the latest image** since [all official mitigations](https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition) are automatically applied by the container startup process. **Please ensure you have pulled the latest image** since [all official mitigations](https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition) are automatically applied by the container startup process.
@@ -86,14 +210,9 @@ 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 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: 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:
-v /home/user/minecraft-data:/data docker run -d -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.
@@ -125,8 +244,6 @@ If you had used the commands in the first section, without the `-v` volume attac
> In this example, it is assumed the original container was given a `--name` of "mc", so change the container identifier accordingly. > In this example, it is assumed the original container was given a `--name` of "mc", so change the container identifier accordingly.
> You can also locate the Docker-managed directory from the `Source` field obtained from `docker inspect <container id or name> -f "{{json .Mounts}}"`
First, stop the existing container: First, stop the existing container:
```shell ```shell
docker stop mc docker stop mc
@@ -142,16 +259,6 @@ Now you can recreate the container with any environment variable changes, etc by
docker run -d -it --name mc-new -v mc:/data -p 25565:25565 -e EULA=TRUE -e MEMORY=2G itzg/minecraft-server docker run -d -it --name mc-new -v mc:/data -p 25565:25565 -e EULA=TRUE -e MEMORY=2G itzg/minecraft-server
``` ```
### Locating filesystem path of anonymous volume
The `Source` field from the output of this command will show where the anonymous volume is mounted from:
```shell
docker inspect -f "{{json .Mounts}}" CONTAINER_NAME_OR_ID
```
> **NOTE** On Windows with WSL the volumes path is `\\wsl$\docker-desktop-data\data\docker\volumes`
## Versions ## Versions
To use a different Minecraft version, pass the `VERSION` environment variable (case sensitive), which can have the value To use a different Minecraft version, pass the `VERSION` environment variable (case sensitive), which can have the value
@@ -175,26 +282,18 @@ 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
> **For Forge versions less than 1.18, you _must_ use the `java8-multiarch` (or other java8) image tag.** 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 | Ubuntu | Hotspot | amd64,arm64,armv7 | | latest | 17 | Debian | Hotspot | amd64,arm64,armv7 |
| java8 | 8 | Alpine | Hotspot | amd64 | | java8 | 8 | Alpine | Hotspot | amd64 |
| java8-jdk | 8 | Ubuntu | Hotspot+JDK | amd64 | | java8-multiarch | 8 | Debian | Hotspot | amd64,arm64,armv7 |
| java8-multiarch | 8 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java8-openj9 | 8 | Debian | OpenJ9 | amd64 | | java8-openj9 | 8 | Debian | OpenJ9 | amd64 |
| java8-graalvm-ce | 8 | Oracle | GraalVM CE | amd64 | | java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 |
| java11 | 11 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java11-jdk | 11 | Ubuntu | Hotspot+JDK | amd64,arm64,armv7 |
| java11-openj9 | 11 | Debian | OpenJ9 | amd64 | | java11-openj9 | 11 | Debian | OpenJ9 | amd64 |
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 | | java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java17-jdk | 17 | Ubuntu | Hotspot+JDK | amd64,arm64,armv7 |
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 | | 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:
@@ -214,43 +313,11 @@ The following image tags have been deprecated and are no longer receiving update
- multiarch-latest - multiarch-latest
- java16/java16-openj9 - java16/java16-openj9
## Related Projects
### [itzg/minecraft-bedrock-server](https://github.com/itzg/docker-minecraft-bedrock-server)
Docker image that runs a Minecraft Bedrock server.
### [mc-router](https://github.com/itzg/mc-router)
Lightweight multiplexer/proxy for Minecraft Java servers. Provided as a stand-alone application and a Docker image.
### [itzg/bungeecord](https://github.com/itzg/docker-bungeecord/)
Docker image that runs a proxy powered by Bungeecord, Velocity, or Waterfall
### [itzg/mc-backup](https://github.com/itzg/docker-mc-backup)
Docker image that runs as a side-car container to backup world data.
### [rcon-cli](https://github.com/itzg/rcon-cli)
A tool that is bundled with this image to provide CLI access to an RCON endpoint.
### [mc-monitor](https://github.com/itzg/mc-monitor)
A tool that is bundled with this image that provides health checks and metrics reporting, such as a Prometheus exporter or a telegraf data source.
### [mc-image-helper](https://github.com/itzg/mc-image-helper)
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 its `status` command to continually check on the container's. That can be observed from the `STATUS` column of `docker ps` 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`
``` ```
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
@@ -264,16 +331,6 @@ 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
@@ -334,13 +391,13 @@ To troubleshoot any issues with memory allocation reported by the JVM, set the e
### Running a Forge Server ### Running a Forge Server
Enable [Forge server](http://www.minecraftforge.net/) mode by adding a `-e TYPE=FORGE` to your command-line. Enable [Forge server](http://www.minecraftforge.net/wiki/) mode by adding a `-e TYPE=FORGE` to your command-line.
The overall version is specified by `VERSION`, [as described in the section above](#versions) and will run the recommended Forge version by default. You can also choose to run a specific Forge version with `FORGE_VERSION`, such as `-e FORGE_VERSION=14.23.5.2854`. The overall version is specified by `VERSION`, [as described in the section above](#versions) and will run the recommended Forge version by default. You can also choose to run a specific Forge version with `FORGEVERSION`, such as `-e FORGEVERSION=14.23.5.2854`.
docker run -d -v /path/on/host:/data \ docker run -d -v /path/on/host:/data \
-e TYPE=FORGE \ -e TYPE=FORGE \
-e VERSION=1.12.2 -e FORGE_VERSION=14.23.5.2854 \ -e VERSION=1.12.2 -e FORGEVERSION=14.23.5.2854 \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
To use a pre-downloaded Forge installer, place it in the attached `/data` directory and To use a pre-downloaded Forge installer, place it in the attached `/data` directory and
@@ -357,11 +414,9 @@ the URL with `FORGE_INSTALLER_URL`, such as:
In both of the cases above, there is no need for the `VERSION` or `FORGEVERSION` variables. In both of the cases above, there is no need for the `VERSION` or `FORGEVERSION` variables.
> If an error occurred while installing Forge, it might be possible to resolve by temporarily setting `FORGE_FORCE_REINSTALL` to "true". Be sure to remove that variable after successfully starting the server.
### Running a Fabric Server ### Running a Fabric Server
Enable [Fabric server](https://fabricmc.net/) mode by adding a `-e TYPE=FABRIC` to your command-line. Enable [Fabric server](https://fabricmc.net/) mode by adding a `-e TYPE=FABRIC` to your command-line. By default, the container will install the latest [fabric-loader](https://fabricmc.net/wiki/documentation:fabric_loader) using the latest [fabric-installer](https://fabricmc.net/use/), against the minecraft server version you have defined with `VERSION` (defaulting to the latest vanilla release of the game).
``` ```
docker run -d -v /path/on/host:/data \ docker run -d -v /path/on/host:/data \
@@ -369,49 +424,19 @@ docker run -d -v /path/on/host:/data \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
``` ```
By default, the container will install the latest [fabric server launcher](https://fabricmc.net/use/server/), using the latest [fabric-loader](https://fabricmc.net/wiki/documentation:fabric_loader) against the minecraft version you have defined with `VERSION` (defaulting to the latest vanilla release of the game).
A specific loader or launcher version other than the latest can be requested using `FABRIC_LOADER_VERSION` and `FABRIC_LAUNCHER_VERSION` respectively, such as:
```
docker run -d -v /path/on/host:/data ... \
-e TYPE=FABRIC \
-e FABRIC_LAUNCHER_VERSION=0.10.2 \
-e FABRIC_LOADER_VERSION=0.13.1
```
> If you wish to use an alternative launcher you can:
> * Provide the path to a custom launcher jar available to the container with `FABRIC_LAUNCHER`, relative to `/data` (such as `-e FABRIC_LAUNCHER=fabric-server-custom.jar`)
> * Provide the URL to a custom launcher jar with `FABRIC_LAUNCHER_URL` (such as `-e FABRIC_LAUNCHER_URL=http://HOST/fabric-server-custom.jar`)
See the [Working with mods and plugins](#working-with-mods-and-plugins) section to set up Fabric mods and configuration. See the [Working with mods and plugins](#working-with-mods-and-plugins) section to set up Fabric mods and configuration.
### Running a Quilt Server A specific loader version other than the latest can be requested using `FABRIC_LOADER_VERSION`, such as:
Enable [Quilt server](https://quiltmc.org/) mode by adding a `-e TYPE=QUILT` to your command-line.
```
docker run -d -v /path/on/host:/data \
-e TYPE=QUILT \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
```
By default, the container will install the latest [quilt server launcher](https://quiltmc.org/install/server/), using the latest [quilt-installer](https://github.com/QuiltMC/quilt-installer) against the minecraft version you have defined with `VERSION` (defaulting to the latest vanilla release of the game).
A specific loader or installer version other than the latest can be requested using `QUILT_LOADER_VERSION` and `QUILT_INSTALLER_VERSION` respectively, such as:
``` ```
docker run -d -v /path/on/host:/data ... \ docker run -d -v /path/on/host:/data ... \
-e TYPE=QUILT \ -e FABRIC_LOADER_VERSION=0.12.8
-e QUILT_LOADER_VERSION=0.16.0 \
-e QUILT_INSTALLER_VERSION=0.4.1
``` ```
> If you wish to use an alternative launcher you can: If you wish to use an alternative installer you can:
> * Provide the path to a custom launcher jar available to the container with `QUILT_LAUNCHER`, relative to `/data` (such as `-e QUILT_LAUNCHER=quilt-server-custom.jar`) * Specify an alternative version using `FABRIC_INSTALLER_VERSION` (such as `-e FABRIC_INSTALLER_VERSION=0.10.2`)
> * Provide the URL to a custom launcher jar with `QUILT_LAUNCHER_URL` (such as `-e QUILT_LAUNCHER_URL=http://HOST/quilt-server-custom.jar`) * Provide the path to a custom installer jar available to the container with `FABRIC_INSTALLER`, relative to `/data` (such as `-e FABRIC_INSTALLER=fabric-installer-0.5.0.32.jar`)
* Provide the URL to a custom installer jar with `FABRIC_INSTALLER_URL` (such as `-e FABRIC_INSTALLER_URL=http://HOST/fabric-installer-0.5.0.32.jar`)
See the [Working with mods and plugins](#working-with-mods-and-plugins) section to set up Quilt mods and configuration.
### Running a Bukkit/Spigot server ### Running a Bukkit/Spigot server
@@ -430,7 +455,7 @@ You can build spigot from source by adding `-e BUILD_FROM_SOURCE=true`
Plugins can either be managed within the `plugins` subdirectory of the [data directory](#data-directory) or you can also [attach a `/plugins` volume](#optional-plugins-mods-and-config-attach-points). If you add plugins while the container is running, you'll need to restart it to pick those up. Plugins can either be managed within the `plugins` subdirectory of the [data directory](#data-directory) or you can also [attach a `/plugins` volume](#optional-plugins-mods-and-config-attach-points). If you add plugins while the container is running, you'll need to restart it to pick those up.
[You can also auto-download plugins using `SPIGET_RESOURCES`.](#auto-downloading-spigotmcbukkitpapermc-plugins-with-spiget) [You can also auto-download plugins using `SPIGET_RESOURCES`.](#auto-downloading-spigotmcbukkitpapermc-plugins)
> NOTE some of the `VERSION` values are not as intuitive as you would think, so make sure to click into the version entry to find the **exact** version needed for the download. For example, "1.8" is not sufficient since their download naming expects `1.8-R0.1-SNAPSHOT-latest` exactly. > NOTE some of the `VERSION` values are not as intuitive as you would think, so make sure to click into the version entry to find the **exact** version needed for the download. For example, "1.8" is not sufficient since their download naming expects `1.8-R0.1-SNAPSHOT-latest` exactly.
@@ -448,7 +473,19 @@ If you are hosting your own copy of Paper you can override the download URL with
If you have attached a host directory to the `/data` volume, then you can install plugins via the `plugins` subdirectory. You can also [attach a `/plugins` volume](#optional-plugins-mods-and-config-attach-points). If you add plugins while the container is running, you'll need to restart it to pick those up. If you have attached a host directory to the `/data` volume, then you can install plugins via the `plugins` subdirectory. You can also [attach a `/plugins` volume](#optional-plugins-mods-and-config-attach-points). If you add plugins while the container is running, you'll need to restart it to pick those up.
[You can also auto-download plugins using `SPIGET_RESOURCES`.](#auto-downloading-spigotmcbukkitpapermc-plugins-with-spiget) [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
@@ -456,16 +493,16 @@ A [Pufferfish](https://github.com/pufferfish-gg/Pufferfish) server, which is "a
-e TYPE=PUFFERFISH -e TYPE=PUFFERFISH
> NOTE: The `VERSION` variable is used to select branch latest, 1.18, or 1.17. Use PUFFERFISH_BUILD to really select the SERVER VERSION number. > NOTE: The `VERSION` variable is used to select a Pufferfish branch to download from. The available options are "LATEST" and "1.18"
Extra variables: Extra variables:
- `PUFFERFISH_BUILD=lastSuccessfulBuild` : set a specific Pufferfish build to use. Example: selecting build 47 => 1.18.1, or build 50 => 1.18.2 etc - `PUFFERFISH_BUILD=lastSuccessfulBuild` : set a specific Pufferfish 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
### Running a Purpur server ### Running a Purpur server
A [Purpur](https://purpurmc.org/) server, which is "a drop-in replacement for Paper servers designed for configurability and new, fun, exciting gameplay features." 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."
-e TYPE=PURPUR -e TYPE=PURPUR
@@ -475,7 +512,6 @@ 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
@@ -483,6 +519,8 @@ 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.
@@ -506,16 +544,6 @@ A [Catserver](http://catserver.moe/) type server can be used with
> **NOTE** Catserver only provides a single release stream, so `VERSION` is ignored > **NOTE** Catserver only provides a single release stream, so `VERSION` is ignored
### Running a Loliserver type server
A [Loliserver](https://github.com/Loli-Server/LoliServer) type server can be used with
-e TYPE=LOLISERVER
> **NOTE** Loliserver only provides a single release stream, so `VERSION` is ignored
> **Disclaimer** The retrieval of the serverjar is not bulletproof. It can and probably will change in the future.
### Running a Canyon server ### Running a Canyon server
[Canyon](https://github.com/canyonmodded/canyon) is a fork of CraftBukkit for Minecraft Beta 1.7.3. It includes multiple enhancements whilst also retaining compatibility with old Bukkit plugins and mods as much as possible. [Canyon](https://github.com/canyonmodded/canyon) is a fork of CraftBukkit for Minecraft Beta 1.7.3. It includes multiple enhancements whilst also retaining compatibility with old Bukkit plugins and mods as much as possible.
@@ -558,10 +586,7 @@ Configuration options with defaults:
- `FORCE_REDOWNLOAD`=false - `FORCE_REDOWNLOAD`=false
- `LIMBO_SCHEMA_FILENAME`=default.schem - `LIMBO_SCHEMA_FILENAME`=default.schem
- `LEVEL`="Default;${LIMBO_SCHEMA - `LEVEL`="Default;${LIMBO_SCHEMA_FILENAME}"
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.
@@ -577,17 +602,13 @@ 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 Ubuntu with Hotspot images listed in [the Java versions section](#running-minecraft-server-on-different-java-version). > **NOTE** requires one of the Debian based 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.
### Environment Variables: ### Environment Variables:
- `FTB_MODPACK_ID`: **required**, the numerical ID of the modpack to install. The ID can be located by [finding the modpack](https://www.feed-the-beast.com/modpack) and locating the ID in this part of the URL: - `FTB_MODPACK_ID`: **required**, the numerical ID of the modpack to install. The ID can be located by [finding the modpack](https://www.feed-the-beast.com/modpack) and using the "ID" displayed next to the name
``` - `FTB_MODPACK_VERSION_ID`: optional, the numerical Id of the version to install. If not specified, the latest version will be installed. The "Version ID" can be obtained by drilling into the Versions tab and clicking a specific version.
https://www.feed-the-beast.com/modpacks/23-ftb-infinity-evolved-17
^^
```
- `FTB_MODPACK_VERSION_ID`: optional, the numerical ID of the version to install. If not specified, the latest version will be installed. The "Version ID" can be obtained by hovering over a server file entry and grabbing [this ID in the URL](docs/ftba-version-id-popup.png).
### Upgrading ### Upgrading
@@ -601,7 +622,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:java8-multiarch itzg/minecraft-server: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.
@@ -681,9 +702,7 @@ 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, 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. 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.
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.
@@ -691,7 +710,7 @@ These paths work well if you want to have a common set of modules in a separate
> For more flexibility with mods/plugins preparation, you can declare directories to use in [the `MODS` variable](#downloadable-modplugin-pack-for-forge-fabric-and-bukkit-like-servers) > For more flexibility with mods/plugins preparation, you can declare directories to use in [the `MODS` variable](#downloadable-modplugin-pack-for-forge-fabric-and-bukkit-like-servers)
### Auto-downloading SpigotMC/Bukkit/PaperMC plugins with Spiget ### Auto-downloading SpigotMC/Bukkit/PaperMC plugins
The `SPIGET_RESOURCES` variable can be set with a comma-separated list of SpigotMC resource IDs to automatically download [SpigotMC resources/plugins](https://www.spigotmc.org/resources/) using [the spiget API](https://spiget.org/). Resources that are zip files will be expanded into the plugins directory and resources that are simply jar files will be moved there. The `SPIGET_RESOURCES` variable can be set with a comma-separated list of SpigotMC resource IDs to automatically download [SpigotMC resources/plugins](https://www.spigotmc.org/resources/) using [the spiget API](https://spiget.org/). Resources that are zip files will be expanded into the plugins directory and resources that are simply jar files will be moved there.
@@ -706,20 +725,6 @@ 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"
@@ -739,25 +744,18 @@ You may also download or copy over individual mods using the `MODS` environment
docker run -d -e MODS=https://www.example.com/mods/mod1.jar,/plugins/common,/plugins/special/mod2.jar ... docker run -d -e MODS=https://www.example.com/mods/mod1.jar,/plugins/common,/plugins/special/mod2.jar ...
### ForgeAPI usage to use non-version specific projects ### **ForgeAPI** usage to use non-version specific projects
**NOTE:** This potentially could lead to unexpected behavior if the Mod receives an update with unexpected behavior. **NOTE:** This potentially could lead to unexpected behavior if the Mod recieves an update with unexpected behavior.
This is more complicated because you will be pulling/using the latest mod for the release of your game. To get started make sure you have a [CursedForge API Key](https://docs.curseforge.com/#getting-started). Then use the environmental parameters in your docker build. This is more complicated because you will be pulling/using the latest mod for the release of your game. To get started make sure you have a [CursedForge API Key](https://docs.curseforge.com/#getting-started). Then use the environmental parameters in your docker build.
Please be aware of the following when using these options for your mods:
* Mod Release types: Release, Beta, and Alpha.
* Mod dependencies: Required and Optional
* Mod family: Fabric, Forge, and Bukkit.
Parameters to use the ForgeAPI: Parameters to use the ForgeAPI:
* `MODS_FORGEAPI_KEY` - Required * `MODS_FORGEAPI_KEY` - Required
* `MODS_FORGEAPI_FILE` - Required or use MODS_FORGEAPI_PROJECTIDS (Overrides MODS_FORGEAPI_PROJECTIDS) * `MODS_FORGEAPI_FILE` - Required or use MODS_FORGEAPI_PROJECTIDS (Overrides MODS_FORGEAPI_PROJECTIDS)
* `MODS_FORGEAPI_PROJECTIDS` - Required or use MODS_FORGEAPI_FILE * `MODS_FORGEAPI_PROJECTIDS` - Required or use MODS_FORGEAPI_FILE
* `MODS_FORGEAPI_RELEASES` - Default is release, Options: [Release|Beta|Alpha] * `MODS_FORGEAPI_RELEASES` - Default is release, Options: [Release|Beta|Alpha]
* `MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES` - Default is False, attempts to download required mods (releaseType Release) defined in Forge.
* `MODS_FORGEAPI_IGNORE_GAMETYPE` - Default is False, Allows for filtering mods on family type: FORGE, FABRIC, and BUKKIT. (Does not filter for Vanilla or custom)
* `REMOVE_OLD_FORGEAPI_MODS` - Default is False * `REMOVE_OLD_FORGEAPI_MODS` - Default is False
* `REMOVE_OLD_DATAPACKS_DEPTH` - Default is 1 * `REMOVE_OLD_DATAPACKS_DEPTH` - Default is 1
* `REMOVE_OLD_DATAPACKS_INCLUDE` - Default is *.jar * `REMOVE_OLD_DATAPACKS_INCLUDE` - Default is *.jar
@@ -770,13 +768,7 @@ Example of expected forge api project ids, releases, and key:
MODS_FORGEAPI_KEY: $WRX... MODS_FORGEAPI_KEY: $WRX...
``` ```
Example of expected ForgeAPI file format. Example of expected ForgeAPI file format: **Note**: name is currently unused, but can be used to document each entry.
**Field Description**:
* `name` is currently unused, but can be used to document each entry.
* `projectId` id is the id found on the CurseForge website for a particular mod
* `releaseType` Type corresponds to forge's R, B, A icon for each file. Default Release, options are (release|beta|alpha).
* `fileName` is used for version pinning if latest file will not work for you.
```json ```json
[ [
@@ -789,35 +781,15 @@ Example of expected ForgeAPI file format.
"name": "fabric voice mod", "name": "fabric voice mod",
"projectId": "416089", "projectId": "416089",
"releaseType": "beta" "releaseType": "beta"
},
{
"name": "Biomes o plenty",
"projectId": "220318",
"fileName": "BiomesOPlenty-1.18.1-15.0.0.100-universal.jar",
"releaseType": "release"
} }
] ]
``` ```
### Generic pack files ### Generic pack file
To install all the server content (jars, mods, plugins, configs, etc.) from a zip or tgz file, then set `GENERIC_PACK` to the container path or URL of the archive file. This can also be used to apply a CurseForge modpack that is missing a server start script and/or Forge installer. To install all of the server content (jars, mods, plugins, configs, etc) from a zip file, such as a CurseForge modpack that is missing a server start script, then set `GENERIC_PACK` to the container path of the zip file. That, combined with `TYPE`, allows for custom content along with container managed server download and install.
If multiple generic packs need to be applied together, set `GENERIC_PACKS` instead, with a comma separated list of archive file paths and/or URLs to files. If multiple generic packs need to be applied together, set `GENERIC_PACKS` instead, with a comma separated list of zip file paths and/or URLs to zip files.
To avoid repetition, each entry will be prefixed by the value of `GENERIC_PACKS_PREFIX` and suffixed by the value of `GENERIC_PACKS_SUFFIX`, both of which are optional. For example, the following variables
```
GENERIC_PACKS=configs-v9.0.1,mods-v4.3.6
GENERIC_PACKS_PREFIX=https://cdn.example.org/
GENERIC_PACKS_SUFFIX=.zip
```
would expand to `https://cdn.example.org/configs-v9.0.1.zip,https://cdn.example.org/mods-v4.3.6.zip`.
If applying large generic packs, the update can be time-consuming. To skip the update set `SKIP_GENERIC_PACK_UPDATE_CHECK` to "true". Conversely, the generic pack(s) can be forced to be applied by setting `FORCE_GENERIC_PACK_UPDATE` to "true".
The most time consuming portion of the generic pack update is generating and comparing the SHA1 checksum. To skip the checksum generation, set `SKIP_GENERIC_PACK_CHECKSUM` to "true.
### Mod/Plugin URL Listing File ### Mod/Plugin URL Listing File
@@ -882,103 +854,68 @@ 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`: comma-separated list of zip file URL, zip file in container, or directory in container * `DATAPACKS_FILE`
* `DATAPACKS_FILE`: a text file within the container where each line is a zip file URL, zip file in container, or directory in container * `REMOVE_OLD_DATAPACKS`
* `REMOVE_OLD_DATAPACKS`: if "true" the datapacks directory is removed of everything matching `REMOVE_OLD_DATAPACKS_INCLUDE`, but excluding `REMOVE_OLD_DATAPACKS_EXCLUDE` no deeper than `REMOVE_OLD_DATAPACKS_DEPTH` * `REMOVE_OLD_DATAPACKS_DEPTH`
* `REMOVE_OLD_DATAPACKS_DEPTH`: default is 16 * `REMOVE_OLD_DATAPACKS_INCLUDE`
* `REMOVE_OLD_DATAPACKS_INCLUDE`: default is `*.zip` * `REMOVE_OLD_DATAPACKS_EXCLUDE`
* `REMOVE_OLD_DATAPACKS_EXCLUDE`: default is empty
Datapacks will be placed in `/data/$LEVEL/datapacks` Datapacks will be placed in `/data/$LEVEL/datapacks`
### VanillaTweaks ### VanillaTweaks
[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. VanillaTweaks datapacks can be installed with a share code from the website UI **OR** a json file to specify packs to download and install.
The share code is the part following the hash sign, as shown here:
```
https://vanillatweaks.net/share/#MGr52E
------
|
+- share code MGr52E
```
Accepted Parameters: Accepted Parameters:
- `VANILLATWEAKS_FILE`: comma separated list of JSON VanillaTweak pack files accessible within the container - `VANILLATWEAKS_FILE`
- `VANILLATWEAKS_SHARECODE`: comma separated list of share codes - `VANILLATWEAKS_SHARECODE`
- `REMOVE_OLD_VANILLATWEAKS`
- `REMOVE_OLD_VANILLATWEAKS_DEPTH`
- `REMOVE_OLD_VANILLATWEAKS_INCLUDE`
- `REMOVE_OLD_VANILLATWEAKS_EXCLUDE`
Example of expected VanillaTweaks share codes: Example of expected Vanillatweaks sharecode:
**Note**: ResourcePacks, DataPacks, and CraftingTweaks all have separate sharecodes
```yaml ```yaml
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT VANILLATWEAKS_SHARECODE: MGr52E
``` ```
Example of expected VanillaTweaks files: Example of expected Vanillatweaks file format:
```yaml
VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
```
Datapacks Json:
```json ```json
{ {
"type": "datapacks",
"version": "1.18", "version": "1.18",
"packs": { "packs": {
"survival": [ "survival": [
"graves", "graves",
"multiplayer sleep" "multiplayer sleep",
"afk display",
"armor statues",
"unlock all recipes",
"fast leaf decay",
"coordinates hud"
], ],
"items": ["armored elytra"] "items": ["armored elytra"]
} }
} }
``` ```
Resourcepacks Json: Datapacks will be placed in `/data/$LEVEL/datapacks`
```json
{
"type": "resourcepacks",
"version": "1.18",
"packs": {
"aesthetic": ["CherryPicking", "BlackNetherBricks", "AlternateBlockDestruction"]
}
}
```
CraftingTweaks Json:
```json
{
"type": "craftingtweaks",
"version": "1.18",
"packs": {
"quality of life": [
"dropper to dispenser",
"double slabs",
"back to blocks"
]
}
}
```
## Server configuration ## Server configuration
By default, the server configuration will be created and set based on the following environment variables, but only the first time the server is started. If the `server.properties` file already exists, the values in them will not be changed. By default, the server configuration will be created and set based on the following environment variables, but only the first time the server is started. If the `server.properties` file already exists, the values in them will not be changed.
If you prefer to manually manage the `server.properties` file, set `OVERRIDE_SERVER_PROPERTIES` to "false". Similarly, you can entirely skip the startup script's creation of `server.properties` by setting `SKIP_SERVER_PROPERTIES` to "true". If you would like to override the server configuration each time the container starts up, you can set the `OVERRIDE_SERVER_PROPERTIES` environment variable like:
docker run -d -e OVERRIDE_SERVER_PROPERTIES=true ...
This will reset any manual configuration of the `server.properties` file, so if you want to make any persistent configuration changes you will need to make sure you have properly set the proper environment variables in your container configuration.
In the opposite case, you can skip the startup script's creation of `server.properties`, by setting `SKIP_SERVER_PROPERTIES` to "true".
> NOTE: to clear a server property, set the variable to an empty string, such as `-e RESOURCE_PACK=""`. A variables that maps to a server property that is unset, is ignored and the existing `server.property` is left unchanged. > NOTE: to clear a server property, set the variable to an empty string, such as `-e RESOURCE_PACK=""`. A variables that maps to a server property that is unset, is ignored and the existing `server.property` is left unchanged.
@@ -1002,10 +939,6 @@ renders
![](docs/motd-example.png) ![](docs/motd-example.png)
To produce a multi-line MOTD, you will need to double escape the newline such as
-e MOTD="Line one\\nLine two"
### Difficulty ### Difficulty
The difficulty level (default: `easy`) can be set like: The difficulty level (default: `easy`) can be set like:
@@ -1021,12 +954,12 @@ values.
> **NOTE** it is very important to set this with servers exposed to the internet where you want only limited players to join. > **NOTE** it is very important to set this with servers exposed to the internet where you want only limited players to join.
To whitelist players for your Minecraft server, you can: To whitelist players for your Minecraft server, you can:
- Provide a list of usernames and/or UUIDs separated by commas via the `WHITELIST` environment variable
`docker run -d -e WHITELIST=user1,uuid2 ...`
- Provide the url or path to a whitelist file via `WHITELIST_FILE` environment variable - Provide the url or path to a whitelist file via `WHITELIST_FILE` environment variable
`docker run -d -e WHITELIST_FILE=/extra/whitelist.json ...` `docker run -d -e WHITELIST_FILE=/extra/whitelist.json ...`
- Provide a list of usernames and/or UUIDs separated by commas via the `WHITELIST` environment variable
`docker run -d -e WHITELIST=user1,uuid2 ...`
When either is set, [whitelisting of connecting users](https://minecraft.fandom.com/wiki/Server.properties#white-list) is enabled . If managing the list manually, `ENABLE_WHITELIST` can be set to "true" to set the `white-list` property. To enforce the whitelist and auto-kick players not included in whitelist configuration, set `ENFORCE_WHITELIST=TRUE`. **By default** any user can join your Minecraft server if it's publicly accessible, regardless of your whitelist configuration.
If whitelist configuration already exists, `WHITELIST_FILE` will not be retrieved and any usernames in `WHITELIST` are **added** to the whitelist configuration. You can enforce regeneration of the whitelist on each server startup by setting `OVERRIDE_WHITELIST` to "true". This will delete the whitelist file before processing whitelist configuration. If whitelist configuration already exists, `WHITELIST_FILE` will not be retrieved and any usernames in `WHITELIST` are **added** to the whitelist configuration. You can enforce regeneration of the whitelist on each server startup by setting `OVERRIDE_WHITELIST` to "true". This will delete the whitelist file before processing whitelist configuration.
@@ -1036,7 +969,7 @@ If whitelist configuration already exists, `WHITELIST_FILE` will not be retrieve
> If running Minecraft 1.7.5 or earlier, these variables will apply to `white-list.txt`, with 1.7.6 implementing support for `whitelist.json`. Make sure your `WHITELIST_FILE` is in the appropriate format. > If running Minecraft 1.7.5 or earlier, these variables will apply to `white-list.txt`, with 1.7.6 implementing support for `whitelist.json`. Make sure your `WHITELIST_FILE` is in the appropriate format.
To [enforce the whitelist changes immediately](https://minecraft.fandom.com/wiki/Server.properties#enforce-whitelist) when whitelist commands are used , set `ENFORCE_WHITELIST` to "true". If either `WHITELIST_FILE` or `WHITELIST` is provided, the server property `white-list` is automatically set to `true`, enabline whitelist functionality. Alternatively you can set `ENABLE_WHITELIST=TRUE` to only set the server property `white-list` without modifying the whitelist file. In this case the whitelist can be managed using the `whitelist add` and `whitelist remove` commands. Remember you can set enforcement via the `ENFORCE_WHITELIST` variable.
### Op/Administrator Players ### Op/Administrator Players
@@ -1050,14 +983,6 @@ If ops configuration already exists, `OPS_FILE` will not be retrieved and any us
> Similar to whitelists, you can provide both `OPS_FILE` and `OPS`, and Minecraft 1.7.5 or earlier will use `ops.txt` rather than `ops.json`. > Similar to whitelists, you can provide both `OPS_FILE` and `OPS`, and Minecraft 1.7.5 or earlier will use `ops.txt` rather than `ops.json`.
### Enable/disable initial selection of datapacks
New to [22W42A](https://www.minecraft.net/en-us/article/minecraft-snapshot-22w42a), datapacks with feature flags can be controlled before initial world creation by setting these to a comma separated list of packs:
- `INITIAL_ENABLED_PACKS`
such as "update_1_20,bundle"
- `INITIAL_DISABLED_PACKS`
### Server icon ### Server icon
A server icon can be configured using the `ICON` variable. The image will be automatically A server icon can be configured using the `ICON` variable. The image will be automatically
@@ -1069,17 +994,13 @@ The server icon which has been set doesn't get overridden by default. It can be
docker run -d -e ICON=http://..../some/other/image.png -e OVERRIDE_ICON=TRUE... docker run -d -e ICON=http://..../some/other/image.png -e OVERRIDE_ICON=TRUE...
### RCON ### Rcon
RCON is **enabled by default** to allow for graceful shut down the server and coordination of save state during backups. RCON can be disabled by setting `ENABLE_RCON` to "false". To use rcon use the `ENABLE_RCON` and `RCON_PASSWORD` variables.
The default RCON password is _"minecraft",_ but it's **highly** recommended to override that.
By default rcon port will be `25575` but can easily be changed with the `RCON_PORT` variable.
The default password is "minecraft" but **change the password before deploying into production** by setting `RCON_PASSWORD`. docker run -d -e ENABLE_RCON=true -e RCON_PASSWORD=testing
**DO NOT MAP THE RCON PORT EXTERNALLY** unless you aware of all the consequences and have set a **secure password** with `RCON_PASSWORD`.
> Mapping ports (`-p` command line or `ports` in compose) outside the container and docker networking needs to be a purposeful choice. Most production Docker deployments do not need any of the Minecraft ports mapped externally from the server itself.
By default, the server listens for RCON on port 25575 within the container. It can be changed with `RCON_PORT` but only do this if you have a very good reason. **DO NOT change `rcon.port` via `server.properties`** or integrations will break.
### Query ### Query
@@ -1229,9 +1150,30 @@ 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 listed here](https://minecraft.fandom.com/wiki/Server.properties#level-type). be configured by setting `LEVEL_TYPE` to an expected type, for example
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). - DEFAULT
- 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
@@ -1320,27 +1262,7 @@ 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'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`. If you want to use a file for value (like when use secrets) you can add suffix `_FILE` to your variable name.
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`.
@@ -1498,17 +1420,10 @@ To let the JVM calculate the heap size from the container declared memory limit,
General JVM options can be passed to the Minecraft Server invocation by passing a `JVM_OPTS` General JVM options can be passed to the Minecraft Server invocation by passing a `JVM_OPTS`
environment variable. The JVM requires `-XX` options to precede `-X` options, so those can be declared in `JVM_XX_OPTS`. Both variables are space-delimited, raw JVM arguments. environment variable. The JVM requires `-XX` options to precede `-X` options, so those can be declared in `JVM_XX_OPTS`. Both variables are space-delimited, raw JVM arguments.
```
-e JVM_OPTS="-someJVMOption someJVMOptionValue"
```
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
@@ -1580,7 +1495,7 @@ To enable remote JMX, such as for profiling with VisualVM or JMC, add the enviro
### Enable Aikar's Flags ### Enable Aikar's Flags
[Aikar has done some research](https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/) into finding the optimal JVM flags for GC tuning, which becomes more important as more users are connected concurrently. The set of flags documented there can be added using [Aikar has does some research](https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/) into finding the optimal JVM flags for GC tuning, which becomes more important as more users are connected concurrently. The set of flags documented there can be added using
-e USE_AIKAR_FLAGS=true -e USE_AIKAR_FLAGS=true
@@ -1617,98 +1532,7 @@ 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 Pufferfish/Purpur, and is available in [plugin form](https://github.com/TECHNOVE/FlarePlugin) for other server types. Flare is built-in to Airplane/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
Before the container starts the Minecraft Server its output is prefixed with `[init]`, such as
```
[init] Starting the Minecraft server...
```
To also include the timestamp with each log, set `LOG_TIMESTAMP` to "true". The log output will then look like:
```
[init] 2022-02-05 16:58:33+00:00 Starting the Minecraft server...
```
### Auto-execute RCON commands
RCON commands can be configured to execute when the server starts, a client connects, or a client disconnects.
> When declaring several commands within a compose file environment variable, it's easiest to use YAML's `|-` [block style indicator](https://yaml-multiline.info/).
**On Server Start:**
```yaml
RCON_CMDS_STARTUP: |-
gamerule doFireTick false
pregen start 200
```
**On Client Connection:**
```yaml
RCON_CMDS_ON_CONNECT: |-
team join New @a[team=]
```
**Note:**
* On client connect we only know there was a connection, and not who connected. RCON commands will need to be used for that.
**On Client Disconnect:**
```yaml
RCON_CMDS_ON_DISCONNECT: |-
gamerule doFireTick true
```
**On First Client Connect**
```yaml
RCON_CMDS_FIRST_CONNECT: |-
pregen stop
```
**On Last Client Disconnect**
```yaml
RCON_CMDS_LAST_DISCONNECT: |-
kill @e[type=minecraft:boat]
pregen start 200
```
**Example of rules for new players**
Uses team NEW and team OLD to track players on the server. So move player with no team to NEW, run a command, move them to team OLD.
[Reference Article](https://www.minecraftforum.net/forums/minecraft-java-edition/redstone-discussion-and/2213523-detect-players-first-join)
```yaml
RCON_CMDS_STARTUP: |-
/pregen start 200
/gamerule doFireTick false
/team add New
/team add Old
RCON_CMDS_ON_CONNECT: |-
/team join New @a[team=]
/give @a[team=New] birch_boat
/team join Old @a[team=New]
RCON_CMDS_FIRST_CONNECT: |-
/pregen stop
RCON_CMDS_LAST_DISCONNECT: |-
/kill @e[type=minecraft:boat]
/pregen start 200
```
## Autopause ## Autopause
@@ -1728,8 +1552,6 @@ On startup the `server.properties` file is checked and, if applicable, a warning
The utility used to wake the server (`knock(d)`) works at network interface level. So the correct interface has to be set using the `AUTOPAUSE_KNOCK_INTERFACE` variable when using non-default networking environments (e.g. host-networking, Portainer oder NAS solutions). See the description of the variable below. The utility used to wake the server (`knock(d)`) works at network interface level. So the correct interface has to be set using the `AUTOPAUSE_KNOCK_INTERFACE` variable when using non-default networking environments (e.g. host-networking, Portainer oder NAS solutions). See the description of the variable below.
A file called `.paused` is created in `/data` directory when the server is paused and removed when the server is resumed. Other services may check for this file's existence before waking the server.
A starting, example compose file has been provided in [examples/docker-compose-autopause.yml](examples/docker-compose-autopause.yml). A starting, example compose file has been provided in [examples/docker-compose-autopause.yml](examples/docker-compose-autopause.yml).
### Enabling Autopause ### Enabling Autopause
@@ -1756,8 +1578,6 @@ 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.
@@ -1780,8 +1600,6 @@ 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

@@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
. "/start-utils"
: "${CONSOLE_IN_NAMED_PIPE:=/tmp/minecraft-console-in}" : "${CONSOLE_IN_NAMED_PIPE:=/tmp/minecraft-console-in}"
if [ $# = 0 ]; then if [ $# = 0 ]; then
@@ -12,12 +12,4 @@ if [ ! -p "${CONSOLE_IN_NAMED_PIPE}" ]; then
exit 1 exit 1
fi fi
if [ "$(id -u)" = 0 ]; then gosu minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'"
if [[ $(getDistro) == alpine ]]; then
exec su-exec minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'"
else
exec gosu minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'"
fi
else
echo "$@" >"${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}"
fi

View File

@@ -1,101 +0,0 @@
#!/bin/bash
: "${RCON_CMDS_STARTUP:=}"
: "${RCON_CMDS_ON_CONNECT:=}"
: "${RCON_CMDS_ON_DISCONNECT:=}"
: "${RCON_CMDS_FIRST_CONNECT:=}"
: "${RCON_CMDS_LAST_DISCONNECT:=}"
: "${RCON_CMDS_PERIOD:=10}"
# needed for the clients connected function residing in autopause
# shellcheck source=../auto/autopause-fcns.sh
. /auto/autopause-fcns.sh
# shellcheck source=start-utils
. ${SCRIPTS:-/}start-utils
run_command(){
rcon_cmd="$1"
logRcon "running - $rcon_cmd"
output=$(rcon-cli "$rcon_cmd")
logRcon "$output"
}
# wait for java process to be started
while :
do
if java_process_exists ; then
break
fi
sleep 0.1
done
CLIENTCONNECTIONS=0
STATE=INIT
while :
do
case X$STATE in
XINIT)
# Server startup
if mc_server_listening ; then
logRcon "MCServer is listening, running startup"
if [[ "$RCON_CMDS_STARTUP" ]]; then
while read -r cmd; do
run_command "$cmd"
done <<< "$RCON_CMDS_STARTUP"
fi
if
[[ -z "$RCON_CMDS_ON_CONNECT" ]] &&
[[ -z "$RCON_CMDS_ON_DISCONNECT" ]] &&
[[ -z "$RCON_CMDS_FIRST_CONNECT" ]] &&
[[ -z "$RCON_CMDS_LAST_DISCONNECT" ]]
then
logRcon "No addition rcon commands are given, stopping rcon cmd service"
exit 0
fi
STATE=II
fi
;;
XII)
CURR_CLIENTCONNECTIONS=$(java_clients_connections)
# First client connection
# Setting priority run order: on first client connection is usually to STOP maintence, aka DO THIS FIRST
if (( CURR_CLIENTCONNECTIONS > 0 )) && (( CLIENTCONNECTIONS == 0 )) && [[ "$RCON_CMDS_FIRST_CONNECT" ]]; then
logRcon "First Clients has Connected, running first connect cmds"
while read -r cmd; do
run_command "$cmd"
done <<< "$RCON_CMDS_FIRST_CONNECT"
fi
# When a client joins
if (( CURR_CLIENTCONNECTIONS > CLIENTCONNECTIONS )) && [[ "$RCON_CMDS_ON_CONNECT" ]]; then
logRcon "Clients have Connected, running connect cmds"
while read -r cmd; do
run_command "$cmd"
done <<< "$RCON_CMDS_ON_CONNECT"
# When a client leaves
elif (( CURR_CLIENTCONNECTIONS < CLIENTCONNECTIONS )) && [[ "$RCON_CMDS_ON_DISCONNECT" ]]; then
logRcon "Clients have Disconnected, running disconnect cmds"
while read -r cmd; do
run_command "$cmd"
done <<< "$RCON_CMDS_ON_DISCONNECT"
fi
# Last client connection
# Setting priority run order: on last client connection is usually to START maintence, aka DO THIS LAST
if (( CURR_CLIENTCONNECTIONS == 0 )) && (( CLIENTCONNECTIONS > 0 )) && [[ "$RCON_CMDS_LAST_DISCONNECT" ]]; then
logRcon "ALL Clients have Disconnected, running last disconnect cmds"
while read -r cmd; do
run_command "$cmd"
done <<< "$RCON_CMDS_LAST_DISCONNECT"
fi
CLIENTCONNECTIONS=$CURR_CLIENTCONNECTIONS
;;
*)
logRcon "Error: invalid state: $STATE"
;;
esac
sleep "$RCON_CMDS_PERIOD"
done

View File

@@ -1,27 +0,0 @@
#!/bin/sh
set -e
apk add --no-cache -U \
openssl \
imagemagick \
file \
lsof \
su-exec \
coreutils \
findutils \
procps \
shadow \
bash \
curl iputils \
git \
jq \
mysql-client \
tzdata \
rsync \
nano \
sudo \
knock \
tar \
zstd \
nfs-utils

View File

@@ -1,6 +0,0 @@
#!/bin/sh
set -e
addgroup -g 1000 minecraft
adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft

View File

@@ -1,12 +0,0 @@
#!/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

View File

@@ -1,38 +0,0 @@
#!/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

View File

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

View File

@@ -1,7 +0,0 @@
#!/bin/sh
set -e
distro=$(cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | sed -e 's/"//g')
"$(dirname "$0")/${distro}/$1".sh

View File

@@ -1,29 +0,0 @@
#!/bin/sh
set -e
apt-get update
DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
imagemagick \
file \
gosu \
sudo \
net-tools \
iputils-ping \
curl \
git \
jq \
dos2unix \
mysql-client \
tzdata \
rsync \
nano \
unzip \
zstd \
lbzip2 \
knockd \
nfs-common
apt-get clean

View File

@@ -1,6 +0,0 @@
#!/bin/sh
set -e
addgroup --gid 1000 minecraft
adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft

View File

@@ -1,16 +0,0 @@
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: {}

157
docker-versions-create.sh Executable file
View File

@@ -0,0 +1,157 @@
#!/bin/bash
#set -x
# Use this variable to indicate a list of branches that docker hub is watching
branches_list=(
'java8'
'java8-multiarch'
'java8-openj9'
'java11'
'java11-openj9'
'java17'
'java17-openj9'
)
function TrapExit {
echo "Checking out back in master"
git checkout master
}
batchMode=false
while getopts "hbt:s" arg
do
case $arg in
b)
batchMode=true
;;
t)
tag=${OPTARG}
;;
s)
tagArgs="-s -m 'Signed during docker-versions-create"
;;
h)
echo "
Usage $0 [options]
Options:
-b enable batch mode, which avoids interactive prompts and causes script to fail immediately
when any merge fails
-t TAG tag and push the current revision on master with the given tag
and apply respective tags to each branch
-s enable signed tags
-h display this help and exit
"
exit
;;
*)
echo "Unsupported arg $arg"
exit 2
;;
esac
done
${batchMode} && echo "Using batch mode"
trap TrapExit EXIT SIGTERM
test -d ./.git || { echo ".git folder was not found. Please start this script from root directory of the project!";
exit 1; }
# Making sure we are in master
git checkout master
git pull --all || { echo "Can't pull the repo!"; \
exit 1; }
if [[ $tag ]]; then
git tag $tag
git push origin $tag
fi
git_branches=$(git branch -a)
for branch in "${branches_list[@]}"; do
if [[ "$git_branches" != *"$branch"* ]]; then
echo "Can't update $branch because I can't find it in the list of branches."
exit 1
else
echo "Branch $branch found. Working with it."
git checkout "$branch" || { echo "Can't checkout into the branch. Don't know the cause."; \
exit 1; }
proceed='False'
while [[ "$proceed" == "False" ]]; do
# Ensure local branch is aligned with remote since docker-versions-create may have been run elsewhere
git pull
if git merge -m 'Auto-merging via docker-versions-create' master; then
proceed="True"
echo "Branch $branch updated to current master successfully"
# pushing changes to remote for this branch
git commit -m "Auto merge branch with master" -a
# push may fail if remote doesn't have this branch yet. In this case - sending branch
git push || git push -u origin "$branch" || { echo "Can't push changes to the origin."; exit 1; }
if [[ $tag ]]; then
git tag "$tag-$branch"
git push origin "$tag-$branch"
fi
elif ${batchMode}; then
status=$?
echo "Git merge failed in batch mode"
exit ${status}
# and trap exit gets us back to master
else
cat<<EOL
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Master merge in the branch $branch encountered an error!
You may try to fix the error and merge again. (Commit changes)
Or skip this branch merge completely.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
EOL
printf "Should we try again? (y):"
read -r answer
if [[ "$answer" == '' ]] || [[ "$answer" == 'y' ]] || [[ "$answer" == 'Y' ]]; then
# If you use non-local editor or files are changed in repo
cat <<EOL
The following commands may encounter an error!
This is completely fine if the changes were made locally and remote branch doesn't know about them.
EOL
# Updating branch from remote before trying again
git checkout master
git fetch --all
git pull -a
git checkout "$branch"
continue
else
break
fi
fi
done
fi
done
if [[ $tag ]]; then
if [ -f "$HOME/.github.env" ]; then
source "$HOME/.github.env"
if [[ $GITHUB_TOKEN ]]
then
auth=(-u ":$GITHUB_TOKEN")
base=https://api.github.com
: "${owner:=itzg}"
: "${repo:=docker-minecraft-server}"
read -r -d '' releaseBody << EOF
{
"tag_name": "$tag",
"name": "$tag",
"generate_release_notes": true
}
EOF
if ! curl "${auth[@]}" -H "Accept: application/vnd.github.v3+json" \
"${base}/repos/${owner}/${repo}/releases" -d "$releaseBody"; then
echo "ERROR failed to create github release $tag"
exit 1
fi
fi
fi
fi

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

1
examples/.gitignore vendored
View File

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

View File

@@ -1,150 +0,0 @@
version: '3.8'
####################################################################
# CURSEFORGE #
# #
# Date: 20221005 #
# #
# Mod: All The Mods 7 0.4.32 #
# #
# 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. #
# #
####################################################################
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_atm7:
####################################################################
# 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_atm7
####################################################################
# 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"
####################################################################
# CURSEFORGE INSTALL #
# #
# Sets install type to FORGE and specifys the zip folder name #
# and location of your mod pack. #
# #
# TYPE: Defines the install type as CURSEFORGE #
# #
# CF_SERVER_MOD: 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: CURSEFORGE
CF_SERVER_MOD: /modpacks/ATM7-0.4.32-server.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"
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

@@ -9,9 +9,7 @@ services:
environment: environment:
EULA: "true" EULA: "true"
TYPE: CURSEFORGE TYPE: CURSEFORGE
CF_SERVER_MOD: /modpacks/SIMPLE-SERVER-FILES-0.3.20.zip CF_SERVER_MOD: https://media.forgecdn.net/files/3482/169/Valhelsia+3-3.4.4-SERVER.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

@@ -1,161 +0,0 @@
version: '3.8'
####################################################################
# FORGE_GENERIC_PACK #
# #
# Date: 20221005 #
# #
# Mod: Better Minecraft Plus v40 #
# #
# Game Version: 1.16.5 #
# #
# 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. #
# #
####################################################################
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_bmp:
####################################################################
# 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:java8
container_name: mc_bmp
####################################################################
# 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. #
# #
# FORGE_VERSION: 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.16.5
FORGE_VERSION: 36.2.39
GENERIC_PACK: /modpacks/Better+MC+Server+Pack+PLUS+1.16.5+v40+HF.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

@@ -1,159 +0,0 @@
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. #
# #
# FORGE_VERSION: 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
FORGE_VERSION: 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: ""
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

@@ -11,7 +11,7 @@ services:
TYPE: FORGE TYPE: FORGE
DEBUG: "${DEBUG:-false}" DEBUG: "${DEBUG:-false}"
VERSION: ${VERSION:-1.17.1} VERSION: ${VERSION:-1.17.1}
FORGE_VERSION: ${FORGE_VERSION:-37.0.90} FORGEVERSION: ${FORGEVERSION:-37.0.90}
GENERIC_PACK: /modpacks/${MODPACK:-Server-Files-0.0.21.zip} GENERIC_PACK: /modpacks/${MODPACK:-Server-Files-0.0.21.zip}
REMOVE_OLD_MODS: "${REMOVE_OLD_MODS:-false}" REMOVE_OLD_MODS: "${REMOVE_OLD_MODS:-false}"
ports: ports:

View File

@@ -1,17 +0,0 @@
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

@@ -1,18 +0,0 @@
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

@@ -1,21 +0,0 @@
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,36 +0,0 @@
version: '3'
services:
minecraft:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
ports:
- "25565:25565"
volumes:
- "mc:/data"
environment:
EULA: "TRUE"
TYPE: FABRIC
MODS_FORGEAPI_PROJECTIDS: 433175
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE"
REMOVE_OLD_FORGEAPI_MODS: "TRUE"
# YAML Heredoc, be sure to use '|-' this will remove the first newline and final new line.
# This is versus '|' that will leaving with two empty strings at top and bottom.
RCON_CMDS_STARTUP: |-
/gamerule doFireTick false
/team add New
/team add Old
/chunky radius 1000
/chunky start
RCON_CMDS_ON_CONNECT: |-
/team join New @a[team=]
/give @a[team=New] birch_boat
/team join Old @a[team=New]
RCON_CMDS_FIRST_CONNECT: |-
/chunky pause
RCON_CMDS_LAST_DISCONNECT: |-
/kill @e[type=minecraft:boat]
/chunky continue
restart: unless-stopped
volumes:
mc: {}

View File

@@ -1,27 +1,27 @@
version: '3.8' version: '3.8'
services: services:
mc: rlcraft:
image: itzg/minecraft-server:java8 image: itzg/minecraft-server:java8
container_name: rlcraft
volumes: volumes:
- data:/data - rlcraft-modpack:/modpacks:ro
- ./modpacks:/modpacks:ro - rlcraft-data:/data
environment: environment:
EULA: "true" EULA: "true"
TYPE: "FORGE" TYPE: "FORGE"
VERSION: "1.12.2" VERSION: "1.12.2"
FORGE_VERSION: "14.23.5.2860" FORGEVERSION: "14.23.5.2855"
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"
# Download from https://www.curseforge.com/minecraft/modpacks/rlcraft and place in modpacks subdir GENERIC_PACK: "/modpacks/RLCraft_Server_Pack_1.12.2_Beta_v2.8.2.zip"
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:
data: rlcraft-data:
rlcraft-modpack:

View File

@@ -3,8 +3,6 @@ version: "3.8"
services: services:
mc: mc:
image: itzg/minecraft-server image: itzg/minecraft-server
tty: true
stdin_open: true
ports: ports:
- 25565:25565 - 25565:25565
environment: environment:

View File

@@ -3,16 +3,13 @@ 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: itzg/minecraft-server image: ${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: 9089,34315,3836
SPIGET_RESOURCES: ""
REMOVE_OLD_MODS: "true"
volumes: volumes:
- data:/data - data:/data

View File

@@ -14,8 +14,8 @@ services:
EULA: "TRUE" EULA: "TRUE"
#VERSION: "1.12.2" (Ensure this is compatbile with the version of SpongeForge you are using!) #VERSION: "1.12.2" (Ensure this is compatbile with the version of SpongeForge you are using!)
TYPE: "FORGE" TYPE: "FORGE"
FORGE_VERSION: "RECOMMENDED" FORGEVERSION: "RECOMMENDED"
#FORGE_VERSION: "14.23.5.2807" #FORGEVERSION: "14.23.5.2807"
CONSOLE: "false" CONSOLE: "false"
ENABLE_RCON: "true" ENABLE_RCON: "true"
RCON_PASSWORD: "testing" RCON_PASSWORD: "testing"

View File

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

View File

@@ -1,10 +0,0 @@
This project demonstrates the use of two compose projects, `dbs` and `servers`, where the following capabilities are demonstrated:
- Managing databases, such as MariaDB, in its own compose project: `dbs`
- Using an `.env` file to avoid including user details within the compose file
- Accessing the database from a separate project, `servers`, via an external network declaration
- LuckPerms is configured to access the MariaDB instance
- Isolating the Minecraft server container by purposely **not** declaring port mappings
- Running Waterfall as a proxy
- Using configuration mount points to pre-configure Waterfall and the Minecraft server
- Using Spiget to download plugins, in this case LuckPerms

View File

@@ -1,2 +0,0 @@
LUCKPERMS_USER=luckperms
LUCKPERMS_PASSWORD=luckpermspw

View File

@@ -1,21 +0,0 @@
version: "3.8"
services:
mariadb:
image: mariadb:10
environment:
MARIADB_RANDOM_ROOT_PASSWORD: yes
MARIADB_DATABASE: luckperms
# These are loaded by compose from .env
MARIADB_USER: ${LUCKPERMS_USER}
MARIADB_PASSWORD: ${LUCKPERMS_PASSWORD}
volumes:
- mariadb:/var/lib/mysql
adminer:
image: adminer
ports:
- "8806:8080"
volumes:
mariadb: {}

View File

@@ -1,41 +0,0 @@
version: "3.8"
services:
proxy:
image: itzg/bungeecord
environment:
TYPE: WATERFALL
ports:
- "25565:25577"
volumes:
- waterfall:/server
- ./waterfall-config:/config
mc:
image: itzg/minecraft-server
environment:
EULA: "true"
TYPE: PAPER
# 28140: luckperms
SPIGET_RESOURCES: "28140"
# since we're behind a proxy
ONLINE_MODE: "false"
volumes:
- mc:/data
# mainly to drop in config files specific to plugins
- ./mc-plugins:/plugins
networks:
# so proxy can reach us
- default
# so we can use databases project
- dbs
volumes:
mc: {}
waterfall: {}
networks:
dbs:
# declared in ../dbs
external: true
name: dbs_default

View File

@@ -1,710 +0,0 @@
####################################################################################################
# +----------------------------------------------------------------------------------------------+ #
# | __ __ ___ __ __ | #
# | | | | / ` |__/ |__) |__ |__) |\/| /__` | #
# | |___ \__/ \__, | \ | |___ | \ | | .__/ | #
# | | #
# | https://luckperms.net | #
# | | #
# | WIKI: https://luckperms.net/wiki | #
# | DISCORD: https://discord.gg/luckperms | #
# | BUG REPORTS: https://github.com/lucko/LuckPerms/issues | #
# | | #
# | Each option in this file is documented and explained here: | #
# | ==> https://luckperms.net/wiki/Configuration | #
# | | #
# | New options are not added to this file automatically. Default values are used if an | #
# | option cannot be found. The latest config versions can be obtained at the link above. | #
# +----------------------------------------------------------------------------------------------+ #
####################################################################################################
# +----------------------------------------------------------------------------------------------+ #
# | | #
# | ESSENTIAL SETTINGS | #
# | | #
# | Important settings that control how LuckPerms functions. | #
# | | #
# +----------------------------------------------------------------------------------------------+ #
# The name of the server, used for server specific permissions.
#
# - When set to "global" this setting is effectively ignored.
# - In all other cases, the value here is added to all players in a "server" context.
# - See: https://luckperms.net/wiki/Context
server: global
# If the servers own UUID cache/lookup facility should be used when there is no record for a player
# already in LuckPerms.
#
# - When this is set to 'false', commands using a player's username will not work unless the player
# has joined since LuckPerms was first installed.
# - To get around this, you can use a player's uuid directly in the command, or enable this option.
# - When this is set to 'true', the server facility is used. This may use a number of methods,
# including checking the servers local cache, or making a request to the Mojang API.
use-server-uuid-cache: false
# +----------------------------------------------------------------------------------------------+ #
# | | #
# | STORAGE SETTINGS | #
# | | #
# | Controls which storage method LuckPerms will use to store data. | #
# | | #
# +----------------------------------------------------------------------------------------------+ #
# How the plugin should store data
#
# - The various options are explained in more detail on the wiki:
# https://luckperms.net/wiki/Storage-types
#
# - Possible options:
#
# | Remote databases - require connection information to be configured below
# |=> MySQL
# |=> MariaDB (preferred over MySQL)
# |=> PostgreSQL
# |=> MongoDB
#
# | Flatfile/local database - don't require any extra configuration
# |=> H2 (preferred over SQLite)
# |=> SQLite
#
# | Readable & editable text files - don't require any extra configuration
# |=> YAML (.yml files)
# |=> JSON (.json files)
# |=> HOCON (.conf files)
# |=> TOML (.toml files)
# |
# | By default, user, group and track data is separated into different files. Data can be combined
# | and all stored in the same file by switching to a combined storage variant.
# | Just add '-combined' to the end of the storage-method, e.g. 'yaml-combined'
#
# - A H2 database is the default option.
# - If you want to edit data manually in "traditional" storage files, we suggest using YAML.
storage-method: MariaDB
# The following block defines the settings for remote database storage methods.
#
# - You don't need to touch any of the settings here if you're using a local storage method!
# - The connection detail options are shared between all remote storage types.
data:
# Define the address and port for the database.
# - The standard DB engine port is used by default
# (MySQL: 3306, PostgreSQL: 5432, MongoDB: 27017)
# - Specify as "host:port" if differs
address: mariadb
# The name of the database to store LuckPerms data in.
# - This must be created already. Don't worry about this setting if you're using MongoDB.
database: luckperms
# Credentials for the database.
username: luckperms
password: 'luckpermspw'
# These settings apply to the MySQL connection pool.
# - The default values will be suitable for the majority of users.
# - Do not change these settings unless you know what you're doing!
pool-settings:
# Sets the maximum size of the MySQL connection pool.
# - Basically this value will determine the maximum number of actual
# connections to the database backend.
# - More information about determining the size of connection pools can be found here:
# https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
maximum-pool-size: 10
# Sets the minimum number of idle connections that the pool will try to maintain.
# - For maximum performance and responsiveness to spike demands, it is recommended to not set
# this value and instead allow the pool to act as a fixed size connection pool.
# (set this value to the same as 'maximum-pool-size')
minimum-idle: 10
# This setting controls the maximum lifetime of a connection in the pool in milliseconds.
# - The value should be at least 30 seconds less than any database or infrastructure imposed
# connection time limit.
maximum-lifetime: 1800000 # 30 minutes
# This setting controls how frequently the pool will 'ping' a connection in order to prevent it
# from being timed out by the database or network infrastructure, measured in milliseconds.
# - The value should be less than maximum-lifetime and greater than 30000 (30 seconds).
# - Setting the value to zero will disable the keepalive functionality.
keepalive-time: 0
# This setting controls the maximum number of milliseconds that the plugin will wait for a
# connection from the pool, before timing out.
connection-timeout: 5000 # 5 seconds
# This setting allows you to define extra properties for connections.
#
# By default, the following options are set to enable utf8 encoding. (you may need to remove
# these if you are using PostgreSQL)
# useUnicode: true
# characterEncoding: utf8
#
# You can also use this section to disable SSL connections, by uncommenting the 'useSSL' and
# 'verifyServerCertificate' options below.
properties:
useUnicode: true
characterEncoding: utf8
#useSSL: false
#verifyServerCertificate: false
# The prefix for all LuckPerms SQL tables.
#
# - This only applies for remote SQL storage types (MySQL, MariaDB, etc).
# - Change this if you want to use different tables for different servers.
table-prefix: 'luckperms_'
# The prefix to use for all LuckPerms MongoDB collections.
#
# - This only applies for the MongoDB storage type.
# - Change this if you want to use different collections for different servers. The default is no
# prefix.
mongodb-collection-prefix: ''
# The connection string URI to use to connect to the MongoDB instance.
#
# - When configured, this setting will override anything defined in the address, database,
# username or password fields above.
# - If you have a connection string that starts with 'mongodb://' or 'mongodb+srv://', enter it
# below.
# - For more information, please see https://docs.mongodb.com/manual/reference/connection-string/
mongodb-connection-uri: ''
# Define settings for a "split" storage setup.
#
# - This allows you to define a storage method for each type of data.
# - The connection options above still have to be correct for each type here.
split-storage:
# Don't touch this if you don't want to use split storage!
enabled: false
methods:
# These options don't need to be modified if split storage isn't enabled.
user: h2
group: h2
track: h2
uuid: h2
log: h2
# +----------------------------------------------------------------------------------------------+ #
# | | #
# | UPDATE PROPAGATION & MESSAGING SERVICE | #
# | | #
# | Controls the ways in which LuckPerms will sync data & notify other servers of changes. | #
# | These options are documented on greater detail on the wiki under "Instant Updates". | #
# | | #
# +----------------------------------------------------------------------------------------------+ #
# This option controls how frequently LuckPerms will perform a sync task.
#
# - A sync task will refresh all data from the storage, and ensure that the most up-to-date data is
# being used by the plugin.
# - This is disabled by default, as most users will not need it. However, if you're using a remote
# storage type without a messaging service setup, you may wish to set this to something like 3.
# - Set to -1 to disable the task completely.
sync-minutes: -1
# If the file watcher should be enabled.
#
# - When using a file-based storage type, LuckPerms can monitor the data files for changes, and
# automatically update when changes are detected.
# - If you don't want this feature to be active, set this option to false.
watch-files: true
# Define which messaging service should be used by the plugin.
#
# - If enabled and configured, LuckPerms will use the messaging service to inform other connected
# servers of changes.
# - Use the command "/lp networksync" to manually push changes.
# - Data is NOT stored using this service. It is only used as a messaging platform.
#
# - If you decide to enable this feature, you should set "sync-minutes" to -1, as there is no need
# for LuckPerms to poll the database for changes.
#
# - Possible options:
# => sql Uses the SQL database to form a queue system for communication. Will only work when
# 'storage-method' is set to MySQL or MariaDB. This is chosen by default if the
# option is set to 'auto' and SQL storage is in use. Set to 'notsql' to disable this.
# => pluginmsg Uses the plugin messaging channels to communicate with the proxy.
# LuckPerms must be installed on your proxy & all connected servers backend servers.
# Won't work if you have more than one proxy.
# => lilypad Uses LilyPad pub-sub to push changes. You need to have the LilyPad-Connect plugin
# installed.
# => redis Uses Redis pub-sub to push changes. Your server connection info must be configured
# below.
# => rabbitmq Uses RabbitMQ pub-sub to push changes. Your server connection info must be
# configured below.
# => custom Uses a messaging service provided using the LuckPerms API.
# => auto Attempts to automatically setup a messaging service using redis or sql.
messaging-service: auto
# If LuckPerms should automatically push updates after a change has been made with a command.
auto-push-updates: true
# If LuckPerms should push logging entries to connected servers via the messaging service.
push-log-entries: true
# If LuckPerms should broadcast received logging entries to players on this platform.
#
# - If you have LuckPerms installed on your backend servers as well as a BungeeCord proxy, you
# should set this option to false on either your backends or your proxies, to avoid players being
# messaged twice about log entries.
broadcast-received-log-entries: true
# Settings for Redis.
# Port 6379 is used by default; set address to "host:port" if differs
redis:
enabled: false
address: localhost
username: ''
password: ''
# Settings for RabbitMQ.
# Port 5672 is used by default; set address to "host:port" if differs
rabbitmq:
enabled: false
address: localhost
vhost: '/'
username: 'guest'
password: 'guest'
# +----------------------------------------------------------------------------------------------+ #
# | | #
# | CUSTOMIZATION SETTINGS | #
# | | #
# | Settings that allow admins to customize the way LuckPerms operates. | #
# | | #
# +----------------------------------------------------------------------------------------------+ #
# Controls how temporary permissions/parents/meta should be accumulated.
#
# - The default behaviour is "deny".
# - This behaviour can also be specified when the command is executed. See the command usage
# documentation for more info.
#
# - Possible options:
# => accumulate durations will be added to the existing expiry time
# => replace durations will be replaced if the new duration is later than the current
# expiration
# => deny the command will just fail if you try to add another node with the same expiry
temporary-add-behaviour: deny
# Controls how LuckPerms will determine a users "primary" group.
#
# - The meaning and influence of "primary groups" are explained in detail on the wiki.
# - The preferred approach is to let LuckPerms automatically determine a users primary group
# based on the relative weight of their parent groups.
#
# - Possible options:
# => stored use the value stored against the users record in the file/database
# => parents-by-weight just use the users most highly weighted parent
# => all-parents-by-weight same as above, but calculates based upon all parents inherited from
# both directly and indirectly
primary-group-calculation: parents-by-weight
# If the plugin should check for "extra" permissions with users run LP commands.
#
# - These extra permissions allow finer control over what users can do with each command, and who
# they have access to edit.
# - The nature of the checks are documented on the wiki under "Argument based command permissions".
# - Argument based permissions are *not* static, unlike the 'base' permissions, and will depend upon
# the arguments given within the command.
argument-based-command-permissions: false
# If the plugin should check whether senders are a member of a given group before they're able to
# edit the groups data or add/remove other users to/from it.
# Note: these limitations do not apply to the web editor!
require-sender-group-membership-to-modify: false
# If the plugin should send log notifications to users whenever permissions are modified.
#
# - Notifications are only sent to those with the appropriate permission to receive them
# - They can also be temporarily enabled/disabled on a per-user basis using
# '/lp log notify <on|off>'
log-notify: true
# Defines a list of log entries which should not be sent as notifications to users.
#
# - Each entry in the list is a RegEx expression which is matched against the log entry description.
log-notify-filtered-descriptions:
# - "parent add example"
# If LuckPerms should automatically install translation bundles and periodically update them.
auto-install-translations: true
# Defines the options for prefix and suffix stacking.
#
# - The feature allows you to display multiple prefixes or suffixes alongside a players username in
# chat.
# - It is explained and documented in more detail on the wiki under "Prefix & Suffix Stacking".
#
# - The options are divided into separate sections for prefixes and suffixes.
# - The 'duplicates' setting refers to how duplicate elements are handled. Can be 'retain-all',
# 'first-only' or 'last-only'.
# - The value of 'start-spacer' is included at the start of the resultant prefix/suffix.
# - The value of 'end-spacer' is included at the end of the resultant prefix/suffix.
# - The value of 'middle-spacer' is included between each element in the resultant prefix/suffix.
#
# - Possible format options:
# => highest Selects the value with the highest weight, from all values
# held by or inherited by the player.
#
# => lowest Same as above, except takes the one with the lowest weight.
#
# => highest_own Selects the value with the highest weight, but will not
# accept any inherited values.
#
# => lowest_own Same as above, except takes the value with the lowest weight.
#
# => highest_inherited Selects the value with the highest weight, but will only
# accept inherited values.
#
# => lowest_inherited Same as above, except takes the value with the lowest weight.
#
# => highest_on_track_<track> Selects the value with the highest weight, but only if the
# value was inherited from a group on the given track.
#
# => lowest_on_track_<track> Same as above, except takes the value with the lowest weight.
#
# => highest_not_on_track_<track> Selects the value with the highest weight, but only if the
# value was inherited from a group not on the given track.
#
# => lowest_not_on_track_<track> Same as above, except takes the value with the lowest weight.
#
# => highest_from_group_<group> Selects the value with the highest weight, but only if the
# value was inherited from the given group.
#
# => lowest_from_group_<group> Same as above, except takes the value with the lowest weight.
#
# => highest_not_from_group_<group> Selects the value with the highest weight, but only if the
# value was not inherited from the given group.
#
# => lowest_not_from_group_<group> Same as above, except takes the value with the lowest weight.
meta-formatting:
prefix:
format:
- "highest"
duplicates: first-only
start-spacer: ""
middle-spacer: " "
end-spacer: ""
suffix:
format:
- "highest"
duplicates: first-only
start-spacer: ""
middle-spacer: " "
end-spacer: ""
# +----------------------------------------------------------------------------------------------+ #
# | | #
# | PERMISSION CALCULATION AND INHERITANCE | #
# | | #
# | Modify the way permission checks, meta lookups and inheritance resolutions are handled. | #
# | | #
# +----------------------------------------------------------------------------------------------+ #
# The algorithm LuckPerms should use when traversing the "inheritance tree".
#
# - Possible options:
# => breadth-first See: https://en.wikipedia.org/wiki/Breadth-first_search
# => depth-first-pre-order See: https://en.wikipedia.org/wiki/Depth-first_search
# => depth-first-post-order See: https://en.wikipedia.org/wiki/Depth-first_search
inheritance-traversal-algorithm: depth-first-pre-order
# If a final sort according to "inheritance rules" should be performed after the traversal algorithm
# has resolved the inheritance tree.
#
# "Inheritance rules" refers to things such as group weightings, primary group status, and the
# natural contextual ordering of the group nodes.
#
# Setting this to 'true' will allow for the inheritance rules to take priority over the structure of
# the inheritance tree.
#
# Effectively when this setting is 'true': the tree is flattened, and rules applied afterwards,
# and when this setting is 'false':, the rules are just applied during each step of the traversal.
post-traversal-inheritance-sort: false
# Defines the mode used to determine whether a set of contexts are satisfied.
#
# - Possible options:
# => at-least-one-value-per-key Set A will be satisfied by another set B, if at least one of the
# key-value entries per key in A are also in B.
# => all-values-per-key Set A will be satisfied by another set B, if all key-value
# entries in A are also in B.
context-satisfy-mode: at-least-one-value-per-key
# LuckPerms has a number of built-in contexts. These can be disabled by adding the context key to
# the list below.
disabled-contexts:
# - "world"
# +----------------------------------------------------------------------------------------------+ #
# | Permission resolution settings | #
# +----------------------------------------------------------------------------------------------+ #
# If users on this server should have their global permissions applied.
# When set to false, only server specific permissions will apply for users on this server
include-global: true
# If users on this server should have their global world permissions applied.
# When set to false, only world specific permissions will apply for users on this server
include-global-world: true
# If users on this server should have global (non-server specific) groups applied
apply-global-groups: true
# If users on this server should have global (non-world specific) groups applied
apply-global-world-groups: true
# +----------------------------------------------------------------------------------------------+ #
# | Meta lookup settings | #
# +----------------------------------------------------------------------------------------------+ #
# Defines how meta values should be selected.
#
# - Possible options:
# => inheritance Selects the meta value that was inherited first
# => highest-number Selects the highest numerical meta value
# => lowest-number Selects the lowest numerical meta value
meta-value-selection-default: inheritance
# Defines how meta values should be selected per key.
meta-value-selection:
# max-homes: highest-number
# +----------------------------------------------------------------------------------------------+ #
# | Inheritance settings | #
# +----------------------------------------------------------------------------------------------+ #
# If the plugin should apply wildcard permissions.
#
# - If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered
# permissions matching the wildcard.
apply-wildcards: true
# If LuckPerms should resolve and apply permissions according to the Sponge style implicit wildcard
# inheritance system.
#
# - That being: If a user has been granted "example", then the player should have also be
# automatically granted "example.function", "example.another", "example.deeper.nesting",
# and so on.
apply-sponge-implicit-wildcards: false
# If the plugin should apply negated Bukkit default permissions before it considers wildcard
# assignments.
#
# - Plugin authors can define permissions which explicitly should not be given automatically to OPs.
# This is usually used for so called "anti-permissions" - permissions which, when granted, apply
# something negative.
# - If this option is set to true, LuckPerms will consider any negated declarations made by
# plugins before it considers wildcards. (similar to the way the OP system works)
# - If this option is set to false, LuckPerms will consider any wildcard assignments first.
apply-default-negated-permissions-before-wildcards: false
# If the plugin should parse regex permissions.
#
# - If set to true, LuckPerms will detect regex permissions, marked with "r=" at the start of the
# node, and resolve & apply all registered permissions matching the regex.
apply-regex: true
# If the plugin should complete and apply shorthand permissions.
#
# - If set to true, LuckPerms will detect and expand shorthand node patterns.
apply-shorthand: true
# If the plugin should apply Bukkit child permissions.
#
# - Plugin authors can define custom permissions structures for their plugin, which will be resolved
# and used by LuckPerms if this setting is enabled.
apply-bukkit-child-permissions: true
# If the plugin should apply Bukkit default permissions.
#
# - Plugin authors can define permissions which should be given to all users by default, or setup
# permissions which should/shouldn't be given to opped players.
# - If this option is set to false, LuckPerms will ignore these defaults.
apply-bukkit-default-permissions: true
# If the plugin should apply attachment permissions.
#
# - Other plugins on the server are able to add their own "permission attachments" to players.
# - This allows them to grant players additional permissions which last until the end of the
# session, or until they're removed.
# - If this option is set to false, LuckPerms will not include these attachment permissions when
# considering if a player should have access to a certain permission.
apply-bukkit-attachment-permissions: true
# +----------------------------------------------------------------------------------------------+ #
# | Extra settings | #
# +----------------------------------------------------------------------------------------------+ #
# A list of context calculators which will be skipped when calculating contexts.
#
# - You can disable context calculators by either:
# => specifying the Java class name used by the calculator (e.g. com.example.ExampleCalculator)
# => specifying a sub-section of the Java package used by the calculator (e.g. com.example)
disabled-context-calculators: []
# Allows you to set "aliases" for the worlds sent forward for context calculation.
#
# - These aliases are provided in addition to the real world name. Applied recursively.
# - Remove the comment characters for the default aliases to apply.
world-rewrite:
# world_nether: world
# world_the_end: world
# Define special group weights for this server.
#
# - Group weights can also be applied directly to group data, using the setweight command.
# - This section allows weights to be set on a per-server basis.
group-weight:
# admin: 10
# +----------------------------------------------------------------------------------------------+ #
# | | #
# | FINE TUNING OPTIONS | #
# | | #
# | A number of more niche settings for tweaking and changing behaviour. The section also | #
# | contains toggles for some more specialised features. It is only necessary to make changes to | #
# | these options if you want to fine-tune LuckPerms behaviour. | #
# | | #
# +----------------------------------------------------------------------------------------------+ #
# +----------------------------------------------------------------------------------------------+ #
# | Server Operator (OP) settings | #
# +----------------------------------------------------------------------------------------------+ #
# Controls whether server operators should exist at all.
#
# - When set to 'false', all players will be de-opped, and the /op and /deop commands will be
# disabled. Note that vanilla features like the spawn-protection require an operator on the
# server to work.
enable-ops: true
# Enables or disables a special permission based system in LuckPerms for controlling OP status.
#
# - If set to true, any user with the permission "luckperms.autoop" will automatically be granted
# server operator status. This permission can be inherited, or set on specific servers/worlds,
# temporarily, etc.
# - Additionally, setting this to true will force the "enable-ops" option above to false. All users
# will be de-opped unless they have the permission node, and the op/deop commands will be
# disabled.
# - It is recommended that you use this option instead of assigning a single '*' permission.
auto-op: false
# Defines if "opped" players should be able to use all LuckPerms commands by default.
#
# - Set to false to only allow users who have the permissions access to the commands
commands-allow-op: true
# +----------------------------------------------------------------------------------------------+ #
# | Vault integration settings | #
# +----------------------------------------------------------------------------------------------+ #
# If Vault lookups for offline players on the main server thread should be enabled.
#
# LuckPerms has a "catch" for plugins attempting to perform unsafe offline player data lookups
# from the main server thread. This catch raises an exception (causes an error to occur) when unsafe
# lookups are made, instead of allowing the lookup to happen, which would likely cause the server
# to lag.
#
# However, if you're willing to accept the consequences, the catch can be disabled by setting this
# option to 'true.
vault-unsafe-lookups: false
# If LuckPerms should use the 'display name' of a group when returning groups in Vault API calls.
#
# - When this option is set to true, the display name of the group is returned.
# - When this option is set to false, the standard name/id of the group is returned.
vault-group-use-displaynames: true
# Controls which group LuckPerms should use for NPC players when handling Vault requests.
#
# - As NPCs aren't actually real players, LuckPerms does not load any user data for them. This
# becomes an issue when plugins want to check for their permissions using Vault.
# - As a solution, Vault checks for NPCs fallback to a group, which is defined below.
vault-npc-group: default
# Controls how LuckPerms should consider the OP status of NPC players when handing Vault requests.
#
# - If you want NPCs to have the same permissions as "normal" players, set this option to false.
# - If you want NPCs to have OP status, set this option to true.
vault-npc-op-status: false
# If the vault-server option below should be used.
#
# - When this option is set to false, the server value defined above under "server" is used.
use-vault-server: false
# The name of the server used within Vault operations.
#
# - If you don't want Vault operations to be server specific, set this to "global".
# - Will only take effect if use-vault-server is set to true above.
vault-server: global
# If global permissions should be considered when retrieving meta or player groups
vault-include-global: true
# If Vault operations should ignore any world arguments if supplied.
vault-ignore-world: false
# +----------------------------------------------------------------------------------------------+ #
# | Miscellaneous (and rarely used) settings | #
# +----------------------------------------------------------------------------------------------+ #
# If LuckPerms should produce extra logging output when it handles logins.
#
# - Useful if you're having issues with UUID forwarding or data not being loaded.
debug-logins: false
# If LuckPerms should allow usernames with non alphanumeric characters.
#
# - Note that due to the design of the storage implementation, usernames must still be 16 characters
# or less.
allow-invalid-usernames: false
# If LuckPerms should not require users to confirm bulkupdate operations.
#
# - When set to true, operations will be executed immediately.
# - This is not recommended, as bulkupdate has the potential to irreversibly delete large amounts of
# data, and is not designed to be executed automatically.
# - If automation is needed, users should prefer using the LuckPerms API.
skip-bulkupdate-confirmation: false
# If LuckPerms should prevent bulkupdate operations.
#
# - When set to true, bulkupdate operations (the /lp bulkupdate command) will not work.
# - When set to false, bulkupdate operations will be allowed via the console.
disable-bulkupdate: false
# If LuckPerms should allow a users primary group to be removed with the 'parent remove' command.
#
# - When this happens, the plugin will set their primary group back to default.
prevent-primary-group-removal: false
# If LuckPerms should update the list of commands sent to the client when permissions are changed.
update-client-command-list: true
# If LuckPerms should attempt to register "Brigadier" command list data for its commands.
register-command-list-data: true
# If LuckPerms should attempt to resolve Vanilla command target selectors for LP commands.
# See here for more info: https://minecraft.gamepedia.com/Commands#Target_selectors
resolve-command-selectors: false

View File

@@ -1,52 +0,0 @@
server_connect_timeout: 5000
enforce_secure_profile: false
remote_ping_cache: -1
forge_support: true
player_limit: -1
permissions:
default:
- bungeecord.command.server
- bungeecord.command.list
admin:
- bungeecord.command.alert
- bungeecord.command.end
- bungeecord.command.ip
- bungeecord.command.reload
- bungeecord.command.kick
timeout: 30000
log_commands: false
network_compression_threshold: 256
online_mode: true
disabled_commands:
- disabledcommandhere
servers:
mc:
motd: 'Lobby'
address: mc:25565
restricted: false
listeners:
- query_port: 25577
motd: '&1Another Bungee server'
tab_list: GLOBAL_PING
query_enabled: false
proxy_protocol: false
forced_hosts:
pvp.md-5.net: pvp
ping_passthrough: false
priorities:
- mc
bind_local_address: true
host: 0.0.0.0:25577
max_players: 1
tab_size: 60
force_default_server: false
ip_forward: false
remote_ping_timeout: 5000
prevent_proxy_connections: false
groups:
md_5:
- admin
connection_throttle: 4000
stats: 39440d41-8d83-40cb-a6a7-d95c3197c4d2
connection_throttle_limit: 3
log_pings: true

View File

@@ -1,10 +0,0 @@
plugin_channel_name_limit: 128
use_netty_dns_resolver: true
disable_modern_tab_limiter: true
log_initial_handler_connections: true
throttling:
tab_complete: 1000
game_version: ''
disable_tab_list_rewrite: true
registered_plugin_channels_limit: 128
disable_entity_metadata_rewrite: false

View File

@@ -1,21 +0,0 @@
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,15 +0,0 @@
#!/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
# remove .paused file from data directory
rm -f /data/.paused
fi

View File

@@ -1,13 +0,0 @@
#!/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,12 +1,9 @@
#!/bin/bash #!/bin/bash
. /auto/autopause-fcns.sh . /autopause/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:"
@@ -42,12 +39,7 @@ if ! [[ -d "/sys/class/net/$AUTOPAUSE_KNOCK_INTERFACE" ]] ; then
autopause_error_loop autopause_error_loop
fi fi
knockdArgs=(-c /tmp/knockd-config.cfg -d -i "$AUTOPAUSE_KNOCK_INTERFACE") sudo /usr/sbin/knockd -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\"."
@@ -58,13 +50,12 @@ 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 - pausing in $AUTOPAUSE_TIMEOUT_INIT seconds" logAutopause "MC Server listening for connections - stopping in $AUTOPAUSE_TIMEOUT_INIT seconds"
STATE=K STATE=K
fi fi
;; ;;
@@ -75,8 +66,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 - pausing" logAutopause "No client connected since startup / knocked - stopping"
/auto/pause.sh /autopause/pause.sh
STATE=S STATE=S
fi fi
fi fi
@@ -85,7 +76,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 - pausing in $AUTOPAUSE_TIMEOUT_EST seconds" logAutopause "All clients disconnected - stopping in $AUTOPAUSE_TIMEOUT_EST seconds"
STATE=I STATE=I
fi fi
;; ;;
@@ -96,8 +87,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 - pausing" logAutopause "No client reconnected - stopping"
/auto/pause.sh /autopause/pause.sh
STATE=S STATE=S
fi fi
fi fi
@@ -105,7 +96,7 @@ do
XS) XS)
# Stopped # Stopped
if rcon_client_exists ; then if rcon_client_exists ; then
/auto/resume.sh /autopause/resume.sh
fi fi
if java_running ; then if java_running ; then
if java_clients_connected ; then if java_clients_connected ; then
@@ -113,11 +104,7 @@ do
STATE=E STATE=E
else else
TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_KN)) TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_KN))
from=unknown logAutopause "Server was knocked - waiting for clients or timeout"
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
@@ -128,8 +115,8 @@ do
esac esac
if [[ "$STATE" == "S" ]] ; then if [[ "$STATE" == "S" ]] ; then
# before rcon times out # before rcon times out
sleep 5 sleep 2
else else
sleep "$AUTOPAUSE_PERIOD" sleep $AUTOPAUSE_PERIOD
fi fi
done done

View File

@@ -20,16 +20,12 @@ mc_server_listening() {
mc-monitor status --host localhost --port "$SERVER_PORT" --timeout 10s >& /dev/null mc-monitor status --host localhost --port "$SERVER_PORT" --timeout 10s >& /dev/null
} }
java_clients_connections() { java_clients_connected() {
local connections local connections
if java_running ; then if java_running ; then
connections=$(mc-monitor status --host localhost --port "$SERVER_PORT" --show-player-count) connections=$(mc-monitor status --host localhost --port "$SERVER_PORT" --show-player-count)
else else
connections=0 connections=0
fi fi
echo $connections (( connections > 0 ))
}
java_clients_connected() {
(( $(java_clients_connections) > 0 ))
} }

View File

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

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

@@ -1,9 +1,6 @@
#!/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
@@ -21,7 +18,4 @@ if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; t
# finally pause the process # finally pause the process
logAutopauseAction "Pausing Java process" logAutopauseAction "Pausing Java process"
pkill -STOP java pkill -STOP java
# create .paused file in data directory
touch /data/.paused
fi fi

8
files/autopause/resume.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/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,13 +1,9 @@
#!/bin/bash #!/bin/bash
# needed for the clients connected function residing in autopause # needed for the clients connected function residing in autopause
. /auto/autopause-fcns.sh . /autopause/autopause-fcns.sh
# shellcheck source=../../scripts/start-utils . ${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 :
@@ -22,12 +18,11 @@ 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
@@ -40,7 +35,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"
/auto/stop.sh /autostop/stop.sh
exit 0 exit 0
fi fi
fi fi
@@ -61,7 +56,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"
/auto/stop.sh /autostop/stop.sh
exit 0 exit 0
fi fi
fi fi

6
files/autostop/stop.sh Executable file
View File

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

View File

@@ -10,16 +10,13 @@
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz"> <RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" /> <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
<Policies> <Policies>
<!-- Based on filePattern resolution, so daily -->
<TimeBasedTriggeringPolicy /> <TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="100 MB" />
<OnStartupTriggeringPolicy /> <OnStartupTriggeringPolicy />
</Policies> </Policies>
<DefaultRolloverStrategy> <DefaultRolloverStrategy>
<Delete basePath="logs"> <Delete basePath="logs">
<IfFileName glob="*.log.gz" /> <IfFileName glob="*.log.gz" />
<IfLastModified age="7d" /> <IfLastModified age="7d" />
<IfAccumulatedFileCount exceeds="20"/>
</Delete> </Delete>
</DefaultRolloverStrategy> </DefaultRolloverStrategy>
</RollingRandomAccessFile> </RollingRandomAccessFile>

View File

@@ -1,2 +1,2 @@
minecraft ALL=(ALL) NOPASSWD:/usr/bin/pkill %minecraft ALL=(ALL) NOPASSWD:/usr/bin/pkill
minecraft ALL=(ALL) NOPASSWD:/usr/sbin/knockd %minecraft ALL=(ALL) NOPASSWD:/usr/sbin/knockd

View File

@@ -1,22 +0,0 @@
This directory provides a base to use with [kubectl kustomize](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/).
## Example overlay content
### kustomization.yml
```yaml
nameSuffix: "-forge"
commonLabels:
server: forge
bases:
- https://github.com/itzg/docker-minecraft-server.git/kustomize/base
configMapGenerator:
- name: mc
envs:
- mc.env
```
### mc.env
```
EULA=true
TYPE=FORGE
```

View File

@@ -1,3 +0,0 @@
resources:
- statefulset.yml
- service.yml

View File

@@ -1,17 +0,0 @@
apiVersion: v1
kind: Service
metadata:
labels:
service: mc
annotations: {}
# Such as
# mc-router.itzg.me/externalServerName: $(EXTERNAL_SERVICE_NAME)
name: mc
spec:
ports:
- name: minecraft
port: 25565
targetPort: 25565
type: NodePort
selector:
server: mc

View File

@@ -1,51 +0,0 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mc
spec:
replicas: 1
serviceName: mc
selector:
matchLabels:
server: mc
template:
metadata:
labels:
server: mc
spec:
containers:
- name: mc
envFrom:
- configMapRef:
name: mc
optional: true
env: []
image: itzg/minecraft-server
stdin: true
tty: true
volumeMounts:
- mountPath: /data
name: data
resources:
requests:
cpu: 150m
livenessProbe:
exec:
command: ["mc-health"]
initialDelaySeconds: 120
periodSeconds: 60
readinessProbe:
exec:
command: ["mc-health"]
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 12
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi

View File

@@ -1,16 +1,11 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
# The Dockerfile ENVs take precedence here, but defaulting for testing consistency
: "${UID:=1000}"
: "${GID:=1000}"
umask 0002 umask 0002
chmod g+w /data chmod g+w /data
if ! isTrue "${SKIP_SUDO:-false}" && [ "$(id -u)" = 0 ]; then if ! isTrue "${SKIP_SUDO:-false}" && [ $(id -u) = 0 ]; then
runAsUser=minecraft runAsUser=minecraft
runAsGroup=minecraft runAsGroup=minecraft
@@ -29,14 +24,14 @@ if ! isTrue "${SKIP_SUDO:-false}" && [ "$(id -u)" = 0 ]; then
if [[ $GID != 0 ]]; then if [[ $GID != 0 ]]; then
if [[ $GID != $(id -g minecraft) ]]; then if [[ $GID != $(id -g minecraft) ]]; then
log "Changing gid of minecraft to $GID" log "Changing gid of minecraft to $GID"
groupmod -o -g "$GID" minecraft groupmod -o -g $GID minecraft
fi fi
else else
runAsGroup=root runAsGroup=root
fi fi
fi fi
if [[ $(stat -c "%u" /data) != "$UID" ]]; then if [[ $(stat -c "%u" /data) != $UID ]]; then
log "Changing ownership of /data to $UID ..." log "Changing ownership of /data to $UID ..."
chown -R ${runAsUser}:${runAsGroup} /data chown -R ${runAsUser}:${runAsGroup} /data
fi fi
@@ -45,12 +40,7 @@ if ! isTrue "${SKIP_SUDO:-false}" && [ "$(id -u)" = 0 ]; then
echo 'hosts: files dns' > /etc/nsswitch.conf echo 'hosts: files dns' > /etc/nsswitch.conf
fi fi
distro=$(getDistro) exec gosu ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration "$@"
if [[ $distro == alpine ]]; then
exec su-exec ${runAsUser}:${runAsGroup} "${SCRIPTS:-/}start-configuration" "$@"
else else
exec gosu ${runAsUser}:${runAsGroup} "${SCRIPTS:-/}start-configuration" "$@" exec ${SCRIPTS:-/}start-configuration "$@"
fi
else
exec "${SCRIPTS:-/}start-configuration" "$@"
fi fi

View File

@@ -4,27 +4,13 @@
. "${SCRIPTS:-/}start-utils" . "${SCRIPTS:-/}start-utils"
: "${SERVER_PORT:=25565}" : "${SERVER_PORT:=25565}"
: "${ENABLE_AUTOPAUSE:=false}"
: "${AUTOPAUSE_TIMEOUT_EST:=3600}"
: "${AUTOPAUSE_TIMEOUT_KN:=120}"
: "${AUTOPAUSE_TIMEOUT_INIT:=600}"
: "${AUTOPAUSE_PERIOD:=10}"
: "${AUTOPAUSE_KNOCK_INTERFACE:=eth0}"
: "${DEBUG_AUTOPAUSE:=false}"
export SERVER_PORT export SERVER_PORT
export ENABLE_AUTOPAUSE
export AUTOPAUSE_TIMEOUT_EST
export AUTOPAUSE_TIMEOUT_KN
export AUTOPAUSE_TIMEOUT_INIT
export AUTOPAUSE_PERIOD
export AUTOPAUSE_KNOCK_INTERFACE
export DEBUG_AUTOPAUSE
log "Autopause functionality enabled" log "Autopause functionality enabled"
isDebugging && set -x isDebugging && set -x
cp /auto/knockd-config.cfg /tmp/knockd-config.cfg cp /autopause/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*$"
@@ -84,4 +70,4 @@ elif [[ -z "$MAX_TICK_TIME" ]] ; then
export MAX_TICK_TIME export MAX_TICK_TIME
fi fi
/auto/autopause-daemon.sh & /autopause/autopause-daemon.sh &

View File

@@ -4,17 +4,7 @@
. "${SCRIPTS:-/}start-utils" . "${SCRIPTS:-/}start-utils"
: "${SERVER_PORT:=25565}" : "${SERVER_PORT:=25565}"
: "${ENABLE_AUTOSTOP:=false}"
: "${AUTOSTOP_TIMEOUT_EST:=3600}"
: "${AUTOSTOP_TIMEOUT_INIT:=1800}"
: "${AUTOSTOP_PERIOD:=10}"
: "${DEBUG_AUTOSTOP:=false}"
export SERVER_PORT export SERVER_PORT
export ENABLE_AUTOSTOP
export AUTOSTOP_TIMEOUT_EST
export AUTOSTOP_TIMEOUT_INIT
export AUTOSTOP_PERIOD
export DEBUG_AUTOSTOP
log "Autostop functionality enabled" log "Autostop functionality enabled"
@@ -41,4 +31,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
/auto/autostop-daemon.sh & /autostop/autostop-daemon.sh &

View File

@@ -3,28 +3,11 @@ set -euo pipefail
IFS=$'\n\t' IFS=$'\n\t'
# shellcheck source=start-utils # shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils" . ${SCRIPTS:-/}start-utils
: "${EULA:=}" : "${EULA:=}"
: "${PROXY:=}" : "${PROXY:=}"
: "${ENABLE_AUTOPAUSE:=false}"
: "${ENABLE_AUTOSTOP:=false}"
: "${RCON_CMDS_STARTUP:=}"
: "${RCON_CMDS_ON_CONNECT:=}"
: "${RCON_CMDS_ON_DISCONNECT:=}"
: "${RCON_CMDS_FIRST_CONNECT:=}"
: "${RCON_CMDS_LAST_DISCONNECT:=}"
: "${RCON_CMDS_PERIOD:=10}"
: "${RCON_PASSWORD_FILE:=}" : "${RCON_PASSWORD_FILE:=}"
: "${ENABLE_RCON:=true}"
: "${RCON_PASSWORD:=minecraft}"
: "${RCON_PORT:=25575}"
export ENABLE_RCON RCON_PASSWORD RCON_PORT
: "${MEMORY=1G}"
: "${INIT_MEMORY=${MEMORY}}"
: "${MAX_MEMORY=${MEMORY}}"
export MEMORY INIT_MEMORY MAX_MEMORY
shopt -s nullglob shopt -s nullglob
@@ -83,28 +66,9 @@ if [[ $RCON_PASSWORD_FILE ]]; then
log "" log ""
fi fi
function fixJavaPath() {
# Some Docker management UIs grab all the image declared variables and present them for configuration.
# When upgrading images across Java versions, that creates a mismatch in PATH's expected by base image.
if ! which java > /dev/null; then if ! which java > /dev/null; then
log "ERROR: your Docker provider has an annoying flaw where it" log "Fixing PATH to include java"
log " tries to set PATH even though the container establishes" PATH="${PATH}:/opt/java/openjdk/bin"
log " a very specific value."
sleep 2
# now find where java might be
for d in /opt/java/openjdk/bin /usr/bin; do
if [ -x "${d}/java" ]; then
PATH="${PATH}:${d}"
return 0
fi
done
return 1
fi
}
if ! fixJavaPath; then
log "ERROR: could not locate path that contains java"
exit 1
fi fi
export VERSIONS_JSON=https://launchermeta.mojang.com/mc/game/version_manifest.json export VERSIONS_JSON=https://launchermeta.mojang.com/mc/game/version_manifest.json
@@ -127,9 +91,7 @@ case "X$VERSION" in
;; ;;
esac esac
export VANILLA_VERSION export VANILLA_VERSION
MAJOR_VANILLA_VERSION=$(get_major_version "$VANILLA_VERSION") log "Resolved version given ${VERSION} into ${VANILLA_VERSION}"
export MAJOR_VANILLA_VERSION
log "Resolved version given ${VERSION} into ${VANILLA_VERSION} and major version ${MAJOR_VANILLA_VERSION}"
cd /data || exit 1 cd /data || exit 1
@@ -143,18 +105,6 @@ if isTrue "${ENABLE_AUTOSTOP}"; then
${SCRIPTS:-/}start-autostop ${SCRIPTS:-/}start-autostop
fi fi
if
[[ "$RCON_CMDS_STARTUP" ]] ||
[[ "$RCON_CMDS_ON_CONNECT" ]] ||
[[ "$RCON_CMDS_ON_DISCONNECT" ]] ||
[[ "$RCON_CMDS_FIRST_CONNECT" ]] ||
[[ "$RCON_CMDS_LAST_DISCONNECT" ]]
then
log "Starting RCON commands"
# shellcheck source=start-rconcmds
${SCRIPTS:-/}start-rconcmds
fi
if versionLessThan 1.7; then if versionLessThan 1.7; then
echo " echo "
MC_HEALTH_EXTRA_ARGS=( MC_HEALTH_EXTRA_ARGS=(
@@ -166,34 +116,37 @@ fi
log "Resolving type given ${TYPE}" log "Resolving type given ${TYPE}"
case "${TYPE^^}" in case "${TYPE^^}" in
*BUKKIT|SPIGOT) *BUKKIT|SPIGOT)
exec "${SCRIPTS:-/}start-deployBukkitSpigot" "$@" exec ${SCRIPTS:-/}start-deployBukkitSpigot "$@"
;; ;;
PAPER) PAPER)
exec "${SCRIPTS:-/}start-deployPaper" "$@" exec ${SCRIPTS:-/}start-deployPaper "$@"
;; ;;
FORGE) FORGE)
evaluateJavaCompatibilityForForge log "**********************************************************************"
exec "${SCRIPTS:-/}start-deployForge" "$@" log "WARNING: The image tag itzg/minecraft-server:java8 is recommended"
log " since some mods require Java 8"
log " Exception traces reporting ClassCastException: class jdk.internal.loader.ClassLoaders\$AppClassLoader"
log " can be fixed with java8"
log "**********************************************************************"
exec ${SCRIPTS:-/}start-deployForge "$@"
;; ;;
FABRIC) FABRIC)
exec "${SCRIPTS:-/}start-deployFabric" "$@" exec ${SCRIPTS:-/}start-deployFabric "$@"
;;
QUILT)
exec "${SCRIPTS:-/}start-deployQuilt" "$@"
;; ;;
FTBA) FTBA)
evaluateJavaCompatibilityForForge exec ${SCRIPTS:-/}start-deployFTBA "$@"
exec "${SCRIPTS:-/}start-deployFTBA" "$@"
;; ;;
FTB|CURSEFORGE) FTB|CURSEFORGE)
evaluateJavaCompatibilityForForge log "**********************************************************************"
exec "${SCRIPTS:-/}start-deployCF" "$@" log "NOTE: Some mods and modpacks may require Java 8."
log " If so, use itzg/minecraft-server:java8"
log "**********************************************************************"
exec ${SCRIPTS:-/}start-deployCF "$@"
;; ;;
VANILLA) VANILLA)
@@ -201,48 +154,43 @@ case "${TYPE^^}" in
;; ;;
SPONGEVANILLA) SPONGEVANILLA)
exec "${SCRIPTS:-/}start-deploySpongeVanilla" "$@" exec ${SCRIPTS:-/}start-deploySpongeVanilla "$@"
;; ;;
CUSTOM) CUSTOM)
evaluateJavaCompatibilityForForge exec ${SCRIPTS:-/}start-deployCustom "$@"
exec "${SCRIPTS:-/}start-deployCustom" "$@"
;; ;;
MAGMA) MAGMA)
evaluateJavaCompatibilityForForge exec ${SCRIPTS:-/}start-deployMagma "$@"
exec "${SCRIPTS:-/}start-deployMagma" "$@"
;; ;;
MOHIST) MOHIST)
evaluateJavaCompatibilityForForge exec ${SCRIPTS:-/}start-deployMohist "$@"
exec "${SCRIPTS:-/}start-deployMohist" "$@"
;; ;;
CATSERVER) CATSERVER)
evaluateJavaCompatibilityForForge exec ${SCRIPTS:-/}start-deployCatserver "$@"
exec "${SCRIPTS:-/}start-deployCatserver" "$@"
;;
LOLISERVER)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployLoliserver" "$@"
;; ;;
PURPUR) PURPUR)
exec "${SCRIPTS:-/}start-deployPurpur" "$@" exec ${SCRIPTS:-/}start-deployPurpur "$@"
;;
AIRPLANE)
exec ${SCRIPTS:-/}start-deployAirplane "$@"
;; ;;
PUFFERFISH) PUFFERFISH)
exec "${SCRIPTS:-/}start-deployPufferfish" "$@" exec ${SCRIPTS:-/}start-deployPufferfish "$@"
;; ;;
CANYON) CANYON)
exec "${SCRIPTS:-/}start-deployCanyon" "$@" exec ${SCRIPTS:-/}start-deployCanyon "$@"
;; ;;
LIMBO) LIMBO)
exec "${SCRIPTS:-/}start-deployLimbo" "$@" exec ${SCRIPTS:-/}start-deployLimbo "$@"
;; ;;
CRUCIBLE) CRUCIBLE)
@@ -259,7 +207,7 @@ case "${TYPE^^}" in
log "Invalid type: '$TYPE'" log "Invalid type: '$TYPE'"
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only)," log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only),"
log " CURSEFORGE, SPONGEVANILLA, PURPUR, CUSTOM," log " CURSEFORGE, SPONGEVANILLA, PURPUR, CUSTOM,"
log " MAGMA, MOHIST, CATSERVER, LOLISERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE" log " MAGMA, MOHIST, CATSERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE"
exit 1 exit 1
;; ;;

47
scripts/start-deployAirplane Executable file
View File

@@ -0,0 +1,47 @@
#!/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
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-spiget" "$@"

View File

@@ -127,5 +127,6 @@ fi
# Normalize on Spigot for operations below # Normalize on Spigot for operations below
export FAMILY=SPIGOT export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@" exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -27,16 +27,13 @@ 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://files.minecraftforge.net/maven/net/minecraftforge/lex/legacyjavafixer/1.0/legacyjavafixer-1.0.jar legacyJavaFixerUrl=https://ftb.forgecdn.net/FTB2/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."
if [[ ! $FTB_SERVER_MOD ]]; then requireVar FTB_SERVER_MOD
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}
@@ -136,34 +133,31 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
exec "${SCRIPTS:-/}start-setupWorld" "$@" exec "${SCRIPTS:-/}start-setupWorld" "$@"
fi fi
entryScriptExpr="
findStartScript() {
entryScriptExpr=(
-name ServerStart.sh -name ServerStart.sh
-o -name serverstart.sh -o -name serverstart.sh
-o -name ServerStartLinux.sh -o -name ServerStartLinux.sh
-o -name LaunchServer.sh -o -name LaunchServer.sh
-o -name server-start.sh -o -name server-start.sh
-o -name SERVER-START.sh
-o -name start-server.sh -o -name start-server.sh
-o -name startserver.sh -o -name startserver.sh
-o -name StartServer.sh -o -name StartServer.sh
-o -name run.sh "
-o -name start.sh
-o -name launch.sh
)
if [ -d "${FTB_BASE_DIR}" ]; then if [[ -d ${FTB_BASE_DIR} ]]; then
find "${FTB_BASE_DIR}" \( "${entryScriptExpr[@]}" \) -print -quit startScriptCount=$(find "${FTB_BASE_DIR}" $entryScriptExpr |wc -l)
if (( startScriptCount > 1 )); then
log "Conflicting FTB/CurseForge packages have been installed. Please cleanup ${FTB_BASE_DIR}"
exit 2
fi
else
startScriptCount=0
fi 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 [[ ! $startScript ]]; then if [[ $startScriptCount = 0 ]]; then
downloadModpack downloadModpack
srv_modpack=${FTB_SERVER_MOD} srv_modpack=${FTB_SERVER_MOD}
@@ -171,30 +165,21 @@ if [[ ! $startScript ]]; 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 ""}'
installScriptExpr=( installScript=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f -name install.sh)
-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 "${installScript}" chmod +x ./install.sh
log "Running included $(basename "${installScript}"). This might take a minute or two..." log "Running included install.sh"
"${installScript}" > install.log ./install.sh
) )
fi fi
startScript=$(findStartScript)
fi fi
# start script provided by unzipped+installed modpack? if [[ $(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l) = 0 ]]; then
if [[ ! $startScript ]]; then
# no, then look for a forge jar to run
# Allow up to 2 levels since some modpacks have a top-level directory named for the modpack # Allow up to 2 levels since some modpacks have a top-level directory named
# for the modpack
forgeJar=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print) forgeJar=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
if [[ "$forgeJar" ]]; then if [[ "$forgeJar" ]]; then
FTB_BASE_DIR=$(dirname "${forgeJar}") FTB_BASE_DIR=$(dirname "${forgeJar}")
@@ -205,27 +190,24 @@ if [[ ! $startScript ]]; then
. ./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
startScript="${FTB_BASE_DIR}/ServerStart.sh" chmod +x "${FTB_BASE_DIR}/ServerStart.sh"
chmod +x "$startScript"
else else
log "ERROR: Modpack missing start script and unable to find Forge jar to generate one" log "Please make sure you are using the server version of the FTB modpack!"
exit 2 exit 2
fi fi
fi fi
# Modpacks that use https://github.com/BloodyMods/ServerStarter will sometimes specify an scriptCount=$(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l)
# extra subpath where all the server files get installed. Need to transplant EULA file there. if [[ $scriptCount = 0 ]]; then
serverSetupConfig=$(find "${FTB_BASE_DIR}" -type f -name server-setup-config.yaml) log "Please make sure you are using the server version of the FTB modpack!"
if [[ $serverSetupConfig && $serverSetupConfig != "~" ]]; then exit 2
if baseInstallPath=$(mc-image-helper yaml-path --file "$serverSetupConfig" ".install.baseInstallPath"); then elif (( scriptCount > 1 )); then
resolvedBaseInstallPath="$(dirname "$serverSetupConfig")/${baseInstallPath}" log "Ambiguous startup scripts in FTB modpack! Found:"
mkdir -p "$resolvedBaseInstallPath" find "${FTB_BASE_DIR}" $entryScriptExpr
exit 2
cp -n /data/eula.txt "${resolvedBaseInstallPath}/eula.txt"
fi
fi fi
FTB_SERVER_START="$startScript" FTB_SERVER_START=$(find "${FTB_BASE_DIR}" $entryScriptExpr)
export FTB_SERVER_START export FTB_SERVER_START
FTB_DIR=$(dirname "${FTB_SERVER_START}") FTB_DIR=$(dirname "${FTB_SERVER_START}")
@@ -244,5 +226,15 @@ 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

@@ -44,5 +44,6 @@ fi
# Normalize on Spigot for later operations # Normalize on Spigot for later operations
export FAMILY=SPIGOT export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@" exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -1,7 +1,6 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
set -o pipefail set -o pipefail
set -e set -e
@@ -27,6 +26,8 @@ if [ ! -f ${SERVER} ]; then
curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/assets/${latestJarId} curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/assets/${latestJarId}
fi fi
export FAMILY=HYBRID export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-setupWorld" "$@" export FAMILY=HYBRID
# Continue to Final Setup
exec ${SCRIPTS:-/}start-setupWorld "$@"

View File

@@ -55,6 +55,7 @@ if [ ! -d "$librariesDir" ]; then
fi fi
export SERVER export SERVER
export SKIP_LOG4J_CONFIG=true
export FAMILY=HYBRID export FAMILY=HYBRID
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@" exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"

View File

@@ -1,7 +1,6 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x isDebugging && set -x
if isURL ${CUSTOM_SERVER}; then if isURL ${CUSTOM_SERVER}; then
@@ -31,7 +30,6 @@ else
fi fi
# Allow for overriding Family on custom for testing. export SKIP_LOG4J_CONFIG=true
export FAMILY="${FAMILY:-HYBRID}" export FAMILY=HYBRID
exec ${SCRIPTS:-/}start-setupWorld $@ exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -2,16 +2,10 @@
ftbInstallMarker=".ftb-installed" ftbInstallMarker=".ftb-installed"
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
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
@@ -32,7 +26,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"
@@ -46,9 +40,10 @@ if ! [ -f "${ftbInstallMarker}" ] || [ "$(cat "${ftbInstallMarker}")" != "${FTB_
chmod +x "${ftbInstaller}" chmod +x "${ftbInstaller}"
fi fi
rm -rf forge*jar mods config libraries defaultconfigs changelogs
log "Installing modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID}" log "Installing modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID}"
log "This could take a while..." ${ftbInstaller} ${FTB_MODPACK_ID} ${FTB_MODPACK_VERSION_ID} --noscript --auto
${ftbInstaller} "${FTB_MODPACK_ID}" "${FTB_MODPACK_VERSION_ID}" --noscript --auto > ftb-installer.log
rm -f forge*installer.jar rm -f forge*installer.jar
echo "${FTB_MODPACK_ID}=${FTB_MODPACK_VERSION_ID}" > ${ftbInstallMarker} echo "${FTB_MODPACK_ID}=${FTB_MODPACK_VERSION_ID}" > ${ftbInstallMarker}
@@ -61,16 +56,16 @@ else
log "FTB modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID} is ready to go" log "FTB modpack ID ${FTB_MODPACK_ID}, version ID ${FTB_MODPACK_VERSION_ID} is ready to go"
fi fi
isDebugging && cat version.json
forgeVersion=$(jq -r '.targets|unique[] | select(.name == "forge") | .version' version.json) forgeVersion=$(jq -r '.targets|unique[] | select(.name == "forge") | .version' version.json)
fabricVersion=$(jq -r '.targets|unique[] | select(.name == "fabric") | .version' version.json) fabricVersion=$(jq -r '.targets|unique[] | select(.name == "fabric") | .version' version.json)
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
) )
for f in "${variants[@]}"; do for f in "${variants[@]}"; do
if [ -f $f ]; then if [ -f $f ]; then
@@ -80,10 +75,9 @@ 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"
log " Tried looking for ${variants[*]}" ls *.jar
exit 2 exit 2
fi fi
export FAMILY=FORGE export FAMILY=FORGE
exec ${SCRIPTS:-/}start-setupWorld $@
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -6,45 +6,76 @@ set -eu
requireVar VANILLA_VERSION requireVar VANILLA_VERSION
export TYPE=FABRIC export TYPE=FABRIC
: "${FABRIC_LAUNCHER_VERSION:=${FABRIC_INSTALLER_VERSION:-LATEST}}" : "${FABRIC_INSTALLER_VERSION:=${FABRICVERSION:-LATEST}}"
: "${FABRIC_LAUNCHER:=}" : "${FABRIC_INSTALLER:=}"
: "${FABRIC_LAUNCHER_URL:=}" : "${FABRIC_INSTALLER_URL:=}"
: "${FABRIC_LOADER_VERSION:=LATEST}" : "${FABRIC_LOADER_VERSION:=LATEST}"
isDebugging && set -x isDebugging && set -x
# Custom fabric jar log "Checking Fabric version information."
if [[ $FABRIC_LAUNCHER ]]; then if [[ $FABRIC_INSTALLER ]]; then
export SERVER=${FABRIC_LAUNCHER} FABRIC_INSTALLER_VERSION=$(echo -n "$FABRIC_INSTALLER" | mc-image-helper hash)
# Custom fabric jar url elif [[ $FABRIC_INSTALLER_URL ]]; then
elif [[ $FABRIC_LAUNCHER_URL ]]; then FABRIC_INSTALLER_VERSION=$(echo -n "$FABRIC_INSTALLER_URL" | mc-image-helper hash)
export SERVER=fabric-server-$(echo -n "$FABRIC_LAUNCHER_URL" | mc-image-helper hash) elif [[ ${FABRIC_INSTALLER_VERSION^^} = LATEST ]]; then
# Official fabric launcher FABRIC_INSTALLER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
else
if [[ ${FABRIC_LAUNCHER_VERSION^^} = LATEST ]]; then
log "Checking Fabric Launcher version information."
FABRIC_LAUNCHER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
fi
if [[ ${FABRIC_LOADER_VERSION^^} = LATEST ]]; then
log "Checking Fabric Loader version information."
FABRIC_LOADER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml)
fi
export SERVER=fabric-server-mc.${VANILLA_VERSION}-loader.${FABRIC_LOADER_VERSION}-launcher.${FABRIC_LAUNCHER_VERSION}.jar
export FABRIC_LAUNCHER_URL="https://meta.fabricmc.net/v2/versions/loader/${VANILLA_VERSION}/${FABRIC_LOADER_VERSION}/${FABRIC_LAUNCHER_VERSION}/server/jar"
fi fi
if [[ ! -e ${SERVER} && ! -z ${FABRIC_LAUNCHER_URL} ]]; then export SERVER=fabric-server-${VANILLA_VERSION}-${FABRIC_INSTALLER_VERSION}.jar
log "Downloading $FABRIC_LAUNCHER_URL ..."
if ! get -o "$SERVER" "$FABRIC_LAUNCHER_URL"; then if [ ! \( -e ${SERVER} -a -e "server-${VANILLA_VERSION}.jar" \) ]; then
log "Failed to download from given location $FABRIC_LAUNCHER_URL"
if [[ -z $FABRIC_INSTALLER && -z $FABRIC_INSTALLER_URL ]]; then
FABRIC_INSTALLER="fabric-installer-${FABRIC_INSTALLER_VERSION}.jar"
FABRIC_INSTALLER_URL="https://maven.fabricmc.net/net/fabricmc/fabric-installer/${FABRIC_INSTALLER_VERSION}/fabric-installer-${FABRIC_INSTALLER_VERSION}.jar"
elif [[ -z $FABRIC_INSTALLER ]]; then
FABRIC_INSTALLER="fabric-installer.jar"
elif [[ ! -e $FABRIC_INSTALLER ]]; then
log "ERROR: the given Fabric installer doesn't exist : $FABRIC_INSTALLER"
exit 2
fi
if [[ -z $FABRIC_LOADER_VERSION || ${FABRIC_LOADER_VERSION^^} = LATEST ]]; then
log "Checking Fabric Loader version information."
FABRIC_LOADER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml)
fi
if [[ ! -e $FABRIC_INSTALLER ]]; then
log "Downloading $FABRIC_INSTALLER_URL ..."
if ! get -o "$FABRIC_INSTALLER" "$FABRIC_INSTALLER_URL"; then
log "Failed to download from given location $FABRIC_INSTALLER_URL"
exit 2 exit 2
fi fi
fi fi
if [[ ! -e ${SERVER} ]]; then log "Installing Fabric ${VANILLA_VERSION} using $FABRIC_INSTALLER with loader version $FABRIC_LOADER_VERSION"
log "$SERVER does not exist, cannot launch server!"
exit 1 tries=3
set +e
while ((--tries >= 0)); do
java -jar $FABRIC_INSTALLER server \
-mcversion $VANILLA_VERSION \
-loader $FABRIC_LOADER_VERSION \
-downloadMinecraft \
-dir /data
if [[ $? == 0 ]]; then
break
fi fi
done
set -e
if (($tries < 0)); then
log "Fabric failed to install after several tries." >&2
exit 10
fi
mv server.jar "server-${VANILLA_VERSION}.jar"
mv fabric-server-launch.jar "${SERVER}"
fi
# Specify which server jar to run
echo "serverJar=server-${VANILLA_VERSION}.jar" > fabric-server-launcher.properties
export FAMILY=FABRIC export FAMILY=FABRIC
exec "${SCRIPTS:-/}start-setupWorld" "$@" exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -1,27 +1,151 @@
#!/bin/bash #!/bin/bash
: "${FORGE_VERSION:=${FORGEVERSION:-RECOMMENDED}}" : "${FORGEVERSION:=RECOMMENDED}"
: "${FORGE_FORCE_REINSTALL:=false}}"
# shellcheck source=start-utils # shellcheck source=start-utils
. "${SCRIPTS:-$(dirname "$0")}/start-utils" . "${SCRIPTS:-$(dirname "$0")}/start-utils"
isDebugging && set -x isDebugging && set -x
if ! mc-image-helper install-forge \ get_installer() {
--output-directory=/data \ if [[ -z $FORGE_INSTALLER_URL ]]; then
--results-file=/data/.run-forge.env \ log "Downloading $normForgeVersion"
--minecraft-version="${VANILLA_VERSION}" \
--forge-version="${FORGE_VERSION}" \ forgeFileNames="
--force-reinstall="${FORGE_FORCE_REINSTALL}"; then $shortForgeVersion/forge-$shortForgeVersion-installer.jar
log "ERROR failed to install forge" $normForgeVersion/forge-$normForgeVersion-installer.jar
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 fi
# grab SERVER and export it log "Installing Forge $shortForgeVersion using $FORGE_INSTALLER"
set -a mkdir -p mods
source /data/.run-forge.env tries=3
set +a while ((--tries >= 0)); do
if java -jar "$FORGE_INSTALLER" --installServer; then
break
fi
done
if ((tries < 0)); then
log "Forge failed to install after several tries." >&2
exit 10
fi
# 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']" "$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 -s --json-path ".promos['$VANILLA_VERSION-recommended']" "$promosUrl"); then
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" "$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
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}
@@ -58,5 +58,7 @@ if [[ ${LEVEL} != *\;* ]]; then
fi fi
export LEVEL export LEVEL
export SKIP_LOG4J_CONFIG=true
export FAMILY=LIMBO export FAMILY=LIMBO
exec ${SCRIPTS:-/}start-setupWorld $@ exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -1,32 +0,0 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
set -o pipefail
set -e
latestAsset=$(
curl -fsSL https://cdn.ci.loliidc.cn:30011/job/LoliServer-1.16.5/lastSuccessfulBuild/artifact/projects/LoliServer/build/libs | \
jq '.assets[] | select(.name | match(".*-server.jar"))'
)
if [[ -z "${latestAsset}" ]]; then
log "ERROR: latest release of Loliserver is missing server.jar asset"
exit 1
fi
isDebugging && log "Latest asset ${latestAsset}"
latestJarName=$(echo ${latestAsset} | jq --raw-output '.name')
latestJarId=$(echo ${latestAsset} | jq --raw-output '.id')
export SERVER="/data/${latestJarName}"
if [ ! -f ${SERVER} ]; then
log "Downloading ${latestJarName}"
curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://cdn.ci.loliidc.cn:30011/job/LoliServer-1.16.5/lastSuccessfulBuild/artifact/projects/LoliServer/build/libs/${latestJarId}
fi
export FAMILY=HYBRID
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -1,22 +1,93 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils" export SKIP_LOG4J_CONFIG=true
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
log "ERROR failed to locate latest Magma download for ${VANILLA_VERSION}. Is that version supported?" magmaDownloadServer() {
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 exit 1
fi fi
if ! SERVER=$(get --output-filename --skip-up-to-date --output /data "$downloadUrl"); then echo -n "$SERVER" > "$markerFile"
log "ERROR: failed to download Magma server jar from $downloadUrl" }
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 exit 1
fi fi
export SERVER 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
fi
tagName=$(echo "${latestMeta}" | jq -r '.tag_name')
markerFile=".magma-installed-${VANILLA_VERSION}-${tagName}"
if [ -f "${markerFile}" ]; then
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
export FAMILY=HYBRID export FAMILY=HYBRID
exec ${SCRIPTS:-/}start-setupWorld "$@"
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -38,6 +38,7 @@ if [ ! -f "${SERVER}" ]; then
get -o "${SERVER}" "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}" get -o "${SERVER}" "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}"
fi fi
export FAMILY=HYBRID export SKIP_LOG4J_CONFIG=true
export FAMILY=HYBRID
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@" exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"

View File

@@ -1,39 +1,10 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
set -o pipefail set -o pipefail
handleDebugMode isDebugging && set -x
: "${PAPER_CUSTOM_JAR:=}" if [[ $PAPER_DOWNLOAD_URL ]]; then
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
@@ -52,16 +23,26 @@ else
0) 0)
;; ;;
22) 22)
handleMissingVersion versions=$(curl -fsSL "https://papermc.io/api/v2/projects/paper" -H "accept: application/json")
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
if [[ $build = null ]]; then echo "ERROR: failed to lookup PaperMC build from version ${VANILLA_VERSION}"
handleMissingVersion exit 1
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" \
@@ -93,5 +74,6 @@ fi
# Normalize on Spigot for downstream operations # Normalize on Spigot for downstream operations
export FAMILY=SPIGOT export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@" exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -1,45 +1,45 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
set -euo pipefail set -euo pipefail
isDebugging && set -x isDebugging && set -x
IFS=$'\n\t' IFS=$'\n\t'
if versionLessThan 1.17; then if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.18" ] ; then
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" log "ERROR: Pufferfish server type only supports VERSION=LATEST, VERSION=1.18. Note that these are branches, not #.#.# versions."
exit 1 exit 1
fi fi
: "${PUFFERFISH_BUILD:=lastSuccessfulBuild}" : ${PUFFERFISH_BUILD:=lastSuccessfulBuild}
PUFFERFISH_BUILD_JSON=$(curl -X GET -s "https://ci.pufferfish.host/job/Pufferfish-${MAJOR_VANILLA_VERSION}/${PUFFERFISH_BUILD}/api/json") if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.18" ]; then
# Example: "url": "https://ci.pufferfish.host/job/Pufferfish-1.18/50/", PUFFERFISH_BRANCH="1.18"
PUFFERFISH_BUILD_URL=$(jq -n "$PUFFERFISH_BUILD_JSON" | jq -jc '.url // empty' ) PUFFERFISH_VERSION="1.18.1-R0.1"
# Example: "fileName": "pufferfish-paperclip-1.18.2-R0.1-SNAPSHOT-reobf.jar", fi
PUFFERFISH_BUILD_FILENAME=$(jq -n "$PUFFERFISH_BUILD_JSON" | jq -jc '.artifacts[].fileName // empty' )
PUFFERFISH_BUILD_DOWNLOAD_URL="${PUFFERFISH_BUILD_URL}artifact/build/libs/${PUFFERFISH_BUILD_FILENAME}"
# Setting server to the Jar filename for export. log "Using Pufferfish-${PUFFERFISH_BRANCH} branch"
export SERVER=$PUFFERFISH_BUILD_FILENAME
export SERVER=pufferfish-${PUFFERFISH_BRANCH}-${PUFFERFISH_BUILD}.jar
log "Removing old Pufferfish versions ..." log "Removing old Pufferfish versions ..."
shopt -s nullglob shopt -s nullglob
for f in pufferfish-*.jar; do for f in pufferfish-*.jar; do
[[ $f != "$SERVER" ]] && rm "$f" [[ $f != $SERVER ]] && rm $f
done done
if [[ ! -f "$SERVER" ]] || isTrue "${FORCE_REDOWNLOAD:-false}"; then if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
log "Downloading Pufferfish from $PUFFERFISH_BUILD_DOWNLOAD_URL ..." artifact="build/libs/pufferfish-paperclip-${PUFFERFISH_VERSION}-SNAPSHOT-reobf.jar"
if ! get -o "$SERVER" "$PUFFERFISH_BUILD_DOWNLOAD_URL"; then downloadUrl="https://ci.pufferfish.host/job/Pufferfish-${PUFFERFISH_BRANCH}/${PUFFERFISH_BUILD}/artifact/${artifact}"
log "ERROR: failed to download from $PUFFERFISH_BUILD_DOWNLOAD_URL (status=$?)" log "Downloading Pufferfish from $downloadUrl ..."
if ! get -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3 exit 3
fi fi
fi fi
# Normalize on Spigot for later operations # Normalize on Spigot for later operations
export FAMILY=SPIGOT export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-spiget" "$@" exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -2,26 +2,13 @@
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
if [[ $PURPUR_DOWNLOAD_URL ]]; then : ${VANILLA_VERSION:?}
export SERVER=$(getFilenameFromUrl "${PURPUR_DOWNLOAD_URL}") : ${PURPUR_BUILD:=LATEST}
: ${FORCE_REDOWNLOAD:=false}
if [ -f "$SERVER" ]; then
zarg=(-z "$SERVER")
fi
echo "Preparing custom Purpur jar from $PURPUR_DOWNLOAD_URL"
curl -fsSL -o "$SERVER" "${zarg[@]}" "${PURPUR_DOWNLOAD_URL}"
else
: "${VANILLA_VERSION:?}"
: "${PURPUR_BUILD:=LATEST}"
: "${FORCE_REDOWNLOAD:=false}"
if [[ ${PURPUR_BUILD} == LATEST ]]; then if [[ ${PURPUR_BUILD} == LATEST ]]; then
if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then
@@ -33,12 +20,6 @@ else
export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar" 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 if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download" downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
log "Downloading Purpur from $downloadUrl ..." log "Downloading Purpur from $downloadUrl ..."
@@ -47,9 +28,9 @@ else
exit 3 exit 3
fi fi
fi fi
fi
# Normalize on Spigot for later operations # Normalize on Spigot for later operations
export FAMILY=SPIGOT export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-spiget" "$@" exec "${SCRIPTS:-/}start-spiget" "$@"

View File

@@ -1,60 +0,0 @@
#!/bin/bash
set -eu
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
requireVar VANILLA_VERSION
export TYPE=QUILT
: "${QUILT_LAUNCHER:=}"
: "${QUILT_LAUNCHER_URL:=}"
: "${QUILT_INSTALLER_URL:=}"
: "${QUILT_INSTALLER_VERSION:=LATEST}"
: "${QUILT_LOADER_VERSION:=LATEST}"
isDebugging && set -x
# Custom quilt jar
if [[ $QUILT_LAUNCHER ]]; then
export SERVER=${QUILT_LAUNCHER}
# Custom quilt jar url
elif [[ $QUILT_LAUNCHER_URL ]]; then
export SERVER=quilt-server-$(echo -n "$QUILT_LAUNCHER_URL" | mc-image-helper hash)
# Official quilt installer
else
if [[ ${QUILT_INSTALLER_VERSION^^} = LATEST ]]; then
log "Checking Quilt Installer version information."
QUILT_INSTALLER_VERSION=$(maven-metadata-release https://maven.quiltmc.org/repository/release/org/quiltmc/quilt-installer/maven-metadata.xml)
fi
if [[ ${QUILT_LOADER_VERSION^^} = LATEST ]]; then
log "Checking Quilt Loader version information."
QUILT_LOADER_VERSION=$(maven-metadata-release https://maven.quiltmc.org/repository/release/org/quiltmc/quilt-loader/maven-metadata.xml)
fi
export INSTALLER=quilt-installer-${QUILT_INSTALLER_VERSION}.jar
export SERVER=quilt-server-${VANILLA_VERSION}-${QUILT_LOADER_VERSION}-launch.jar
export QUILT_INSTALLER_URL="https://maven.quiltmc.org/repository/release/org/quiltmc/quilt-installer/${QUILT_INSTALLER_VERSION}/quilt-installer-${QUILT_INSTALLER_VERSION}.jar"
fi
if [[ ! -e ${SERVER} && ! -z ${QUILT_INSTALLER_URL} ]]; then
log "Downloading and installing $QUILT_INSTALLER_URL ..."
if ! get -o "$INSTALLER" "$QUILT_INSTALLER_URL"; then
log "Failed to download from given location $QUILT_INSTALLER_URL"
exit 2
fi
if ! java -jar ${INSTALLER} install server ${VANILLA_VERSION} ${QUILT_LOADER_VERSION} --install-dir=./ --download-server; then
log "Failed to install $INSTALLER"
exit 2
fi
if ! mv quilt-server-launch.jar ${SERVER}; then
log "Failed to rename $SERVER"
exit 2
fi
fi
if [[ ! -e ${SERVER} ]]; then
log "$SERVER does not exist, cannot launch server!"
exit 1
fi
export FAMILY=FABRIC
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -24,14 +24,12 @@ esac
if [ -z $SPONGEVERSION ]; then if [ -z $SPONGEVERSION ]; then
log "Choosing Version for Sponge" log "Choosing Version for Sponge"
if [ "$SPONGEBRANCH" == "stable" ]; then if [ "$SPONGEBRANCH" == "stable" ]; then
SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.stable.latest.version'` export SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.stable.latest.version'`
else else
SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.bleeding.latest.version'` export SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.bleeding.latest.version'`
fi fi
fi fi
VANILLA_VERSION="$SPONGEVERSION"
export VANILLA_VERSION
export SERVER="spongevanilla-$SPONGEVERSION.jar" export SERVER="spongevanilla-$SPONGEVERSION.jar"
if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then

View File

@@ -8,33 +8,35 @@ set -o pipefail
export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar" export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar"
if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
log "Downloading $SERVER ..."
debug "Finding version manifest for $VANILLA_VERSION" debug "Finding version manifest for $VANILLA_VERSION"
versionManifestUrl=$(get 'https://launchermeta.mojang.com/mc/game/version_manifest.json' | jq --arg VANILLA_VERSION "$VANILLA_VERSION" --raw-output '[.versions[]|select(.id == $VANILLA_VERSION)][0].url') versionManifestUrl=$(get 'https://launchermeta.mojang.com/mc/game/version_manifest.json' | jq --arg VANILLA_VERSION "$VANILLA_VERSION" --raw-output '[.versions[]|select(.id == $VANILLA_VERSION)][0].url')
result=$? result=$?
if [ $result != 0 ]; then if [ $result != 0 ]; then
log "ERROR: failed to obtain version manifest URL ($result)" log "ERROR failed to obtain version manifest URL ($result)"
exit 1 exit 1
fi fi
if [ "$versionManifestUrl" = "null" ]; then if [ "$versionManifestUrl" = "null" ]; then
log "ERROR: couldn't find a matching manifest entry for $VANILLA_VERSION" log "ERROR couldn't find a matching manifest entry for $VANILLA_VERSION"
exit 1 exit 1
fi fi
debug "Found version manifest at $versionManifestUrl" debug "Found version manifest at $versionManifestUrl"
if ! serverDownloadUrl=$(get --json-path '$.downloads.server.url' "${versionManifestUrl}"); then serverDownloadUrl=$(get --json-path '$.downloads.server.url' "${versionManifestUrl}")
log "ERROR: failed to obtain version manifest from $versionManifestUrl ($result)" result=$?
if [ $result != 0 ]; then
log "ERROR failed to obtain version manifest from $versionManifestUrl ($result)"
exit 1 exit 1
elif [ "$serverDownloadUrl" = "null" ]; then elif [ "$serverDownloadUrl" = "null" ]; then
log "ERROR: there is not a server download for version $VANILLA_VERSION" log "ERROR version $VANILLA_VERSION does not provide a server download"
exit 1 exit 1
fi fi
log "Downloading $VANILLA_VERSION server..."
debug "Downloading server from $serverDownloadUrl" debug "Downloading server from $serverDownloadUrl"
get -o "$SERVER" "$serverDownloadUrl" get -o "$SERVER" "$serverDownloadUrl"
result=$? result=$?
if [ $result != 0 ]; then if [ $result != 0 ]; then
log "ERROR: failed to download server from $serverDownloadUrl ($result)" log "ERROR failed to download server from $serverDownloadUrl ($result)"
exit 1 exit 1
fi fi
fi fi

View File

@@ -1,56 +1,120 @@
#!/bin/bash #!/bin/bash
: "${DEBUG_EXEC:=false}" . ${SCRIPTS:-/}start-utils
: "${SETUP_ONLY:=false}"
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x isDebugging && set -x
if versionLessThan 1.7.6; then
opsFile=ops.txt
whitelistFile=white-list.txt
else
opsFile=ops.json
whitelistFile=whitelist.json
fi
function process_user_file() {
local output=$1
local source=$2
if isURL "$source"; then
log "Downloading $output from $source"
if ! get -o /data/$output "$source"; then
log "ERROR: failed to download from $source"
exit 2
fi
else
log "Copying $output from $source"
if ! cp "$source" /data/$output; then
log "ERROR: failed to copy from $source"
exit 1
fi
fi
}
function process_user_csv() {
local output=$1
local list=$2
local playerDataList
if [[ "$output" == *"ops"* ]]; then
# Extra data for ops.json
userData='{"uuid": .id, "name": .username, "level": 4}'
else
userData='{"uuid": .id, "name": .username}'
fi
log "Updating ${output%.*}"
for i in ${list//,/ }
do
if [ -e "$output" ] && grep -q "$i" "$output"; then
log "$i already present in $output, skipping"
continue
fi
if ! playerData=$(get "https://playerdb.co/api/player/minecraft/$i" | jq -re ".data.player"); then
log "WARNING: Could not lookup user $i for ${output} addition"
else
playerDataList=$playerDataList$(echo $playerData | jq -r "$userData")
fi
done
local newUsers=$(echo $playerDataList | jq -s .)
if [[ $output =~ .*\.txt ]]; then
# username list for txt config (Minecraft <= 1.7.5)
echo $newUsers | jq -r '.[].name' >> /data/${output}
sort -u /data/${output} -o /data/${output}
elif [ -e /data/${output} ]; then
# Merge with existing json file
local currentUsers=$(cat /data/${output})
jq --argjson current "$currentUsers" --argjson new "$newUsers" -n '$new + $current | unique_by(.uuid)' > /data/${output}
else
# New json file
echo $newUsers > /data/${output}
fi
}
if isTrue "${OVERRIDE_OPS}"; then
log "Recreating ${opsFile} file at server startup"
rm -f /data/${opsFile}
fi
if [ -n "${OPS_FILE}" ] && [ ! -e "/data/${opsFile}" ]; then
process_user_file ${opsFile} "$OPS_FILE"
fi
if [ -n "${OPS}" ]; then
process_user_csv ${opsFile} "$OPS"
fi
if isTrue "${OVERRIDE_WHITELIST}"; then
log "Recreating ${whitelistFile} file at server startup"
rm -f /data/${whitelistFile}
fi
if [ -n "${WHITELIST_FILE}" ] && [ ! -e "/data/${whitelistFile}" ]; then
process_user_file ${whitelistFile} "$WHITELIST_FILE"
fi
if [ -n "${WHITELIST}" ]; then
process_user_csv ${whitelistFile} "$WHITELIST"
fi
if [ -n "$ICON" ]; then if [ -n "$ICON" ]; then
if [ ! -e server-icon.png ] || isTrue "${OVERRIDE_ICON}"; then if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then
log "Using server icon from $ICON..." log "Using server icon from $ICON..."
if isURL "$ICON"; then
# Not sure what it is yet...call it "img" # Not sure what it is yet...call it "img"
if ! get -o /tmp/icon.img "$ICON"; then curl -sSL -o /tmp/icon.img $ICON
log "ERROR: failed to download icon from $ICON" specs=$(identify /tmp/icon.img | awk '{print $2,$3}')
exit 1 if [ "$specs" = "PNG 64x64" ]; then
fi mv /tmp/icon.img /data/server-icon.png
ICON=/tmp/icon.img
iconSrc="url"
elif [ -f "$ICON" ]; then
iconSrc="file"
else
log "ERROR: $ICON does not appear to be a URL or existing file"
exit 1
fi
read -r -a specs < <(identify "$ICON" | awk 'NR == 1 { print $2, $3 }')
if [ "${specs[0]} ${specs[1]}" = "PNG 64x64" ]; then
if [ $iconSrc = url ]; then
mv -f /tmp/icon.img /data/server-icon.png
else
cp -f "$ICON" /data/server-icon.png
fi
elif [ "${specs[0]}" = GIF ]; then
log "Converting GIF image to 64x64 PNG..."
convert "$ICON"[0] -resize 64x64! /data/server-icon.png
else else
log "Converting image to 64x64 PNG..." log "Converting image to 64x64 PNG..."
convert "$ICON" -resize 64x64! /data/server-icon.png convert /tmp/icon.img -resize 64x64! /data/server-icon.png
fi fi
fi fi
fi fi
canUseRollingLogs=true canUseRollingLogs=true
useFallbackJvmFlag=false
patchLog4jConfig() { patchLog4jConfig() {
file=${1?} file=${1?}
url=${2?} url=${2?}
if ! get -o "$file" "$url"; then if ! get -o "$file" "$url"; then
log "ERROR: failed to download corrected log4j config, fallback to JVM flag" log "ERROR: failed to download corrected log4j config"
useFallbackJvmFlag=true exit 1
return 1
fi fi
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}" JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
canUseRollingLogs=false canUseRollingLogs=false
@@ -70,10 +134,6 @@ elif isType PURPUR && versionLessThan 1.17; then
elif isType PURPUR && versionLessThan 1.18.1; then elif isType PURPUR && versionLessThan 1.18.1; then
patchLog4jConfig purpur_log4j2_117.xml https://purpurmc.org/docs/xml/purpur_log4j2_117.xml patchLog4jConfig purpur_log4j2_117.xml https://purpurmc.org/docs/xml/purpur_log4j2_117.xml
elif versionLessThan 1.18.1; then elif versionLessThan 1.18.1; then
useFallbackJvmFlag=true
fi
if ${useFallbackJvmFlag}; then
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}" JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
fi fi
@@ -86,23 +146,36 @@ 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 /image/log4j2.xml "$LOGFILE" cp /tmp/log4j2.xml "$LOGFILE"
else else
log "log4j2.xml already created, skipping" log "log4j2.xml already created, skipping"
fi fi
JVM_OPTS="-Dlog4j.configurationFile=/data/log4j2.xml ${JVM_OPTS}" JVM_OPTS="-Dlog4j.configurationFile=/data/log4j2.xml ${JVM_OPTS}"
fi fi
# Make sure files exist and are valid JSON (for pre-1.12 to 1.12 upgrades)
log "Checking for JSON files."
JSON_FILES=$(find /data -maxdepth 1 -name '*.json')
for j in $JSON_FILES; do
if [[ $(cat "$j" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') == "" ]]; then
log "Fixing JSON $j"
echo '[]' > $j
fi
done
# Optional disable console # Optional disable console
if versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then if versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then
EXTRA_ARGS+=" --noconsole" EXTRA_ARGS+=" --noconsole"
fi fi
# Optional disable GUI for headless servers # Optional disable GUI for headless servers
if [[ ${GUI,,} = false ]]; then if [[ ${GUI} = false || ${GUI} = FALSE ]]; then
EXTRA_ARGS+=" nogui" EXTRA_ARGS+=" nogui"
fi fi
: "${INIT_MEMORY:=${MEMORY}}"
: "${MAX_MEMORY:=${MEMORY}}"
expandedDOpts= expandedDOpts=
if [ -n "$JVM_DD_OPTS" ]; then if [ -n "$JVM_DD_OPTS" ]; then
for dopt in $JVM_DD_OPTS for dopt in $JVM_DD_OPTS
@@ -111,8 +184,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}
@@ -175,12 +248,6 @@ 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
@@ -203,7 +270,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" ] && [ -e /data/server-icon.png ]; then if [ ! -e "${FTB_DIR}/server-icon.png" -a -e /data/server-icon.png ]; then
cp -f /data/server-icon.png "${FTB_DIR}/" cp -f /data/server-icon.png "${FTB_DIR}/"
fi fi
@@ -223,10 +290,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)
@@ -248,15 +315,15 @@ EOF
finalArgs="${FTB_SERVER_START}" finalArgs="${FTB_SERVER_START}"
if isTrue "${SETUP_ONLY}"; then if isTrue "${SETUP_ONLY:=false}"; 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[@]}"
@@ -264,10 +331,6 @@ 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}; then
echo "SETUP_ONLY: bash ${SERVER}"
exit
fi
exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash "${SERVER}" exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash "${SERVER}"
else else
# If we have a bootstrap.txt file... feed that in to the server stdin # If we have a bootstrap.txt file... feed that in to the server stdin
@@ -277,7 +340,6 @@ else
log "Starting the Minecraft server..." log "Starting the Minecraft server..."
# shellcheck disable=SC2206
finalArgs=( finalArgs=(
$JVM_XX_OPTS $JVM_XX_OPTS
$JVM_OPTS $JVM_OPTS
@@ -286,7 +348,7 @@ else
"$@" $EXTRA_ARGS "$@" $EXTRA_ARGS
) )
if isTrue ${SETUP_ONLY}; then if isTrue ${SETUP_ONLY:=false}; then
echo "SETUP_ONLY: java ${finalArgs[*]}" echo "SETUP_ONLY: java ${finalArgs[*]}"
exit exit
fi fi

View File

@@ -1,36 +0,0 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
: "${RCON_CMDS_STARTUP:=}"
: "${RCON_CMDS_ON_CONNECT:=}"
: "${RCON_CMDS_ON_DISCONNECT:=}"
: "${RCON_CMDS_FIRST_CONNECT:=}"
: "${RCON_CMDS_LAST_DISCONNECT:=}"
: "${RCON_CMDS_PERIOD:=10}"
: "${SERVER_PORT:=25565}"
export RCON_CMDS_STARTUP
export RCON_CMDS_ON_CONNECT
export RCON_CMDS_ON_DISCONNECT
export RCON_CMDS_FIRST_CONNECT
export RCON_CMDS_LAST_DISCONNECT
export RCON_CMDS_PERIOD
export SERVER_PORT
log "Rcon cmds functionality enabled"
isDebugging && set -x
if ! [[ $RCON_CMDS_PERIOD =~ ^[0-9]+$ ]]; then
RCON_CMDS_PERIOD=10
export RCON_CMDS_PERIOD
log "Warning: RCON_CMDS_PERIOD is not numeric, set to 10 (seconds)"
fi
if [ "$RCON_CMDS_PERIOD" -eq "0" ] ; then
RCON_CMDS_PERIOD=10
export RCON_CMDS_PERIOD
log "Warning: RCON_CMDS_PERIOD must not be 0, set to 10 (seconds)"
fi
/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 interpolate \ mc-image-helper --debug=${DEBUG} 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,9 +27,9 @@ 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 patch \ mc-image-helper --debug=${DEBUG} patch \
--patch-env-prefix="${REPLACE_ENV_VARIABLE_PREFIX}" \ --patch-env-prefix="${REPLACE_ENV_VARIABLE_PREFIX}" \
"${PATCH_DEFINITIONS}" "${PATCH_DEFINITIONS}"
fi fi
exec "${SCRIPTS:-/}start-setupRbac" "$@" exec "${SCRIPTS:-/}start-finalExec" "$@"

View File

@@ -7,17 +7,13 @@ set -e -o pipefail
: "${MODS_FORGEAPI_PROJECTIDS:=}" : "${MODS_FORGEAPI_PROJECTIDS:=}"
: "${MODS_FORGEAPI_FILE:=}" : "${MODS_FORGEAPI_FILE:=}"
: "${MODS_FORGEAPI_RELEASES:=RELEASE}" : "${MODS_FORGEAPI_RELEASES:=RELEASE}"
: "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES:=false}"
: "${MODS_FORGEAPI_IGNORE_GAMETYPE:=false}"
: "${REMOVE_OLD_MODS_DEPTH:=1} " : "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar,*-version.json}" : "${REMOVE_OLD_MODS_INCLUDE:=*.jar}"
# 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}
RELEASE_NUMBER_FILTER=1 RELEASE_NUMBER_FILTER=1
MINECRAFT_GAME_ID=432 MINECRAFT_GAME_ID=432
FILTER_BY_FAMILY=false
DOWNLOADED_MODIDS=()
out_dir=/data/mods out_dir=/data/mods
# shellcheck source=start-utils # shellcheck source=start-utils
@@ -25,17 +21,10 @@ out_dir=/data/mods
isDebugging && set -x isDebugging && set -x
# Remove old mods/plugins # Remove old mods/plugins
if isTrue "${REMOVE_OLD_FORGEAPI_MODS}"; then if isTrue "${REMOVE_OLD_FORGEAPI_MODS}" && [ -z "${MODS_FORGEAPI_FILE}" ]; then
removeOldMods "/data/mods" removeOldMods /data/mods
fi fi
# Family filter is on by default for Forge, Fabric, and Bukkit
updateFamilyFilter(){
if isFamily "FORGE" "FABRIC" "BUKKIT"; then
FILTER_BY_FAMILY=true
fi
}
ensureModKey(){ ensureModKey(){
if [ -z "$MODS_FORGEAPI_KEY" ]; then if [ -z "$MODS_FORGEAPI_KEY" ]; then
log "ERROR: MODS_FORGEAPI_KEY REQUIRED to Connect to FORGE API, you supplied: ${MODS_FORGEAPI_KEY}" log "ERROR: MODS_FORGEAPI_KEY REQUIRED to Connect to FORGE API, you supplied: ${MODS_FORGEAPI_KEY}"
@@ -47,28 +36,28 @@ ensureModKey(){
# NOTE: downcasing release type for comparing types. # NOTE: downcasing release type for comparing types.
updateReleaseNumber(){ updateReleaseNumber(){
releaseType=$1 releaseType=$1
if [ "release" = "${releaseType,,}" ] || [ 1 = "${releaseType,,}" ]; then if [ "release" = "${releaseType,,}" ]; then
RELEASE_NUMBER_FILTER=1 RELEASE_NUMBER_FILTER=1
elif [ "beta" = "${releaseType,,}" ] || [ 2 = "${releaseType,,}" ]; then elif [ "beta" = "${releaseType,,}" ]; then
RELEASE_NUMBER_FILTER=2 RELEASE_NUMBER_FILTER=2
elif [ "alpha" = "${releaseType,,}" ] || [ 3 = "${releaseType,,}" ]; then elif [ "alpha" = "${releaseType,,}" ]; then
RELEASE_NUMBER_FILTER=3 RELEASE_NUMBER_FILTER=3
fi fi
} }
retrieveVersionTypeNumber(){ retrieveVersionTypeNumber(){
VERSION_NAME="Minecraft ${MAJOR_VANILLA_VERSION}" VERSION_NAME="Minecraft ${VANILLA_VERSION%.*}"
minecraft_types=$(curl -X GET -s \ minecraft_types=$(curl -X GET -s \
"${FORGEAPI_BASE_URL}/games/${MINECRAFT_GAME_ID}/version-types" \ "${FORGEAPI_BASE_URL}/games/${MINECRAFT_GAME_ID}/version-types" \
-H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'') -H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
if [ ! "$minecraft_types" ]; then if [ ! "$minecraft_types" ]; then
log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI. Check Forge API key or supplied Minecraft version" log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI"
exit 2 exit 2
fi fi
TYPE_ID=$(jq -n "$minecraft_types" | jq --arg VERSION_NAME "$VERSION_NAME" -jc ' TYPE_ID=$(jq -n "$minecraft_types" | jq --arg VERSION_NAME "$VERSION_NAME" -jc '
.data[]? | select(.name==$VERSION_NAME) | .id') .data[] | select(.name==$VERSION_NAME) | .id')
if [ ! "$TYPE_ID" ]; then if [ ! "$TYPE_ID" ]; then
log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI" log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI"
@@ -77,9 +66,8 @@ retrieveVersionTypeNumber(){
} }
modFileByProjectID(){ modFileByProjectID(){
project_id=$(echo "$1" | tr -d '"') project_id=$(echo $1 | tr -d '"')
project_id_release_type=$2 project_id_release_type=$2
project_id_file_name=$3
unset PROJECT_FILE unset PROJECT_FILE
# if Type id isn't defined use minecraft version to go get it. # if Type id isn't defined use minecraft version to go get it.
@@ -105,52 +93,35 @@ modFileByProjectID(){
total_count=$(jq -n "$project_files" | jq -c '.pagination.totalCount' ) total_count=$(jq -n "$project_files" | jq -c '.pagination.totalCount' )
# Checking for a individual release type input, if not use global # Checking for a individual release type input, if not use global
if [ "$project_id_release_type" ]; then if [ $project_id_release_type ]; then
updateReleaseNumber "$project_id_release_type" updateReleaseNumber $project_id_release_type
unset project_id_release_type
else else
updateReleaseNumber $MODS_FORGEAPI_RELEASES updateReleaseNumber $MODS_FORGEAPI_RELEASES
fi fi
# grabs the highest ID of the releaseTypes selected. # grabs the highest ID of the releaseTypes selected.
# Default is 1 for Release, Beta is 2, and Alpha is 3. Using less than we can validate highest release. # Default is 1 for Release, Beta is 2, and Alpha is 3. Using less than we can validate highest release.
if [ "$project_id_file_name" ]; then current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" -jc '
# Looks for file by name .data | sort_by(.id) | reverse | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0]')
current_project_file=$(jq -n "$project_files" | jq --arg FILE_NAME "$project_id_file_name" -jc '
.data | map(select(.fileName<=($FILE_NAME))) | .[0] // empty')
elif isFalse "${MODS_FORGEAPI_IGNORE_GAMETYPE}" && $FILTER_BY_FAMILY ; then
# 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 '
.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')
else
# Looks for file by version only.
current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" --arg VERSION "$VANILLA_VERSION" -jc '
.data | sort_by(.id) | reverse | map(select(.gameVersions[] | contains ($VERSION))) | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0] // empty')
fi
# Logic to grab the latest release over the entire pagination # Logic to grab the latest release over the entire pagination
if [ ! "$PROJECT_FILE" ]; then if [ ! "$PROJECT_FILE" ]; then
PROJECT_FILE=$current_project_file PROJECT_FILE=$current_project_file
elif [ "$current_project_file" ]; then elif [ "$current_project_file" ]; then
current_project_file_id=$(jq -n "$current_project_file" | jq -jc '.id // empty' ) current_project_file_id=$(jq -n "$current_project_file" | jq -jc '.id' )
PROJECT_FILE_ID=$(jq -n "$PROJECT_FILE" | jq -jc '.id // empty' ) PROJECT_FILE_ID=$(jq -n "$PROJECT_FILE" | jq -jc '.id' )
if (( current_project_file_id > PROJECT_FILE_ID )); then if (( current_project_file_id > PROJECT_FILE_ID )); then
PROJECT_FILE=$current_project_file PROJECT_FILE=$current_project_file
fi fi
fi fi
# check to see if we have gone to far or lost our index and exit with an error # check to see if we have gone to far or lost our index and exit with an error
if [ -z "$index" ] || [ -z "$total_count" ] || [ $index -ge "$total_count" ]; then if [ -z "$index" ] || [ -z "$total_count" ] || [ $index -ge $total_count ]; then
log "ERROR: Unable to retrieve any files for ${project_id} from ForgeAPI also Validate files have release type associated with no. ${RELEASE_NUMBER_FILTER}" log "ERROR: Unable to retrieve any files for ${project_id} from ForgeAPI also Validate files have release type associated with no. ${RELEASE_NUMBER_FILTER}"
exit 2 exit 2
fi fi
# Increment start index to new set. # Increment start index to new set.
index=$((index + pageSize)) index=$(($index + $pageSize))
done done
if [ ! "$PROJECT_FILE" ]; then
log "ERROR: Unable to retrieve any files for ${project_id}, Release Type: ${RELEASE_NUMBER_FILTER}, FAMILY_TYPE: ${FAMILY,,}"
exit 2
fi
} }
downloadModPackfromModFile() { downloadModPackfromModFile() {
@@ -158,86 +129,48 @@ downloadModPackfromModFile() {
log "ERROR: Project File not found from the ForgeAPI" log "ERROR: Project File not found from the ForgeAPI"
exit 2 exit 2
fi fi
# grabs needed values from our json return
file_name=$(jq -n "$PROJECT_FILE" | jq -jc '.fileName' )
download_url=$(jq -n "$PROJECT_FILE" | jq -jc '.downloadUrl' )
# 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
file_name=$(jq -n "$PROJECT_FILE" | jq -jc '.fileName // empty' )
download_url=$(jq -n "$PROJECT_FILE" | jq -jc '.downloadUrl // empty' )
mod_id=$(jq -n "$PROJECT_FILE" | jq -jc '.modId // empty' )
if [ ! -f "${out_dir}/${file_name}" ]; then
echo "Downloading ${download_url}" echo "Downloading ${download_url}"
# Track the mods we have downloaded. if ! get -o "${out_dir}/${file_name}" $download_url ; then
DOWNLOADED_MODIDS+=("${mod_id}")
if ! get --skip-up-to-date -o "${out_dir}/${file_name}" "${download_url}"; then
log "ERROR: failed to download from ${download_url}" log "ERROR: failed to download from ${download_url}"
exit 2 exit 2
fi fi
fi
}
downloadDependencies(){
if [ "$PROJECT_FILE" ]; then
dependencies=$(jq -n "$PROJECT_FILE" | jq -jc '.dependencies' )
required_dependencies=$(jq -n "$dependencies" | jq --arg REQUIRED_FILTER "3" -jc '
map(select(.relationType==($REQUIRED_FILTER|tonumber)))')
if [ "$required_dependencies" ]; then
while read -r current_dependency; do
mod_id=$(jq -n "$current_dependency" | jq -jc '.modId' )
# Validate we have not tried to download the mod yet.
if [[ ! "${DOWNLOADED_MODIDS[*]}" =~ $mod_id ]]; then
modFileByProjectID "$mod_id" "release"
downloadModPackfromModFile
fi
# needs to be piped in to keep look in main process
done < <(jq -n "$required_dependencies" | jq -c '.[]?')
fi
fi
} }
# Use forge api json file to filter and download the correct mods # Use forge api json file to filter and download the correct mods
if [ "$MODS_FORGEAPI_FILE" ] && [ -z "$MODS_FORGEAPI_PROJECTIDS" ]; then if [ "$MODS_FORGEAPI_FILE" ] && [ -z "$MODS_FORGEAPI_PROJECTIDS" ]; then
ensureModKey ensureModKey
updateFamilyFilter
if [ ! -f "$MODS_FORGEAPI_FILE" ]; then if [ ! -f "$MODS_FORGEAPI_FILE" ]; 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}" MODS_FORGEAPI_PROJECTIDS=$(jq --raw-output '[.[] | .projectId] | join(",")' $MODS_FORGEAPI_FILE)
# Needs loop here to look up release types befor calling download. if [ ! "$MODS_FORGEAPI_PROJECTIDS" ]; then
while read -r current_project; do log "ERROR: unable to retrieve packs from $MODS_FORGEAPI_FILE"
debug "DEBUG: current_project: ${current_project}" exit 2
# Per stack overflow we can use //empty to return empty string that works with -z fi
project_id=$(jq -n "$current_project" | jq -r '.projectId // empty' )
current_release_type=$(jq -n "$current_project" | jq -r '.releaseType // empty' )
current_file_name=$(jq -n "$current_project" | jq -r '.fileName // empty' )
# Validate we have not tried to download the mod yet. # Needs loop here to look up release types befor calling download.
if [[ ! "${DOWNLOADED_MODIDS[*]}" =~ $project_id ]]; then for project_id in ${MODS_FORGEAPI_PROJECTIDS//,/ }; do
modFileByProjectID "$project_id" "$current_release_type" "$current_file_name" current_release_type=$(jq --arg PROJECT_ID "$project_id" -jc '
.[] | select(.projectId==$PROJECT_ID) | .releaseType' "$MODS_FORGEAPI_FILE")
modFileByProjectID $project_id $current_release_type
downloadModPackfromModFile downloadModPackfromModFile
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then done
downloadDependencies
fi
fi
# needs to be piped in to keep look in main process
done < <(jq -c '.[]?' $MODS_FORGEAPI_FILE)
fi fi
# Use only project ids and global release data. # Use only project ids and global release data.
if [ "$MODS_FORGEAPI_PROJECTIDS" ] && [ -z "$MODS_FORGEAPI_FILE" ]; then if [ "$MODS_FORGEAPI_PROJECTIDS" ] && [ -z "$MODS_FORGEAPI_FILE" ]; then
ensureModKey ensureModKey
updateFamilyFilter
for project_id in ${MODS_FORGEAPI_PROJECTIDS//,/ }; do for project_id in ${MODS_FORGEAPI_PROJECTIDS//,/ }; do
# Validate we have not tried to download the mod yet.
if [[ ! "${DOWNLOADED_MODIDS[*]}" =~ $project_id ]]; then
modFileByProjectID $project_id modFileByProjectID $project_id
downloadModPackfromModFile downloadModPackfromModFile
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
downloadDependencies
fi
fi
done done
fi fi

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,*-version.json}" : "${REMOVE_OLD_MODS_INCLUDE:=*.jar}"
sum_file=/data/.generic_pack.sum sum_file=/data/.generic_pack.sum
# shellcheck source=start-utils # shellcheck source=start-utils
@@ -22,26 +22,33 @@ if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
rm -f "$sum_file" rm -f "$sum_file"
fi fi
function handlePackwiz() {
# If packwiz url passed, bootstrap packwiz and update mods before other modpack processing # If packwiz url passed, bootstrap packwiz and update mods before other modpack processing
if [[ "${PACKWIZ_URL:-}" ]]; then if [[ "${PACKWIZ_URL}" ]]; then
if ! packwizInstaller=$(mc-image-helper maven-download \ # Ensure we have the latest packwiz bootstrap installer
--maven-repo=https://maven.packwiz.infra.link/repository/release/ \ latestPackwiz=$(curl -fsSL https://api.github.com/repos/packwiz/packwiz-installer-bootstrap/releases/latest)
--group=link.infra.packwiz --artifact=packwiz-installer --classifier=dist \ if [[ -z "${latestPackwiz}" ]]; then
--skip-existing); then log "WARNING: Could not retrieve Packwiz bootstrap installer release information"
log "ERROR: failed to get packwiz installer" else
isDebugging && log "Latest packwiz ${latestPackWiz}"
latestPackwizVer=$(echo ${latestPackwiz} | jq --raw-output '.tag_name')
latestPackwizUrl=$(echo ${latestPackwiz} | jq --raw-output '.assets[] | select(.name | match("packwiz-installer-bootstrap.jar")) | .url')
: "${PACKWIZ_JAR:=packwiz-installer-bootstrap_${latestPackwizVer}.jar}"
if [[ ! -e $PACKWIZ_JAR ]]; then
log "Downloading Packwiz ${latestPackwizVer}"
curl -H "Accept:application/octet-stream" -o "$PACKWIZ_JAR" -fsSL ${latestPackwizUrl}
ln -sf "${PACKWIZ_JAR}" packwiz-installer-bootstrap.jar
fi
fi
if [[ ! -e packwiz-installer-bootstrap.jar ]]; then
log "ERROR: Packwiz not available or could not be downloaded from Github!"
exit 1 exit 1
fi fi
if isURL "${PACKWIZ_URL}"; then
log "Running packwiz installer against URL: ${PACKWIZ_URL}" log "Running packwiz against URL: ${PACKWIZ_URL}"
if ! java -cp "${packwizInstaller}" link.infra.packwiz.installer.Main -s server "${PACKWIZ_URL}"; then java -jar packwiz-installer-bootstrap.jar -g -s server "${PACKWIZ_URL}"
log "ERROR failed to run packwiz installer"
exit 1
fi fi
fi 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
@@ -85,7 +92,7 @@ elif [[ "$MODS" ]]; then
do do
if isURL "$i"; then if isURL "$i"; then
log "Downloading mod/plugin $i ..." log "Downloading mod/plugin $i ..."
if ! get --skip-up-to-date -o "${out_dir}" "$i"; then if ! get -o "${out_dir}" "$i"; then
log "ERROR: failed to download from $i into $out_dir" log "ERROR: failed to download from $i into $out_dir"
exit 2 exit 2
fi fi
@@ -121,7 +128,7 @@ elif [[ "$MODS_FILE" ]]; then
args=( args=(
-o "${out_dir}" -o "${out_dir}"
--log-progress-each --log-progress-each
--skip-up-to-date --skip-existing
--uris-file "${MODS_FILE}" --uris-file "${MODS_FILE}"
) )
if isTrue "${REMOVE_OLD_MODS}"; then if isTrue "${REMOVE_OLD_MODS}"; then
@@ -136,15 +143,13 @@ 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"
@@ -161,11 +166,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..."
jq -r '.files[] | (.projectID|tostring) + " " + (.fileID|tostring)' "${EFFECTIVE_MANIFEST_FILE}" | while read -r p f cat "${EFFECTIVE_MANIFEST_FILE}" | jq -r '.files[] | (.projectID|tostring) + " " + (.fileID|tostring)'| 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
@@ -181,23 +186,17 @@ case "X$EFFECTIVE_MANIFEST_FILE" in
;; ;;
esac esac
fi fi
}
function genericPacks() {
: "${GENERIC_PACKS:=${GENERIC_PACK}}" : "${GENERIC_PACKS:=${GENERIC_PACK}}"
: "${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 pack in "${packs[@]}"; do
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" if ! outfile=$(get -o /data/packs --output-filename --skip-existing "$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 fi
@@ -208,32 +207,19 @@ function genericPacks() {
done done
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file" isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
if ! sha256sum -c "${sum_file}" --status 2> /dev/null; then
log "Checking if generic packs are up to date" base_dir=/tmp/generic_pack_base
if isTrue "${SKIP_GENERIC_PACK_UPDATE_CHECK:-false}" && [ -f "$sum_file" ]; then mkdir -p ${base_dir}
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..."
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 for pack in "${packFiles[@]}"; do
isDebugging && ls -l "${pack}" isDebugging && ls -l "${pack}"
extract "${pack}" "${base_dir}" unzip -q -d ${base_dir} "${pack}"
done done
# Remove any eula file since container manages it
rm -f "${base_dir}/eula.txt"
# recalculate the actual base directory of content # recalculate the actual base directory of content
if ! base_dir=$(mc-image-helper find \ base_dir=$(find "$base_dir" -type d \( -name mods -o -name plugins -o -name config \) -printf '%h' -quit)
--max-depth=3 --type=directory --name=mods,plugins,config \ if [[ ! $base_dir ]]; then
--only-shallowest --fail-no-matches --format '%h' \
"$base_dir"); then
log "ERROR: Unable to find content base of generic packs ${GENERIC_PACKS}. Directories:" 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" find /tmp/generic_pack_base -type d -printf ' - %P\n'
exit 1 exit 1
fi fi
@@ -252,50 +238,11 @@ function genericPacks() {
log "Applying generic pack ..." log "Applying generic pack ..."
cp -R -f "${base_dir}"/* /data cp -R -f "${base_dir}"/* /data
rm -rf $original_base_dir rm -rf /tmp/generic_pack_base
if isTrue "${SKIP_GENERIC_PACK_CHECKSUM:-false}"; then sha256sum "${packFiles[@]}" > "${sum_file}"
log "Skipping generic pack(s) checksum" isDebugging && cat "$sum_file"
else
log "Saving generic pack(s) checksum"
sha1sum "${packFiles[@]}" > "${sum_file}"
if isDebugging; then
cat "$sum_file"
fi fi
fi 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 \
${subcommand} $updateArg \ --debug=${DEBUG} ${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 \
${subcommand} $updateArg \ --debug=${DEBUG} ${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 \
${subcommand} $updateArg \ --debug=${DEBUG} ${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

@@ -1,98 +0,0 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
if versionLessThan 1.7.6; then
opsFile=ops.txt
whitelistFile=white-list.txt
else
opsFile=ops.json
whitelistFile=whitelist.json
fi
function process_user_file() {
local output=$1
local source=$2
if isURL "$source"; then
log "Downloading $output from $source"
if ! get -o "/data/$output" "$source"; then
log "ERROR: failed to download from $source"
exit 2
fi
else
log "Copying $output from $source"
if ! cp "$source" "/data/$output"; then
log "ERROR: failed to copy from $source"
exit 1
fi
fi
}
function process_user_csv() {
local output=$1
local list=$2
local playerDataList
if [[ "$output" == *"ops"* ]]; then
# Extra data for ops.json
userData='{"uuid": .id, "name": .username, "level": 4}'
else
userData='{"uuid": .id, "name": .username}'
fi
log "Updating ${output%.*}"
for i in ${list//,/ }
do
if [ -e "$output" ] && grep -q "$i" "$output"; then
log "$i already present in $output, skipping"
continue
fi
if ! playerData=$(get "https://playerdb.co/api/player/minecraft/$i" | jq -re ".data.player"); then
log "WARNING: Could not lookup user $i for ${output} addition"
else
playerDataList=$playerDataList$(echo "$playerData" | jq -r "$userData")
fi
done
local newUsers=$(echo "$playerDataList" | jq -s .)
if [[ $output =~ .*\.txt ]]; then
# username list for txt config (Minecraft <= 1.7.5)
echo $newUsers | jq -r '.[].name' >> "/data/${output}"
sort -u /data/${output} -o /data/${output}
elif [ -e /data/${output} ]; then
# Merge with existing json file
local currentUsers=$(cat "/data/${output}")
jq --argjson current "$currentUsers" --argjson new "$newUsers" -n '$new + $current | unique_by(.uuid)' > "/data/${output}"
else
# New json file
echo $newUsers > "/data/${output}"
fi
}
if isTrue "${OVERRIDE_OPS}"; then
log "Recreating ${opsFile} file at server startup"
rm -f /data/${opsFile}
fi
if [ -n "${OPS_FILE}" ] && [ ! -e "/data/${opsFile}" ]; then
process_user_file ${opsFile} "$OPS_FILE"
fi
if [ -n "${OPS}" ]; then
process_user_csv ${opsFile} "$OPS"
fi
if isTrue "${OVERRIDE_WHITELIST}"; then
log "Recreating ${whitelistFile} file at server startup"
rm -f /data/${whitelistFile}
fi
if [ -n "${WHITELIST_FILE}" ] && [ ! -e "/data/${whitelistFile}" ]; then
process_user_file ${whitelistFile} "$WHITELIST_FILE"
fi
if [ -n "${WHITELIST}" ]; then
process_user_csv ${whitelistFile} "$WHITELIST"
fi
exec "${SCRIPTS:-/}start-finalExec" "$@"

View File

@@ -4,9 +4,6 @@
. "${SCRIPTS:-/}start-utils" . "${SCRIPTS:-/}start-utils"
: "${SERVER_PROPERTIES:=/data/server.properties}" : "${SERVER_PROPERTIES:=/data/server.properties}"
: "${OVERRIDE_SERVER_PROPERTIES:=true}"
: "${SKIP_SERVER_PROPERTIES:=false}"
: "${ENABLE_WHITELIST:=}"
# FUNCTIONS # FUNCTIONS
function setServerPropValue { function setServerPropValue {
@@ -17,16 +14,11 @@ function setServerPropValue {
TRUE|FALSE) TRUE|FALSE)
value=${value,,} ;; value=${value,,} ;;
esac esac
if [[ $prop =~ password ]]; then if grep "${prop}" "$SERVER_PROPERTIES" > /dev/null; then
showValue="*****" log "Setting ${prop} to '${value}' in ${SERVER_PROPERTIES}"
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
debug "Adding ${prop} with '${showValue}' in ${SERVER_PROPERTIES}" log "Adding ${prop} with '${value}' in ${SERVER_PROPERTIES}"
echo "${prop}=${value}" >> "$SERVER_PROPERTIES" echo "${prop}=${value}" >> "$SERVER_PROPERTIES"
fi fi
} }
@@ -41,16 +33,33 @@ function setServerProp {
} }
function customizeServerProps { function customizeServerProps {
local firstSetup=$1
# Whitelist processing # Whitelist processing
if [ -n "$WHITELIST" ] || [ -n "$WHITELIST_FILE" ] || isTrue "${ENABLE_WHITELIST}"; 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
elif isTrue "$firstSetup" || isFalse "${ENABLE_WHITELIST}"; then
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
# If not provided, generate a reasonable default message-of-the-day,
# which shows up in the server listing in the client
if ! [ -v MOTD ]; then
# snapshot is the odd case where we have to look at version to identify that label
if [[ ${ORIGINAL_TYPE} == "VANILLA" && ${VERSION} == "SNAPSHOT" ]]; then
label=SNAPSHOT
else
label=${ORIGINAL_TYPE}
fi
# Convert label to title-case
label=${label,,}
label=${label^}
MOTD="A ${label} Minecraft Server powered by Docker"
fi fi
# normalize MOTD # normalize MOTD
@@ -106,13 +115,7 @@ 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
setServerProp "initial-enabled-packs" INITIAL_ENABLED_PACKS
setServerProp "initial-disabled-packs" INITIAL_DISABLED_PACKS
if [[ $MOTD ]]; then
setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)" setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)"
fi
[[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}" [[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}"
if [ -n "$DIFFICULTY" ]; then if [ -n "$DIFFICULTY" ]; then
@@ -199,48 +202,37 @@ if [[ ${TYPE} == "CURSEFORGE" ]]; then
log "detected FTB, changing properties path to ${SERVER_PROPERTIES}" log "detected FTB, changing properties path to ${SERVER_PROPERTIES}"
fi fi
if ! isTrue "${SKIP_SERVER_PROPERTIES}"; 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"
# If not provided, generate a reasonable default message-of-the-day, customizeServerProps
# which shows up in the server listing in the client elif [ -n "${OVERRIDE_SERVER_PROPERTIES}" ]; then
if ! [ -v MOTD ]; then case ${OVERRIDE_SERVER_PROPERTIES^^} in
# snapshot is the odd case where we have to look at version to identify that label TRUE|1)
if [[ ${ORIGINAL_TYPE} == "VANILLA" && ${VERSION} == "SNAPSHOT" ]]; then customizeServerProps
label=SNAPSHOT ;;
*)
log "server.properties already created, skipping"
;;
esac
else else
label=${ORIGINAL_TYPE} log "server.properties already created, skipping"
fi
# Convert label to title-case
label=${label,,}
label=${label^}
MOTD="A ${label} Minecraft Server powered by Docker"
fi
customizeServerProps true
elif isTrue "${OVERRIDE_SERVER_PROPERTIES}"; then
customizeServerProps false
else
log "server.properties already created and managed manually"
fi fi
else else
log "Skipping setup of server.properties" log "Skipping setup of server.properties"
fi fi
if isTrue "${ENABLE_AUTOPAUSE}"; then if isTrue "${ENABLE_AUTOPAUSE}"; then
if [ -f "$SERVER_PROPERTIES" ]; then
current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' ) current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' )
if (( current_max_tick > 0 && current_max_tick < 86400000 )); then if (( current_max_tick > 0 && current_max_tick < 86400000 )); then
log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled." log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled."
log " Autopause functionality resuming the process might trigger the Watchdog and restart the server completely." log "Warning (cont): 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+)." 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+)."
fi
fi fi
fi fi
if isTrue "${DUMP_SERVER_PROPERTIES:-false}"; then if isDebugging && [ -f "${SERVER_PROPERTIES}" ]; then
log "DEBUG Dumping server.properties" log "DEBUG Dumping server.properties"
cat "${SERVER_PROPERTIES}" cat "${SERVER_PROPERTIES}"
fi fi

View File

@@ -2,18 +2,83 @@
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
if [[ ${VANILLATWEAKS_FILE} || ${VANILLATWEAKS_SHARECODE} ]]; then out_dir=/data/${LEVEL:-world}/datapacks
mc-image-helper vanillatweaks \
--output-directory="/data" \ # Remove old VANILLATWEAKS
--world-subdir="${LEVEL:-world}" \ if isTrue "${REMOVE_OLD_VANILLATWEAKS}" && [ -z "${VANILLATWEAKS_FILE}" ]; then
--share-codes="$VANILLATWEAKS_SHARECODE" \ if [ -d "$out_dir" ]; then
--pack-files="$VANILLATWEAKS_FILE" find "$out_dir" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
fi
fi
# Example: VANILLATWEAKS_SHARECODE=MGr52E
# Code generated from the UI website, typically a alphanumeric 6 digit code.
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
VANILLATWEAKS_FILE=/tmp/vanillatweaksfile.json
SHARECODE_LOOKUP_URL="https://vanillatweaks.net/assets/server/sharecode.php?code=${VANILLATWEAKS_SHARECODE}"
curl -f $SHARECODE_LOOKUP_URL -o $VANILLATWEAKS_FILE
if [ ! -f "$VANILLATWEAKS_FILE" ]; then
log "ERROR: Unable to use share code provided to retreive vanillatweaks file"
exit 2
fi
fi
# Use vanillatweaks file to specify VT and datapacks
if [[ "$VANILLATWEAKS_FILE" ]]; then
if [ ! -f "$VANILLATWEAKS_FILE" ]; then
log "ERROR: given VANILLATWEAKS_FILE file does not exist"
exit 2
fi
PACKS=$(jq -jc '.packs' $VANILLATWEAKS_FILE)
if [ ! "$PACKS" ]; then
log "ERROR: unable to retrieve packs from $VANILLATWEAKS_FILE"
exit 2
fi
VT_VERSION=$(jq -jc '.version' $VANILLATWEAKS_FILE)
if [ ! "$VT_VERSION" ]; then
log "ERROR: unable to retrieve version from $VANILLATWEAKS_FILE"
exit 2
fi
fi
# Download and unzip packs
if [[ "$PACKS" ]] && [[ "$VT_VERSION" ]]; then
VT_ZIPDATA_URL=https://vanillatweaks.net/assets/server/zipdatapacks.php
DOWNLOAD_URL=$(curl -X POST -F "packs=${PACKS}" -F "version=${VT_VERSION}" $VT_ZIPDATA_URL | jq -r '.link')
if [ ! "$DOWNLOAD_URL" ]; then
log "ERROR: unable to retrieve DOWNLOAD_URL from vanillatweaks.net!"
exit 2
fi
TEMPZIP=/tmp/vanillatweaks.zip
if ! get -o $TEMPZIP "https://vanillatweaks.net${DOWNLOAD_URL}"; then
log "ERROR: failed to download from ${DOWNLOAD_URL}"
exit 2
fi
mkdir -p "$out_dir"
if ! unzip -o -d "$out_dir" $TEMPZIP; then
log "ERROR: failed to unzip the ${PACKS} from ${$TEMPZIP}"
fi
# clean up files time!
rm -f $TEMPZIP
# cleans up temp vanilla tweaks file download to get stored packs
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
rm -f $VANILLATWEAKS_FILE
fi
fi fi
exec "${SCRIPTS:-/}start-setupDatapack" "$@" exec "${SCRIPTS:-/}start-setupDatapack" "$@"

Some files were not shown because too many files have changed in this diff Show More