Compare commits

..

123 Commits

Author SHA1 Message Date
Geoff Bourne
8d7a5275a8 docs: Updated description of LEVEL_TYPE (#1575) 2022-06-22 13:04:27 -05:00
Geoff Bourne
30fa6d02c7 build: output time spent on each setuponly test (#1569) 2022-06-18 09:56:53 -05:00
Davide A
a18cf3348a packwiz manually download bootstrap and skip update when initial download fails 2022-06-17 09:21:41 -05:00
Mathéo CIMBARO
a84cdaf355 Added support for optimized SIMD operations (#1570) 2022-06-16 18:19:15 -05:00
Mathéo CIMBARO
23c8fc65a4 Added support for Pufferfish 1.19 (#1566)
* Added support for Pufferfish 1.19

* Update scripts/start-deployPufferfish

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

* Removed wrong negation

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

* Added lbzip2
2022-05-26 22:02:26 -05:00
Bensuperpc
ea7046f93d Fixed older purpur versions not being removed (#1531) 2022-05-24 07:21:30 -05:00
Geoff Bourne
6768795594 docs: Corrected image tag in FTB example (#1530) 2022-05-22 15:25:44 -05:00
Skyler Spaeth
e7236212d8 Add jarfile options and custom worlds directory path (Multiverse) to docs (#1527) 2022-05-22 12:00:38 -05:00
Geoff Bourne
3e3abda71e Constrain GENERIC_PACK base detection depth (#1528) 2022-05-22 11:35:52 -05:00
Geoff Bourne
f67d3948d2 docs: Cleanup RCON_CMDS examples (#1526) 2022-05-21 11:04:00 -05:00
SeanWcom
bc3c3db080 Adding 'run.sh' as a variant for FTBA server types (#1521) 2022-05-19 07:29:52 -05:00
Felix
691be801d8 Add initial support for Quilt server (#1514) 2022-05-13 07:31:36 -05:00
Geoff Bourne
56b9326c09 docs: Embedded table of contents is redundant and makes it hard to see top part of docs (#1516) 2022-05-11 11:20:39 -05:00
md5nake
b6ea33dce1 Fix memory env vars being overridden if set to "" (#1512) 2022-05-11 08:15:53 -05:00
dependabot[bot]
367876e8b8 build(deps): bump docker/metadata-action from 3 to 4 (#1510) 2022-05-10 21:34:15 -05:00
dependabot[bot]
eb096142d6 build(deps): bump docker/setup-qemu-action from 1.2.0 to 2.0.0 (#1507) 2022-05-10 18:01:05 -05:00
dependabot[bot]
9ccd5bdee7 build(deps): bump docker/login-action from 1 to 2 (#1508) 2022-05-10 17:19:53 -05:00
dependabot[bot]
dc05029ef5 build(deps): bump docker/setup-buildx-action from 1 to 2 (#1509) 2022-05-10 12:41:28 -05:00
dependabot[bot]
926a3a5688 build(deps): bump docker/build-push-action from 2.10.0 to 3.0.0 (#1511) 2022-05-09 21:39:34 -05:00
Geoff Bourne
b27556e1eb Fix invalid -s arg with TYPE=FORGE (#1501) 2022-05-03 17:42:13 -05:00
Geoff Bourne
64521f7a39 Disable forgeapi tests for now (#1499) 2022-05-02 13:39:10 -05:00
Dessa Simpson
b4ca00bd3b Download spiget resources to tempdir under plugins (#1486) 2022-05-01 17:56:54 -05:00
Geoff Bourne
bca7b79f77 Avoid brittle testing of Loliserver due to download site (#1489) 2022-04-25 09:38:04 -05:00
itzg
2e0c8901a1 docs: Auto update markdown TOC 2022-04-24 22:11:22 +00:00
Sylensky
3e6ef1a605 Added Loliserver support (#1483)
* added Loliserver support

* added 'setup only' test for loliserver
2022-04-24 17:11:03 -05:00
Dario Crosa
d9a55ae938 remove isUrl check (#1488) 2022-04-24 15:51:12 -05:00
Bartosz Stefańczyk
7e843ea100 Fix alpine incompatibility (#1481) 2022-04-19 17:42:40 -05:00
dependabot[bot]
b241f74615 build(deps): bump stefanzweifel/git-auto-commit-action (#1479) 2022-04-18 07:33:56 -05:00
Geoff Bourne
c5460941c4 Updated rolling logs config to also be size based (#1478) 2022-04-17 21:36:12 -05:00
Geoff Bourne
890425a8b6 Updated rcon-cli to support variables cleanup (#1476) 2022-04-15 07:56:04 -05:00
Bartosz Stefańczyk
8c5c4664ea Fix forge using 1.17+ version after downgrade (#1474) 2022-04-14 22:03:34 -05:00
Geoff Bourne
901b889f2d Fixed running as uid=0 even with UID unset (#1475) 2022-04-14 11:41:43 -05:00
Geoff Bourne
cf1dd9f9e1 Corrected default of UID/GID via start script (#1471)
Fixes #1469
2022-04-11 18:00:16 -05:00
Geoff Bourne
8ef3fe199f Allow ICON to reference a local file (#1466) 2022-04-10 11:39:58 -05:00
Geoff Bourne
97fe6b1f14 Corrected autopause's resume to work with alpine images (#1464) 2022-04-10 10:58:18 -05:00
Geoff Bourne
4af80debe2 Correct spiget handling of jars that contain jars (#1462) 2022-04-09 22:02:20 -05:00
itzg
513492192b docs: Auto update markdown TOC 2022-04-02 20:38:29 +00:00
Geoff Bourne
e0b4a819b1 Fixed version comparisons when using SPONGEVANILLA (#1455)
Fixes #1452
2022-04-02 15:38:13 -05:00
itzg
5c0cf11bfe docs: Auto update markdown TOC 2022-04-02 19:02:45 +00:00
Michael Vorburger ⛑️
63a884ea75 Add hint that SPONGEVANILLA requires VERSION to README (#1452) (#1453) 2022-04-02 14:02:29 -05:00
chblodg
7c7090a582 ForgeAPI fixed lower sub version with a higher ID number (#1451)
Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
2022-04-01 18:26:12 -05:00
dependabot[bot]
fc70a976bd build(deps): bump docker/build-push-action from 2.9.0 to 2.10.0 (#1438) 2022-03-22 20:52:32 -05:00
itzg
0de90b134c docs: Auto update markdown TOC 2022-03-23 00:23:06 +00:00
Nick Martin
6eca74698b Update README.md (#1442) 2022-03-22 19:22:49 -05:00
dependabot[bot]
7c85f0926c build(deps): bump stefanzweifel/git-auto-commit-action (#1437) 2022-03-21 06:54:40 -05:00
Geoff Bourne
4ff158266a Use file content to detect spiget resource type (#1432)
For #1426
2022-03-17 22:07:34 -05:00
Geoff Bourne
fda8981028 Silence content type error for external spiget resources (#1431) 2022-03-15 20:56:25 -05:00
itzg
7f44a04490 docs: Auto update markdown TOC 2022-03-16 00:48:32 +00:00
chblodg
818ab46b73 fixing readme example for Vt (#1430)
Fixes #1429 

Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
2022-03-15 19:48:20 -05:00
Geoff Bourne
5ae5733741 Determine SPIGET file type from API (#1427) 2022-03-14 21:07:06 -05:00
Geoff Bourne
2042450f9b When ICON is GIF, extract only first frame (#1420) 2022-03-14 20:28:41 -05:00
Geoff Bourne
676b0f88cf mc-send-to-console skips user change when non-root (#1419)
Fixes #1393
2022-03-11 14:34:10 -06:00
Geoff Bourne
65d6c5bb32 Verify content type when downloading SPIGET_RESOURCES entry (#1413)
For #1378
2022-03-10 16:16:18 -06:00
dependabot[bot]
5168698498 build(deps): bump actions/stale from 4.1.0 to 5 (#1408) 2022-03-07 08:17:48 -06:00
dependabot[bot]
f512b9510c build(deps): bump actions/checkout from 2.4.0 to 3 (#1409) 2022-03-07 08:17:30 -06:00
Geoff Bourne
ba71a7f5a2 Re-fixed pufferfish tests (#1406) 2022-03-06 15:54:25 -06:00
chblodg
1ebe9d3f47 adding major version for pufferfish (#1405)
* adding major version for pufferfish

* fixing test as well as fixing a quote that was added due to linter recommendation

* Changing get major version to using a simple cut command

Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
2022-03-06 14:57:00 -06:00
Geoff Bourne
d9bddabbf8 Provide better debug logs with mc-image-helper get (#1404) 2022-03-05 20:50:28 -06:00
Geoff Bourne
3c3aea9c86 ci: adjusted pufferfish test (#1403) 2022-03-05 20:22:08 -06:00
Geoff Bourne
3806364197 ci: added build variants to main list 2022-03-05 15:53:00 -06:00
Bram
e9d3512383 Pufferfish: Remove regex processing (#1402)
Fixes #1401
2022-03-05 15:49:36 -06:00
itzg
09cc5003cd docs: Auto update markdown TOC 2022-03-05 01:53:09 +00:00
chblodg
1781ca282a added variables for pufferfish, also added setup only test (#1399) 2022-03-04 19:52:55 -06:00
chblodg
ba08a5d8f1 Fixing missing export, fixed run order, added real world working example (#1397) 2022-03-04 16:52:00 -06:00
itzg
b1e00b43be docs: Auto update markdown TOC 2022-03-04 02:47:47 +00:00
chblodg
a2499a8713 RCON: Adding on last disconnect (#1395) 2022-03-03 20:47:30 -06:00
itzg
07665d7571 docs: Auto update markdown TOC 2022-03-02 17:29:33 +00:00
chblodg
4587b32480 RCON commands feature (#1391)
Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
2022-03-02 11:29:12 -06:00
Geoff Bourne
15869fd774 docs: added tty and stdin_open to example file 2022-02-28 21:40:47 -06:00
Geoff Bourne
2e24bdfff8 Restored error handling when missing vanilla version (#1389) 2022-02-26 21:28:30 -06:00
itzg
1f8a3d85d1 docs: Auto update markdown TOC 2022-02-26 20:58:31 +00:00
Geoff Bourne
f359324bea docs: added mc-backup to related projects
#1385
2022-02-26 14:58:17 -06:00
itzg
e0ff1365cf docs: Auto update markdown TOC 2022-02-26 19:29:53 +00:00
Geoff Bourne
b347a7d0bf docs: added Related Projects section (#1387)
Fixes #1385
2022-02-26 13:29:39 -06:00
itzg
977ac22df9 docs: Auto update markdown TOC 2022-02-26 19:15:03 +00:00
Geoff Bourne
323d41603c docs: updated info to find FTB identifiers (#1386)
Fixes #612
2022-02-26 13:14:50 -06:00
chblodg
8dadfecf28 ForgeAPI: Random failure fix (#1384)
* Fix for Random forge api failure, removing dependency duplication messages

* pushing array test for review

* Fixing while loops that were causing downloaded modids to reset

Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
2022-02-24 16:47:22 -06:00
chblodg
5f1d7c6d31 Changing builds to JRE, and moving Java8 to pinned version for forge (#1382) 2022-02-24 12:18:49 -06:00
Geoff Bourne
7ba6ef9ad8 ci: MODS_FORGEAPI_KEY was missing from tests step 2022-02-24 07:26:04 -06:00
Geoff Bourne
eb1170408f Pin java8-multiarch to 8u312 due to Forge (#1383) 2022-02-24 07:08:06 -06:00
Geoff Bourne
c50c9988fc Fix PATH for annoying docker providers (#1371)
Fixes #1365
2022-02-19 11:34:13 -06:00
Geoff Bourne
d46384f68a Removing unused ttf-dejavu package (#1362) 2022-02-19 09:38:49 -06:00
Michael Kirsch
b7f8239235 use user instead of group in sudoers file (#1367) 2022-02-15 17:28:05 -06:00
itzg
f31c57b897 docs: Auto update markdown TOC 2022-02-14 00:02:27 +00:00
Geoff Bourne
5d68a57910 Added procps to alpine image to resolve autopause compatibility (#1361) 2022-02-13 18:02:09 -06:00
itzg
3886bca93f docs: Auto update markdown TOC 2022-02-13 15:02:50 +00:00
Daschi1
48f79f54bf Added an example for JVM_OPTS (#1359) 2022-02-13 09:02:37 -06:00
Geoff Bourne
179bb267fb build: add alpine support to matrix builds (#1349) 2022-02-11 21:00:24 -06:00
itzg
1458329e97 docs: Auto update markdown TOC 2022-02-12 02:37:54 +00:00
StealthCT
fdddece984 Migrate Fabric server to launcher method (#1351) 2022-02-11 20:37:39 -06:00
chblodg
700703fe8c Adding notifications for on close, reopen, and delete (#1355) 2022-02-10 17:49:08 -06:00
itzg
3131a340d4 docs: Auto update markdown TOC 2022-02-09 01:24:56 +00:00
chblodg
a57adc04ff Add GameType filter, and add ForgeAPI Verify Files to validate Mod Downloads (#1337)
Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
2022-02-08 19:24:38 -06:00
Jordy Hulck
4cb227629f Distro aware checksum (#1345) 2022-02-08 19:17:26 -06:00
dependabot[bot]
932cd8f89e build(deps): bump docker/build-push-action from 2.8.0 to 2.9.0 (#1339) 2022-02-07 06:54:56 -06:00
Geoff Bourne
f2f8d58d3b Only skip up-to-date files with MODS and MODS_FILE (#1338)
Fixes #1254
2022-02-06 17:46:17 -06:00
Luc Ritchie
b7bbe1b0a6 Support Spigot-style and vanilla-style world zips, for any server type (#1305) 2022-02-06 15:51:28 -06:00
itzg
1dd9a2e6e0 docs: Auto update markdown TOC 2022-02-06 18:45:40 +00:00
chblodg
aa7b997697 Adding support for crafting tweaks and resource packs (#1336)
Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
Co-authored-by: Floyd Everest <me@floydeverest.com>
2022-02-06 12:45:25 -06:00
Geoff Bourne
eb6c7c98f0 build: adjusted discord workflow name 2022-02-05 22:40:42 -06:00
Geoff Bourne
3472c67ca8 build: give issue-label workflow a name 2022-02-05 16:10:12 -06:00
Geoff Bourne
8995e63b72 build: fixed typo in push condition 2022-02-05 16:03:40 -06:00
Geoff Bourne
b65f108917 build: also push git tag builds 2022-02-05 16:02:27 -06:00
itzg
2b374a2073 docs: Auto update markdown TOC 2022-02-05 18:38:46 +00:00
Geoff Bourne
b5b164d5d3 feat: added SKIP_GENERIC_PACK_UPDATE_CHECK and FORCE_GENERIC_PACK_UPDATE (#1333) 2022-02-05 12:38:33 -06:00
itzg
0cde40604e docs: Auto update markdown TOC 2022-02-05 18:27:33 +00:00
Geoff Bourne
22f2eb7308 feat: add option to include timestamp with init logs (#1332) 2022-02-05 12:27:17 -06:00
Geoff Bourne
4a1d2d2b80 build: adjusted for eclipse-temurin:8-jdk not being on armv7 2022-02-02 22:27:38 -06:00
Geoff Bourne
10922b261b build: build-multiarch tags were too broad 2022-02-02 22:18:54 -06:00
139 changed files with 2061 additions and 1101 deletions

19
.gitattributes vendored
View File

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

View File

@@ -6,7 +6,6 @@ on:
- test/**
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+-*"
paths-ignore:
- "*.md"
- "docs/**"
@@ -14,64 +13,91 @@ on:
jobs:
build:
if: github.repository == 'itzg/docker-minecraft-server'
strategy:
fail-fast: false
matrix:
variant:
- java17
- java17-jdk
- java17-openj9
- java17-alpine
- java8
- java8-multiarch
- java8-openj9
- java8-jdk
- java11
- java11-openj9
- java11-jdk
include:
# JAVA 17:
- variant: java17
baseImage: eclipse-temurin:17
tagPrefix: 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: LATEST
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-jdk
tagPrefix: java17-openj9-
baseImage: ibm-semeru-runtimes:open-17-jre
platforms: linux/amd64,linux/arm64
mcVersion: LATEST
- variant: java8-multiarch
baseImage: eclipse-temurin:8-jdk
tagPrefix: java8-
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.12.2
- variant: java8-openj9
baseImage: ibm-semeru-runtimes:open-8-jdk
tagPrefix: java8-openj9-
platforms: linux/amd64,linux/arm64
mcVersion: 1.12.2
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
tagPrefix: java11-
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.16.5
- variant: java11-openj9
baseImage: ibm-semeru-runtimes:open-11-jdk
tagPrefix: 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-multiarch
baseImage: eclipse-temurin:8u312-b07-jre-focal
platforms: linux/amd64,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: itzg/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}
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@v2.4.0
uses: actions/checkout@v3
with:
# for build-files step
fetch-depth: 0
- name: Docker meta
id: meta
uses: docker/metadata-action@v3
uses: docker/metadata-action@v4
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: |
itzg/minecraft-server
${{ github.repository_owner }}/minecraft-server
tags: |
type=ref,event=tag,enable=${{ matrix.variant == 'java17' }}
type=ref,event=tag,prefix=${{ matrix.variant }}-
type=ref,event=tag,suffix=-${{ matrix.variant }}
type=raw,value=${{ matrix.variant }}
flavor: |
latest=${{ matrix.variant == 'java17' }}
@@ -79,19 +105,19 @@ jobs:
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.2.0
uses: docker/setup-qemu-action@v2.0.0
- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test
uses: docker/build-push-action@v2.8.0
uses: docker/build-push-action@v3.0.0
with:
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
@@ -108,20 +134,23 @@ jobs:
- name: Run tests
env:
MINECRAFT_VERSION: ${{ matrix.mcVersion }}
VARIANT: ${{ matrix.variant }}
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
run: |
tests/test.sh
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2.8.0
uses: docker/build-push-action@v3.0.0
with:
platforms: ${{ matrix.platforms }}
push: ${{ github.ref_name == 'master' }}
push: ${{ github.ref_type == 'tag' || github.ref_name == 'master' }}
tags: ${{ steps.meta.outputs.tags }}
# ensure latest base image is used
pull: true
labels: ${{ steps.meta.outputs.labels }}
build-args: |
BASE_IMAGE=${{ matrix.baseImage }}
BUILD_FILES_REV=${{ steps.build-files-rev.outputs.REV }}
cache-from: type=gha,scope=${{ matrix.variant }}
cache-to: type=gha,mode=max,scope=${{ matrix.variant }}

View File

@@ -21,13 +21,13 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2.4.0
- uses: actions/checkout@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
- name: Build
uses: docker/build-push-action@v2.8.0
uses: docker/build-push-action@v3.0.0
with:
context: .
platforms: linux/amd64

View File

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

View File

@@ -1,21 +0,0 @@
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,6 +1,8 @@
name: Issue labels
on:
issues:
types: [labeled]
types: [labeled, reopened, closed, deleted]
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_ISSUES_WEBHOOK }}
@@ -10,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: notify
- name: notify on label
if: >
github.event.label.name == 'enhancement'
|| github.event.label.name == 'bug'
@@ -21,3 +23,11 @@ jobs:
uses: Ilshidur/action-discord@master
with:
args: "[${{ github.event.issue.title }} (#${{ github.event.issue.number }})](<${{ 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 }}`"

View File

@@ -1,88 +0,0 @@
name: Build and Publish
on:
push:
branches:
- java8
- test/alpine/*
tags:
- "[0-9]+.[0-9]+.[0-9]+-java8"
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.8.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.8.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 }}
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>

View File

@@ -11,20 +11,19 @@ on:
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
- uses: actions/checkout@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
- name: Build
uses: docker/build-push-action@v2.8.0
uses: docker/build-push-action@v3.0.0
with:
context: .
platforms: linux/amd64
@@ -33,30 +32,40 @@ jobs:
cache-from: type=gha
- name: Run tests
env:
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
MINECRAFT_VERSION: 1.18.2
run: |
tests/test.sh
push:
runs-on: ubuntu-20.04
needs:
- test
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
steps:
- uses: actions/checkout@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Gather Docker metadata
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
id: meta
uses: docker/metadata-action@v3
uses: docker/metadata-action@v4
with:
images: |
itzg/minecraft-server
- name: Login to DockerHub
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
uses: docker/build-push-action@v2.8.0
uses: docker/build-push-action@v3.0.0
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64
platforms: linux/amd64
tags: ${{ steps.meta.outputs.tags }}
pull: true
push: true

View File

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

1
.gitignore vendored
View File

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

View File

@@ -15,8 +15,35 @@ 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:
```shell script
docker build -t mc-dev .
PowerShell: (Example of building and testing ForgeAPI)
```powershell
$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.
@@ -63,31 +90,6 @@ Note the port that was selected by http-server and pass the build arguments, suc
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
The following git command can be used to provide the bulk of release notes content:
@@ -95,25 +97,3 @@ The following git command can be used to provide the bulk of release notes conte
```shell script
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,94 +1,75 @@
ARG BASE_IMAGE=openjdk:8-jdk-alpine
FROM ${BASE_IMAGE}
RUN apk add --no-cache -U \
openssl \
imagemagick \
file \
lsof \
su-exec \
# GNU compatible 'find'
findutils \
shadow \
bash \
curl iputils \
git \
jq \
mysql-client \
tzdata \
rsync \
nano \
sudo \
knock \
ttf-dejavu
RUN addgroup -g 1000 minecraft \
&& adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft \
&& mkdir -m 777 /data \
&& chown minecraft:minecraft /data /home/minecraft
COPY --chmod=644 files/sudoers* /etc/sudoers.d
EXPOSE 25565 25575
# hook into docker BuildKit --platform support
# see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
ARG TARGETOS=linux
ARG TARGETARCH=amd64
ARG TARGETVARIANT=""
ARG EASY_ADD_VER=0.7.1
ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
RUN chmod +x /usr/bin/easy-add
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.2.0 --var app=restify --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--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
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--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
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--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
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--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
ARG MC_HELPER_VERSION=1.16.3
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 \
| tar -C /usr/share -zxf - \
&& ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin
VOLUME ["/data"]
WORKDIR /data
STOPSIGNAL SIGTERM
ENV UID=1000 GID=1000 \
JVM_XX_OPTS="-XX:+UseG1GC" 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 bin/ /usr/local/bin/
COPY --chmod=755 bin/mc-health /health.sh
COPY --chmod=644 files/server.properties /tmp/server.properties
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml
COPY --chmod=755 files/autopause /autopause
COPY --chmod=755 files/autostop /autostop
RUN dos2unix /start* /autopause/* /autostop/*
ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m CMD mc-health
# syntax = docker/dockerfile:1.3
ARG BASE_IMAGE=eclipse-temurin:17-jre-focal
FROM ${BASE_IMAGE}
# CI system should set this to a hash or git revision of the build directory and it's contents to
# ensure consistent cache updates.
ARG BUILD_FILES_REV=1
RUN --mount=target=/build,source=build \
REV=${BUILD_FILES_REV} /build/run.sh install-packages
RUN --mount=target=/build,source=build \
REV=${BUILD_FILES_REV} /build/run.sh setup-user
COPY --chmod=644 files/sudoers* /etc/sudoers.d
EXPOSE 25565 25575
# hook into docker BuildKit --platform support
# see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT
ARG EASY_ADD_VER=0.7.1
ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
RUN chmod +x /usr/bin/easy-add
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.2.0 --var app=restify --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.6.0 --var app=rcon-cli --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--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
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.8.1 --var app=mc-server-runner --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--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
ARG MC_HELPER_VERSION=1.17.0
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 \
| tar -C /usr/share -zxf - \
&& ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin
VOLUME ["/data"]
WORKDIR /data
STOPSIGNAL SIGTERM
# End user MUST set EULA and change RCON_PASSWORD
ENV TYPE=VANILLA VERSION=LATEST EULA="" UID=1000 GID=1000 RCON_PASSWORD=minecraft
COPY --chmod=755 scripts/start* /
COPY --chmod=755 bin/ /usr/local/bin/
COPY --chmod=755 bin/mc-health /health.sh
COPY --chmod=644 files/server.properties /tmp/server.properties
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml
COPY --chmod=755 files/autopause /autopause
COPY --chmod=755 files/autostop /autostop
COPY --chmod=755 files/rconcmds /rconcmds
RUN dos2unix /start* /autopause/* /autostop/* /rconcmds/*
ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m CMD mc-health

453
README.md
View File

@@ -21,130 +21,6 @@ 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.
**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 files](#generic-pack-files)
* [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: Wed Feb 2 02:53:20 UTC 2022 -->
<!--te-->
## 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.
@@ -210,9 +86,14 @@ Everything the container manages is located under the **container's** `/data` pa
### Attaching data directory to host filesystem
In most cases the easier way to persist and work with the minecraft data files is to use the `-v` argument to map a directory on your host machine to the container's `/data` directory, such as the following where `/home/user/minecraft-data` would be a directory of your choosing on your host machine:
In most cases the easiest way to persist and work with the minecraft data files is to use the [volume mounting](https://docs.docker.com/storage/volumes/) `-v` argument to map a directory on your host machine to the container's `/data` directory. In the following example, the path `/home/user/minecraft-data` **must be** a directory on your host machine:
docker run -d -v /home/user/minecraft-data:/data ...
-v /home/user/minecraft-data:/data
------------------------- -----
| |
| +-- must always be /data
|
+-- replace with a directory on your host machine
When attached in this way you can stop the server, edit the configuration under your attached directory and start the server again to pick up the new configuration.
@@ -286,16 +167,17 @@ the server jar remain in the `/data` directory. It is safe to remove those._
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 |
| -------------- | -------------|--------|----------|-------------------|
| latest | 16 | Debian | Hotspot | amd64,arm64,armv7 |
| java8 | 8 | Alpine | Hotspot | amd64 |
| Tag name | Java version | Linux | JVM Type | Architecture |
|-----------------|-------------|--------|----------|-------------------|
| latest | 17 | Debian | Hotspot | amd64,arm64,armv7 |
| java8 | 8 | Alpine | Hotspot | amd64 |
| java8-multiarch | 8 | Debian | Hotspot | amd64,arm64,armv7 |
| java8-openj9 | 8 | Debian | OpenJ9 | amd64 |
| java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 |
| java11-openj9 | 11 | Debian | OpenJ9 | amd64 |
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 |
| java8-openj9 | 8 | Debian | OpenJ9 | amd64 |
| java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 |
| java11-openj9 | 11 | Debian | OpenJ9 | amd64 |
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 |
| java17-alpine | 17 | Alpine | Hotspot | amd64 |
For example, to use Java version 8 on any supported architecture:
@@ -315,6 +197,40 @@ The following image tags have been deprecated and are no longer receiving update
- multiarch-latest
- 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
This image contains [mc-monitor](https://github.com/itzg/mc-monitor) and uses
@@ -418,7 +334,7 @@ In both of the cases above, there is no need for the `VERSION` or `FORGEVERSION`
### Running a Fabric Server
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).
Enable [Fabric server](https://fabricmc.net/) mode by adding a `-e TYPE=FABRIC` to your command-line.
```
docker run -d -v /path/on/host:/data \
@@ -426,19 +342,49 @@ docker run -d -v /path/on/host:/data \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
```
See the [Working with mods and plugins](#working-with-mods-and-plugins) section to set up Fabric mods and configuration.
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 version other than the latest can be requested using `FABRIC_LOADER_VERSION`, such as:
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 FABRIC_LOADER_VERSION=0.12.8
-e TYPE=FABRIC \
-e FABRIC_LAUNCHER_VERSION=0.10.2 \
-e FABRIC_LOADER_VERSION=0.13.1
```
If you wish to use an alternative installer you can:
* Specify an alternative version using `FABRIC_INSTALLER_VERSION` (such as `-e FABRIC_INSTALLER_VERSION=0.10.2`)
* 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`)
> 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.
### Running a Quilt Server
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 ... \
-e TYPE=QUILT \
-e QUILT_LOADER_VERSION=0.16.0 \
-e QUILT_INSTALLER_VERSION=0.4.1
```
> If you wish to use an alternative launcher 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`)
> * Provide the URL to a custom launcher jar with `QUILT_LAUNCHER_URL` (such as `-e QUILT_LAUNCHER_URL=http://HOST/quilt-server-custom.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
@@ -495,10 +441,10 @@ A [Pufferfish](https://github.com/pufferfish-gg/Pufferfish) server, which is "a
-e TYPE=PUFFERFISH
> NOTE: The `VERSION` variable is used to select a Pufferfish branch to download from. The available options are "LATEST" and "1.18"
> 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.
Extra variables:
- `PUFFERFISH_BUILD=lastSuccessfulBuild` : set a specific Pufferfish build to use
- `PUFFERFISH_BUILD=lastSuccessfulBuild` : set a specific Pufferfish build to use. Example: selecting build 47 => 1.18.1, or build 50 => 1.18.2 etc
- `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
@@ -514,6 +460,7 @@ Extra variables:
- `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
- `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
@@ -546,6 +493,16 @@ A [Catserver](http://catserver.moe/) type server can be used with
> **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
[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.
@@ -564,7 +521,7 @@ Enable SpongeVanilla server mode by adding a `-e TYPE=SPONGEVANILLA` to your com
By default the container will run the latest `STABLE` version.
If you want to run a specific version, you can add `-e SPONGEVERSION=1.11.2-6.1.0-BETA-19` to your command-line.
Beware that current [Sponge](https://www.spongepowered.org) `STABLE` versions for Minecraft 1.12 require using [the Java 8 tag](#running-minecraft-server-on-different-java-version):
docker run -d -v /path/on/host:/data -e TYPE=SPONGEVANILLA \
@@ -609,8 +566,8 @@ Crucible is only available for 1.7.10, so be sure to set `VERSION=1.7.10`.
[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:
- `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.
- `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 hovering over the name of the modpack, [as shown here](docs/ftba-identifier-popup.png).
- `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 hovering over the version name, [as shown here](docs/ftba-version-id-popup.png).
### Upgrading
@@ -624,7 +581,7 @@ The following example runs the latest version of [FTB Presents Direwolf20 1.12](
docker run -d --name mc-ftb -e EULA=TRUE \
-e TYPE=FTBA -e FTB_MODPACK_ID=31 \
-p 25565:25565 \
itzg/minecraft-server:multiarch
itzg/minecraft-server:java8-multiarch
```
> Normally you will also add `-v` volume for `/data` since the mods and config are installed there along with world data.
@@ -746,12 +703,17 @@ 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 ...
### **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 recieves an update with unexpected behavior.
**NOTE:** This potentially could lead to unexpected behavior if the Mod receives 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.
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:
* `MODS_FORGEAPI_KEY` - Required
@@ -759,6 +721,7 @@ Parameters to use the ForgeAPI:
* `MODS_FORGEAPI_PROJECTIDS` - Required or use MODS_FORGEAPI_FILE
* `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_DATAPACKS_DEPTH` - Default is 1
* `REMOVE_OLD_DATAPACKS_INCLUDE` - Default is *.jar
@@ -774,10 +737,10 @@ Example of expected forge api project ids, releases, and key:
Example of expected ForgeAPI file format.
**Field Description**:
* Name is currently unused, but can be used to document each entry.
* Project id is the id found on the CurseForge website for a particular mod
* Release 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.
* `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
[
@@ -802,7 +765,7 @@ Example of expected ForgeAPI file format.
### Generic pack files
To install all of the server content (jars, mods, plugins, configs, etc) from a zip or tgz file, such as a CurseForge modpack that is missing a server start script, then set `GENERIC_PACK` to the container path or URL of the archive 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.
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.
@@ -816,6 +779,8 @@ 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 check can be time-consuming since a SHA1 checksum is compared. To skip the update check set `SKIP_GENERIC_PACK_UPDATE_CHECK` to "true". Conversely, the generic pack(s) can be forced to be applied without comparing the checksum by setting `FORCE_GENERIC_PACK_UPDATE` to "true".
### Mod/Plugin URL Listing File
As an alternative to `MODS`, the variable `MODS_FILE` can be set with the path to a text file listing a mod/plugin URL on each line. For example, the following
@@ -879,6 +844,14 @@ The following diagram shows how this option can be used in a compose deployment
### 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.
### 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 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`
@@ -893,6 +866,9 @@ Datapacks will be placed in `/data/$LEVEL/datapacks`
VanillaTweaks datapacks can be installed with a share code from the website UI **OR** a json file to specify packs to download and install.
Datapacks will be placed in `/data/$LEVEL/datapacks`
Resourcepacks will be placed in `/data/resourcepacks`
Accepted Parameters:
- `VANILLATWEAKS_FILE`
@@ -903,32 +879,60 @@ Accepted Parameters:
- `REMOVE_OLD_VANILLATWEAKS_EXCLUDE`
Example of expected Vanillatweaks sharecode:
**Note**: ResourcePacks, DataPacks, and CraftingTweaks all have separate sharecodes
```yaml
VANILLATWEAKS_SHARECODE: MGr52E
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT
```
Example of expected Vanillatweaks file format:
```yaml
VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
```
Datapacks Json:
```json
{
"type": "datapacks",
"version": "1.18",
"packs": {
"survival": [
"graves",
"multiplayer sleep",
"afk display",
"armor statues",
"unlock all recipes",
"fast leaf decay",
"coordinates hud"
],
"items": ["armored elytra"]
}
}
```
Datapacks will be placed in `/data/$LEVEL/datapacks`
Resourcepacks Json:
```json
{
"type": "resourcepacks",
"version": "1.18",
"packs": {
"aesthetic": ["CherryPicking", "BlackNetherBricks", "AlternateBlockDestruction"]
},
"result": "ok"
}
```
CraftingTweaks Json:
```json
{
"type": "craftingtweaks",
"version": "1.18",
"packs": {
"quality of life": [
"dropper to dispenser",
"double slabs",
"back to blocks"
]
},
"result": "ok"
}
```
## Server configuration
@@ -1175,30 +1179,9 @@ environment variable set to `false`, such as
### Level Type and Generator Settings
By default, a standard world is generated with hills, valleys, water, etc. A different level type can
be configured by setting `LEVEL_TYPE` to an expected type, for example
be configured by setting `LEVEL_TYPE` to [an expected type listed here](https://minecraft.fandom.com/wiki/Server.properties#level-type).
- DEFAULT
- 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":{}}}'
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).
### Custom Server Resource Pack
@@ -1445,10 +1428,17 @@ 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`
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:
`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
If you would like to `docker attach` to the Minecraft server console with color and interactive capabilities, then add
@@ -1559,6 +1549,97 @@ To enable the JVM flags required to fully support the [Flare profiling suite](ht
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
### Description

View File

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

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

6
build/alpine/setup-user.sh Executable file
View File

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

7
build/run.sh Executable file
View File

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

@@ -0,0 +1,28 @@
#!/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
apt-get clean

6
build/ubuntu/setup-user.sh Executable file
View File

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

View File

@@ -1,151 +0,0 @@
#!/bin/bash
#set -x
# Use this variable to indicate a list of branches that docker hub is watching
branches_list=(
'java8'
)
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.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,11 +5,11 @@ services:
# Only using IMAGE variable to allow for local testing
image: ${IMAGE:-itzg/minecraft-server}
ports:
- 25565:25565
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: SPIGOT
SPIGET_RESOURCES: 9089,34315,3836
SPIGET_RESOURCES: 34315,3836
volumes:
- data:/data

View File

@@ -5,27 +5,31 @@ current_uptime() {
}
java_running() {
[[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]]
[[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]]
}
java_process_exists() {
[[ -n "$(ps -a -o comm | grep 'java')" ]]
[[ -n "$(ps -ax -o comm | grep 'java')" ]]
}
rcon_client_exists() {
[[ -n "$(ps -a -o comm | grep 'rcon-cli')" ]]
[[ -n "$(ps -ax -o comm | grep 'rcon-cli')" ]]
}
mc_server_listening() {
mc-monitor status --host localhost --port "$SERVER_PORT" --timeout 10s >& /dev/null
}
java_clients_connected() {
java_clients_connections() {
local connections
if java_running ; then
connections=$(mc-monitor status --host localhost --port "$SERVER_PORT" --show-player-count)
else
connections=0
fi
(( connections > 0 ))
echo $connections
}
java_clients_connected() {
(( $(java_clients_connections) > 0 ))
}

View File

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

View File

@@ -2,7 +2,7 @@
. /start-utils
if [[ $( ps -a -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
rcon-cli save-all >/dev/null

View File

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

View File

@@ -10,13 +10,16 @@
<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" />
<Policies>
<!-- Based on filePattern resolution, so daily -->
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="100 MB" />
<OnStartupTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="logs">
<IfFileName glob="*.log.gz" />
<IfLastModified age="7d" />
<IfAccumulatedFileCount exceeds="20"/>
</Delete>
</DefaultRolloverStrategy>
</RollingRandomAccessFile>

View File

@@ -0,0 +1,101 @@
#!/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=/autopause/autopause-fcns.sh
. /autopause/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,2 +1,2 @@
%minecraft ALL=(ALL) NOPASSWD:/usr/bin/pkill
%minecraft ALL=(ALL) NOPASSWD:/usr/sbin/knockd
minecraft ALL=(ALL) NOPASSWD:/usr/bin/pkill
minecraft ALL=(ALL) NOPASSWD:/usr/sbin/knockd

View File

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

View File

@@ -4,7 +4,19 @@
. "${SCRIPTS:-/}start-utils"
: "${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}"
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
log "Autopause functionality enabled"

View File

@@ -4,7 +4,15 @@
. "${SCRIPTS:-/}start-utils"
: "${SERVER_PORT:=25565}"
: "${ENABLE_AUTOSTOP:=false}"
: "${AUTOSTOP_TIMEOUT_EST:=3600}"
: "${AUTOSTOP_TIMEOUT_INIT:=1800}"
: "${AUTOSTOP_PERIOD:=10}"
export SERVER_PORT
export ENABLE_AUTOSTOP
export AUTOSTOP_TIMEOUT_EST
export AUTOSTOP_TIMEOUT_INIT
export AUTOSTOP_PERIOD
log "Autostop functionality enabled"

View File

@@ -7,7 +7,18 @@ IFS=$'\n\t'
: "${EULA:=}"
: "${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:=minecraft}"
: "${RCON_PORT:=25575}"
export RCON_PASSWORD RCON_PORT
shopt -s nullglob
@@ -66,11 +77,27 @@ if [[ $RCON_PASSWORD_FILE ]]; then
log ""
fi
# 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
log "ERROR: PATH should not be explicitly passed into the container"
log " Remove configuration of that variable."
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
log "ERROR: your Docker provider has an annoying flaw where it"
log " tries to set PATH even though the container establishes"
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
@@ -94,7 +121,9 @@ case "X$VERSION" in
;;
esac
export VANILLA_VERSION
log "Resolved version given ${VERSION} into ${VANILLA_VERSION}"
MAJOR_VANILLA_VERSION=$(get_major_version "$VANILLA_VERSION")
export MAJOR_VANILLA_VERSION
log "Resolved version given ${VERSION} into ${VANILLA_VERSION} and major version ${MAJOR_VANILLA_VERSION}"
cd /data || exit 1
@@ -108,6 +137,18 @@ if isTrue "${ENABLE_AUTOSTOP}"; then
${SCRIPTS:-/}start-autostop
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
echo "
MC_HEALTH_EXTRA_ARGS=(
@@ -135,10 +176,13 @@ case "${TYPE^^}" in
exec "${SCRIPTS:-/}start-deployFabric" "$@"
;;
QUILT)
exec "${SCRIPTS:-/}start-deployQuilt" "$@"
;;
FTBA)
log "ERROR: TYPE=FTBA is not supported with this image variant."
log " Use itzg/minecraft-server:java8-multiarch instead."
exit 1
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployFTBA" "$@"
;;
FTB|CURSEFORGE)
@@ -174,6 +218,11 @@ case "${TYPE^^}" in
exec "${SCRIPTS:-/}start-deployCatserver" "$@"
;;
LOLISERVER)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployLoliserver" "$@"
;;
PURPUR)
exec "${SCRIPTS:-/}start-deployPurpur" "$@"
;;
@@ -195,6 +244,12 @@ case "${TYPE^^}" in
;;
CRUCIBLE)
log "**********************************************************************"
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-deployCrucible" "$@"
;;
@@ -202,7 +257,7 @@ case "${TYPE^^}" in
log "Invalid type: '$TYPE'"
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only),"
log " CURSEFORGE, SPONGEVANILLA, PURPUR, CUSTOM,"
log " MAGMA, MOHIST, CATSERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE"
log " MAGMA, MOHIST, CATSERVER, LOLISERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE"
exit 1
;;

View File

@@ -33,7 +33,10 @@ export TYPE=CURSEFORGE
FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD}
log "Looking for Feed-The-Beast / CurseForge server modpack."
requireVar FTB_SERVER_MOD
if [[ ! $FTB_SERVER_MOD ]]; then
log "ERROR: CF_SERVER_MOD or FTB_SERVER_MOD is required to be set"
exit 1
fi
downloadModpack() {
srv_modpack=${FTB_SERVER_MOD}
@@ -111,8 +114,6 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
exit 2
fi
forgeInstallerJar=$(ls -t "${forgeInstallerJar}" | head -1)
log "Installing forge server"
dirOfInstaller=$(dirname "${forgeInstallerJar}")
(cd "${dirOfInstaller}"; java -jar "$(basename "${forgeInstallerJar}")" --installServer)
@@ -135,31 +136,31 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
exec "${SCRIPTS:-/}start-setupWorld" "$@"
fi
entryScriptExpr="
-name ServerStart.sh
-o -name serverstart.sh
-o -name ServerStartLinux.sh
-o -name LaunchServer.sh
-o -name server-start.sh
-o -name start-server.sh
-o -name startserver.sh
-o -name StartServer.sh
"
if [[ -d ${FTB_BASE_DIR} ]]; then
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
findStartScript() {
entryScriptExpr=(
-name ServerStart.sh
-o -name serverstart.sh
-o -name ServerStartLinux.sh
-o -name LaunchServer.sh
-o -name server-start.sh
-o -name start-server.sh
-o -name startserver.sh
-o -name StartServer.sh
-o -name run.sh
)
if [ -d "${FTB_BASE_DIR}" ]; then
find "${FTB_BASE_DIR}" \( "${entryScriptExpr[@]}" \) -print -quit
fi
else
startScriptCount=0
fi
}
startScript=$(findStartScript)
# only download and install if a mod pack isn't already installed
# 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
if [[ $startScriptCount = 0 ]]; then
if [[ ! $startScript ]]; then
downloadModpack
srv_modpack=${FTB_SERVER_MOD}
@@ -167,49 +168,61 @@ if [[ $startScriptCount = 0 ]]; then
mkdir -p "${FTB_BASE_DIR}"
unzip -o "${srv_modpack}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}'
installScript=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f -name install.sh)
installScriptExpr=(
-name install.sh
-o -name FTBInstall.sh
-o -name Install.sh
)
installScript=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( "${installScriptExpr[@]}" \) -print -quit)
if [[ "$installScript" ]]; then
(
cd "$(dirname "${installScript}")"
chmod +x ./install.sh
log "Running included install.sh"
./install.sh
chmod +x "${installScript}"
log "Running included $(basename "${installScript}"). This might take a minute or two..."
"${installScript}" > install.log
)
fi
startScript=$(findStartScript)
fi
if [[ $(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l) = 0 ]]; then
# start script provided by unzipped+installed modpack?
if [[ ! $startScript ]]; then
# no, then look for a forge jar to run
# Allow up to 2 levels since some modpacks have a top-level directory named
# 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)
if [[ "$forgeJar" ]]; then
FTB_BASE_DIR=$(dirname "${forgeJar}")
export FTB_BASE_DIR
log "No entry script found, so building one for ${forgeJar}"
cat > "${FTB_BASE_DIR}/ServerStart.sh" <<EOF
# 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)
if [[ "$forgeJar" ]]; then
FTB_BASE_DIR=$(dirname "${forgeJar}")
export FTB_BASE_DIR
log "No entry script found, so building one for ${forgeJar}"
cat > "${FTB_BASE_DIR}/ServerStart.sh" <<EOF
#!/bin/sh
. ./settings-local.sh
java \${JAVA_PARAMETERS} -Xmx\${MAX_RAM} -jar $(basename "${forgeJar}") nogui
EOF
chmod +x "${FTB_BASE_DIR}/ServerStart.sh"
else
log "Please make sure you are using the server version of the FTB modpack!"
exit 2
fi
startScript="${FTB_BASE_DIR}/ServerStart.sh"
chmod +x "$startScript"
else
log "ERROR: Modpack missing start script and unable to find Forge jar to generate one"
exit 2
fi
fi
scriptCount=$(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l)
if [[ $scriptCount = 0 ]]; then
log "Please make sure you are using the server version of the FTB modpack!"
exit 2
elif (( scriptCount > 1 )); then
log "Ambiguous startup scripts in FTB modpack! Found:"
find "${FTB_BASE_DIR}" $entryScriptExpr
exit 2
# Modpacks that use https://github.com/BloodyMods/ServerStarter will sometimes specify an
# extra subpath where all the server files get installed. Need to transplant EULA file there.
serverSetupConfig=$(find "${FTB_BASE_DIR}" -type f -name server-setup-config.yaml)
if [[ $serverSetupConfig && $serverSetupConfig != "~" ]]; then
if baseInstallPath=$(mc-image-helper yaml-path --file "$serverSetupConfig" ".install.baseInstallPath"); then
resolvedBaseInstallPath="$(dirname "$serverSetupConfig")/${baseInstallPath}"
mkdir -p "$resolvedBaseInstallPath"
cp -n /data/eula.txt "${resolvedBaseInstallPath}/eula.txt"
fi
fi
FTB_SERVER_START=$(find "${FTB_BASE_DIR}" $entryScriptExpr)
FTB_SERVER_START="$startScript"
export FTB_SERVER_START
FTB_DIR=$(dirname "${FTB_SERVER_START}")
@@ -228,15 +241,5 @@ if isTrue "${FTB_LEGACYJAVAFIXER}" && [ ! -e "${legacyJavaFixerPath}" ]; then
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
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -47,7 +47,6 @@ if [ ! -d "$librariesDir" ]; then
exit 1
fi
mkdir "$librariesDir"
if ! unzip /tmp/libraries.zip -d "$librariesDir"; then
log "ERROR: failed to unzip Crucible libraries"
exit 1

View File

@@ -31,6 +31,7 @@ else
fi
export FAMILY=HYBRID
# Allow for overriding Family on custom for testing.
export FAMILY="${FAMILY:-HYBRID}"
exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -67,6 +67,7 @@ variants=(
forge-${mcVersion}-${forgeVersion}-universal.jar
forge-${mcVersion}-${forgeVersion}-${mcVersion}-universal.jar
fabric-${mcVersion}-${fabricVersion}-server-launch.jar
run.sh
)
for f in "${variants[@]}"; do
if [ -f $f ]; then

View File

@@ -6,76 +6,45 @@ set -eu
requireVar VANILLA_VERSION
export TYPE=FABRIC
: "${FABRIC_INSTALLER_VERSION:=${FABRICVERSION:-LATEST}}"
: "${FABRIC_INSTALLER:=}"
: "${FABRIC_INSTALLER_URL:=}"
: "${FABRIC_LAUNCHER_VERSION:=${FABRIC_INSTALLER_VERSION:-LATEST}}"
: "${FABRIC_LAUNCHER:=}"
: "${FABRIC_LAUNCHER_URL:=}"
: "${FABRIC_LOADER_VERSION:=LATEST}"
isDebugging && set -x
log "Checking Fabric version information."
if [[ $FABRIC_INSTALLER ]]; then
FABRIC_INSTALLER_VERSION=$(echo -n "$FABRIC_INSTALLER" | mc-image-helper hash)
elif [[ $FABRIC_INSTALLER_URL ]]; then
FABRIC_INSTALLER_VERSION=$(echo -n "$FABRIC_INSTALLER_URL" | mc-image-helper hash)
elif [[ ${FABRIC_INSTALLER_VERSION^^} = LATEST ]]; then
FABRIC_INSTALLER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
fi
export SERVER=fabric-server-${VANILLA_VERSION}-${FABRIC_INSTALLER_VERSION}.jar
if [ ! \( -e ${SERVER} -a -e "server-${VANILLA_VERSION}.jar" \) ]; then
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
# Custom fabric jar
if [[ $FABRIC_LAUNCHER ]]; then
export SERVER=${FABRIC_LAUNCHER}
# Custom fabric jar url
elif [[ $FABRIC_LAUNCHER_URL ]]; then
export SERVER=fabric-server-$(echo -n "$FABRIC_LAUNCHER_URL" | mc-image-helper hash)
# Official fabric launcher
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 [[ -z $FABRIC_LOADER_VERSION || ${FABRIC_LOADER_VERSION^^} = LATEST ]]; then
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
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
fi
fi
log "Installing Fabric ${VANILLA_VERSION} using $FABRIC_INSTALLER with loader version $FABRIC_LOADER_VERSION"
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
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}"
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
# Specify which server jar to run
echo "serverJar=server-${VANILLA_VERSION}.jar" > fabric-server-launcher.properties
if [[ ! -e ${SERVER} && ! -z ${FABRIC_LAUNCHER_URL} ]]; then
log "Downloading $FABRIC_LAUNCHER_URL ..."
if ! get -o "$SERVER" "$FABRIC_LAUNCHER_URL"; then
log "Failed to download from given location $FABRIC_LAUNCHER_URL"
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

@@ -8,7 +8,7 @@ isDebugging && set -x
get_installer() {
if [[ -z $FORGE_INSTALLER_URL ]]; then
log "Downloading $normForgeVersion"
log "Downloading Forge Installer $normForgeVersion"
forgeFileNames="
$shortForgeVersion/forge-$shortForgeVersion-installer.jar
@@ -25,7 +25,7 @@ get_installer() {
log "Unable to locate usable URL for $normForgeVersion"
exit 2
else
log "Downloading $FORGE_INSTALLER_URL ..."
log "Downloading Forge Installer from $FORGE_INSTALLER_URL ..."
if ! get -o "$FORGE_INSTALLER" "$FORGE_INSTALLER_URL"; then
log "Failed to download from given location $FORGE_INSTALLER_URL"
exit 2
@@ -38,6 +38,9 @@ install() {
get_installer "$normForgeVersion" "$shortForgeVersion"
fi
# reference issue #1459
rm -f run.sh
log "Installing Forge $shortForgeVersion. This might take a minute or two..."
mkdir -p mods
tries=3
@@ -99,7 +102,7 @@ resolve_versions() {
log "Checking Forge version information."
case $FORGEVERSION in
LATEST)
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" "$promosUrl"); then
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" --json-value-when-missing "" "$promosUrl"); then
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
log " Refer to http://files.minecraftforge.net/ for supported versions"
exit 2
@@ -107,8 +110,8 @@ resolve_versions() {
;;
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
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-recommended']" --json-value-when-missing "" "$promosUrl"); then
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" --json-value-when-missing "" "$promosUrl"); then
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
log " Refer to http://files.minecraftforge.net/ for supported versions"
exit 2

32
scripts/start-deployLoliserver Executable file
View File

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

@@ -4,6 +4,30 @@
set -o pipefail
isDebugging && set -x
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_DOWNLOAD_URL ]]; then
export SERVER=$(getFilenameFromUrl "${PAPER_DOWNLOAD_URL}")
@@ -23,26 +47,16 @@ else
0)
;;
22)
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
handleMissingVersion
;;
*)
echo "ERROR: unknown error while looking up PaperMC version=${VANILLA_VERSION}"
exit 1
;;
esac
if [ $? != 0 ]; then
echo "ERROR: failed to lookup PaperMC build from version ${VANILLA_VERSION}"
exit 1
if [[ $build = null ]]; then
handleMissingVersion
fi
export SERVER=$(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}/builds/${build}" -H "accept: application/json" \

View File

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

View File

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

60
scripts/start-deployQuilt Executable file
View File

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

View File

@@ -8,27 +8,25 @@ set -o pipefail
export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar"
if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
log "Downloading $SERVER ..."
log "Locating download for $SERVER ..."
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')
result=$?
if [ $result != 0 ]; then
log "ERROR failed to obtain version manifest URL ($result)"
log "ERROR: failed to obtain version manifest URL ($result)"
exit 1
fi
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
fi
debug "Found version manifest at $versionManifestUrl"
serverDownloadUrl=$(get --json-path '$.downloads.server.url' "${versionManifestUrl}")
result=$?
if [ $result != 0 ]; then
log "ERROR failed to obtain version manifest from $versionManifestUrl ($result)"
if ! serverDownloadUrl=$(get --json-path '$.downloads.server.url' "${versionManifestUrl}"); then
log "ERROR: failed to obtain version manifest from $versionManifestUrl ($result)"
exit 1
elif [ "$serverDownloadUrl" = "null" ]; then
log "ERROR version $VANILLA_VERSION does not provide a server download"
log "ERROR: there is not a server download for version $VANILLA_VERSION"
exit 1
fi
@@ -36,7 +34,7 @@ if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
get -o "$SERVER" "$serverDownloadUrl"
result=$?
if [ $result != 0 ]; then
log "ERROR failed to download server from $serverDownloadUrl ($result)"
log "ERROR: failed to download server from $serverDownloadUrl ($result)"
exit 1
fi
fi

View File

@@ -5,16 +5,35 @@
isDebugging && set -x
if [ -n "$ICON" ]; then
if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then
if [ ! -e server-icon.png ] || isTrue "${OVERRIDE_ICON}"; then
log "Using server icon from $ICON..."
# Not sure what it is yet...call it "img"
curl -sSL -o /tmp/icon.img $ICON
specs=$(identify /tmp/icon.img | awk '{print $2,$3}')
if [ "$specs" = "PNG 64x64" ]; then
mv /tmp/icon.img /data/server-icon.png
if isURL "$ICON"; then
# Not sure what it is yet...call it "img"
if ! get -o /tmp/icon.img "$ICON"; then
log "ERROR: failed to download icon from $ICON"
exit 1
fi
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
log "Converting image to 64x64 PNG..."
convert /tmp/icon.img -resize 64x64! /data/server-icon.png
convert "$ICON" -resize 64x64! /data/server-icon.png
fi
fi
fi
@@ -91,8 +110,9 @@ if [[ ${GUI,,} = false ]]; then
EXTRA_ARGS+=" nogui"
fi
: "${INIT_MEMORY:=${MEMORY}}"
: "${MAX_MEMORY:=${MEMORY}}"
: "${MEMORY=1G}"
: "${INIT_MEMORY=${MEMORY}}"
: "${MAX_MEMORY=${MEMORY}}"
expandedDOpts=
if [ -n "$JVM_DD_OPTS" ]; then
@@ -102,8 +122,8 @@ if [ -n "$JVM_DD_OPTS" ]; then
done
fi
if isTrue ${ENABLE_JMX}; then
: ${JMX_PORT:=7091}
if isTrue "${ENABLE_JMX}"; then
: "${JMX_PORT:=7091}"
JVM_OPTS="${JVM_OPTS}
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.port=${JMX_PORT}
@@ -166,6 +186,12 @@ if isTrue "${USE_FLARE_FLAGS}"; then
"
fi
if isTrue "${USE_SIMD_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
--add-modules=jdk.incubator.vector
"
fi
if isTrue "${DEBUG_MEMORY}"; then
log "Memory usage and availability (in MB)"
uname -a

36
scripts/start-rconcmds Normal file
View File

@@ -0,0 +1,36 @@
#!/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
/rconcmds/rcon-cmds-daemon.sh &

View File

@@ -8,6 +8,7 @@ set -e -o pipefail
: "${MODS_FORGEAPI_FILE:=}"
: "${MODS_FORGEAPI_RELEASES:=RELEASE}"
: "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES:=false}"
: "${MODS_FORGEAPI_IGNORE_GAMETYPE:=false}"
: "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar}"
@@ -15,6 +16,8 @@ set -e -o pipefail
FORGEAPI_BASE_URL=${FORGEAPI_BASE_URL:-https://api.curseforge.com/v1}
RELEASE_NUMBER_FILTER=1
MINECRAFT_GAME_ID=432
FILTER_BY_FAMILY=false
DOWNLOADED_MODIDS=()
out_dir=/data/mods
# shellcheck source=start-utils
@@ -22,10 +25,17 @@ out_dir=/data/mods
isDebugging && set -x
# Remove old mods/plugins
if isTrue "${REMOVE_OLD_FORGEAPI_MODS}" && [ -z "${MODS_FORGEAPI_FILE}" ]; then
removeOldMods /data/mods
if isTrue "${REMOVE_OLD_FORGEAPI_MODS}"; then
removeOldMods "/data/mods"
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(){
if [ -z "$MODS_FORGEAPI_KEY" ]; then
log "ERROR: MODS_FORGEAPI_KEY REQUIRED to Connect to FORGE API, you supplied: ${MODS_FORGEAPI_KEY}"
@@ -47,7 +57,7 @@ updateReleaseNumber(){
}
retrieveVersionTypeNumber(){
VERSION_NAME="Minecraft ${VANILLA_VERSION%.*}"
VERSION_NAME="Minecraft ${MAJOR_VANILLA_VERSION}"
minecraft_types=$(curl -X GET -s \
"${FORGEAPI_BASE_URL}/games/${MINECRAFT_GAME_ID}/version-types" \
-H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
@@ -67,7 +77,7 @@ retrieveVersionTypeNumber(){
}
modFileByProjectID(){
project_id=$(echo $1 | tr -d '"')
project_id=$(echo "$1" | tr -d '"')
project_id_release_type=$2
project_id_file_name=$3
unset PROJECT_FILE
@@ -95,39 +105,52 @@ modFileByProjectID(){
total_count=$(jq -n "$project_files" | jq -c '.pagination.totalCount' )
# Checking for a individual release type input, if not use global
if [ $project_id_release_type ]; then
updateReleaseNumber $project_id_release_type
if [ "$project_id_release_type" ]; then
updateReleaseNumber "$project_id_release_type"
unset project_id_release_type
else
updateReleaseNumber $MODS_FORGEAPI_RELEASES
fi
# 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.
if [ $project_id_file_name ]; then
if [ "$project_id_file_name" ]; then
# Looks for file by name
current_project_file=$(jq -n "$project_files" | jq --arg FILE_NAME "$project_id_file_name" -jc '
.data | map(select(.fileName<=($FILE_NAME))) | .[0]')
.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
current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" -jc '
.data | sort_by(.id) | reverse | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0]')
# 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
if [ ! "$PROJECT_FILE" ]; then
PROJECT_FILE=$current_project_file
elif [ "$current_project_file" ]; then
current_project_file_id=$(jq -n "$current_project_file" | jq -jc '.id' )
PROJECT_FILE_ID=$(jq -n "$PROJECT_FILE" | jq -jc '.id' )
current_project_file_id=$(jq -n "$current_project_file" | jq -jc '.id // empty' )
PROJECT_FILE_ID=$(jq -n "$PROJECT_FILE" | jq -jc '.id // empty' )
if (( current_project_file_id > PROJECT_FILE_ID )); then
PROJECT_FILE=$current_project_file
fi
fi
# 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}"
exit 2
fi
# Increment start index to new set.
index=$(($index + $pageSize))
index=$((index + pageSize))
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() {
@@ -135,17 +158,22 @@ downloadModPackfromModFile() {
log "ERROR: Project File not found from the ForgeAPI"
exit 2
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.
mkdir -p "$out_dir"
echo "Downloading ${download_url}"
if ! get -o "${out_dir}/${file_name}" $download_url ; then
log "ERROR: failed to download from ${download_url}"
exit 2
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}"
# Track the mods we have downloaded.
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}"
exit 2
fi
fi
}
@@ -155,30 +183,15 @@ downloadDependencies(){
required_dependencies=$(jq -n "$dependencies" | jq --arg REQUIRED_FILTER "3" -jc '
map(select(.relationType==($REQUIRED_FILTER|tonumber)))')
if [ "$required_dependencies" ]; then
jq -n "$required_dependencies" | jq -c '.[]?' | while read current_dependency; do
while read -r current_dependency; do
mod_id=$(jq -n "$current_dependency" | jq -jc '.modId' )
# BROKEN: Example Voice mod keeps returning the voice mod file id instead of the mod file id.
# file_id=$(jq -n "$current_dependency" | jq -jc '.fileId' )
# dependency_data=$(curl -X GET -s \
# "${FORGEAPI_BASE_URL}/mods/${mod_id}/files/${file_id}/download-url" \
# -H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
# if [ ! "$dependency_data" ]; then
# log "ERROR: unable to retrieve dependency data files for ${project_id} from ForgeAPI"
# exit 2
# fi
# dependency_download_url=$(jq -n "$dependency_data" | jq -jc '.data' )
# echo "Downloading dependency ${dependency_download_url}"
# if ! get -o "${out_dir}/" $dependency_download_url ; then
# log "ERROR: failed to download dependency from ${dependency_download_url}"
# exit 2
# fi
# Using current mod path and release to go get the REQUIRED DEPENDENCY
# NOTE: we are ASUMING it will be release.
modFileByProjectID $mod_id "release"
downloadModPackfromModFile
done
# 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
}
@@ -186,34 +199,44 @@ downloadDependencies(){
# Use forge api json file to filter and download the correct mods
if [ "$MODS_FORGEAPI_FILE" ] && [ -z "$MODS_FORGEAPI_PROJECTIDS" ]; then
ensureModKey
updateFamilyFilter
if [ ! -f "$MODS_FORGEAPI_FILE" ]; then
log "ERROR: given MODS_FORGEAPI_FILE file does not exist"
exit 2
fi
debug "DEBUG: MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_FILE}"
# Needs loop here to look up release types befor calling download.
jq -n "$required_dependencies" | jq -c '.[]?' | while read current_project; do
while read -r current_project; do
debug "DEBUG: current_project: ${current_project}"
# Per stack overflow we can use //empty to return empty string that works with -z
project_id=$(jq -n "$current_project" | jq -jc '.projectId // empty' )
current_release_type=$(jq -n "$current_project" | jq -jc '.releaseType // empty' )
current_file_name=$(jq -n "$current_project" | jq -jc '.fileName // empty' )
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' )
modFileByProjectID $project_id $current_release_type $current_file_name
downloadModPackfromModFile
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
downloadDependencies
# Validate we have not tried to download the mod yet.
if [[ ! "${DOWNLOADED_MODIDS[*]}" =~ $project_id ]]; then
modFileByProjectID "$project_id" "$current_release_type" "$current_file_name"
downloadModPackfromModFile
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
downloadDependencies
fi
fi
done
# needs to be piped in to keep look in main process
done < <(jq -c '.[]?' $MODS_FORGEAPI_FILE)
fi
# Use only project ids and global release data.
if [ "$MODS_FORGEAPI_PROJECTIDS" ] && [ -z "$MODS_FORGEAPI_FILE" ]; then
ensureModKey
updateFamilyFilter
for project_id in ${MODS_FORGEAPI_PROJECTIDS//,/ }; do
modFileByProjectID $project_id
downloadModPackfromModFile
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
downloadDependencies
# Validate we have not tried to download the mod yet.
if [[ ! "${DOWNLOADED_MODIDS[*]}" =~ $project_id ]]; then
modFileByProjectID $project_id
downloadModPackfromModFile
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
downloadDependencies
fi
fi
done
fi

View File

@@ -29,7 +29,7 @@ if [[ "${PACKWIZ_URL}" ]]; then
if [[ -z "${latestPackwiz}" ]]; then
log "WARNING: Could not retrieve Packwiz bootstrap installer release information"
else
isDebugging && log "Latest packwiz ${latestPackWiz}"
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}"
@@ -39,13 +39,21 @@ if [[ "${PACKWIZ_URL}" ]]; then
ln -sf "${PACKWIZ_JAR}" packwiz-installer-bootstrap.jar
fi
fi
if [[ ! -e packwiz-installer-bootstrap.jar ]]; then
if [[ ! -f packwiz-installer-bootstrap.jar ]]; then
log "ERROR: Packwiz not available or could not be downloaded from Github!"
exit 1
fi
if isURL "${PACKWIZ_URL}"; then
log "Running packwiz against URL: ${PACKWIZ_URL}"
java -jar packwiz-installer-bootstrap.jar -g -s server "${PACKWIZ_URL}"
log "Running packwiz against URL: ${PACKWIZ_URL}"
java -jar packwiz-installer-bootstrap.jar -g -s server "${PACKWIZ_URL}"
#if bootstrap download fails, download installer manually - then run without updating
returnVal=$?
if [[ $returnVal ]]; then
latestPackwizInstaller=$(curl -fsSL https://api.github.com/repos/packwiz/packwiz-installer/releases/latest)
latestPackwizInstallerVer=$(echo ${latestPackwizInstaller} | jq --raw-output '.tag_name')
latestPackwizInstallerUrl=$(echo ${latestPackwizInstaller} | jq --raw-output '.assets[] | select(.name | match("packwiz-installer.jar")) | .url')
log "Packwiz couldn't update - Downloading Packwiz Installer ${latestPackwizInstallerVer}"
curl -H "Accept:application/octet-stream" -o "packwiz-installer.jar" -fsSL ${latestPackwizInstallerUrl}
java -jar packwiz-installer-bootstrap.jar -g -bootstrap-no-update -s server "${PACKWIZ_URL}"
fi
fi
@@ -92,7 +100,7 @@ elif [[ "$MODS" ]]; then
do
if isURL "$i"; then
log "Downloading mod/plugin $i ..."
if ! get -o "${out_dir}" "$i"; then
if ! get --skip-up-to-date -o "${out_dir}" "$i"; then
log "ERROR: failed to download from $i into $out_dir"
exit 2
fi
@@ -128,7 +136,7 @@ elif [[ "$MODS_FILE" ]]; then
args=(
-o "${out_dir}"
--log-progress-each
--skip-existing
--skip-up-to-date
--uris-file "${MODS_FILE}"
)
if isTrue "${REMOVE_OLD_MODS}"; then
@@ -199,7 +207,8 @@ if [[ "${GENERIC_PACKS}" ]]; then
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
if isURL "${pack}"; then
mkdir -p /data/packs
if ! outfile=$(get -o /data/packs --output-filename --skip-existing "$pack"); then
log "Downloading generic pack from $pack"
if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
log "ERROR: failed to download $pack"
exit 2
fi
@@ -210,19 +219,27 @@ if [[ "${GENERIC_PACKS}" ]]; then
done
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
if ! sha1sum -c "${sum_file}" --status 2> /dev/null; then
base_dir=/tmp/generic_pack_base
mkdir -p ${base_dir}
log "Checking if generic packs are up to date"
if isTrue "${SKIP_GENERIC_PACK_UPDATE_CHECK:-false}" && [ -f "$sum_file" ]; then
log "Skipping generic pack update check"
elif isTrue "${FORCE_GENERIC_PACK_UPDATE}" || ! checkSum "${sum_file}"; then
log "Generic pack(s) are out of date. Re-applying..."
original_base_dir=/data/.tmp/generic_pack_base
base_dir=$original_base_dir
rm -rf "${base_dir}"
mkdir -p "${base_dir}"
for pack in "${packFiles[@]}"; do
isDebugging && ls -l "${pack}"
extract "${pack}" "${base_dir}"
done
# recalculate the actual base directory of content
base_dir=$(find "$base_dir" -type d \( -name mods -o -name plugins -o -name config \) -printf '%h' -quit)
base_dir=$(find "$base_dir" -maxdepth 3 -type d \( -name mods -o -name plugins -o -name config \) -printf '%h' -quit)
if [[ ! $base_dir ]]; then
log "ERROR: Unable to find content base of generic packs ${GENERIC_PACKS}. Directories:"
find /tmp/generic_pack_base -type d -printf ' - %P\n'
find $original_base_dir -maxdepth 3 -type d -printf ' - %P\n'
exit 1
fi
@@ -241,8 +258,9 @@ if [[ "${GENERIC_PACKS}" ]]; then
log "Applying generic pack ..."
cp -R -f "${base_dir}"/* /data
rm -rf /tmp/generic_pack_base
rm -rf $original_base_dir
log "Saving generic pack(s) checksum"
sha1sum "${packFiles[@]}" > "${sum_file}"
isDebugging && cat "$sum_file"
fi

View File

@@ -4,6 +4,7 @@
. "${SCRIPTS:-/}start-utils"
: "${SERVER_PROPERTIES:=/data/server.properties}"
: "${ENABLE_RCON:=true}"
# FUNCTIONS
function setServerPropValue {
@@ -115,6 +116,8 @@ function customizeServerProps {
setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS
setServerProp "use-native-transport" USE_NATIVE_TRANSPORT
setServerProp "simulation-distance" SIMULATION_DISTANCE
setServerProp "previews-chat" PREVIEWS_CHAT
setServerProp "enforce-secure-profile" ENFORCE_SECURE_PROFILE
setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)"
[[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}"

View File

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

View File

@@ -34,14 +34,11 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
# Stage contents so that the correct subdirectory can be picked off
mkdir -p /tmp/world-data
if ! extract "$WORLD" /tmp/world-data; then
log "ERROR extracting world from $WORLD"
exit 1
fi
if [ "$FAMILY" = "SPIGOT" ]; then
baseDirs=$(find /tmp/world-data -name "level.dat" -not -path "*_nether*" -not -path "*_the_end*" -exec dirname "{}" \;)
else
baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;)
fi
baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;)
if ! [[ $baseDirs ]]; then
log "ERROR world content is not valid since level.dat could not be found"
@@ -50,20 +47,65 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
count=$(echo "$baseDirs" | wc -l)
if [[ $count -gt 1 ]]; then
baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)"
baseName=$(basename "$baseDir")
log "WARN multiple levels found, picking: $baseName"
baseDirsNoSpigotSuffix=$(echo "$baseDirs" | sed -re 's:(_nether|_the_end)/?$::' | sort -u)
if [ $(echo "$baseDirsNoSpigotSuffix" | wc -l) -eq 1 ]; then
baseDir="$baseDirsNoSpigotSuffix"
baseName=$(basename "$baseDir")
log "Found Spigot naming conventions, taking $baseName as main dimension"
else
baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)"
baseName=$(basename "$baseDir")
log "WARN multiple levels found, picking: $baseName"
fi
elif [[ $count -gt 0 ]]; then
baseDir="$baseDirs"
else
log "ERROR invalid world content"
exit 1
fi
if [ -d "${baseDir}_nether/DIM-1" ]; then
if [ -d "$baseDir/DIM-1" ]; then
log "WARN found Nether dimension in both $baseDir and ${baseDir}_nether, picking ${baseDir}_nether"
rm -r "$baseDir/DIM-1"
fi
fi
if [ -d "${baseDir}_the_end/DIM1" ]; then
if [ -d "$baseDir/DIM1" ]; then
log "WARN found End dimension in both $baseDir and ${baseDir}_the_end, picking ${baseDir}_the_end"
rm -r "$baseDir/DIM1"
fi
fi
log "Copying world..."
rsync --remove-source-files --recursive --delete "$baseDir/" "$worldDest"
if [ "$FAMILY" = "SPIGOT" ]; then
log "Copying end and nether ..."
[ -d "${baseDir}_nether" ] && rsync --remove-source-files --recursive --delete "${baseDir}_nether/" "${worldDest}_nether"
[ -d "${baseDir}_the_end" ] && rsync --remove-source-files --recursive --delete "${baseDir}_the_end/" "${worldDest}_the_end"
if [ -d "${baseDir}_nether" ]; then
log "Copying Spigot Nether..."
rsync --remove-source-files --recursive --delete "${baseDir}_nether/" "${worldDest}_nether"
elif [ -d "$worldDest/DIM-1" ]; then
log "Moving Nether to Spigot location..."
mkdir -p "${worldDest}_nether"
mv -f "$worldDest/DIM-1" "${worldDest}_nether/"
fi
if [ -d "${baseDir}_the_end" ]; then
log "Copying Spigot End..."
rsync --remove-source-files --recursive --delete "${baseDir}_the_end/" "${worldDest}_the_end"
elif [ -d "$worldDest/DIM1" ]; then
log "Moving End to Spigot location..."
mkdir -p "${worldDest}_the_end"
mv -f "$worldDest/DIM1" "${worldDest}_the_end/"
fi
else
if [ -d "${baseDir}_nether/DIM-1" ]; then
log "Copying Spigot Nether to vanilla location..."
rsync --remove-source-files --recursive --delete "${baseDir}_nether/DIM-1" "${worldDest}/"
fi
if [ -d "${baseDir}_the_end/DIM1" ]; then
log "Copying Spigot End to vanilla location..."
rsync --remove-source-files --recursive --delete "${baseDir}_the_end/DIM1" "${worldDest}/"
fi
fi
elif [ -d "$WORLD" ]; then
log "Cloning world directory from $WORLD ..."

View File

@@ -2,11 +2,14 @@
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
handleDebugMode
: ${SPIGET_RESOURCES:=}
: ${SPIGET_DOWNLOAD_TOLERANCE:=5} # in minutes
: "${SPIGET_RESOURCES:=}"
: "${SPIGET_DOWNLOAD_TOLERANCE:=5}" # in minutes
acceptArgs=(--accept application/zip --accept application/java-archive --accept application/octet-stream)
containsJars() {
file=${1?}
@@ -17,7 +20,7 @@ containsJars() {
if [[ $line =~ $pat ]]; then
return 0
fi
done <<<$(unzip -l "$file")
done < <(unzip -l "$file" | tail -n +4)
return 1
}
@@ -31,7 +34,7 @@ containsPlugin() {
if [[ $line =~ $pat ]]; then
return 0
fi
done <<<$(unzip -l "$file")
done < <(unzip -l "$file" | tail -n +4)
return 1
}
@@ -44,12 +47,12 @@ getResourceFromSpiget() {
mkdir -p /data/plugins
versionfile="/data/plugins/.${resource}-version.json"
versionfileNew="/tmp/.${resource}-version.json"
versionfileNew="${versionfile}.tmp"
if [ -f "$versionfile" ]; then
if [[ -n $(find "$versionfile" -mmin +${SPIGET_DOWNLOAD_TOLERANCE}) ]]; then
urlVersion="https://api.spiget.org/v2/resources/${resource}/versions/latest"
if ! curl -o "${versionfileNew}" -fsSL -H "User-Agent: itzg/minecraft-server" "${extraCurlArgs[@]}" "${urlVersion}"; then
if ! get -o "${versionfileNew}" "${urlVersion}"; then
log "ERROR failed to download resource version meta data '${resource}' from ${urlVersion}"
exit 2
fi
@@ -71,7 +74,7 @@ getResourceFromSpiget() {
else
if downloadResourceFromSpiget "${resource}"; then
urlVersion="https://api.spiget.org/v2/resources/${resource}/versions/latest"
if ! curl -o "${versionfileNew}" -fsSL -H "User-Agent: itzg/minecraft-server" "${extraCurlArgs[@]}" "${urlVersion}"; then
if ! get -o "${versionfileNew}" "${urlVersion}"; then
log "ERROR failed to download resource version meta data '${resource}' from ${urlVersion}"
exit 2
fi
@@ -84,29 +87,37 @@ getResourceFromSpiget() {
downloadResourceFromSpiget() {
resource=${1?}
tmpfile="/tmp/${resource}.zip"
url="https://api.spiget.org/v2/resources/${resource}/download"
if ! curl -o "${tmpfile}" -fsSL -H "User-Agent: itzg/minecraft-server" "${extraCurlArgs[@]}" "${url}"; then
log "ERROR failed to download resource '${resource}' from ${url}"
exit 2
tempDir="/data/plugins/tmp-${resource}"
mkdir -p $tempDir
resourceUrl="https://api.spiget.org/v2/resources/${resource}"
if ! outfile=$(get_silent --output-filename -o $tempDir "${acceptArgs[@]}" "${resourceUrl}/download"); then
log "ERROR: failed to download resource '${resource}' from ${resourceUrl}/download"
if externalUrl=$(get --json-path '$.file.externalUrl' "${resourceUrl}"); then
log " Visit $externalUrl to pre-download the resource"
log " instead of using SPIGET_RESOURCES"
fi
exit 1
fi
if containsJars "${tmpfile}"; then
log "Extracting contents of resource ${resource} into plugins"
unzip -o -q -d /data/plugins "${tmpfile}"
rm "${tmpfile}"
elif containsPlugin "${tmpfile}"; then
if ! fileType=$(get --json-path '.file.type' "${resourceUrl}"); then
log "ERROR: failed to retrieve file type of resource $resource"
exit 1
fi
if containsPlugin "${outfile}"; then
log "Moving resource ${resource} into plugins"
mv "${tmpfile}" "/data/plugins/${resource}.jar"
mv "$outfile" /data/plugins
elif containsJars "${outfile}"; then
log "Extracting contents of resource ${resource} into plugins"
extract "$outfile" /data/plugins
else
log "ERROR downloaded resource '${resource}' seems to be not a valid plugin"
log "ERROR: file for resource ${resource} has an unexpected file type: ${fileType}"
exit 2
fi
rm -rf "$tempDir"
}
if [[ ${SPIGET_RESOURCES} ]]; then
if isTrue ${REMOVE_OLD_MODS:-false}; then
if isTrue "${REMOVE_OLD_MODS:-false}"; then
removeOldMods /data/plugins
REMOVE_OLD_MODS=false
fi
@@ -118,4 +129,4 @@ if [[ ${SPIGET_RESOURCES} ]]; then
done
fi
exec ${SCRIPTS:-/}start-setupWorld $@
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -8,6 +8,11 @@ function join_by() {
printf "%s" "${@/#/$d}"
}
function get_major_version() {
version=$1
echo "$version" | cut -d. -f 1-2
}
function isURL() {
local value=$1
@@ -40,6 +45,10 @@ function getFilenameFromUrl() {
}
function isTrue() {
local oldState
oldState=$(shopt -po xtrace)
shopt -u -o xtrace
local value=${1,,}
result=
@@ -53,6 +62,29 @@ function isTrue() {
;;
esac
eval "$oldState"
return ${result}
}
function isFalse() {
local oldState
oldState=$(shopt -po xtrace)
shopt -u -o xtrace
local value=${1,,}
result=
case ${value} in
false | off)
result=0
;;
*)
result=1
;;
esac
eval "$oldState"
return ${result}
}
@@ -82,7 +114,18 @@ function logn() {
}
function log() {
echo "[init] $*"
local oldState
# The return status when listing options is zero if all optnames are enabled, non- zero otherwise.
oldState=$(shopt -po xtrace || true)
shopt -u -o xtrace
if isDebugging || isTrue "${LOG_TIMESTAMP:-false}"; then
ts=" $(date --rfc-3339=seconds)"
else
ts=
fi
echo "[init]${ts} $*"
eval "$oldState"
}
function logAutopause() {
@@ -101,6 +144,10 @@ function logAutostopAction() {
echo "[$(date -Iseconds)] [Autostop] $*"
}
function logRcon() {
echo "[Rcon loop] $*"
}
function normalizeMemSize() {
local scale=1
case ${1,,} in
@@ -172,15 +219,23 @@ function get() {
mc-image-helper "${flags[@]}" get "$@"
}
function get_silent() {
local flags=(-s)
if isTrue "${DEBUG_GET:-false}"; then
flags+=("--debug")
fi
mc-image-helper "${flags[@]}" get "$@"
}
function isFamily() {
for f in "${@}"; do
if [[ $FAMILY == "$f" ]]; then
if [[ ${FAMILY^^} == "${f^^}" ]]; then
return 0
fi
done
return 1
}
function isType() {
for t in "${@}"; do
# shellcheck disable=SC2153
@@ -209,9 +264,9 @@ function extract() {
type=$(file -b --mime-type "${src}")
case "${type}" in
application/zip)
unzip -q -d "${destDir}" "${src}"
unzip -o -q -d "${destDir}" "${src}"
;;
application/x-tar|application/gzip|application/x-gzip|application/x-bzip2|application/zstd)
application/x-tar|application/gzip|application/x-gzip|application/x-bzip2|application/zstd|application/x-zstd)
tar -C "${destDir}" -xf "${src}"
;;
*)
@@ -220,3 +275,24 @@ function extract() {
;;
esac
}
function getDistro() {
cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | sed -e 's/"//g'
}
function checkSum() {
local sum_file=${1?}
# Get distro
distro=$(getDistro)
if [ "${distro}" == "debian" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
return 0
elif [ "${distro}" == "ubuntu" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
return 0
elif [ "${distro}" == "alpine" ] && sha1sum -c "${sum_file}" -s 2> /dev/null; then
return 0
else
return 1
fi
}

View File

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

View File

@@ -8,7 +8,8 @@ services:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
VANILLATWEAKS_FILE: /config/vanillatweaks-datapacks.json
REMOVE_OLD_VANILLATWEAKS: "TRUE"
TYPE: "PAPER"
WORLD: /worlds/world-for-testing.zip
volumes:
- ./vanillatweaks-datapacks.json:/config/vanillatweaks-datapacks.json:ro
- ./worlds:/worlds:ro
- ./data:/data

View File

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

View File

@@ -0,0 +1,14 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
WORLD: /worlds/world-for-testing.zip
volumes:
- ./worlds:/worlds:ro
- ./data:/data

View File

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

View File

@@ -0,0 +1,16 @@
version: "3"
services:
mc:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server:java8-multiarch}
environment:
EULA: "true"
SETUP_ONLY: "TRUE"
TYPE: CURSEFORGE
CF_SERVER_MOD: /modpacks/pack.zip
INIT_MEMORY: 2G
MAX_MEMORY: 6G
volumes:
- ./data:/data
- ./modpacks:/modpacks:ro

Binary file not shown.

View File

@@ -0,0 +1 @@
[[ $VARIANT == java8* ]] || exit 1

View File

@@ -0,0 +1,2 @@
mc-image-helper assert fileExists "/data/FeedTheBeast/forge-installer.jar"
mc-image-helper assert fileExists "/data/FeedTheBeast/forge.jar"

View File

@@ -0,0 +1,11 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
volumes:
- ./data:/data

View File

@@ -0,0 +1,3 @@
mc-image-helper assert propertyEquals --file=server.properties --property=rcon.password --expect=minecraft
mc-image-helper assert propertyEquals --file=server.properties --property=rcon.port --expect=25575
mc-image-helper assert propertyEquals --file=server.properties --property=enable-rcon --expect=true

View File

@@ -7,12 +7,21 @@ services:
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
DEBUG: "FALSE"
# Using custom to bypass Fabric setup
TYPE: CUSTOM
# Using family to test FORGEAPI Family filter.
FAMILY: FABRIC
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.2
MODS_FORGEAPI_FILE: /config/forgeapi_mods.json
# Key is defined in .github/workflows/pr.yml and ci.yml
# This should be coming from github secrets.
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
REMOVE_OLD_FORGEAPI_MODS: "TRUE"
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "FALSE"
# Validates that Fabric API gets download as a dependency.
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE"
volumes:
- ./forgeapi_mods.json:/config/forgeapi_mods.json:ro
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -1,17 +1,11 @@
[{
"name": "fabric api",
"projectId": "306612",
"releaseType": "release"
},
{
"name": "Fabric Voice Mod",
"projectId": "416089",
"releaseType": "beta"
},
{
"name": "Biomes o plenty",
"projectId": "220318",
"fileName": "BiomesOPlenty-1.18.1-15.0.0.100-universal.jar",
"releaseType": "release"
}
]
[
{
"name": "Flan (Land Claim Tool)",
"projectId": "404578"
},
{
"name": "Fabric Voice Mod",
"projectId": "416089",
"releaseType": "beta"
}
]

View File

@@ -1 +1,2 @@
[[ $MODS_FORGEAPI_KEY ]] || exit 1
[[ $MINECRAFT_VERSION == LATEST ]] || exit 1
[[ $MODS_FORGEAPI_KEY ]] || exit 1

View File

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

View File

@@ -0,0 +1,30 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
DEBUG: "FALSE"
# Using custom to bypass Fabric setup
TYPE: CUSTOM
# Using family to test FORGEAPI Family filter.
FAMILY: FABRIC
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.2
# Validate Skip Gametype Filter:
MODS_FORGEAPI_IGNORE_GAMETYPE: "TRUE"
# Validates that Biomes does not download terrablender
# Using default false for testing:
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "FALSE"
# Contains mix of Forge and Fabric mods
MODS_FORGEAPI_PROJECTIDS: 416089,493246
# Allows for Beta releases of 416089 the Fabric Voice Mod
MODS_FORGEAPI_RELEASES: BETA
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
REMOVE_OLD_FORGEAPI_MODS: "TRUE"
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -0,0 +1,2 @@
[[ $MINECRAFT_VERSION == LATEST ]] || exit 1
[[ $MODS_FORGEAPI_KEY ]] || exit 1

View File

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

View File

@@ -7,10 +7,20 @@ services:
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
# Using custom to bypass Fabric setup
TYPE: CUSTOM
# Validate Skip Gametype Filter for vanilla
# - Currently we do not support filtering on vanilla.
FAMILY: VANILLA
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.2
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE"
MODS_FORGEAPI_PROJECTIDS: 306612,416089,220318
# Contains mix of Forge and Fabric mods
MODS_FORGEAPI_PROJECTIDS: 416089,419697
# Allows for Beta releases of 416089 the Fabric Voice Mod
MODS_FORGEAPI_RELEASES: BETA
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
REMOVE_OLD_FORGEAPI_MODS: "TRUE"
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -1 +1,2 @@
[[ $MODS_FORGEAPI_KEY ]] || exit 1
[[ $MINECRAFT_VERSION == LATEST ]] || exit 1
[[ $MODS_FORGEAPI_KEY ]] || exit 1

View File

@@ -0,0 +1,6 @@
# No family filter applied, DO NOT use Fabric or Forge specific name validation as it may cause random breakage.
mc-image-helper assert fileExists "/data/mods/voicechat-fabric-1*"
# Should be pull v4 and higher for 1.18.2:
mc-image-helper assert fileExists "/data/mods/architectury-4*"
mc-image-helper assert fileExists "/data/mods/fabric-api*"

View File

@@ -11,8 +11,14 @@ services:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "TRUE"
SETUP_ONLY: "true"
GENERIC_PACKS: http://web/configs.zip,/packs/testing.zip
LOG_TIMESTAMP: "true"
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes:
- ./packs:/packs
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -0,0 +1,17 @@
version: "3"
services:
mc:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
ICON: /extra/4737386_minecraft_squircle_icon_64x64.png
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes:
- ./data:/data
- ./extra:/extra
- ./fake.jar:/servers/fake.jar

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
mc-image-helper assert fileExists server-icon.png

View File

@@ -0,0 +1,17 @@
version: "3"
services:
mc:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
ICON: /extra/4737386_minecraft_squircle_icon.png
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes:
- ./data:/data
- ./extra:/extra
- ./fake.jar:/servers/fake.jar

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
mc-image-helper assert fileExists server-icon.png

View File

@@ -0,0 +1,22 @@
version: "3"
services:
web:
image: nginx
volumes:
- ./web:/usr/share/nginx/html
mc:
depends_on:
- web
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
ICON: http://web/motion-tween-example.gif
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -0,0 +1 @@
mc-image-helper assert fileExists server-icon.png

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