Compare commits

...

184 Commits

Author SHA1 Message Date
Geoff Bourne
3f2022da40 Merge branch 'master' of github.com:itzg/docker-minecraft-server 2021-12-11 16:23:25 -06:00
Geoff Bourne
0f7464403c build: added github release creation step to docker-versions-create.sh 2021-12-11 16:09:15 -06:00
itzg
bee39343a6 docs: Auto update markdown TOC 2021-12-11 22:09:11 +00:00
StealthCT
e9326db933 Improved whitelist and ops support (#1182) 2021-12-11 16:08:53 -06:00
itzg
dd1cc82fcd docs: Auto update markdown TOC 2021-12-11 19:01:44 +00:00
Brett Randall
93825895b9 Startup fail-fast with error message if both ENABLE_AUTOPAUSE=true and EXEC_DIRECTLY=true are set. (#1186) 2021-12-11 13:01:30 -06:00
Bram
492aebc718 Remove old Airplane versions (#1185) 2021-12-11 12:56:11 -06:00
Levy Ehrstein
e66b2eda60 fix: log4j patch being applied to <1.7 versions (#1183)
As described in https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition,
versions below 1.7 are not affected by the log4j exploit. They should therefore not use any mitigations.

See #1179 discussion after merge.

Reported-and-tested-by: Daniel Porter "Stealthii" <dan.porter@rehabstudio.com>
2021-12-11 11:33:44 -06:00
Geoff Bourne
3bb21d8581 Used log4j2.formatMsgNoLookups as fallback for non-vanilla
#1180
2021-12-10 20:50:40 -06:00
Geoff Bourne
fb6fa9b7d7 fix: use Mojang log4j config file fixes by version (#1179) 2021-12-10 10:40:56 -06:00
Pascal Sthamer
0718a62007 security: patch log4j remote code execution vulnerability (#1178) 2021-12-10 07:52:19 -06:00
Geoff Bourne
529d92fa63 build: also run tests with java8 2021-12-06 22:19:49 -06:00
Geoff Bourne
f7836abc06 build: fixed combined test/build jobs 2021-12-06 22:18:21 -06:00
itzg
cd09a932f9 docs: Auto update markdown TOC 2021-12-07 03:43:47 +00:00
StealthCT
46d21f58cf Fabric documentation update (#1166) 2021-12-06 21:43:33 -06:00
itzg
3e63be9988 docs: Auto update markdown TOC 2021-12-07 03:40:20 +00:00
StealthCT
aaaf7796b0 Add support for packwiz toml definitions (#1163) 2021-12-06 21:40:00 -06:00
Alexandre Boucey
aba10c1d99 Update Purpur version API (#1162) 2021-12-06 07:25:01 -06:00
Geoff Bourne
c4dd0d2bae build: Switched to GHA cache (#1153) 2021-12-04 18:42:03 -06:00
Geoff Bourne
6c636c3d9c fix: corrected versionLessThan to handle b1.7.3 style
#1159
2021-12-04 09:58:28 -06:00
itzg
9098b198c3 docs: Auto update markdown TOC 2021-12-03 14:07:53 +00:00
Geoff Bourne
927ec2a2c3 docs: let users do their own research about Mohist
#1107
2021-12-03 08:07:40 -06:00
Paul Heidenreich
07a251b544 Fix downloading of craftbukkit when using 1.16.5 (#1150) 2021-12-02 19:45:50 -06:00
itzg
b8e163d8b1 docs: Auto update markdown TOC 2021-12-03 01:28:10 +00:00
StealthCT
cd72acb6c6 Feature: Enforcing resource packs (#1149) 2021-12-02 19:27:55 -06:00
itzg
24942a6f04 docs: Auto update markdown TOC 2021-12-02 03:13:16 +00:00
Kyle
75dcc746f8 Added UUID Support for WHITELIST (#1139) 2021-12-01 21:12:58 -06:00
dependabot[bot]
263a10848a build(deps): bump actions/cache from 2.1.6 to 2.1.7 (#1138) 2021-11-29 06:46:56 -06:00
Geoff Bourne
ff4d46d509 fix: corrected versionLessThan for versions with dashes
#1132
2021-11-24 15:52:36 -06:00
itzg
66ead9128a docs: Auto update markdown TOC 2021-11-24 20:40:16 +00:00
Geoff Bourne
55ff76a85d docs: clarified java version compatibilities
#1130
2021-11-24 14:39:50 -06:00
Geoff Bourne
dca29dcbb5 feat: use server list ping for versions less than 1.7
#1131
2021-11-24 14:30:29 -06:00
itzg
84c577cc96 docs: Auto update markdown TOC 2021-11-23 02:51:46 +00:00
Geoff Bourne
5e8fc43857 fix: removed Java 8 constraint of Canyon server type
#1129
2021-11-22 20:51:30 -06:00
Geoff Bourne
66a17c8d58 docs: added readinessProbe to k8s example 2021-11-22 17:19:49 -06:00
itzg
57f7ee50a6 docs: Auto update markdown TOC 2021-11-21 21:00:21 +00:00
Geoff Bourne
f8ac58e200 misc: deprecated java16 2021-11-21 15:00:17 -06:00
Geoff Bourne
71954edf75 misc: silence misleading error when resolving forge version 2021-11-21 14:58:55 -06:00
Geoff Bourne
597faa102a misc: only run stale-check on cron schedule 2021-11-21 11:16:58 -06:00
itzg
442fccfc41 docs: Auto update markdown TOC 2021-11-17 20:22:20 +00:00
Michael Vorburger ⛑️
784ec6104c Docs: Fix broken link to Aikar's Flags (#1126) 2021-11-17 14:22:01 -06:00
Geoff Bourne
817a01bbc3 misc: noted git ours merge strategy 2021-11-16 19:05:23 -06:00
itzg
66c0558174 docs: Auto update markdown TOC 2021-11-17 00:55:17 +00:00
Geoff Bourne
9116be11ae Updated latest to Java 17 to match 1.18-pre2 2021-11-16 18:55:05 -06:00
Geoff Bourne
969f4c8db6 misc: update changelog processing notes 2021-11-16 18:49:48 -06:00
Geoff Bourne
e6916e91e7 misc: cleaned up warnings in start-setupEnvVariables and autopause-fcns.sh 2021-11-15 20:50:47 -06:00
itzg
9544aeaf7a docs: Auto update markdown TOC 2021-11-16 02:46:53 +00:00
Geoff Bourne
babeac1693 docs: removed dangling sentence in Fabric section
#1121
2021-11-15 20:46:40 -06:00
Geoff Bourne
130b067955 fix: changed logging config's queue to TerminalConsole
#1119
2021-11-13 19:17:20 -06:00
Geoff Bourne
df7d6c298a fix: defaulted SERVER_PORT for health and autopause
#1120
2021-11-13 18:42:24 -06:00
Geoff Bourne
a8a60264e9 misc: code cleanup in start-setupServerProperties 2021-11-12 21:21:01 -06:00
itzg
721df8d32b docs: Auto update markdown TOC 2021-11-13 03:18:08 +00:00
Geoff Bourne
2375a6796c feat: Allowed for server properties to be cleared vs skipped
#1117
2021-11-12 21:17:21 -06:00
dependabot[bot]
e04e943e1c build(deps): bump actions/checkout from 2.3.5 to 2.4.0 (#1112) 2021-11-08 07:00:59 -06:00
Geoff Bourne
1bf75671f6 misc: adjusted bug and question templates 2021-11-06 21:58:22 -05:00
Geoff Bourne
7d56de9d15 Cleaned up minecraft_server.jar for versions >= 1.6
#306
2021-11-06 21:46:31 -05:00
Geoff Bourne
a8de790b57 Used minecraft_server.jar for versions before 1.6
#306
2021-11-06 21:35:57 -05:00
Geoff Bourne
cafddd3b12 Used minecraft_server.jar for versions before 1.6
#306
2021-11-06 21:34:24 -05:00
itzg
fc958faf7b docs: Auto update markdown TOC 2021-11-05 19:39:25 +00:00
Michael Vorburger ⛑️
402894cd8d document that default RCON_PASSWORD = minecraft in README (#1109) 2021-11-05 14:38:02 -05:00
Geoff Bourne
f97cea4b06 misc: adjusted debug logs when SKIP_SERVER_PROPERTIES
#1108
2021-11-04 21:49:03 -05:00
itzg
0198c15b8c docs: Auto update markdown TOC 2021-11-05 02:00:07 +00:00
Geoff Bourne
e813007f49 docs: added cautionary note to Mohist section
#1107
2021-11-04 20:59:52 -05:00
itzg
df2962bdb3 docs: Auto update markdown TOC 2021-11-05 01:55:28 +00:00
Geoff Bourne
367f07b784 feat: added SKIP_SERVER_PROPERTIES
#1108
2021-11-04 20:55:15 -05:00
itzg
9de9ec2e34 docs: Auto update markdown TOC 2021-11-01 22:29:26 +00:00
Geoff Bourne
6ad7773e2b docs: clarified JVM_OPTS and JVM_XX_OPTS syntax 2021-11-01 17:29:10 -05:00
itzg
8177dd9a5a docs: Auto update markdown TOC 2021-11-01 22:24:07 +00:00
Geoff Bourne
81994ec3b3 docs: described using MaxRAMPercentage when MEMORY is unset 2021-11-01 17:23:45 -05:00
itzg
ecee4069f1 docs: Auto update markdown TOC 2021-10-31 14:43:07 +00:00
Geoff Bourne
3713d9c4e8 Allowed MEMORY to be unset and let JVM calculate from container
#742
2021-10-31 09:42:46 -05:00
itzg
c7f1d13f9b docs: Auto update markdown TOC 2021-10-29 21:39:37 +00:00
Michael Vorburger ⛑️
cc8d18d41f docs: add links to Development and Building in README (#1096) 2021-10-29 16:39:23 -05:00
itzg
afd863ab89 docs: Auto update markdown TOC 2021-10-29 21:38:33 +00:00
Michael Vorburger ⛑️
46f6653b13 docs: clarify java8-multiarch tag for TYPE=SPONGEVANILLA in README (#1095) 2021-10-29 16:38:17 -05:00
itzg
3237d1a996 docs: Auto update markdown TOC 2021-10-29 17:34:39 +00:00
Geoff Bourne
386e34e05b docs: clarified Forge pre-1.17 requirement of Java 8 2021-10-29 12:34:24 -05:00
itzg
4fd234e482 docs: Auto update markdown TOC 2021-10-29 02:31:34 +00:00
Geoff Bourne
38fd0dac8b docs: fixed architecture designation of java17
#1074
2021-10-28 21:31:12 -05:00
Geoff Bourne
11ac111036 ci: tweak formatting in issue templates 2021-10-28 13:35:02 -05:00
Geoff Bourne
9803547967 ci: added issue templates 2021-10-28 13:24:13 -05:00
Geoff Bourne
1a0c7c4f85 ci: updated stale status label 2021-10-28 12:58:39 -05:00
Geoff Bourne
7b7d5db796 misc: switched to stale action 2021-10-28 09:10:31 -05:00
Geoff Bourne
34baf8a354 Switched base image to Eclipse Temurin JDK
#1054 #1064
2021-10-27 21:12:18 -05:00
Geoff Bourne
cc9e0fe1ef Upgraded mc-image-helper to fix URL handling
#1092
2021-10-25 19:19:51 -05:00
itzg
9c354d5775 docs: Auto update markdown TOC 2021-10-25 01:23:54 +00:00
Geoff Bourne
2dce24c1bd Added support for multiple files with GENERIC_PACKS
#1087
2021-10-24 20:23:34 -05:00
itzg
6f80ce5584 docs: Auto update markdown TOC 2021-10-23 15:20:34 +00:00
Geoff Bourne
c8df2d8e31 docs: Noted SELinux scenario for volume host directory mount
#390
2021-10-23 10:20:19 -05:00
Geoff Bourne
2e8f27a8ef Allowed FTB_MODPACK_VERSION_ID to be an empty value
#1081
2021-10-23 09:40:36 -05:00
Geoff Bourne
e20dd63f76 Added FORCE_REINSTALL for FORGE type
#1085
2021-10-23 09:33:12 -05:00
Geoff Bourne
3e62389325 misc: moved legacy minecraft-server directory 2021-10-22 21:23:50 -05:00
Geoff Bourne
f3c880f96a misc: moved baseline files to files 2021-10-22 21:23:16 -05:00
Geoff Bourne
2c7796ea0b misc: moved start scripts into scripts 2021-10-22 21:18:45 -05:00
Geoff Bourne
0daeeb70f7 misc: removed deprecated CURSE_INSTANCE type 2021-10-22 21:11:11 -05:00
itzg
86782865c4 docs: Auto update markdown TOC 2021-10-22 21:06:59 +00:00
Geoff Bourne
ddcabb175a misc: deprecating multiarch-latest image variant 2021-10-22 16:06:42 -05:00
Geoff Bourne
7b09e525e8 Converted TYPE=CURSEFORGE to use image helper 2021-10-21 21:53:06 -05:00
itzg
2eefb12e6b docs: Auto update markdown TOC 2021-10-20 20:36:23 +00:00
Geoff Bourne
5777a248d4 Improved and documented GENERIC_PACK feature
#1077
2021-10-20 15:36:02 -05:00
itzg
97a6a4ba85 docs: Auto update markdown TOC 2021-10-20 02:36:48 +00:00
Geoff Bourne
531d33af1c Added java17 variant
#1054
2021-10-19 21:36:31 -05:00
itzg
0618d690fa docs: Auto update markdown TOC 2021-10-19 03:33:58 +00:00
Geoff Bourne
6aa3b1066f Merge branch 'master' of github.com:itzg/docker-minecraft-server 2021-10-18 22:06:41 -05:00
Geoff Bourne
393544a194 Added support for Crucible server type
#1052
2021-10-18 22:05:22 -05:00
dependabot[bot]
4aea1753bd build(deps): bump actions/checkout from 2.3.4 to 2.3.5 (#1075) 2021-10-18 07:01:48 -05:00
itzg
c42d8971ca docs: Auto update markdown TOC 2021-10-17 19:43:59 +00:00
Marijn
ee7f2ee739 Add option to specify specific Fabric loader version (#1073) 2021-10-17 14:43:41 -05:00
Geoff Bourne
6008660a81 Converted TYPE=FORGE to use image helper 2021-10-17 12:35:45 -05:00
Geoff Bourne
043d9778b8 Converted MODPACK to use image helper 2021-10-16 22:10:09 -05:00
Geoff Bourne
8bf7c6cccd Converted mohist deployment to use image helper 2021-10-16 22:10:09 -05:00
itzg
80d7efb365 docs: Auto update markdown TOC 2021-10-16 00:07:37 +00:00
Geoff Bourne
32ed58692c Added MODS_FILE option
#1072
2021-10-15 18:42:44 -05:00
Geoff Bourne
63b919f1a9 Used json-path of image helper get for vanilla lookup 2021-10-11 15:53:09 -05:00
Geoff Bourne
57d9da96a1 Converted vanilla downloads to image helper get
#1031
2021-10-10 12:05:37 -05:00
Geoff Bourne
ec97c67aca Propagated debug flag to image helper get
#1031
2021-10-10 09:53:52 -05:00
Geoff Bourne
e5e9b0d928 Using image helper to download MODS
#1031
2021-10-10 09:33:17 -05:00
Geoff Bourne
2e37c16b2c Fabric deployment no longer uses curl
#1031
2021-10-09 15:22:42 -05:00
itzg
bcdab80f41 docs: Auto update markdown TOC 2021-10-09 16:34:52 +00:00
Geoff Bourne
c3cf892e40 Added mc-send-to-console as rcon/attach alternative
#1071
2021-10-09 11:34:37 -05:00
Geoff Bourne
1d41593a84 Verify forge server from marker file exists
#1067
2021-10-02 19:20:08 -05:00
itzg
52452020dd docs: Auto update markdown TOC 2021-09-30 21:55:07 +00:00
Geoff Bourne
65f2562d52 Added property mapping for simulation-distance
#1065
2021-09-30 16:54:44 -05:00
Geoff Bourne
3482944ac8 For autopause, added use of mc-monitor to detect players connected (#1059) 2021-09-30 16:51:51 -05:00
Geoff Bourne
9d03a1dc13 Upgraded mc-monitor to handle packet read timeout 2021-09-29 21:09:30 -05:00
Geoff Bourne
012d3e7b65 Upgraded rcon-cli to support format code processing 2021-09-29 10:26:15 -05:00
avionix-g
10d254bbbc Fix 'curl: unknown --write-out variable' for .zip modpacks (#1060) 2021-09-27 06:53:56 -05:00
itzg
8acb3f8a90 docs: Auto update markdown TOC 2021-09-25 14:39:20 +00:00
Geoff Bourne
1b00a8692b docs: noted whitelist importance 2021-09-25 09:38:47 -05:00
itzg
814559bef8 docs: Auto update markdown TOC 2021-09-20 02:33:20 +00:00
Geoff Bourne
8bac02bbcf Added JSON-patching support
#1051
2021-09-19 21:32:59 -05:00
itzg
7ef031e244 docs: Auto update markdown TOC 2021-09-19 14:46:55 +00:00
Jawa_Juice
250d32e3dc Remove Yatopia support as discontinued (#1049) 2021-09-19 09:46:40 -05:00
Geoff Bourne
bdeab5bb9c Upgraded mc-image-helper to 1.2.1
#1048
2021-09-16 22:11:45 -05:00
itzg
764e1e9363 docs: Auto update markdown TOC 2021-09-16 16:26:22 +00:00
Mufin
72461546b8 Remove tuinity section from README.md (#1045) 2021-09-16 11:26:05 -05:00
Geoff Bourne
98ad3b0f4a misc: fixed execute bit on scripts 2021-09-15 21:37:10 -05:00
itzg
7afd2adacf docs: Auto update markdown TOC 2021-09-16 02:28:03 +00:00
Geoff Bourne
4c52d0ec42 Replace/interpolate variables in files sync'ed from mounts (#1039) 2021-09-15 21:27:48 -05:00
Geoff Bourne
9f66622472 Added bedrock port to allow for waking from pause
#1046
2021-09-15 21:23:38 -05:00
Geoff Bourne
1f2f33d6c0 Merge branch 'master' of github.com:itzg/docker-minecraft-server 2021-09-15 21:02:05 -05:00
Geoff Bourne
1a3c454d7f Added ping
#891 #1041
2021-09-15 20:53:44 -05:00
itzg
fa11d313fb docs: Auto update markdown TOC 2021-09-16 01:45:45 +00:00
Geoff Bourne
20bc2a97d9 docs: fixed java version example 2021-09-15 20:45:27 -05:00
dependabot[bot]
0cd49c4c81 build(deps): bump stefanzweifel/git-auto-commit-action (#1042) 2021-09-13 06:55:47 -05:00
Geoff Bourne
6c1cd2537d misc: created FUNDING.yml 2021-09-12 21:02:13 -05:00
brutalgg
cf31f24752 docs: Add RLCraft example (#1036) 2021-09-10 10:26:19 -05:00
itzg
27523a1c45 docs: Auto update markdown TOC 2021-09-06 15:53:03 +00:00
Geoff Bourne
e1d0fe6b92 docs: added world data diagram to README 2021-09-06 10:52:44 -05:00
itzg
d3f4a4991e docs: Auto update markdown TOC 2021-09-05 19:11:45 +00:00
Geoff Bourne
296ddbdec5 docs: described unicode conversion for MOTD 2021-09-05 14:11:26 -05:00
Geoff Bourne
f7cd34b8d8 Added unicode conversion for MOTD
#1025
2021-09-04 19:46:18 -05:00
itzg
7bafffbd06 docs: Auto update markdown TOC 2021-09-04 16:04:43 +00:00
Geoff Bourne
201ec3be5a docs: added SETUP_ONLY 2021-09-04 11:04:23 -05:00
itzg
7d1d5af097 docs: Auto update markdown TOC 2021-09-03 21:51:18 +00:00
Geoff Bourne
f9ce5bce4d docs: fixed heading level of timezone config 2021-09-03 16:51:00 -05:00
itzg
748768c771 docs: Auto update markdown TOC 2021-09-02 02:21:29 +00:00
Ross Holmberg
f307077636 Typo (#1027) 2021-09-01 21:21:11 -05:00
Geoff Bourne
179cd878a9 Added error check on download of GENERIC_PACK
#1017
2021-08-30 21:31:06 -05:00
Geoff Bourne
788548d1f4 misc: upgraded mc-server-runner to 1.7.0 2021-08-30 21:17:48 -05:00
Geoff Bourne
0ae15c2b3c Fixed binding address of Limbo server
#994
2021-08-29 17:11:29 -05:00
itzg
b5b4257032 docs: Auto update markdown TOC 2021-08-29 21:26:47 +00:00
Daniel Ramp
657db124b2 docs: generator_settings json for 1.13+ (#1020) 2021-08-29 16:26:35 -05:00
dependabot[bot]
f5ea43b3d3 build(deps): bump docker/build-push-action from 2.6.1 to 2.7.0 (#1011) 2021-08-23 07:27:58 -05:00
itzg
01747510d5 docs: Auto update markdown TOC 2021-08-21 18:52:25 +00:00
Geoff Bourne
ff8b160a2b docs: added troubleshooting section 2021-08-21 13:52:25 -05:00
itzg
28b7afda15 docs: Auto update markdown TOC 2021-08-15 17:44:45 +00:00
Geoff Bourne
ecd253dd3e Added support for TYPE=LIMBO (#994) 2021-08-15 12:44:31 -05:00
Chris Fowles
8d0dbcd50e Detect and download FTB ARM installer (#995)
Co-authored-by: Chris Fowles <chris.fowles@plenti.com.au>
2021-08-10 12:53:01 -05:00
itzg
327f21f1bb docs: Auto update markdown TOC 2021-08-01 17:09:37 +00:00
Geoff Bourne
c96d6b2958 Added support for STOP_SERVER_ANNOUNCE_DELAY 2021-08-01 12:09:18 -05:00
itzg
da8fb37317 docs: Auto update markdown TOC 2021-07-31 14:24:59 +00:00
Geoff Bourne
4d7e29cb3a Corrected support for Magma dev channel forge-based installer 2021-07-31 09:24:38 -05:00
itzg
17099320e9 docs: Auto update markdown TOC 2021-07-27 00:33:11 +00:00
Geoff Bourne
f3dbb4dd2d Added support for Magma dev channel downloads 2021-07-26 19:32:26 -05:00
Geoff Bourne
b3b3cdde08 Don't warn about Forge on Java 8 for 1.17+ 2021-07-25 09:50:40 -05:00
itzg
b8cd510a0e docs: Auto update markdown TOC 2021-07-24 21:26:28 +00:00
Geoff Bourne
0d5eb2ea9e docs: fixed heading depth
#988
2021-07-24 16:26:09 -05:00
Geoff Bourne
2b0fd2e5c0 Added support for Forge 1.17's run.sh mechanism
#986
2021-07-23 21:17:05 -05:00
Jawa_Juice
4168821ec4 Reflect different jar names for airplane/airplanepurpur (#985) 2021-07-21 10:16:05 -05:00
itzg
6353488db7 docs: Auto update markdown TOC 2021-07-18 21:20:49 +00:00
Geoff Bourne
b446d4cc3f docs: added recommendation of management layer 2021-07-18 16:19:57 -05:00
Geoff Bourne
16b2762025 Removed extra quotes in spiget log when resource already new enough 2021-07-17 21:11:21 -05:00
Daniel Ramp
c5a3e2e376 Cache spiget version resolution (#978) 2021-07-17 18:44:18 -05:00
82 changed files with 2302 additions and 1354 deletions

5
.github/FUNDING.yml vendored Normal file
View File

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

40
.github/ISSUE_TEMPLATE/bug.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Bug Report
description: File a bug report
labels:
- bug
- status/needs triage
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report a bug.
Please double check some things first:
- Do you just have a question about something? If so, asking in the [Q&A Discussions](https://github.com/itzg/docker-minecraft-server/discussions/categories/q-a) or asking on [the Discord server](https://discord.gg/DXfKpjB) would be best.
- Is this bug happening after the `[init]` prefixed logs and after the log that says "Starting the Minecraft server"? If so, please report the bug with Mojang or the respective server provider.
- Are you seeing a performance problem? If so, that is typically outside the scope of the image setup mechanims. Ask a question as above or contact the respective server provider.
- type: textarea
id: problem
attributes:
label: Describe the problem
validations:
required: true
- type: textarea
id: container
attributes:
label: Container definition
description: Please provide the compose file or run command used to create the container
value: |
```
Paste run command or compose file here
```
- type: textarea
id: logs
attributes:
label: Container logs
description: |
Please provide container logs from the start of the container, which will be the ones prefixed with `[init]`. It is even better if you can set the variable `DEBUG` to "true" and provide those debug container logs.
value: |
```
Paste logs here
```

7
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
contact_links:
- name: Ask a question in discussions
url: https://github.com/itzg/docker-minecraft-server/discussions
about: Please ask questions here
- name: Ask a question on Discord
url: https://discord.gg/DXfKpjB
about: Please ask questions here

29
.github/ISSUE_TEMPLATE/enhancement.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: Enhancement Request
description: Request an enhancement
labels:
- enhancement
- status/needs triage
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to request an enhancement.
Even if you plan on submitting a pull request with a contributed enhancement it is best to describe the enhancement here first. Somebody might already be working on a similar thing and could use your help.
- type: dropdown
id: type
attributes:
label: Enhancement Type
options:
- Improve an existing feature
- A completely new feature
- New server type
- Not sure
validations:
required: true
- type: textarea
id: description
attributes:
label: Describe the enhancement
validations:
required: true

View File

@@ -1,6 +0,0 @@
daysUntilClose: 14
responseRequiredLabel: "status/waiting on feedback"
closeComment: >
This issue has been automatically closed because there has been no response
after requesting feedback. Please feel free to re-open this issue if the
scenario still exists and provide a comment with more information.

View File

@@ -3,16 +3,16 @@ on:
push:
branches:
- master
- "*-multiarch"
- "multiarch*"
- java8-multiarch
- java8-openj9
- java11*
- java16*
- test/multiarch/*
- java17*
- test/*
- fix/*
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+-multiarch*"
- "[0-9]+.[0-9]+.[0-9]+-*multiarch"
- "[0-9]+.[0-9]+.[0-9]+-java8-multiarch"
- "[0-9]+.[0-9]+.[0-9]+-java8-openj9"
- "[0-9]+.[0-9]+.[0-9]+-java11*"
- "[0-9]+.[0-9]+.[0-9]+-java16*"
@@ -21,13 +21,16 @@ on:
- "docs/**"
- "examples/**"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
jobs:
docker-buildx:
build:
if: github.repository == 'itzg/docker-minecraft-server'
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2.3.4
uses: actions/checkout@v2.4.0
- name: Docker meta
id: meta
@@ -44,14 +47,6 @@ jobs:
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
uses: actions/cache@v2.1.6
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Set up QEMU
uses: docker/setup-qemu-action@v1.2.0
@@ -61,9 +56,29 @@ jobs:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test
uses: docker/build-push-action@v2.7.0
if: github.ref_name == 'master'
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
# no cache-to to avoid cross-cache update from next build step
- name: Run tests
# It is assumed that image variants are merged from master and tested there
if: github.ref_name == 'master'
run: |
tests/test.sh
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2.6.1
uses: docker/build-push-action@v2.7.0
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64
@@ -71,17 +86,9 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
# ensure latest base image is used
pull: true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
cache-from: type=gha
cache-to: type=gha,mode=max
labels: ${{ steps.meta.outputs.labels }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
- # Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

View File

@@ -11,11 +11,11 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v2.3.4
- 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.11.0
- uses: stefanzweifel/git-auto-commit-action@v4.12.0
with:
commit_message: "docs: Auto update markdown TOC"

View File

@@ -7,7 +7,7 @@ on:
- openj9
- openj9-11
- adopt11
- test/*
- test/alpine/*
tags:
- "[0-9]+.[0-9]+.[0-9]+-java8"
- "[0-9]+.[0-9]+.[0-9]+-openj9"
@@ -15,23 +15,15 @@ on:
- "[0-9]+.[0-9]+.[0-9]+-openj9-nightly"
- "[0-9]+.[0-9]+.[0-9]+-adopt11"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
jobs:
test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2.3.4
- name: Run tests
run: |
tests/test.sh
build:
needs:
- test
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2.3.4
- uses: actions/checkout@v2.4.0
- name: Prepare
id: prep
@@ -54,23 +46,36 @@ jobs:
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
uses: actions/cache@v2.1.6
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test
uses: docker/build-push-action@v2.7.0
if: github.ref_name == 'java8'
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
# ensure latest base image is used
pull: true
load: true
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Run tests
if: github.ref_name == 'java8'
run: |
tests/test.sh
env:
MINECRAFT_VERSION: 1.12.2
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2.6.1
uses: docker/build-push-action@v2.7.0
with:
context: .
file: ./Dockerfile
@@ -80,8 +85,8 @@ jobs:
push: true
# tags determined by prep step
tags: ${{ steps.prep.outputs.tags }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
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 }}
@@ -90,11 +95,3 @@ jobs:
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
- # Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

View File

@@ -4,12 +4,28 @@ on:
pull_request:
branches: [ master ]
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: actions/checkout@v2.4.0
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build
uses: docker/build-push-action@v2.7.0
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
load: true
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Run tests
run: |

25
.github/workflows/stale-check.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Stale Check
on:
schedule:
- cron: 0 2 * * *
jobs:
check:
runs-on: ubuntu-20.04
permissions:
issues: write
pull-requests: write
steps:
- name: Process Stale Issues
uses: actions/stale@v4.0.0
with:
stale-issue-label: status/stale
stale-pr-label: status/stale
stale-issue-message: >
This issue is stale because it has been open 30 days with no activity.
Please add a comment describing the reason to keep this issue open.
days-before-stale: 30
days-before-close: 5
exempt-issue-labels: 'enhancement,keep,status/needs triage'

View File

@@ -2,10 +2,10 @@
Adding a new server `TYPE` can vary due to the complexity of obtaining and configuring each type; however, the addition of any server type includes at least the following steps:
1. Copy an existing "start-deploy*" script, such as [start-deployMohist](start-deployMohist) and rename it accordingly making sure to retain the "start-deploy" prefix
2. Modify the type-specific behavior between the "start-utils" preamble and the hand-off to `start-finalSetupWorld` at the end of the script
1. Copy an existing "start-deploy*" script, such as [start-deployMohist](scripts/start-deployMohist) and rename it accordingly making sure to retain the "start-deploy" prefix
2. Modify the type-specific behavior between the "start-utils" preamble and the hand-off to `start-setupWorld` at the end of the script
3. Develop and test the changes using the [iterative process described below](#iterative-script-development)
4. Add a case-entry to the `case "${TYPE^^}"` in [start-configuration](start-configuration)
4. Add a case-entry to the `case "${TYPE^^}"` in [start-configuration](scripts/start-configuration)
5. Add a section to the [README](README.md). It is recommended to copy-modify an existing section to retain a similar wording and level of detail
6. [Submit a pull request](https://github.com/itzg/docker-minecraft-server/pulls)
@@ -40,6 +40,29 @@ VANILLA_VERSION=1.12.2 /scripts/start-magma
> NOTE: You may want to temporarily add an `exit` statement near the end of your script to isolate execution to just the script you're developing.
## Using development copy of mc-image-helper
In the cloned copy of [`mc-image-helper`](https://github.com/itzg/mc-image-helper), create an up-to-date snapshot build of the tgz distribution using:
```shell
./gradlew distTar
```
Assuming [http-server](https://www.npmjs.com/package/http-server) is installed globally, start a static web server using:
```shell
http-server ./build/distributions -p 0
```
Note the port that was selected by http-server and pass the build arguments, such as:
```shell
--build-arg MC_HELPER_VERSION=1.8.1-SNAPSHOT \
--build-arg MC_HELPER_BASE_URL=http://host.docker.internal:8080
```
Now the image can be built like normal and it will install mc-image-helper from the locally built copy.
## 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:
@@ -70,5 +93,27 @@ The multiarch images are built and published by [a Github action](https://github
The following git command can be used to provide the bulk of release notes content:
```shell script
git log --invert-grep --grep "^ci:" --grep "^misc:" --grep "^docs:" --pretty="- %s" 1.1.0..1.2.0
git log --invert-grep --grep "^ci:" --grep "^misc:" --grep "^docs:" --pretty="* %s" 1.1.0..1.2.0
```
## Tracking changes from master without content
The following script uses the [ours](https://git-scm.com/docs/merge-strategies#Documentation/merge-strategies.txt-ours) merging strategy to track the history from master into the other branches without actually bringing the changes over. It is useful when a change is specific to master only, such as bumping the base Java version for the `latest` image tag.
```shell
branches=(
java8
java8-multiarch
java8-openj9
java11
java11-openj9
java16
java16-openj9
java17
)
for b in "${branches[@]}"; do
git checkout "$b"
git merge -s ours -m "Track latest from master" master
git push origin
done
```

View File

@@ -1,4 +1,4 @@
FROM adoptopenjdk:16-jre
FROM eclipse-temurin:17-jdk
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
@@ -9,6 +9,7 @@ RUN apt-get update \
gosu \
sudo \
net-tools \
iputils-ping \
curl wget \
git \
jq \
@@ -44,26 +45,28 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.4.7 --var app=rcon-cli --file {{.app}} \
--var version=1.5.1 --var app=rcon-cli --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=0.7.1 --var app=mc-monitor --file {{.app}} \
--var version=0.10.3 --var app=mc-monitor --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.5.0 --var app=mc-server-runner --file {{.app}} \
--var version=1.8.0 --var app=mc-server-runner --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
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
COPY mcstatus /usr/local/bin
ARG MC_HELPER_VERSION=1.10.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"]
COPY server.properties /tmp/server.properties
COPY log4j2.xml /tmp/log4j2.xml
WORKDIR /data
STOPSIGNAL SIGTERM
@@ -72,18 +75,18 @@ ENV UID=1000 GID=1000 \
MEMORY="1G" \
TYPE=VANILLA VERSION=LATEST \
ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \
SERVER_PORT=25565 ONLINE_MODE=TRUE SERVER_NAME="Dedicated Server" \
ENABLE_AUTOPAUSE=false AUTOPAUSE_TIMEOUT_EST=3600 AUTOPAUSE_TIMEOUT_KN=120 AUTOPAUSE_TIMEOUT_INIT=600 \
AUTOPAUSE_PERIOD=10 AUTOPAUSE_KNOCK_INTERFACE=eth0
COPY start* /
COPY health.sh /
ADD files/autopause /autopause
RUN dos2unix /start* && chmod +x /start*
RUN dos2unix /health.sh && chmod +x /health.sh
RUN dos2unix /autopause/* && chmod +x /autopause/*.sh
COPY scripts/start* /
COPY bin/ /usr/local/bin/
COPY bin/mc-health /health.sh
COPY files/server.properties /tmp/server.properties
COPY files/log4j2.xml /tmp/log4j2.xml
COPY files/autopause /autopause
RUN dos2unix /start* && chmod +x /start* \
&& dos2unix /autopause/* && chmod +x /autopause/*.sh
ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m CMD /health.sh
HEALTHCHECK --start-period=1m CMD mc-health

474
README.md
View File

@@ -13,30 +13,11 @@ To simply use the latest stable version, run
docker run -d -it -p 25565:25565 -e EULA=TRUE itzg/minecraft-server
where the standard server port, 25565, will be exposed on your host machine.
where, in this case, the standard server port 25565, will be exposed on your host machine.
If you want to serve up multiple Minecraft servers or just use an alternate port,
change the host-side port mapping such as
> If you plan on running a server for a longer amount of time it is highly recommended using a management layer such as [Docker Compose](#using-docker-compose) or [Kubernetes](#deployment-templates-and-examples) to allow for incremental reconfiguration and image upgrades.
... -p 25566:25565 ...
will serve your Minecraft server on your host's port 25566 since the `-p` syntax is
`host-port`:`container-port`.
Speaking of multiple servers, it's handy to give your containers explicit names using `--name`, such as naming this one "mc"
... --name mc itzg/minecraft-server
With that you can easily view the logs, stop, or re-start the container:
docker logs -f mc
( Ctrl-C to exit logs action )
docker stop mc
docker start mc
> Be sure to always include `-e EULA=TRUE` in your commands, as Mojang/Microsoft requires EULA acceptance.
> Be sure to always include `-e EULA=TRUE` in your commands and container definitions, as Mojang/Microsoft requires EULA acceptance.
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.
@@ -57,40 +38,43 @@ By default, the container will download the latest version of the "vanilla" [Min
* [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 a Tuinity server](#running-a-tuinity-server)
* [Running an Airplane server](#running-an-airplane-server)
* [Running a Purpur server](#running-a-purpur-server)
* [Running a Yatopia server](#running-a-yatopia-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 an Canyon server](#running-an-canyon-server)
* [Running a Canyon server](#running-a-canyon-server)
* [Running a SpongeVanilla server](#running-a-spongevanilla-server)
* [Running a Fabric Server](#running-a-fabric-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)
* [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, Bukkit, and Spigot Servers](#downloadable-modplugin-pack-for-forge-bukkit-and-spigot-servers)
* [Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers](#downloadable-modplugin-pack-for-forge-fabric-and-bukkit-like-servers)
* [Generic pack file](#generic-pack-file)
* [Mod/Plugin URL Listing File](#modplugin-url-listing-file)
* [Remove old mods/plugins](#remove-old-modsplugins)
* [Working with world data](#working-with-world-data)
* [Downloadable world](#downloadable-world)
* [Cloning world from a container path](#cloning-world-from-a-container-path)
* [Overwrite world on start](#overwrite-world-on-start)
* [Server configuration](#server-configuration)
* [Server name](#server-name)
* [Server port](#server-port)
* [Message of the Day](#message-of-the-day)
* [Difficulty](#difficulty)
* [Whitelist Players](#whitelist-players)
* [Op/Administrator Players](#opadministrator-players)
@@ -115,37 +99,42 @@ By default, the container will download the latest version of the "vanilla" [Min
* [View Distance](#view-distance)
* [Level Seed](#level-seed)
* [Game Mode](#game-mode)
* [Message of the Day](#message-of-the-day)
* [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)
* [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)
* [Autopause](#autopause)
* [Description](#description)
* [Enabling Autopause](#enabling-autopause)
* [Running on RaspberryPi](#running-on-raspberrypi)
* [Contributing](#contributing)
<!-- Added by: runner, at: Thu Jul 15 13:34:00 UTC 2021 -->
<!-- Added by: runner, at: Sat Dec 11 22:09:10 UTC 2021 -->
<!--te-->
@@ -167,8 +156,7 @@ docker exec -i mc rcon-cli
Note: The `-i` is required for interactive use of rcon-cli.
To run a simple, one-shot command, such as stopping a Minecraft server, pass the command as
arguments to `rcon-cli`, such as:
To run a simple, one-shot command, such as stopping a Minecraft server, pass the command as arguments to `rcon-cli`, such as:
```
docker exec mc rcon-cli stop
@@ -176,6 +164,14 @@ docker exec mc rcon-cli stop
_The `-i` is not needed in this case._
If rcon is disabled you can send commands by passing them as arguments to the packaged `mc-send-to-console` script. For example, a player can be op'ed in the container `mc` with:
```shell
docker exec mc mc-send-to-console op player
| |
+- container name +- Minecraft commands start here
```
In order to attach and interact with the Minecraft server, add `-it` when starting the container, such as
docker run -d -it -p 25565:25565 --name mc itzg/minecraft-server
@@ -229,6 +225,8 @@ services:
- ./minecraft-data:/data
```
> NOTE: if you have SELinux enabled, then you might need to add `:Z` to the end of volume mount specifications, [as described here](https://prefetch.net/blog/2017/09/30/using-docker-volumes-on-selinux-enabled-servers/).
### Converting anonymous `/data` volume to named volume
If you had used the commands in the first section, without the `-v` volume attachment, then an anonymous data volume was created by Docker. You can later bring over that content to a named or host attached volume using the following procedure.
@@ -273,25 +271,26 @@ the server jar remain in the `/data` directory. It is safe to remove those._
## Running Minecraft server on different Java version
To use a different version of Java, please use a docker tag to run your Minecraft server.
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 |
| 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 |
| java16 | 16 | Debian | Hotspot | amd64,arm64,armv7 |
| java16-openj9 | 16 | Debian | OpenJ9 | amd64 |
| multiarch-latest | 15+ | Debian | Hotspot | amd64,arm64,armv7 |
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
For example, to use Java version 15 on any supported architecture:
For example, to use Java version 8 on any supported architecture:
docker run --name mc itzg/minecraft-server:java15
docker run --name mc itzg/minecraft-server:java8-multiarch
> Keep in mind that some versions of Minecraft server can't work on the newest versions of Java. Also, FORGE doesn't support openj9 JVM implementation.
> Keep in mind that some versions of Minecraft server, such as Forge before 1.17, can't work on the newest versions of Java. Instead, one of the Java 8 images should be used. Also, FORGE doesn't support openj9 JVM implementation.
>
> Some versions of vanilla Minecraft, such as 1.10, also do not run correctly with Java 17. If in doubt, use `java8-multiarch` for any version less than 1.17.
### Deprecated Image Tags
@@ -300,6 +299,8 @@ The following image tags have been deprecated and are no longer receiving update
- adopt14
- adopt15
- openj9-nightly
- multiarch-latest
- java16
## Healthcheck
@@ -367,6 +368,14 @@ and in the same directory as that file run
Now, go play...or adjust the `environment` section to configure
this server instance.
## Troubleshooting
To troubleshoot the container initialization, such as when server files are pre-downloaded, set the environment variable `DEBUG` to `true`. The container logs will include **much more** output, and it is highly recommended including that output when reporting any [issues](https://github.com/itzg/docker-minecraft-server/issues).
To troubleshoot just the command-line used to start the Minecraft server, set the environment variable `DEBUG_EXEC` to `true`.
To troubleshoot any issues with memory allocation reported by the JVM, set the environment variable `DEBUG_MEMORY` to `true`.
## Server types
### Running a Forge Server
@@ -394,6 +403,30 @@ the URL with `FORGE_INSTALLER_URL`, such as:
In both of the cases above, there is no need for the `VERSION` or `FORGEVERSION` variables.
### 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).
```
docker run -d -v /path/on/host:/data \
-e TYPE=FABRIC \
-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.
A specific loader version other than the latest can be requested using `FABRIC_LOADER_VERSION`, such as:
```
docker run -d -v /path/on/host:/data ... \
-e FABRIC_LOADER_VERSION=0.12.8
```
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`)
### Running a Bukkit/Spigot server
Enable Bukkit/Spigot server mode by adding a `-e TYPE=BUKKIT` or `-e TYPE=SPIGOT` to your command-line.
@@ -409,7 +442,7 @@ If you are hosting your own copy of Bukkit/Spigot you can override the download
You can build spigot from source by adding `-e BUILD_FROM_SOURCE=true`
Plugins can either be managed within the `plugins` subdirectory of the [data directory](#data-directory) or you can also [attach a `/plugins` volume](#deploying-plugins-from-attached-volume). If you add plugins while the container is running, you'll need to restart it to pick those up.
Plugins can either be managed within the `plugins` subdirectory of the [data directory](#data-directory) or you can also [attach a `/plugins` volume](#optional-plugins-mods-and-config-attach-points). If you add plugins while the container is running, you'll need to restart it to pick those up.
[You can also auto-download plugins using `SPIGET_RESOURCES`.](#auto-downloading-spigotmcbukkitpapermc-plugins)
@@ -433,21 +466,13 @@ If you are hosting your own copy of Paper you can override the download URL with
An example compose file is provided at
[examples/docker-compose-paper.yml](examples/docker-compose-paper.yml).
If you have attached a host directory to the `/data` volume, then you can install plugins via the `plugins` subdirectory. You can also [attach a `/plugins` volume](#deploying-plugins-from-attached-volume). If you add plugins while the container is running, you'll need to restart it to pick those up.
If you have attached a host directory to the `/data` volume, then you can install plugins via the `plugins` subdirectory. You can also [attach a `/plugins` volume](#optional-plugins-mods-and-config-attach-points). If you add plugins while the container is running, you'll need to restart it to pick those up.
[You can also auto-download plugins using `SPIGET_RESOURCES`.](#auto-downloading-spigotmcbukkitpapermc-plugins)
### Running a Tuinity server
A [Tuinity](https://github.com/Spottedleaf/Tuinity) server, which is a fork of Paper aimed at improving server performance at high playercounts.
-e TYPE=TUINITY
> **NOTE** only `VERSION=LATEST` is supported
### Running an Airplane server
An [Airplane](https://github.com/TECHNOVE/Airplane) server, which is a fork of Tuinity aimed at further improving server performance at high playercounts.
An [Airplane](https://airplane.gg) server, which is "a stable, optimized, well supported 1.17 Paper fork."
-e TYPE=AIRPLANE
@@ -460,7 +485,7 @@ Extra variables:
### Running a Purpur server
A [Purpur](https://purpur.pl3x.net/) server, which is "a drop-in replacement for Paper servers designed for configurability, new fun and exciting gameplay features, and high performance built on top of Tuinity."
A [Purpur](https://purpur.pl3x.net/) server, which is "drop-in replacement for Paper servers designed for configurability, new fun and exciting gameplay features, and performance built on top of Airplane."
-e TYPE=PURPUR
@@ -469,18 +494,6 @@ A [Purpur](https://purpur.pl3x.net/) server, which is "a drop-in replacement for
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
### Running a Yatopia server
A [Yatopia](https://github.com/YatopiaMC/Yatopia) server, which is a "blazing fast Tuinity fork with best in class performance".
-e TYPE=YATOPIA
> NOTE: the `VERSION` variable is used to locate the Yatopia version to download
Extra variables:
- `RELEASE=stable` : set to `stable` or `latest`
- `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 [Flare](https://blog.airplane.gg/flare) profiler
### Running a Magma server
@@ -489,7 +502,9 @@ A [Magma](https://magmafoundation.org/) server, which is a combination of Forge
-e TYPE=MAGMA
> **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2"
By default, the "stable" channel is used, but you can set `MAGMA_CHANNEL` to "dev" to access dev channel versions.
> **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2", "1.16.5", etc.
### Running a Mohist server
@@ -512,28 +527,29 @@ A [Catserver](http://catserver.moe/) type server can be used with
> **NOTE** Catserver only provides a single release stream, so `VERSION` is ignored
### Running an Canyon server
### Running a Canyon server
[Canyon](https://github.com/canyonmodded/canyon) is a fork of CraftBukkit for Minecraft Beta 1.7.3. It includes multiple enhancements whilst also retaining compatibility with old Bukkit plugins and mods as much as possible.
-e VERSION=b1.7.3 -e TYPE=CANYON
> **NOTE** only `VERSION=b1.7.3` is supported
> **NOTE** only `VERSION=b1.7.3` is supported. Since that version pre-dates the health check mechanism used by this image, that will need to be disabled by setting `DISABLE_HEALTHCHECK=true`.
> **NOTE** only Java 8 is supported
By default the latest build will be used; however, a specific build number can be selected by setting `CANYON_BUILD`, such as
By default, the latest build will be used; however, a specific build number can be selected by setting `CANYON_BUILD`, such as
-e CANYON_BUILD=11
### Running a SpongeVanilla server
Enable SpongeVanilla server mode by adding a `-e TYPE=SPONGEVANILLA` to your command-line.
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 \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server:java8-multiarch
You can also choose to use the `EXPERIMENTAL` branch.
Just change it with `SPONGEBRANCH`, such as:
@@ -541,33 +557,29 @@ Just change it with `SPONGEBRANCH`, such as:
$ docker run -d -v /path/on/host:/data ... \
-e TYPE=SPONGEVANILLA -e SPONGEBRANCH=EXPERIMENTAL ...
### Running a Fabric Server
### Running a Limbo server
Enable [Fabric server](http://fabricmc.net/use/) mode by adding a `-e TYPE=FABRIC` to your command-line. By default, the container will run the latest version, but you can also choose to run a specific version with `VERSION`.
A [Limbo](https://github.com/LOOHP/Limbo) server can be run by setting `TYPE` to `LIMBO`.
```
docker run -d -v /path/on/host:/data \
-e TYPE=FABRIC \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
```
Configuration options with defaults:
A specific installer version can be requested using `FABRIC_INSTALLER_VERSION`.
- `LIMBO_BUILD`=LATEST
To use a pre-downloaded Fabric installer, place it in a directory attached into the container, such as the `/data` volume and specify the name of the installer file with `FABRIC_INSTALLER`, such as:
The `VERSION` will be ignored so locate the appropriate value from [here](https://ci.loohpjames.com/job/Limbo/) to match the version expected by clients.
```
docker run -d -v /path/on/host:/data ... \
-e FABRIC_INSTALLER=fabric-installer-0.5.0.32.jar ...
```
- `FORCE_REDOWNLOAD`=false
- `LIMBO_SCHEMA_FILENAME`=default.schem
- `LEVEL`="Default;${LIMBO_SCHEMA_FILENAME}"
To download a Fabric installer from a custom location, such as your own file repository, specify the URL with `FABRIC_INSTALLER_URL`, such as:
### Running a Crucible server
```
docker run -d -v /path/on/host:/data ... \
-e FABRIC_INSTALLER_URL=http://HOST/fabric-installer-0.5.0.32.jar ...
```
A [Crucible](https://github.com/CrucibleMC/Crucible) server can be run by setting `TYPE` to `CRUCIBLE`.
In order to add mods, you have two options:
Configuration options with defaults:
- `CRUCIBLE_RELEASE`=latest
Crucible is only available for 1.7.10, so be sure to set `VERSION=1.7.10`.
## Running a server with a Feed the Beast modpack
@@ -620,13 +632,13 @@ The following example uses `/modpacks` as the container path as the pre-download
-e CF_SERVER_MOD=/modpacks/SkyFactory_4_Server_4.1.0.zip \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
#### Modpack data directory
### Modpack data directory
By default, CurseForge modpacks are expanded into the sub-directory `/data/FeedTheBeast` and executed from there. (The default location was chosen for legacy reasons, when Curse and FTB were maintained together.)
The directory can be changed by setting `CF_BASE_DIR`, such as `-e CF_BASE_DIR=/data`.
#### Buggy start scripts
### Buggy start scripts
Some modpacks have buggy or overly complex start scripts. You can avoid using the bundled start script and use this image's standard server-starting logic by adding `-e USE_MODPACK_START_SCRIPT=false`.
@@ -640,6 +652,20 @@ then you apply a workaround by adding this to the run invocation:
-e FTB_LEGACYJAVAFIXER=true
## Running a server with a packwiz modpack
[packwiz](https://packwiz.infra.link/) is a CLI tool for maintaining and providing modpack definitions, with support for both CurseForge and Modrinth as sources. See the [packwiz tutorial](https://packwiz.infra.link/tutorials/getting-started/) for more information.
To configure server mods using a packwiz modpack, set the `PACKWIZ_URL` environment variable to the location of your `pack.toml` modpack definition:
docker run -d -v /path/on/host:/data -e TYPE=FABRIC \
-e "PACKWIZ_URL=https://example.com/modpack/pack.toml" \
itzg/minecraft-server
packwiz modpack defitions are processed before other mod definitions (`MODPACK`, `MODS`, etc.) to allow for additional processing/overrides you may want to perform (in case of mods not available via Modrinth/CurseForge, or you do not maintain the pack).
> packwiz is pre-configured to only download server mods. If client-side mods are downloaded and cause issues, check your pack.toml configuration, and make sure any client-only mods are not set to `"both"`, but rather `"client"` for the side configuration item.
## Working with mods and plugins
### Optional plugins, mods, and config attach points
@@ -647,23 +673,23 @@ then you apply a workaround by adding this to the run invocation:
There are optional volume paths that can be attached to supply content to be copied into the data area:
`/plugins`
: contents are copied into `/data/plugins` for Bukkit related server types. Set `PLUGINS_SYNC_UPDATE=false` if you want files from `/plugins` to take precedence over newer files in `/data/plugins`.
: contents are synchronized into `/data/plugins` for Bukkit related server types. Set `SYNC_SKIP_NEWER_IN_DESTINATION=false` if you want files from `/plugins` to take precedence over newer files in `/data/plugins`.
`/mods`
: contents are copied into `/data/mods` for Forge related server types
: contents are synchronized into `/data/mods` for Fabric and Forge related server types. The destination can be changed by setting `COPY_MODS_DEST`.
`/config`
: contents are copied into `/data/config` by default, but can be changed with `COPY_CONFIG_DEST`
: contents are synchronized into `/data/config` by default, but can be changed with `COPY_CONFIG_DEST`. For example, `-v ./config:/config -e COPY_CONFIG_DEST=/data` will allow you to copy over files like `bukkit.yml` and so on directly into the server directory. Set `SYNC_SKIP_NEWER_IN_DESTINATION=false` if you want files from `/config` to take precedence over newer files in `/data/config`.
By default, the [environment variable processing](#replacing-variables-inside-configs) is performed on synchronized files that match the expected suffixes in `REPLACE_ENV_SUFFIXES` (by default "yml,yaml,txt,cfg,conf,properties,hjson,json,tml,toml") and are not excluded by `REPLACE_ENV_VARIABLES_EXCLUDES` and `REPLACE_ENV_VARIABLES_EXCLUDE_PATHS`. This processing can be disabled by setting `REPLACE_ENV_DURING_SYNC` to `false`.
If you want old mods/plugins to be removed before the content is brought over from those attach points, then add `-e REMOVE_OLD_MODS=TRUE`. You can fine tune the removal process by specifying the `REMOVE_OLD_MODS_INCLUDE` and `REMOVE_OLD_MODS_EXCLUDE` variables. By default, everything will be removed. You can also specify the `REMOVE_OLD_MODS_DEPTH` (default is 16) variable to only delete files up to a certain level.
For example: `-e REMOVE_OLD_MODS=TRUE -e REMOVE_OLD_MODS_INCLUDE="*.jar" -e REMOVE_OLD_MODS_DEPTH=1` will remove all old jar files that are directly inside the `plugins/` or `mods/` directory.
You can specify the destination of the files that are copied from `/mods` and `/config` by setting the `COPY_MODS_DEST` and `COPY_CONFIG_DEST`, where the default is `/data/mods` and `/data/config`. For example, `-v ./config:/config -e COPY_CONFIG_DEST=/data` will allow you to copy over files like `bukkit.yml` and so on directly into the server directory.
These paths work well if you want to have a common set of modules in a separate location, but still have multiple worlds with different server requirements in either persistent volumes or a downloadable archive.
> For more flexibility with mods/plugins preparation, you can declare directories to use in [the `MODS` variable](#downloadable-modplugin-pack-for-forge-bukkit-and-spigot-servers)
> For more flexibility with mods/plugins preparation, you can declare directories to use in [the `MODS` variable](#downloadable-modplugin-pack-for-forge-fabric-and-bukkit-like-servers)
### Auto-downloading SpigotMC/Bukkit/PaperMC plugins
@@ -680,10 +706,10 @@ For example, the following will auto-download the [EssentialsX](https://www.spig
-e SPIGET_RESOURCES=9089,34315
### Downloadable mod/plugin pack for Forge, Bukkit, and Spigot Servers
### Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers
Like the `WORLD` option above, you can specify the URL or path of a "mod pack"
to download and install into `mods` for Forge or `plugins` for Bukkit/Spigot.
to download and install into `mods` for Forge/Fabric or `plugins` for Bukkit/Spigot.
To use this option pass the environment variable `MODPACK`, such as
docker run -d -e MODPACK=http://www.example.com/mods/modpack.zip ...
@@ -699,14 +725,42 @@ 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 ...
### Generic pack file
To install all of the server content (jars, mods, plugins, configs, etc) from a zip file, such as a CurseForge modpack that is missing a server start script, then set `GENERIC_PACK` to the container path of the zip file. That, combined with `TYPE`, allows for custom content along with container managed server download and install.
If multiple generic packs need to be applied together, set `GENERIC_PACKS` instead, with a comma separated list of zip file paths and/or URLs to zip files.
### 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
-e MODS_FILE=/extras/mods.txt
would load from a file mounted into the container at `/extras/mods.txt`. That file might look like:
```text
https://edge.forgecdn.net/files/2965/233/Bookshelf-1.15.2-5.6.40.jar
https://edge.forgecdn.net/files/2926/27/ProgressiveBosses-2.1.5-mc1.15.2.jar
# This and next line are ignored
#https://edge.forgecdn.net/files/3248/905/goblintraders-1.3.1-1.15.2.jar
https://edge.forgecdn.net/files/3272/32/jei-1.15.2-6.0.3.16.jar
https://edge.forgecdn.net/files/2871/647/ToastControl-1.15.2-3.0.1.jar
```
> Blank lines and lines that start with a `#` will be ignored
> [This compose file](examples/docker-compose-mods-file.yml) shows another example of using this feature.
> It is recommended to combine this option with `REMOVE_OLD_MODS=TRUE` to ensure the mods/plugins remain consistent with the file's listing.
### Remove old mods/plugins
When the option above is specified (`MODPACK`) you can also instruct script to
delete old mods/plugins prior to installing new ones. This behaviour is desirable
in case you want to upgrade mods/plugins from downloaded zip file.
To use this option pass the environment variable `REMOVE_OLD_MODS="TRUE"`, such as
To use this option pass the environment variable `REMOVE_OLD_MODS=TRUE`, such as
docker run -d -e REMOVE_OLD_MODS="TRUE" -e MODPACK=http://www.example.com/mods/modpack.zip ...
docker run -d -e REMOVE_OLD_MODS=TRUE -e MODPACK=http://www.example.com/mods/modpack.zip ...
**WARNING:** All content of the `mods` or `plugins` directory will be deleted
before unpacking new content from the MODPACK or MODS.
@@ -737,39 +791,46 @@ read-only volume attachment to ensure the clone source remains pristine.
docker run ... -v $HOME/worlds:/worlds:ro -e WORLD=/worlds/basic
```
The following diagram shows how this option can be used in a compose deployment with a relative directory:
![](docs/world-copy-compose-project.drawio.png)
### 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.
## Server configuration
By default the server configuration will be created and set based on the following
environment variables, but only the first time the server is started. If the
`server.properties` file already exists, the values in them will not be changed.
By default, the server configuration will be created and set based on the following environment variables, but only the first time the server is started. If the `server.properties` file already exists, the values in them will not be changed.
If you would like to override the server configuration each time the container
starts up, you can set the OVERRIDE_SERVER_PROPERTIES environment variable like:
If you would like to override the server configuration each time the container starts up, you can set the `OVERRIDE_SERVER_PROPERTIES` environment variable like:
docker run -d -e OVERRIDE_SERVER_PROPERTIES=true ...
This will reset any manual configuration of the `server.properties` file, so if
you want to make any persistent configuration changes you will need to make sure
you have properly set the proper environment variables in your docker run command (described below).
This will reset any manual configuration of the `server.properties` file, so if you want to make any persistent configuration changes you will need to make sure you have properly set the proper environment variables in your container configuration.
### Server name
In the opposite case, you can skip the startup script's creation of `server.properties`, by setting `SKIP_SERVER_PROPERTIES` to "true".
The server name (e.g. for bungeecord) can be set like:
> NOTE: to clear a server property, set the variable to an empty string, such as `-e RESOURCE_PACK=""`. A variables that maps to a server property that is unset, is ignored and the existing `server.property` is left unchanged.
docker run -d -e SERVER_NAME=MyServer ...
### Message of the Day
### Server port
The message of the day, shown below each server entry in the client UI, can be changed with the `MOTD` environment variable, such as
> **WARNING:** only change this value if you know what you're doing. It is only needed when using host networking and it is rare that host networking should be used. Use `-p` port mappings instead.
-e MOTD="My Server"
If you must, the server port can be set like:
If you leave it off, a default is computed from the server type and version, such as
docker run -d -e SERVER_PORT=25566 ...
A Paper Minecraft Server powered by Docker
**however**, be sure to change your port mapping accordingly and be prepared for some features to break.
That way you can easily differentiate between several servers you may have started.
The section symbol (§) and other unicode characters are automatically converted to allow [formatting codes](https://minecraft.fandom.com/wiki/Formatting_codes) to be used consistently with all server versions. For example,
-e MOTD="A §l§cMinecraft§r §nserver"
renders
![](docs/motd-example.png)
### Difficulty
@@ -783,24 +844,37 @@ values.
### Whitelist Players
To whitelist players for your Minecraft server, pass the Minecraft usernames separated by commas via the `WHITELIST` environment variable, such as
> **NOTE** it is very important to set this with servers exposed to the internet where you want only limited players to join.
docker run -d -e WHITELIST=user1,user2 ...
To whitelist players for your Minecraft server, you can:
- Provide the url or path to a whitelist file via `WHITELIST_FILE` environment variable
`docker run -d -e WHITELIST_FILE=/extra/whitelist.json ...`
- Provide a list of usernames and/or UUIDs separated by commas via the `WHITELIST` environment variable
`docker run -d -e WHITELIST=user1,uuid2 ...`
If the `WHITELIST` environment variable is not used, any user can join your Minecraft server if it's publicly accessible.
To enforce the whitelist and auto-kick players not included in whitelist configuration, set `ENFORCE_WHITELIST=TRUE`. **By default** any user can join your Minecraft server if it's publicly accessible, regardless of your whitelist configuration.
> NOTE: When `WHITELIST` is used the server properties `white-list` and `whitelist` will automatically get set to `true`.
If whitelist configuration already exists, `WHITELIST_FILE` will not be retrieved and any usernames in `WHITELIST` are **added** to the whitelist configuration. You can enforce regeneration of the whitelist on each server startup by setting `OVERRIDE_WHITELIST` to "true". This will delete the whitelist file before processing whitelist configuration.
> By default, the players in `WHITELIST` are **added** to the final `whitelist.json` file by the Minecraft server. If you set `OVERRIDE_WHITELIST` to "true" then the `whitelist.json` file will be recreated on each server startup.
> NOTE: You can provide both `WHITELIST_FILE` and `WHITELIST`, which are processed in that order.
> NOTE: UUIDs passed via `WHITELIST` need to be the dashed variant, otherwise it not be recognised and instead added as a username.
> If running Minecraft 1.7.5 or earlier, these variables will apply to `white-list.txt`, with 1.7.6 implementing support for `whitelist.json`. Make sure your `WHITELIST_FILE` is in the appropriate format.
If either `WHITELIST_FILE` or `WHITELIST` is provided, the server property `white-list` is automatically set to `true`, enabline whitelist functionality. Alternatively you can set `ENABLE_WHITELIST=TRUE` to only set the server property `white-list` without modifying the whitelist file. In this case the whitelist can be managed using the `whitelist add` and `whitelist remove` commands. Remember you can set enforcement via the `ENFORCE_WHITELIST` variable.
Alternatively, you can set `ENABLE_WHITELIST=true` to only set the server properties `white-list` and `whitelist` without modifying the whitelist file. In this case the whitelist is solely managed using the `whitelist add` and `whitelist remove` commands.
### Op/Administrator Players
To add more "op" (aka adminstrator) users to your Minecraft server, pass the Minecraft usernames separated by commas via the `OPS` environment variable, such as
Similar to the whitelist, to add users as operators (aka adminstrators) to your Minecraft server, you can:
- Provide te url or path to an ops file via `OPS_FILE` environment variable
`docker run -d -e OPS_FILE=https://config.example.com/extra/ops.json ...`
- Provide a list of usernames and/or UUIDs separated by commas via the `OPS` environment variable
`docker run -d -e OPS=user1,uuid2 ...`
docker run -d -e OPS=user1,user2 ...
If ops configuration already exists, `OPS_FILE` will not be retrieved and any usernames in `OPS` are **added** to the ops configuration. You can enforce regeneration of the ops configuration on each server startup by setting `OVERRIDE_OPS` to "true". This will delete the ops file before processing ops configuration.
> By default, the players in `OPS` are **added** to the final `ops.json` file by the Minecraft server. If you set `OVERRIDE_OPS` to "true" then the `ops.json` file will be recreated on each server startup.
> Similar to whitelists, you can provide both `OPS_FILE` and `OPS`, and Minecraft 1.7.5 or earlier will use `ops.txt` rather than `ops.json`.
### Server icon
@@ -815,7 +889,8 @@ The server icon which has been set doesn't get overridden by default. It can be
### Rcon
To use rcon use the `ENABLE_RCON` and `RCON_PASSORD` variables.
To use rcon use the `ENABLE_RCON` and `RCON_PASSWORD` variables.
The default RCON password is _"minecraft",_ but it's **highly** recommended to override that.
By default rcon port will be `25575` but can easily be changed with the `RCON_PORT` variable.
docker run -d -e ENABLE_RCON=true -e RCON_PASSWORD=testing
@@ -958,18 +1033,6 @@ For example:
docker run -d -e MODE=creative ...
### Message of the Day
The message of the day, shown below each server entry in the UI, can be changed with the `MOTD` environment variable, such as
-e MOTD="My Server"
If you leave it off, a default is computed from the server type and version, such as
A Paper Minecraft Server powered by Docker
That way you can easily differentiate between several servers you may have started.
### PVP Mode
By default, servers are created with player-vs-player (PVP) mode enabled. You can disable this with the `PVP`
@@ -1001,13 +1064,17 @@ For example (just the `-e` bits):
-e LEVEL_TYPE=flat -e 'GENERATOR_SETTINGS=3;minecraft:bedrock,3*minecraft:stone,52*minecraft:sandstone;2;'
In Minecraft 1.13+ you need to pass json ([generator site](https://misode.github.io/world/)) like this (details see [here](https://github.com/itzg/docker-minecraft-server/issues/999#issuecomment-907849644)):
-e LEVEL_TYPE=flat -e 'GENERATOR_SETTINGS={"biome":"minecraft:the_void","layers":[{"block":"minecraft:bedrock","height":1},{"block":"minecraft:stone","height":10},{"block":"minecraft:dirt","height":1}],"structures":{"structures":{}}}'
### Custom Server Resource Pack
You can set a link to a custom resource pack and set it's checksum using the `RESOURCE_PACK` and `RESOURCE_PACK_SHA1` options respectively, the default is blank:
docker run -d -e 'RESOURCE_PACK=http\://link.com/to/pack.zip?\=1' -e 'RESOURCE_PACK_SHA1=d5db29cd03a2ed055086cef9c31c252b4587d6d0'
docker run -d -e 'RESOURCE_PACK=http://link.com/to/pack.zip?=1' -e 'RESOURCE_PACK_SHA1=d5db29cd03a2ed055086cef9c31c252b4587d6d0'
**NOTE:** `:` and `=` must be escaped using `\`. The checksum plain-text hexadecimal.
You can enforce the resource pack on clients by setting `RESOURCE_PACK_ENFORCE` to `TRUE` (default: `FALSE`).
### Level / World Save Name
@@ -1033,6 +1100,22 @@ Allows users to use flight on your server while in Survival mode, if they have a
-e ALLOW_FLIGHT=TRUE|FALSE
### Server name
The server name (e.g. for bungeecord) can be set like:
docker run -d -e SERVER_NAME=MyServer ...
### Server port
> **WARNING:** only change this value if you know what you're doing. It is only needed when using host networking and it is rare that host networking should be used. Use `-p` port mappings instead.
If you must, the server port can be set like:
docker run -d -e SERVER_PORT=25566 ...
**however**, be sure to change your port mapping accordingly and be prepared for some features to break.
### Other server property mappings
| Environment Variable | Server Property |
@@ -1051,6 +1134,7 @@ Allows users to use flight on your server while in Survival mode, if they have a
| USE_NATIVE_TRANSPORT | use-native-transport |
| ENFORCE_WHITELIST | enforce-whitelist |
| ENABLE_WHITELIST | white-list and whitelist |
| SIMULATION_DISTANCE | simulation-distance |
## Miscellaneous Options
@@ -1065,24 +1149,13 @@ in your config files after the container starts.
For those cases there is the option to replace defined variables inside your configs
with environment variables defined at container runtime.
If you set the enviroment variable `REPLACE_ENV_VARIABLES` to `TRUE` the startup script
will go thru all files inside your `/data` volume and replace variables that match your
defined environment variables. Variables that you want to replace need to be wrapped
inside `${YOUR_VARIABLE}` curly brackets and prefixed with a dollar sign. This is the regular
syntax for enviromment variables inside strings or config files.
When the environment variable `REPLACE_ENV_IN_PLACE` is set to `true` (the default), the startup script will go through all files inside the container's `/data` path and replace variables that match the container's environment variables. Variables can instead (or in addition to) be replaced in files sync'ed from `/plugins`, `/mods`, and `/config` by setting `REPLACE_ENV_DURING_SYNC` to `true` (defaults to `false`).
Optionally you can also define a prefix to only match predefined environment variables.
Variables that you want to replace need to be declared inside curly brackets and prefixed with a dollar sign, such as `${CFG_YOUR_VARIABLE}`, which is same as many scripting languages.
`ENV_VARIABLE_PREFIX="CFG_"` <-- this is the default prefix
You can also change `REPLACE_ENV_VARIABLE_PREFIX`, which defaults to "CFG_", to limit which environment variables are allowed to be used. For example, with "CFG_" as the prefix, the variable `${CFG_DB_HOST}` would be subsituted, but not `${DB_HOST}`.
If you want use file for value (like when use secrets) you can add suffix `_FILE` to your variable name (in run command).
There are some limitations to what characters you can use.
| Type | Allowed Characters |
| ----- | ------------------- |
| Name | `0-9a-zA-Z_-` |
| Value | `0-9a-zA-Z_-:/=?.+` |
If you want to use a file for value (like when use secrets) you can add suffix `_FILE` to your variable name.
Variables will be replaced in files with the following extensions:
`.yml`, `.yaml`, `.txt`, `.cfg`, `.conf`, `.properties`.
@@ -1132,14 +1205,6 @@ services:
CFG_DB_HOST: "http://localhost:3306"
CFG_DB_NAME: "minecraft"
CFG_DB_PASSWORD_FILE: "/run/secrets/db_password"
restart: always
rcon:
image: itzg/rcon
ports:
- "4326:4326"
- "4327:4327"
volumes:
- "rcon:/opt/rcon-web-admin/db"
volumes:
mc:
@@ -1150,9 +1215,47 @@ secrets:
file: ./db_password
```
The content of `db_password`:
### Patching existing files
ug23u3bg39o-ogADSs
JSON path based patches can be applied to one or more existing files by setting the variable `PATCH_DEFINITIONS` to the path of a directory that contains one or more [patch definition json files](https://github.com/itzg/mc-image-helper#patchdefinition) or a [patch set json file](https://github.com/itzg/mc-image-helper#patchset).
Variable placeholders in the patch values can be restricted by setting `REPLACE_ENV_VARIABLE_PREFIX`, which defaults to "CFG_".
The following example shows a patch-set file were various fields in the `paper.yaml` configuration file can be modified and added:
```json
{
"patches": [
{
"file": "/data/paper.yml",
"ops": [
{
"$set": {
"path": "$.verbose",
"value": true
}
},
{
"$set": {
"path": "$.settings['velocity-support'].enabled",
"value": "${CFG_VELOCITY_ENABLED}",
"value-type": "bool"
}
},
{
"$put": {
"path": "$.settings",
"key": "my-test-setting",
"value": "testing"
}
}
]
}
]
}
```
> **NOTES:** Only JSON and Yaml files can be patched at this time. TOML support is planned to be added next. Removal of comments and other cosmetic changes will occur when patched files are processed.
### Running with a custom server JAR
@@ -1200,13 +1303,16 @@ The values of all three are passed directly to the JVM and support format/units
-e MEMORY=2G
> NOTE: the settings above only set the Java **heap** limits. Memory resource requests and limits on the overall container should also account for non-heap memory usage. An extra 25% is [a general best practice](https://dzone.com/articles/best-practices-java-memory-arguments-for-container).
To let the JVM calculate the heap size from the container declared memory limit, unset `MEMORY` with an empty value, such as `-e MEMORY=""`. By default, the JVM will use 25% of the container memory limit as the heap limit; however, as an example the following would tell the JVM to use 75% of the container limit of 2GB of memory:
-e MEMORY="" -e JVM_XX_OPTS="-XX:MaxRAMPercentage=75" -m 2000M
> The settings above only set the Java **heap** limits. Memory resource requests and limits on the overall container should also account for non-heap memory usage. An extra 25% is [a general best practice](https://dzone.com/articles/best-practices-java-memory-arguments-for-container).
### JVM Options
General JVM options can be passed to the Minecraft Server invocation by passing a `JVM_OPTS`
environment variable. Options like `-X` that need to proceed general JVM options can be passed
via a `JVM_XX_OPTS` environment variable.
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.
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`.
@@ -1226,6 +1332,14 @@ If you would like to `docker attach` to the Minecraft server console with color
> This will bypass graceful server shutdown handling when using `docker stop`, so be sure the server console's `stop` command.
>
> Make to enable stdin and tty with `-it` when using `docker run` or `stdin_open: true` and `tty: true` when using docker compose.
>
> This feature is incompatible with Autopause and cannot be set when `ENABLE_AUTOPAUSE=true`.
### Server Shutdown Options
To allow time for players to finish what they're doing during a graceful server shutdown, set `STOP_SERVER_ANNOUNCE_DELAY` to a number of seconds to delay after an announcement is posted by the server.
> **NOTE** be sure to adjust Docker's shutdown timeout accordingly, such as using [the -t option on docker-compose down](https://docs.docker.com/compose/reference/down/).
### OpenJ9 Specific Options
@@ -1246,7 +1360,7 @@ By default the vanilla log file will grow without limit. The logger can be recon
> **NOTE** this will interfere with interactive/color consoles [as described in the section above](#interactive-and-color-console)
## Timezone Configuration
### Timezone Configuration
You can configure the timezone to match yours by setting the `TZ` environment variable:
@@ -1274,7 +1388,7 @@ To enable remote JMX, such as for profiling with VisualVM or JMC, add the enviro
### Enable Aikar's Flags
[Aikar has does some research](https://mcflags.emc.gs/) into finding the optimal JVM flags for GC tuning, which becomes more important as more users are connected concurrently. The set of flags documented there can be added using
[Aikar has does some research](https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/) into finding the optimal JVM flags for GC tuning, which becomes more important as more users are connected concurrently. The set of flags documented there can be added using
-e USE_AIKAR_FLAGS=true
@@ -1305,6 +1419,10 @@ disable that by passing `-e GUI=FALSE`.
When the container is signalled to stop, the Minecraft process wrapper will attempt to send a "stop" command via RCON or console and waits for the process to gracefully finish. By default it waits 60 seconds, but that duration can be configured by setting the environment variable `STOP_DURATION` to the number of seconds.
### Setup only
If you are using a host-attached data directory, then you can have the image setup the Minecraft server files and stop prior to launching the server process by setting `SETUP_ONLY` to `true`.
## Autopause
### Description
@@ -1333,6 +1451,8 @@ Enable the Autopause functionality by setting:
-e ENABLE_AUTOPAUSE=TRUE
```
Autopause is not compatible with `EXEC_DIRECTLY=true` and the two cannot be set together.
The following environment variables define the behaviour of auto-pausing:
* `AUTOPAUSE_TIMEOUT_EST`, default `3600` (seconds)
describes the time between the last client disconnect and the pausing of the process (read as timeout established)
@@ -1352,3 +1472,7 @@ To run this image on a RaspberryPi 3 B+, 4, or newer, use any of the image tags
> NOTE: you may need to lower the memory allocation, such as `-e MEMORY=750m`
> If experiencing issues such as "sleep: cannot read realtime clock: Operation not permitted", ensure `libseccomp` is up to date on your host. In some cases adding `:Z` flag to the `/data` mount may be needed, [but use cautiously](https://docs.docker.com/storage/bind-mounts/#configure-the-selinux-label).
## Contributing
See [Development](DEVELOPMENT.md) and [Building](BUILDING.md).

8
health.sh → bin/mc-health Normal file → Executable file
View File

@@ -1,6 +1,10 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
# shellcheck source=../scripts/start-utils
. "${SCRIPTS:-/}start-utils"
if [ -f /data/.mc-health.env ]; then
. /data/.mc-health.env
fi
if isTrue "${DISABLE_HEALTHCHECK}"; then
echo "Healthcheck disabled"
@@ -9,6 +13,6 @@ elif isTrue "${ENABLE_AUTOPAUSE}" && [[ "$( ps -ax -o stat,comm | grep 'java' |
echo "Java process suspended by Autopause function"
exit 0
else
mc-monitor status --host localhost --port $SERVER_PORT
mc-monitor status "${MC_HEALTH_EXTRA_ARGS[@]}" --host localhost --port "${SERVER_PORT:-25565}"
exit $?
fi

15
bin/mc-send-to-console Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
: "${CONSOLE_IN_NAMED_PIPE:=/tmp/minecraft-console-in}"
if [ $# = 0 ]; then
echo "ERROR: pass console commands as arguments"
exit 1
fi
if [ ! -p "${CONSOLE_IN_NAMED_PIPE}" ]; then
echo "ERROR: named pipe ${CONSOLE_IN_NAMED_PIPE} is missing"
exit 1
fi
echo "$@" > "${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}"

View File

@@ -7,9 +7,8 @@ branches_list=(
'java8-openj9'
'java11'
'java11-openj9'
'java16'
'java16-openj9'
'multiarch-latest'
'java17'
)
function TrapExit {
@@ -131,3 +130,28 @@ EOL
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 ! echo 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

BIN
docs/motd-example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 985 B

1
examples/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/data/

View File

@@ -12,7 +12,10 @@ services:
ENABLE_AUTOPAUSE: "TRUE"
OVERRIDE_SERVER_PROPERTIES: "TRUE"
MAX_TICK_TIME: "-1"
restart: always
# More aggressive settings for demo purposes
AUTOPAUSE_TIMEOUT_INIT: "30"
AUTOPAUSE_TIMEOUT_EST: "10"
restart: unless-stopped
volumes:
mc: {}

View File

@@ -2,12 +2,18 @@ version: '3.8'
services:
mc:
image: itzg/minecraft-server:java8
image: itzg/minecraft-server:${IMAGE_TAG:-java8}
volumes:
- ./modpacks:/modpacks:ro
- data:/data
environment:
EULA: "true"
TYPE: CURSEFORGE
CF_SERVER_MOD: /modpacks/SkyFactory_4_Server_4.1.0.zip
CF_SERVER_MOD: https://media.forgecdn.net/files/3482/169/Valhelsia+3-3.4.4-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:
- 25565:25565
- "25565:25565"
volumes:
data: {}

View File

@@ -2,15 +2,16 @@ version: "3.8"
services:
mc:
image: itzg/minecraft-server:java8
image: itzg/minecraft-server
ports:
# expose the Minecraft server port outside of container
- 25565:25565
- "25565:25565"
environment:
# REQUIRED for all types
EULA: "TRUE"
# Set server type (vs the default of vanilla)
TYPE: FORGE
DEBUG: "true"
volumes:
# use a named, managed volume for data volume
- mc_forge:/data

View File

@@ -3,7 +3,7 @@ version: "3.8"
services:
mc:
# FTBA support is only available in non-Alpine images
image: itzg/minecraft-server:java8-multiarch
image: itzg/minecraft-server:${IMAGE_TAG:-java8-multiarch}
ports:
# expose the Minecraft server port outside of container
- 25565:25565
@@ -14,10 +14,11 @@ services:
TYPE: FTBA
# Use Pack ID from https://ftb.neptunepowered.org/pack/ftb-presents-direwolf20-1-12/
FTB_MODPACK_ID: "31"
FTB_MODPACK_VERSION_ID: ""
volumes:
# use a named, managed volume for data volume
- mc_ftb:/data
- ftba:/data
volumes:
# declared the named volume, but use default/local storage engine
mc_ftb: {}
ftba: {}

View File

@@ -0,0 +1,20 @@
version: '3.8'
services:
mc:
image: itzg/minecraft-server:${IMAGE_TAG:-latest}
volumes:
- data:/data
- ./modpacks:/modpacks:ro
environment:
EULA: "true"
TYPE: FORGE
DEBUG: "${DEBUG:-false}"
VERSION: ${VERSION:-1.17.1}
FORGEVERSION: ${FORGEVERSION:-37.0.90}
GENERIC_PACK: /modpacks/${MODPACK:-Server-Files-0.0.21.zip}
ports:
- "25565:25565"
volumes:
data: {}

View File

@@ -0,0 +1,19 @@
version: '3.8'
services:
mc:
image: itzg/minecraft-server
environment:
EULA: "true"
TYPE: FORGE
VERSION: 1.15.2
MODS_FILE: /extras/mods.txt
REMOVE_OLD_MODS: "true"
ports:
- 25565:25565
volumes:
- data:/data
- ./mods.txt:/extras/mods.txt:ro
volumes:
data:

View File

@@ -0,0 +1,17 @@
version: "3.8"
services:
mc:
image: itzg/minecraft-server
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: MOHIST
VERSION: 1.12.2
DEBUG: "true"
volumes:
- data:/data
volumes:
data: {}

View File

@@ -0,0 +1,27 @@
version: '3.8'
services:
rlcraft:
image: itzg/minecraft-server:java8
container_name: rlcraft
volumes:
- rlcraft-modpack:/modpacks:ro
- rlcraft-data:/data
environment:
EULA: "true"
TYPE: "FORGE"
VERSION: "1.12.2"
FORGEVERSION: "14.23.5.2855"
DIFFICULTY: "hard"
MAX_TICK_TIME: "-1"
VIEW_DISTANCE: "6"
ALLOW_FLIGHT: "true"
MEMORY: "4G"
GENERIC_PACK: "/modpacks/RLCraft_Server_Pack_1.12.2_Beta_v2.8.2.zip"
ports:
- 25565:25565
restart: unless-stopped
volumes:
rlcraft-data:
rlcraft-modpack:

View File

@@ -3,18 +3,18 @@ apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: example
name: example
app: mc-example
name: mc-example
spec:
replicas: 1
serviceName: example
serviceName: mc-example
selector:
matchLabels:
app: example
app: mc-example
template:
metadata:
labels:
app: example
app: mc-example
spec:
containers:
- name: mc
@@ -25,6 +25,18 @@ spec:
volumeMounts:
- mountPath: /data
name: data
readinessProbe:
exec:
command:
- mc-monitor
- status
- --host
- localhost
- --port
- "25565"
initialDelaySeconds: 30
periodSeconds: 5
failureThreshold: 18
volumeClaimTemplates:
- metadata:
name: data
@@ -39,12 +51,12 @@ apiVersion: v1
kind: Service
metadata:
labels:
service: example
name: example
service: mc-example
name: mc-example
spec:
ports:
- port: 25565
targetPort: 25565
selector:
app: example
type: LoadBalancer
app: mc-example
type: NodePort

80
examples/mods.txt Normal file
View File

@@ -0,0 +1,80 @@
https://edge.forgecdn.net/files/2965/233/Bookshelf-1.15.2-5.6.40.jar
https://edge.forgecdn.net/files/2926/27/ProgressiveBosses-2.1.5-mc1.15.2.jar
https://edge.forgecdn.net/files/3248/905/goblintraders-1.3.1-1.15.2.jar
https://edge.forgecdn.net/files/3272/32/jei-1.15.2-6.0.3.16.jar
https://edge.forgecdn.net/files/2871/647/ToastControl-1.15.2-3.0.1.jar
https://edge.forgecdn.net/files/3101/903/Druidcraft-1.15-0.4.45.jar
https://edge.forgecdn.net/files/2880/426/DefaultOptions_1.15.2-11.0.1.jar
https://edge.forgecdn.net/files/2996/535/MekanismAdditions-1.15.2-9.10.9.422.jar
https://edge.forgecdn.net/files/3147/275/blockcarpentry-1.15-0.8.2.jar
https://edge.forgecdn.net/files/3005/715/refinedstorageaddons-0.6.3.jar
https://edge.forgecdn.net/files/3140/146/rftoolsbase-1.15-1.1.10.jar
https://edge.forgecdn.net/files/3236/649/cc-tweaked-1.15.2-1.95.3.jar
https://edge.forgecdn.net/files/3048/970/light-overlay-4.7.2.jar
https://edge.forgecdn.net/files/3015/904/randompatches-1.15.2-1.22.1.1.jar
https://edge.forgecdn.net/files/3131/439/engineersdecor-1.15.2-1.1.4.jar
https://edge.forgecdn.net/files/3051/255/carryon-1.15.2-1.13.0.5.jar
https://edge.forgecdn.net/files/3175/752/EnderStorage-1.15.2-2.5.2.164-universal.jar
https://edge.forgecdn.net/files/2997/84/Savage-and-Ravage-1.15.2-1.1.4.jar
https://edge.forgecdn.net/files/3053/840/PackMenu-1.15.2-1.2.8.jar
https://edge.forgecdn.net/files/3003/397/JEITweaker-1.15.2-1.0.1.3.jar
https://edge.forgecdn.net/files/3069/489/absentbydesign-1.15.2-1.1.1.jar
https://edge.forgecdn.net/files/2997/601/Upgrade-Aquatic-1.15.2-1.7.1.jar
https://edge.forgecdn.net/files/2950/766/ReAuth-1.14-1.15-3.8.1.jar
https://edge.forgecdn.net/files/3024/179/Powah-1.15.2-1.1.15.jar
https://edge.forgecdn.net/files/3092/975/StorageDrawers-1.15.2-7.0.3.jar
https://edge.forgecdn.net/files/2853/267/furniture-7.0.0-pre16-1.15.1.jar
https://edge.forgecdn.net/files/2987/251/AppleSkin-mc1.15.2-forge-1.0.14.jar
https://edge.forgecdn.net/files/2980/323/industrial-foregoing-1.15.2-2.3.3-e356e61.jar
https://edge.forgecdn.net/files/3024/178/Lollipop-1.15.2-1.0.16.jar
https://edge.forgecdn.net/files/3210/106/tablechair-1.4.jar
https://edge.forgecdn.net/files/3047/358/xercapaint-1.15.2-3.3.jar
https://edge.forgecdn.net/files/2873/657/BonsaiTrees-2.1.2.6.jar
https://edge.forgecdn.net/files/2938/583/config-2-3.0.jar
https://edge.forgecdn.net/files/2991/235/Waystones_1.15.2-6.0.2.jar
https://edge.forgecdn.net/files/2957/23/OpenLoader-1.15.2-4.0.5.jar
https://edge.forgecdn.net/files/3275/718/XaerosWorldMap_1.13.2_Forge_1.15.2.jar
https://edge.forgecdn.net/files/2876/104/AI-Improvements-1.15.2-0.3.0.jar
https://edge.forgecdn.net/files/3005/515/mysticallib-1.15.2-2.0.1.jar
https://edge.forgecdn.net/files/3008/867/WAWLA-1.15.2-3.0.4.jar
https://edge.forgecdn.net/files/2964/474/WailaHarvestability-mc1.15.2-1.1.12.jar
https://edge.forgecdn.net/files/3103/508/Kiwi-1.15.2-2.8.5.jar
https://edge.forgecdn.net/files/3128/662/Atum-1.15.2-2.1.12.jar
https://edge.forgecdn.net/files/2988/910/Buzzier-Bees-1.15.2-1.5.2.jar
https://edge.forgecdn.net/files/3030/627/u_team_core-1.15.2-3.0.2.169.jar
https://edge.forgecdn.net/files/3003/984/SilentLib-1.15.2-4.6.6+59.jar
https://edge.forgecdn.net/files/2968/353/refinedpipes-0.4.2.jar
https://edge.forgecdn.net/files/3140/149/rftoolsbuilder-1.15-2.1.16.jar
https://edge.forgecdn.net/files/3067/203/mightyarchitect-mc1.15.2_v0.5.jar
https://edge.forgecdn.net/files/2980/153/EquipmentTooltips-1.15.2-1.4.3+14.jar
https://edge.forgecdn.net/files/3103/510/FruitTrees-1.15.2-1.7.0.jar
https://edge.forgecdn.net/files/2989/38/Atmospheric-1.15.2-1.4.1.jar
https://edge.forgecdn.net/files/3096/836/rftoolscontrol-1.15-3.0.9.jar
https://edge.forgecdn.net/files/2989/662/Enhanced-Mushrooms-1.15.2-v1.2.2.jar
https://edge.forgecdn.net/files/3227/891/SimpleStorageNetwork-1.15.2-1.0.2.jar
https://edge.forgecdn.net/files/3217/290/minecolonies-0.13.645-RELEASE-universal.jar
https://edge.forgecdn.net/files/2935/384/SnowRealMagic-1.15.2-1.7.5.jar
https://edge.forgecdn.net/files/2988/584/aiotbotania-1.15.2-1.2.3.jar
https://edge.forgecdn.net/files/3255/408/mowziesmobs-1.5.15.jar
https://edge.forgecdn.net/files/3062/510/HealthOverlay-1.15.2-1.0.2.jar
https://edge.forgecdn.net/files/3023/121/neoncraft-1.1.jar
https://edge.forgecdn.net/files/2997/617/Swamp-Expansion-1.15.2-1.7.3.jar
https://edge.forgecdn.net/files/2980/252/titanium-1.15.2-2.4.2.jar
https://edge.forgecdn.net/files/3152/946/rftoolsutility-1.15-2.1.20.jar
https://edge.forgecdn.net/files/3083/277/swingthroughgrass-1.15.2-1.4.1.jar
https://edge.forgecdn.net/files/3138/530/SilentGear-1.15.2-1.11.4+187.jar
https://edge.forgecdn.net/files/3105/429/DarkUtilities-1.15.2-3.1.9.jar
https://edge.forgecdn.net/files/3099/23/ImmersiveEngineering-1.15.2-4.1.1-125.jar
https://edge.forgecdn.net/files/2856/529/FastFurnace-1.15.1-3.0.0.jar
https://edge.forgecdn.net/files/2988/999/BiomesOPlenty-1.15.2-10.0.0.366-universal.jar
https://edge.forgecdn.net/files/2989/95/The-Endergetic-Expansion-1.15.2-v1.3.2.jar
https://edge.forgecdn.net/files/2993/960/FluxNetworks-1.15.2-5.0.3-4.jar
https://edge.forgecdn.net/files/3028/611/ServerTabInfo-1.15.2-1.2.8.jar
https://edge.forgecdn.net/files/3134/277/fairylights-3.0.15-1.15.2.jar
https://edge.forgecdn.net/files/3048/54/useful_backpacks-1.15.2-1.10.3.77.jar
https://edge.forgecdn.net/files/3273/515/mcw-trapdoors-1.0.2-mc1.15.2.jar
https://edge.forgecdn.net/files/2986/639/CraftingTweaks_1.15.2-11.0.1.jar
https://edge.forgecdn.net/files/3261/454/create-mc1.15.2_v0.3.1a.jar
https://edge.forgecdn.net/files/3211/10/supermartijn642configlib-1.0.5-mc1.15.jar
https://edge.forgecdn.net/files/2995/786/TerraForged-1.15.2-0.0.15.jar
https://edge.forgecdn.net/files/2892/562/leavesdecayonotherleaves-1.1.jar

0
files/autopause/autopause-daemon.sh Normal file → Executable file
View File

25
files/autopause/autopause-fcns.sh Normal file → Executable file
View File

@@ -1,7 +1,7 @@
#!/bin/bash
current_uptime() {
echo $(awk '{print $1}' /proc/uptime | cut -d . -f 1)
awk '{print $1}' /proc/uptime | cut -d . -f 1
}
java_running() {
@@ -17,26 +17,15 @@ rcon_client_exists() {
}
mc_server_listening() {
[[ -n $(netstat -tln | grep -e "0.0.0.0:$SERVER_PORT" -e ":::$SERVER_PORT" | grep LISTEN) ]]
mc-monitor status --host localhost --port "$SERVER_PORT" --timeout 10s >& /dev/null
}
java_clients_connected() {
local connections
connections=$(netstat -tn | grep ":$SERVER_PORT" | grep ESTABLISHED)
if [[ -z "$connections" ]] ; then
return 1
if java_running ; then
connections=$(mc-monitor status --host localhost --port "$SERVER_PORT" --show-player-count)
else
connections=0
fi
IFS=$'\n'
connections=($connections)
unset IFS
# check that at least one external address is not localhost
# remember, that the host network mode does not work with autopause because of the knockd utility
for (( i=0; i<${#connections[@]}; i++ ))
do
if [[ ! $(echo "${connections[$i]}" | awk '{print $5}') =~ ^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$ ]] ; then
# not localhost
return 0
fi
done
return 1
(( connections > 0 ))
}

View File

@@ -10,3 +10,6 @@
seq_timeout = 1
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
tcpflags = syn
[unpauseMCServer-bedrock]
sequence = 19132:udp
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh

View File

@@ -4,7 +4,7 @@
<Console name="SysOut" target="SYSTEM_OUT">
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
</Console>
<Queue name="ServerGuiConsole">
<Queue name="TerminalConsole">
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n" />
</Queue>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
@@ -28,7 +28,7 @@
</filters>
<AppenderRef ref="SysOut"/>
<AppenderRef ref="File"/>
<AppenderRef ref="ServerGuiConsole"/>
<AppenderRef ref="TerminalConsole"/>
</Root>
</Loggers>
</Configuration>

View File

@@ -1,4 +0,0 @@
# Moved to top-level
The contents of this directory have now been moved to the top level of
[itzg/docker-minecraft-server](https://github.com/itzg/docker-minecraft-server).

0
start → scripts/start Normal file → Executable file
View File

View File

@@ -1,9 +1,15 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
: "${SERVER_PORT:=25565}"
export SERVER_PORT
log "Autopause functionality enabled"
isDebugging && set -x
cp /autopause/knockd-config.cfg /tmp/knockd-config.cfg
# update server port to listen to

71
start-configuration → scripts/start-configuration Normal file → Executable file
View File

@@ -2,14 +2,17 @@
set -euo pipefail
IFS=$'\n\t'
# shellcheck source=start-utils
. ${SCRIPTS:-/}start-utils
: ${EULA:=}
: ${PROXY:=}
: ${RCON_PASSWORD_FILE:=}
: "${EULA:=}"
: "${PROXY:=}"
: "${RCON_PASSWORD_FILE:=}"
shopt -s nullglob
isDebugging && set -x
#umask 002
export HOME=/data
@@ -29,6 +32,10 @@ if [ ! -e /data/eula.txt ]; then
writeEula
fi
if isTrue "${ENABLE_AUTOPAUSE}" && isTrue "${EXEC_DIRECTLY:-false}"; then
log "EXEC_DIRECTLY=true is incompatible with ENABLE_AUTOPAUSE=true"
exit 1
fi
if [[ $PROXY ]]; then
export http_proxy="$PROXY"
@@ -63,10 +70,16 @@ export VERSIONS_JSON=https://launchermeta.mojang.com/mc/game/version_manifest.js
case "X$VERSION" in
X|XLATEST|Xlatest)
VANILLA_VERSION=$(curl -fsSL $VERSIONS_JSON | jq -r '.latest.release')
if ! VANILLA_VERSION=$(get --json-path '$.latest.release' "$VERSIONS_JSON"); then
log "ERROR: version lookup failed: $VANILLA_VERSION"
exit 1
fi
;;
XSNAPSHOT|Xsnapshot)
VANILLA_VERSION=$(curl -fsSL $VERSIONS_JSON | jq -r '.latest.snapshot')
if ! VANILLA_VERSION=$(get --json-path '$.latest.snapshot' "$VERSIONS_JSON"); then
log "ERROR: version lookup failed: $VANILLA_VERSION"
exit 1
fi
;;
*)
VANILLA_VERSION=$VERSION
@@ -83,6 +96,14 @@ if isTrue "${ENABLE_AUTOPAUSE}"; then
${SCRIPTS:-/}start-autopause
fi
if versionLessThan 1.7; then
echo "
MC_HEALTH_EXTRA_ARGS=(
--use-server-list-ping
)
" > /data/.mc-health.env
fi
log "Resolving type given ${TYPE}"
case "${TYPE^^}" in
*BUKKIT|SPIGOT)
@@ -93,17 +114,15 @@ case "${TYPE^^}" in
exec ${SCRIPTS:-/}start-deployPaper "$@"
;;
TUINITY)
exec ${SCRIPTS:-/}start-deployTuinity "$@"
;;
FORGE)
if versionLessThan 1.17; then
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 "**********************************************************************"
fi
exec ${SCRIPTS:-/}start-deployForge "$@"
;;
@@ -117,16 +136,14 @@ case "${TYPE^^}" in
FTB|CURSEFORGE)
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 "NOTE: Some mods and modpacks may require Java 8."
log " If so, use itzg/minecraft-server:java8"
log "**********************************************************************"
exec ${SCRIPTS:-/}start-deployCF "$@"
;;
VANILLA)
exec ${SCRIPTS:-/}start-deployVanilla "$@"
exec "${SCRIPTS:-/}start-deployVanilla" "$@"
;;
SPONGEVANILLA)
@@ -137,10 +154,6 @@ case "${TYPE^^}" in
exec ${SCRIPTS:-/}start-deployCustom "$@"
;;
CURSE_INSTANCE)
exec ${SCRIPTS:-/}start-validateCurseInstance "$@"
;;
MAGMA)
exec ${SCRIPTS:-/}start-deployMagma "$@"
;;
@@ -157,10 +170,6 @@ case "${TYPE^^}" in
exec ${SCRIPTS:-/}start-deployPurpur "$@"
;;
YATOPIA)
exec ${SCRIPTS:-/}start-deployYatopia "$@"
;;
AIRPLANE)
exec ${SCRIPTS:-/}start-deployAirplane "$@"
;;
@@ -169,11 +178,25 @@ case "${TYPE^^}" in
exec ${SCRIPTS:-/}start-deployCanyon "$@"
;;
LIMBO)
exec ${SCRIPTS:-/}start-deployLimbo "$@"
;;
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" "$@"
;;
*)
log "Invalid type: '$TYPE'"
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only),"
log " CURSE_INSTANCE, CURSEFORGE, SPONGEVANILLA, TUINITY, PURPUR"
log " CUSTOM, MAGMA, MOHIST, CATSERVER, YATOPIA, AIRPLANE, CANYON"
log " CURSEFORGE, SPONGEVANILLA, PURPUR, CUSTOM,"
log " MAGMA, MOHIST, CATSERVER, AIRPLANE, CANYON, LIMBO, CRUCIBLE"
exit 1
;;

17
start-deployAirplane → scripts/start-deployAirplane Normal file → Executable file
View File

@@ -1,16 +1,18 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
set -euo pipefail
isDebugging && set -x
IFS=$'\n\t'
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.16" ] && [ "${VERSION}" != "1.17" ] && [ "${VERSION}" != "PURPUR" ] && [ "${VERSION}" != "PURPUR-1.16" ] ; then
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=1.17, VERSION=1.16, VERSION=PURPUR or VERSION=PURPUR-1.16. Note that these are branches, not #.#.# versions."
exit 1
fi
: ${AIRPLANE_BUILD:=lastSuccessfulBuild}
: ${AIRPLANE_TYPE:=airplane}
if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.17" ]; then
AIRPLANE_BRANCH="1.17"
@@ -22,18 +24,26 @@ fi
if [ "${VERSION}" = "PURPUR" ]; then
AIRPLANE_BRANCH="Purpur-1.17"
AIRPLANE_TYPE="airplanepurpur"
fi
if [ "${VERSION}" = "PURPUR-1.16" ]; then
AIRPLANE_BRANCH="Purpur-1.16"
AIRPLANE_TYPE="airplanepurpur"
fi
log "Using Airplane-${AIRPLANE_BRANCH} branch"
export SERVER=airplane-${AIRPLANE_BRANCH}-${AIRPLANE_BUILD}.jar
log "Removing old Airplane versions ..."
shopt -s nullglob
for f in airplane-*.jar; do
[[ $f != $SERVER ]] && rm $f
done
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
downloadUrl="https://ci.tivy.ca/job/Airplane-${AIRPLANE_BRANCH}/${AIRPLANE_BUILD}/artifact/launcher-airplane.jar"
downloadUrl="https://ci.tivy.ca/job/Airplane-${AIRPLANE_BRANCH}/${AIRPLANE_BUILD}/artifact/launcher-${AIRPLANE_TYPE}.jar"
log "Downloading Airplane from $downloadUrl ..."
curl -fsSL -o "$SERVER" "$downloadUrl"
if [ ! -f "$SERVER" ]; then
@@ -44,6 +54,7 @@ fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -64,7 +64,7 @@ function downloadSpigot {
fi
if [[ -z $downloadUrl ]]; then
if versionLessThan 1.16.5; then
if versionLessThan 1.16.5 || ([[ ${getbukkitFlavor} = "craftbukkit" ]] && [[ ${VANILLA_VERSION} = "1.16.5" ]]); then
downloadUrl="https://cdn.getbukkit.org/${getbukkitFlavor}/${getbukkitFlavor}-${VANILLA_VERSION}.jar"
else
downloadUrl="https://download.getbukkit.org/${getbukkitFlavor}/${getbukkitFlavor}-${VANILLA_VERSION}.jar"
@@ -127,6 +127,7 @@ fi
# Normalize on Spigot for operations below
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

89
start-deployCF → scripts/start-deployCF Normal file → Executable file
View File

@@ -2,7 +2,8 @@
set -e
. ${SCRIPTS:-/}start-utils
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
loadForgeVars() {
cfgFile=${1?}
@@ -23,7 +24,7 @@ loadForgeVars() {
isDebugging && set -x
: ${FTB_BASE_DIR:=${CF_BASE_DIR:-/data/FeedTheBeast}}
: "${FTB_BASE_DIR:=${CF_BASE_DIR:-/data/FeedTheBeast}}"
export FTB_BASE_DIR
legacyJavaFixerUrl=https://ftb.forgecdn.net/FTB2/maven/net/minecraftforge/lex/legacyjavafixer/1.0/legacyjavafixer-1.0.jar
@@ -34,7 +35,7 @@ FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD}
log "Looking for Feed-The-Beast / CurseForge server modpack."
requireVar FTB_SERVER_MOD
if ! isTrue ${USE_MODPACK_START_SCRIPT:-true}; then
if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
if ! [ -f "${FTB_SERVER_MOD}" ]; then
log "ERROR unable to find requested modpack file ${FTB_SERVER_MOD}"
exit 2
@@ -46,9 +47,9 @@ if ! isTrue ${USE_MODPACK_START_SCRIPT:-true}; then
if [ "$(cat $installMarker)" != "${FTB_SERVER_MOD}" ]; then
log "Upgrading modpack"
serverJar=$(find ${FTB_BASE_DIR} -not -name "forge*installer.jar" -name "forge*.jar")
serverJar=$(find "${FTB_BASE_DIR}" -not -name "forge*installer.jar" -name "forge*.jar")
if [[ "${serverJar}" ]]; then
rm -rf $(dirname "${serverJar}")/{mods,*.jar,libraries,resources,scripts,config}
rm -rf "$(dirname "${serverJar}")"/{mods,*.jar,libraries,resources,scripts,config}
fi
else
needsInstall=false
@@ -57,10 +58,10 @@ if ! isTrue ${USE_MODPACK_START_SCRIPT:-true}; then
if $needsInstall; then
log "Unpacking FTB server modpack ${FTB_SERVER_MOD} ..."
mkdir -p ${FTB_BASE_DIR}
unzip -o "${FTB_SERVER_MOD}" -d ${FTB_BASE_DIR} | awk '{printf "."} END {print ""}'
mkdir -p "${FTB_BASE_DIR}"
unzip -o "${FTB_SERVER_MOD}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}'
serverJar=$(find ${FTB_BASE_DIR} -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
serverJar=$(find "${FTB_BASE_DIR}" -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
if [[ -z "$serverJar" ]]; then
if [ -f "${FTB_BASE_DIR}/settings.cfg" ]; then
@@ -86,22 +87,24 @@ if ! isTrue ${USE_MODPACK_START_SCRIPT:-true}; then
log "Installing forge server"
dirOfInstaller=$(dirname "${forgeInstallerJar}")
(cd "${dirOfInstaller}"; java -jar $(basename "${forgeInstallerJar}") --installServer)
(cd "${dirOfInstaller}"; java -jar "$(basename "${forgeInstallerJar}")" --installServer)
fi
echo "${FTB_SERVER_MOD}" > $installMarker
fi
export SERVER=$(find ${FTB_BASE_DIR} -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -maxdepth 2 -print)
SERVER=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
if [[ -z "${SERVER}" || ! -f "${SERVER}" ]]; then
log "ERROR unable to locate installed forge server jar"
isDebugging && find ${FTB_BASE_DIR} -name "forge*.jar"
isDebugging && find "${FTB_BASE_DIR}" -name "forge*.jar"
exit 2
fi
export SERVER
export FTB_DIR=$(dirname "${SERVER}")
FTB_DIR=$(dirname "${SERVER}")
export FTB_DIR
exec ${SCRIPTS:-/}start-finalSetupWorld $@
exec "${SCRIPTS:-/}start-setupWorld" "$@"
fi
entryScriptExpr="
@@ -116,8 +119,8 @@ entryScriptExpr="
"
if [[ -d ${FTB_BASE_DIR} ]]; then
startScriptCount=$(find ${FTB_BASE_DIR} $entryScriptExpr |wc -l)
if [[ $startScriptCount > 1 ]]; 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
fi
@@ -131,22 +134,11 @@ fi
if [[ $startScriptCount = 0 ]]; then
srv_modpack=${FTB_SERVER_MOD}
if isURL "${srv_modpack}"; then
case $srv_modpack in
https://www.feed-the-beast.com/*/download|https://www.curseforge.com/minecraft/modpacks/*/download/*/file)
;;
https://www.curseforge.com/minecraft/modpacks/*/download/*)
srv_modpack=${srv_modpack}/file;;
https://www.feed-the-beast.com/*)
srv_modpack=${srv_modpack}/download;;
esac
file=$(basename $(dirname $srv_modpack))
downloaded=/data/${file}.zip
if [ ! -e $downloaded ]; then
log "Downloading FTB modpack...
$srv_modpack -> $downloaded"
curl -sSL -o $downloaded $srv_modpack
fi
srv_modpack=$downloaded
log "Downloading modpack from ${srv_modpack}..."
if ! srv_modpack=$(get -o /data --output-filename --skip-existing "${srv_modpack}"); then
log "ERROR: failed to download modpack"
exit 1
fi
fi
if [[ "${srv_modpack:0:5}" == "data/" ]]; then
# Prepend with "/"
@@ -167,8 +159,8 @@ if [[ $startScriptCount = 0 ]]; then
fi
log "Unpacking FTB server modpack ${srv_modpack} ..."
mkdir -p ${FTB_BASE_DIR}
unzip -o "${srv_modpack}" -d ${FTB_BASE_DIR} | awk '{printf "."} END {print ""}'
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)
if [[ "$installScript" ]]; then
@@ -181,13 +173,14 @@ if [[ $startScriptCount = 0 ]]; then
fi
fi
if [[ $(find ${FTB_BASE_DIR} $entryScriptExpr | wc -l) = 0 ]]; then
if [[ $(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l) = 0 ]]; then
# Allow up to 2 levels since some modpacks have a top-level directory named
# for the modpack
forgeJar=$(find ${FTB_BASE_DIR} -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -maxdepth 2 -print)
forgeJar=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
if [[ "$forgeJar" ]]; then
export FTB_BASE_DIR=$(dirname "${forgeJar}")
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
@@ -205,25 +198,29 @@ 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 "Ambigous startup scripts in FTB modpack!"
log "found:"
find ${FTB_BASE_DIR} $entryScriptExpr
elif (( scriptCount > 1 )); then
log "Ambiguous startup scripts in FTB modpack! Found:"
find "${FTB_BASE_DIR}" $entryScriptExpr
exit 2
fi
export FTB_SERVER_START=$(find "${FTB_BASE_DIR}" $entryScriptExpr)
FTB_SERVER_START=$(find "${FTB_BASE_DIR}" $entryScriptExpr)
export FTB_SERVER_START
export FTB_DIR=$(dirname "${FTB_SERVER_START}")
FTB_DIR=$(dirname "${FTB_SERVER_START}")
export FTB_DIR
chmod a+x "${FTB_SERVER_START}"
grep fml.queryResult=confirm "${FTB_SERVER_START}" > /dev/null || \
sed -i 's/-jar/-Dfml.queryResult=confirm -jar/' "${FTB_SERVER_START}"
sed -i 's/.*read.*Restart now/#\0/' "${FTB_SERVER_START}"
legacyJavaFixerPath="${FTB_DIR}/mods/legacyjavafixer.jar"
if isTrue ${FTB_LEGACYJAVAFIXER} && [ ! -e "${legacyJavaFixerPath}" ]; then
if isTrue "${FTB_LEGACYJAVAFIXER}" && [ ! -e "${legacyJavaFixerPath}" ]; then
log "Installing legacy java fixer to ${legacyJavaFixerPath}"
curl -sSL -o "${legacyJavaFixerPath}" ${legacyJavaFixerUrl}
if ! get -o "${legacyJavaFixerPath}" ${legacyJavaFixerUrl}; then
log "ERROR failed to download legacy java fixer from ${legacyJavaFixerUrl}"
exit 1
fi
fi
if [ -e "${FTB_DIR}/FTBInstall.sh" ]; then
@@ -236,5 +233,5 @@ elif [ -e "${FTB_DIR}/Install.sh" ]; then
popd
fi
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@
export FAMILY=FORGE
exec "${SCRIPTS:-/}start-setupWorld" "$@"

12
start-deployCanyon → scripts/start-deployCanyon Normal file → Executable file
View File

@@ -2,16 +2,11 @@
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
: ${CANYON_BUILD:=lastSuccessfulBuild}
JAVA_VER=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
if [ "${JAVA_VER}" != "8" ]; then
log "ERROR: Canyon server type only supports Java version 8"
exit 1
fi
: "${CANYON_BUILD:=lastSuccessfulBuild}"
if [ "${VERSION}" != "b1.7.3" ]; then
log "ERROR: Canyon server type only supports VERSION=b1.7.3"
@@ -49,6 +44,7 @@ fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -28,5 +28,6 @@ fi
export SKIP_LOG4J_CONFIG=true
export FAMILY=HYBRID
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld "$@"
exec ${SCRIPTS:-/}start-setupWorld "$@"

61
scripts/start-deployCrucible Executable file
View File

@@ -0,0 +1,61 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-$(dirname "$0")}/start-utils"
set -o pipefail
set -e
isDebugging && set -x
requireVar VANILLA_VERSION
: "${CRUCIBLE_RELEASE:=latest}"
crucibleReleasesUrl=https://api.github.com/repos/CrucibleMC/Crucible/releases
if [[ ${CRUCIBLE_RELEASE^^} = LATEST ]]; then
crucibleReleaseUrl=${crucibleReleasesUrl}/latest
else
crucibleReleaseUrl=${crucibleReleasesUrl}/tags/${CRUCIBLE_RELEASE}
fi
if ! downloadUrl=$(get --json-path "$.assets[?(@.name =~ /Crucible-${VANILLA_VERSION}-.*\.jar/)].browser_download_url" \
--accept "application/vnd.github.v3+json" "$crucibleReleaseUrl"); then
log "ERROR: failed to access ${CRUCIBLE_RELEASE} release of Crucible"
exit 1
fi
if [[ $downloadUrl = null ]]; then
log "ERROR: failed to locate Crucible jar for $VANILLA_VERSION from ${CRUCIBLE_RELEASE}"
exit 1
fi
log "Downloading Crucible from $downloadUrl"
if ! SERVER=$(get --skip-existing --output-filename -o /data "$downloadUrl"); then
log "ERROR: failed to download Crucible jar from $downloadUrl"
exit 1
fi
librariesDir=/data/libraries
if [ ! -d "$librariesDir" ]; then
if ! librariesUrl=$(get --json-path "$.assets[?(@.name == 'libraries.zip')].browser_download_url" \
--accept "application/vnd.github.v3+json" "$crucibleReleaseUrl"); then
log "ERROR: failed to access ${CRUCIBLE_RELEASE} release of Crucible for libraries"
exit 1
fi
log "Downloading Crucible libraries"
if ! get -o /tmp/libraries.zip "$librariesUrl"; then
log "ERROR: failed to download Crucible libraries from $librariesUrl"
exit 1
fi
if ! unzip /tmp/libraries.zip -d "$librariesDir"; then
log "ERROR: failed to unzip Crucible libraries"
exit 1
fi
rm /tmp/libraries.zip
fi
export SERVER
export SKIP_LOG4J_CONFIG=true
export FAMILY=HYBRID
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"

5
start-deployCustom → scripts/start-deployCustom Normal file → Executable file
View File

@@ -31,6 +31,5 @@ else
fi
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@
export FAMILY=HYBRID
exec ${SCRIPTS:-/}start-setupWorld $@

16
start-deployFTBA → scripts/start-deployFTBA Normal file → Executable file
View File

@@ -16,7 +16,7 @@ if ! [[ ${FTB_MODPACK_ID} =~ [0-9]+ ]]; then
exit 1
fi
if ! [[ -v FTB_MODPACK_VERSION_ID ]]; then
if [[ ! $FTB_MODPACK_VERSION_ID ]]; then
if ! FTB_MODPACK_VERSION_ID=$(curl -fsSL https://api.modpacks.ch/public/modpack/${FTB_MODPACK_ID} | jq -r '.versions | sort_by(.updated)[-1].id'); then
log "ERROR unable to resolve latest modpack version ID for modpack ${FTB_MODPACK_ID}"
exit 1
@@ -30,7 +30,13 @@ if ! [ -f "${ftbInstallMarker}" ] || [ $(cat "${ftbInstallMarker}") != "${FTB_MO
ftbInstaller=/data/ftb-installer
if ! [[ -f "${ftbInstaller}" ]]; then
log "Downloading FTB installer"
curl -fsSL https://api.modpacks.ch/public/modpack/1/1/server/linux -o "${ftbInstaller}"
if [ "$(uname -m)" == "aarch64" ]; then
log "Downloading ARM installer"
curl -fsSL https://api.modpacks.ch/public/modpack/1/1/server/arm/linux -o "${ftbInstaller}"
else
log "Downloading x86 installer"
curl -fsSL https://api.modpacks.ch/public/modpack/1/1/server/linux -o "${ftbInstaller}"
fi
chmod +x "${ftbInstaller}"
fi
@@ -61,7 +67,7 @@ variants=(
forge-${mcVersion}-${forgeVersion}-${mcVersion}-universal.jar
fabric-${mcVersion}-${fabricVersion}-server-launch.jar
)
for f in ${variants[@]}; do
for f in "${variants[@]}"; do
if [ -f $f ]; then
export SERVER=$f
break
@@ -73,5 +79,5 @@ if ! [ -v SERVER ]; then
exit 2
fi
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@
export FAMILY=FORGE
exec ${SCRIPTS:-/}start-setupWorld $@

19
start-deployFabric → scripts/start-deployFabric Normal file → Executable file
View File

@@ -1,6 +1,7 @@
#!/bin/bash
set -eu
# shellcheck source=start-utils
. ${SCRIPTS:-/}start-utils
requireVar VANILLA_VERSION
@@ -13,6 +14,7 @@ if [[ ! -e ${SERVER} ]]; then
: ${FABRIC_INSTALLER:=}
: ${FABRIC_INSTALLER_URL:=}
: ${FABRIC_LOADER_VERSION:=LATEST}
: ${FABRIC_INSTALLER_VERSION:=${FABRICVERSION:-LATEST}}
if [[ -z $FABRIC_INSTALLER && -z $FABRIC_INSTALLER_URL ]]; then
@@ -30,21 +32,28 @@ if [[ ! -e ${SERVER} ]]; then
exit 2
fi
if [[ -z $FABRIC_LOADER_VERSION || ${FABRIC_LOADER_VERSION^^} = LATEST ]]; then
log "Checking Fabric Loader version information."
FABRIC_LOADER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml)
fi
if [[ ! -e $FABRIC_INSTALLER ]]; then
log "Downloading $FABRIC_INSTALLER_URL ..."
if ! curl -o $FABRIC_INSTALLER -fsSL $FABRIC_INSTALLER_URL; then
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"
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
@@ -57,8 +66,8 @@ if [[ ! -e ${SERVER} ]]; then
exit 10
fi
mv fabric-server-launch.jar ${SERVER}
mv fabric-server-launch.jar "${SERVER}"
fi
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@
export FAMILY=FABRIC
exec ${SCRIPTS:-/}start-setupWorld "$@"

151
scripts/start-deployForge Executable file
View File

@@ -0,0 +1,151 @@
#!/bin/bash
: "${FORGEVERSION:=RECOMMENDED}"
# shellcheck source=start-utils
. "${SCRIPTS:-$(dirname "$0")}/start-utils"
isDebugging && set -x
get_installer() {
if [[ -z $FORGE_INSTALLER_URL ]]; then
log "Downloading $normForgeVersion"
forgeFileNames="
$shortForgeVersion/forge-$shortForgeVersion-installer.jar
$normForgeVersion/forge-$normForgeVersion-installer.jar
"
for fn in $forgeFileNames; do
downloadUrl=https://maven.minecraftforge.net/net/minecraftforge/forge/$fn
log "...trying $downloadUrl"
if get -o "$FORGE_INSTALLER" "$downloadUrl"; then
return
fi
done
log "Unable to locate usable URL for $normForgeVersion"
exit 2
else
log "Downloading $FORGE_INSTALLER_URL ..."
if ! get -o "$FORGE_INSTALLER" "$FORGE_INSTALLER_URL"; then
log "Failed to download from given location $FORGE_INSTALLER_URL"
exit 2
fi
fi
}
install() {
if [ ! -e "$FORGE_INSTALLER" ]; then
get_installer "$normForgeVersion" "$shortForgeVersion"
fi
log "Installing Forge $shortForgeVersion using $FORGE_INSTALLER"
mkdir -p mods
tries=3
while ((--tries >= 0)); do
if java -jar "$FORGE_INSTALLER" --installServer; then
break
fi
done
if ((tries < 0)); then
log "Forge failed to install after several tries." >&2
exit 10
fi
# NOTE $shortForgeVersion will be empty if installer location was given to us
log "Finding installed server jar..."
unset -v latest
# 1.17+ ?
if [ -f /data/run.sh ]; then
latest=/data/run.sh
# else pre 1.17
else
for file in *forge*.jar; do
if ! [[ $file =~ installer ]]; then
if [[ -z $latest ]] || [[ $file -nt $latest ]]; then
latest=$file
fi
fi
done
fi
if [[ -z $latest ]]; then
log "Unable to derive server jar for Forge"
exit 2
fi
export SERVER=$latest
log "Using server $SERVER"
debug "Writing install marker at $installMarker"
echo "$SERVER" > "$installMarker"
}
resolve_versions() {
if [[ -z $FORGE_INSTALLER && -z $FORGE_INSTALLER_URL ]]; then
norm=$VANILLA_VERSION
case $VANILLA_VERSION in
*.*.*)
norm=$VANILLA_VERSION ;;
*.*)
norm=${VANILLA_VERSION}.0 ;;
esac
#################################################################################
promosUrl=http://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json
log "Checking Forge version information."
case $FORGEVERSION in
LATEST)
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" "$promosUrl"); then
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
log " Refer to http://files.minecraftforge.net/ for supported versions"
exit 2
fi
;;
RECOMMENDED)
if ! FORGE_VERSION=$(get -s --json-path ".promos['$VANILLA_VERSION-recommended']" "$promosUrl"); then
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" "$promosUrl"); then
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
log " Refer to http://files.minecraftforge.net/ for supported versions"
exit 2
fi
fi
;;
*)
FORGE_VERSION=$FORGEVERSION
;;
esac
normForgeVersion=$VANILLA_VERSION-$FORGE_VERSION-$norm
shortForgeVersion=$VANILLA_VERSION-$FORGE_VERSION
FORGE_INSTALLER="/tmp/forge-$shortForgeVersion-installer.jar"
elif [[ -z $FORGE_INSTALLER ]]; then
FORGE_INSTALLER="/tmp/forge-installer.jar"
elif [[ ! -e $FORGE_INSTALLER ]]; then
log "ERROR: the given Forge installer doesn't exist : $FORGE_INSTALLER"
exit 2
else
shortForgeVersion=$VANILLA_VERSION-${FORGE_INSTALLER_CUSTOM_VERSION:-custom}
fi
}
### main
resolve_versions
installMarker="/data/.forge-installed-$shortForgeVersion"
if [ ! -e "$installMarker" ] || isTrue "${FORCE_REINSTALL:-false}"; then
install
else
SERVER=$(cat "$installMarker")
export SERVER
if [ ! -e "$SERVER" ]; then
rm "$installMarker"
install
fi
fi
export FAMILY=FORGE
exec "${SCRIPTS:-/}start-setupWorld" "$@"

64
scripts/start-deployLimbo Executable file
View File

@@ -0,0 +1,64 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
: ${LIMBO_BUILD:=LATEST}
: ${FORCE_REDOWNLOAD:=false}
: ${LIMBO_SCHEMA_FILENAME:=default.schem}
: ${LEVEL:=Default;${LIMBO_SCHEMA_FILENAME}}
# defaults to localhost, if this is not set
: ${SERVER_IP:=0.0.0.0}
export LEVEL SERVER_IP
if [[ ${LIMBO_BUILD^^} == LATEST ]]; then
LIMBO_BUILD=lastStableBuild
fi
baseUrl="https://ci.loohpjames.com/job/Limbo/${LIMBO_BUILD}"
buildInfoUrl="${baseUrl}/api/json"
buildJson=$(curl -fsSL "${buildInfoUrl}")
if [ $? != 0 ]; then
log "ERROR failed to get build info from ${buildInfoUrl} (status=$?)"
exit 1
fi
if [[ ${LIMBO_BUILD} = lastStableBuild ]]; then
LIMBO_BUILD=$(jq -r '.number' <<<${buildJson})
log "Resolved latest Limbo build to ${LIMBO_BUILD}"
fi
artifactPath=$(jq -r '.artifacts[] | select(.fileName|test("^Limbo-")) | .relativePath' <<<${buildJson})
defaultSchemaPath=$(jq -r '.artifacts[] | select(.fileName|test(".*\\.schem")) | .relativePath' <<<${buildJson})
export SERVER="limbo-${LIMBO_BUILD}.jar"
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
downloadUrl="${baseUrl}/artifact/${artifactPath}"
log "Downloading Limbo from $downloadUrl ..."
if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
if [ ! -f "${LIMBO_SCHEMA_FILENAME}" ]; then
log "Downloading default schem file"
if ! curl -o "${LIMBO_SCHEMA_FILENAME}" -fsSL "${baseUrl}/artifact/${defaultSchemaPath}"; then
log "ERROR: failed to download schema file $baseUrl (status=$?)"
exit 3
fi
fi
if [[ ${LEVEL} != *\;* ]]; then
LEVEL="${LEVEL};${LIMBO_SCHEMA_FILENAME}"
fi
export LEVEL
export SKIP_LOG4J_CONFIG=true
export FAMILY=LIMBO
exec ${SCRIPTS:-/}start-setupWorld $@

93
scripts/start-deployMagma Executable file
View File

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

18
start-deployMohist → scripts/start-deployMohist Normal file → Executable file
View File

@@ -1,17 +1,18 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
# shellcheck source=start-utils
. "${SCRIPTS:-$(dirname "$0")}/start-utils"
set -o pipefail
set -e
isDebugging && set -x
requireVar VANILLA_VERSION
: ${MOHIST_BUILD:=lastSuccessfulBuild}
: "${MOHIST_BUILD:=lastSuccessfulBuild}"
mohistJobs=https://ci.codemc.io/job/MohistMC/job/
mohistJob=${mohistJobs}Mohist-${VANILLA_VERSION}/
if ! curl -X HEAD -o /dev/null -fsSL "${mohistJob}"; then
if ! get --exists "${mohistJob}"; then
log "ERROR: mohist builds do not exist for ${VANILLA_VERSION}"
log " check https://ci.codemc.io/job/MohistMC/ for available versions"
log " and set VERSION accordingly"
@@ -19,8 +20,7 @@ if ! curl -X HEAD -o /dev/null -fsSL "${mohistJob}"; then
fi
buildRelPath=$(
curl -fsSL "${mohistJob}${MOHIST_BUILD}/api/json" |
jq -r '.artifacts[0].relativePath'
get --json-path '$.artifacts[0].relativePath' "${mohistJob}${MOHIST_BUILD}/api/json"
)
baseName=$(basename "${buildRelPath}")
@@ -33,12 +33,12 @@ fi
export SERVER="/data/${baseName}"
if [ ! -f ${SERVER} ]; then
if [ ! -f "${SERVER}" ]; then
log "Downloading ${baseName}"
curl -o "${SERVER}" -fsSL "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}"
get -o "${SERVER}" "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}"
fi
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld "$@"
export FAMILY=HYBRID
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"

1
start-deployPaper → scripts/start-deployPaper Normal file → Executable file
View File

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

View File

@@ -10,7 +10,7 @@ isDebugging && set -x
: ${FORCE_REDOWNLOAD:=false}
if [[ ${PURPUR_BUILD} == LATEST ]]; then
PURPUR_BUILD=$(curl -fsSL "https://api.pl3x.net/v2/purpur/${VANILLA_VERSION}" |
PURPUR_BUILD=$(curl -fsSL "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}" |
jq -r '.builds.latest' || echo "")
if [[ -z ${PURPUR_BUILD} ]]; then
log "ERROR: Failed to locate a Purpur build for ${VANILLA_VERSION}."
@@ -22,7 +22,7 @@ fi
export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar"
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
downloadUrl="https://api.pl3x.net/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
log "Downloading Purpur from $downloadUrl ..."
if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
@@ -32,6 +32,7 @@ fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -37,5 +37,5 @@ if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
curl -sSL -o $SERVER https://repo.spongepowered.org/maven/org/spongepowered/$TYPE/$SPONGEVERSION/$SERVER
fi
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@
export FAMILY=SPONGE
exec ${SCRIPTS:-/}start-setupWorld "$@"

56
scripts/start-deployVanilla Executable file
View File

@@ -0,0 +1,56 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
set -o pipefail
export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar"
if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
log "Downloading $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)"
exit 1
fi
if [ "$versionManifestUrl" = "null" ]; then
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)"
exit 1
elif [ "$serverDownloadUrl" = "null" ]; then
log "ERROR version $VANILLA_VERSION does not provide a server download"
exit 1
fi
debug "Downloading server from $serverDownloadUrl"
get -o "$SERVER" "$serverDownloadUrl"
result=$?
if [ $result != 0 ]; then
log "ERROR failed to download server from $serverDownloadUrl ($result)"
exit 1
fi
fi
if versionLessThan 1.6; then
if ! [[ -L /data/minecraft_server.jar && /data/minecraft_server.jar -ef "/data/$SERVER" ]]; then
rm -f /data/minecraft_server.jar
ln -s "/data/$SERVER" /data/minecraft_server.jar
fi
SERVER=minecraft_server.jar
elif [[ -L /data/minecraft_server.jar ]]; then
rm -f /data/minecraft_server.jar
fi
isDebugging && ls -l
export FAMILY=VANILLA
exec "${SCRIPTS:-/}start-setupWorld" "$@"

187
start-minecraftFinalSetup → scripts/start-finalExec Normal file → Executable file
View File

@@ -3,24 +3,93 @@
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
if [ -n "$OPS" ]; then
log "Updating ops"
rm -f /data/ops.txt.converted
echo $OPS | awk -v RS=, '{print}' > /data/ops.txt
fi
if isTrue "${OVERRIDE_OPS}"; then
log "Recreating ops.json file at server startup"
rm -f /data/ops.json
if versionLessThan 1.7.6; then
opsFile=ops.txt
whitelistFile=white-list.txt
else
opsFile=ops.json
whitelistFile=whitelist.json
fi
if [ -n "$WHITELIST" ]; then
log "Updating whitelist"
rm -f /data/white-list.txt.converted
echo $WHITELIST | awk -v RS=, '{print}' > /data/white-list.txt
function process_user_file() {
local output=$1
local source=$2
if isURL "$source"; then
log "Downloading $output from $source"
if ! get -o /data/$output "$source"; then
log "ERROR: failed to download from $source"
exit 2
fi
else
log "Copying $output from $source"
if ! cp "$source" /data/$output; then
log "ERROR: failed to copy from $source"
exit 1
fi
fi
}
function process_user_csv() {
local output=$1
local list=$2
local playerDataList
if [[ "$output" == *"ops"* ]]; then
# Extra data for ops.json
userData='{"uuid": .id, "name": .username, "level": 4}'
else
userData='{"uuid": .id, "name": .username}'
fi
log "Updating ${output%.*}"
for i in ${list//,/ }
do
if [ -e "$output" ] && grep -q "$i" "$output"; then
log "$i already present in $output, skipping"
continue
fi
if ! playerData=$(get "https://playerdb.co/api/player/minecraft/$i" | jq -re ".data.player"); then
log "WARNING: Could not lookup user $i for ${output} addition"
else
playerDataList=$playerDataList$(echo $playerData | jq -r "$userData")
fi
done
local newUsers=$(echo $playerDataList | jq -s .)
if [[ $output =~ .*\.txt ]]; then
# username list for txt config (Minecraft <= 1.7.5)
echo $newUsers | jq -r '.[].name' >> /data/${output}
sort -u /data/${output} -o /data/${output}
elif [ -e /data/${output} ]; then
# Merge with existing json file
local currentUsers=$(cat /data/${output})
jq --argjson current "$currentUsers" --argjson new "$newUsers" -n '$new + $current | unique_by(.uuid)' > /data/${output}
else
# New json file
echo $newUsers > /data/${output}
fi
}
if isTrue "${OVERRIDE_OPS}"; then
log "Recreating ${opsFile} file at server startup"
rm -f /data/${opsFile}
fi
if [ -n "${OPS_FILE}" ] && [ ! -e "/data/${opsFile}" ]; then
process_user_file ${opsFile} "$OPS_FILE"
fi
if [ -n "${OPS}" ]; then
process_user_csv ${opsFile} "$OPS"
fi
if isTrue "${OVERRIDE_WHITELIST}"; then
log "Recreating whitelist.json file at server startup"
rm -f /data/whitelist.json
log "Recreating ${whitelistFile} file at server startup"
rm -f /data/${whitelistFile}
fi
if [ -n "${WHITELIST_FILE}" ] && [ ! -e "/data/${whitelistFile}" ]; then
process_user_file ${whitelistFile} "$WHITELIST_FILE"
fi
if [ -n "${WHITELIST}" ]; then
process_user_csv ${whitelistFile} "$WHITELIST"
fi
if [ -n "$ICON" ]; then
@@ -70,8 +139,8 @@ if [[ ${GUI} = false || ${GUI} = FALSE ]]; then
EXTRA_ARGS+=" nogui"
fi
# put these prior JVM_OPTS at the end to give any memory settings there higher precedence
log "Setting initial memory to ${INIT_MEMORY:=${MEMORY}} and max to ${MAX_MEMORY:=${MEMORY}}"
: "${INIT_MEMORY:=${MEMORY}}"
: "${MAX_MEMORY:=${MEMORY}}"
expandedDOpts=
if [ -n "$JVM_DD_OPTS" ]; then
@@ -81,6 +150,28 @@ if [ -n "$JVM_DD_OPTS" ]; then
done
fi
patchLog4jConfig() {
file=${1?}
url=${2?}
if ! get -o "$file" "$url"; then
log "ERROR: failed to download corrected log4j config"
exit 1
fi
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
}
# Patch Log4j remote code execution vulnerability
# See https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition
if versionLessThan 1.7; then
: # No patch required here.
elif isFamily VANILLA && versionLessThan 1.12; then
patchLog4jConfig log4j2_17-111.xml https://launcher.mojang.com/v1/objects/dd2b723346a8dcd48e7f4d245f6bf09e98db9696/log4j2_17-111.xml
elif isFamily VANILLA && versionLessThan 1.17; then
patchLog4jConfig log4j2_112-116.xml https://launcher.mojang.com/v1/objects/02937d122c86ce73319ef9975b58896fc1b491d1/log4j2_112-116.xml
elif versionLessThan 1.18.1; then
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
fi
if isTrue ${ENABLE_JMX}; then
: ${JMX_PORT:=7091}
JVM_OPTS="${JVM_OPTS}
@@ -157,7 +248,15 @@ if isTrue "${DEBUG_MEMORY}"; then
free -m
fi
JVM_OPTS="-Xms${INIT_MEMORY} -Xmx${MAX_MEMORY} ${JVM_OPTS}"
if [[ ${INIT_MEMORY} || ${MAX_MEMORY} ]]; then
log "Setting initial memory to ${INIT_MEMORY:=${MEMORY}} and max to ${MAX_MEMORY:=${MEMORY}}"
if [[ ${INIT_MEMORY} ]]; then
JVM_OPTS="-Xms${INIT_MEMORY} ${JVM_OPTS}"
fi
if [[ ${MAX_MEMORY} ]]; then
JVM_OPTS="-Xmx${MAX_MEMORY} ${JVM_OPTS}"
fi
fi
function copyFilesForCurseForge() {
# copy player modification files unconditionally since their
@@ -172,48 +271,46 @@ function copyFilesForCurseForge() {
cp -f /data/eula.txt "${FTB_DIR}/"
}
mcServerRunnerArgs="--stop-duration ${STOP_DURATION:-60}s"
if [[ ${TYPE} == "CURSE_INSTANCE" ]]; then
if isTrue ${DEBUG_EXEC}; then
set -x
fi
exec mc-server-runner ${mcServerRunnerArgs} \
--cf-instance-file "${CURSE_INSTANCE_JSON}" \
java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar _SERVERJAR_ "$@" $EXTRA_ARGS
elif [[ ${TYPE} == "CURSEFORGE" && "${SERVER}" ]]; then
mcServerRunnerArgs=(
--stop-duration "${STOP_DURATION:-60}s"
--named-pipe "${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}"
)
if [[ ${STOP_SERVER_ANNOUNCE_DELAY} ]]; then
mcServerRunnerArgs+=(--stop-server-announce-delay "${STOP_SERVER_ANNOUNCE_DELAY}s")
fi
if [[ ${TYPE} == "CURSEFORGE" && "${SERVER}" ]]; then
copyFilesForCurseForge
cd "${FTB_DIR}"
cd "${FTB_DIR}" || (log "ERROR: can't go into ${FTB_DIR}"; exit 1)
log "Starting CurseForge server in ${FTB_DIR}..."
if isTrue ${DEBUG_EXEC}; then
set -x
fi
exec mc-server-runner ${bootstrapArgs} ${mcServerRunnerArgs} java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar $(basename "${SERVER}") "$@" $EXTRA_ARGS
exec mc-server-runner ${bootstrapArgs} "${mcServerRunnerArgs[@]}" java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar $(basename "${SERVER}") "$@" $EXTRA_ARGS
elif [[ ${TYPE} == "CURSEFORGE" ]]; then
mcServerRunnerArgs="${mcServerRunnerArgs} --shell bash"
mcServerRunnerArgs+=(--shell bash)
copyFilesForCurseForge
cat > "${FTB_DIR}/settings-local.sh" <<EOF
export MIN_RAM="${INIT_MEMORY}"
export MAX_RAM="${MAX_MEMORY}"
export JAVA_PARAMETERS="${JVM_XX_OPTS} -Xms${INIT_MEMORY} ${JVM_OPTS} $expandedDOpts"
export JAVA_PARAMETERS="${JVM_XX_OPTS} ${JVM_OPTS} $expandedDOpts"
EOF
# patch CurseForge cfg file, if present
if [ -f "${FTB_DIR}/settings.cfg" ]; then
if [ -f "${FTB_DIR}/settings.cfg" ] && [[ ${MAX_MEMORY} ]]; then
sed -i "s/MAX_RAM=[^;]*/MAX_RAM=${MAX_MEMORY}/" "${FTB_DIR}/settings.cfg"
fi
cd "${FTB_DIR}"
cd "${FTB_DIR}" || (log "ERROR: can't go into ${FTB_DIR}"; exit 1)
log "Running FTB ${FTB_SERVER_START} in ${FTB_DIR} ..."
finalArgs=(
"${FTB_SERVER_START}"
)
finalArgs="${FTB_SERVER_START}"
if isTrue ${SETUP_ONLY:=false}; then
echo "SETUP_ONLY: ${finalArgs[@]}"
if isTrue "${SETUP_ONLY:=false}"; then
echo "SETUP_ONLY: ${finalArgs}"
exit
fi
@@ -223,8 +320,12 @@ EOF
if isTrue ${EXEC_DIRECTLY:-false}; then
"${finalArgs[@]}"
else
exec mc-server-runner ${mcServerRunnerArgs} "${finalArgs[@]}"
exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}"
fi
elif [[ -x run.sh ]]; then
log "Using Forge supplied run.sh script..."
echo $JVM_XX_OPTS $JVM_OPTS $expandedDOpts > user_jvm_args.txt
exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash run.sh
else
# If we have a bootstrap.txt file... feed that in to the server stdin
if [ -f /data/bootstrap.txt ]; then
@@ -237,23 +338,23 @@ else
$JVM_XX_OPTS
$JVM_OPTS
$expandedDOpts
-jar $SERVER
-jar "$SERVER"
"$@" $EXTRA_ARGS
)
if isTrue ${SETUP_ONLY:=false}; then
echo "SETUP_ONLY: java ${finalArgs[@]}"
echo "SETUP_ONLY: java ${finalArgs[*]}"
exit
fi
if isTrue ${DEBUG_EXEC}; then
if isTrue "${DEBUG_EXEC}"; then
set -x
fi
if isTrue ${EXEC_DIRECTLY:-false}; then
if isTrue "${EXEC_DIRECTLY:-false}"; then
exec java "${finalArgs[@]}"
else
exec mc-server-runner ${bootstrapArgs} ${mcServerRunnerArgs} java "${finalArgs[@]}"
exec mc-server-runner ${bootstrapArgs} "${mcServerRunnerArgs[@]}" java "${finalArgs[@]}"
fi
fi

35
scripts/start-setupEnvVariables Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
set -e
: "${REPLACE_ENV_IN_PLACE:=${REPLACE_ENV_VARIABLES:-false}}"
: "${REPLACE_ENV_PATHS:=/data}"
: "${REPLACE_ENV_SUFFIXES:=yml,yaml,txt,cfg,conf,properties,hjson,json,tml,toml}"
: "${REPLACE_ENV_VARIABLE_PREFIX:=${ENV_VARIABLE_PREFIX:-CFG_}}"
: "${REPLACE_ENV_VARIABLES_EXCLUDES:=}"
: "${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS:=}"
: "${PATCH_DEFINITIONS:=}"
: "${DEBUG:=false}"
if isTrue "${REPLACE_ENV_IN_PLACE}"; then
log "Replacing env variables in ${REPLACE_ENV_PATHS} that match the prefix $REPLACE_ENV_VARIABLE_PREFIX ..."
mc-image-helper --debug=${DEBUG} interpolate \
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
--replace-env-prefix="${REPLACE_ENV_VARIABLE_PREFIX}" \
"${REPLACE_ENV_PATHS[@]}"
fi
if [[ ${PATCH_DEFINITIONS} ]]; then
log "Applying patch definitions from ${PATCH_DEFINITIONS}"
mc-image-helper --debug=${DEBUG} patch \
--patch-env-prefix="${REPLACE_ENV_VARIABLE_PREFIX}" \
"${PATCH_DEFINITIONS}"
fi
exec "${SCRIPTS:-/}start-finalExec" "$@"

View File

@@ -24,4 +24,4 @@ case "X$MODCONFIG" in
esac
fi
exec ${SCRIPTS:-/}start-finalSetupMounts $@
exec ${SCRIPTS:-/}start-setupMounts $@

247
scripts/start-setupModpack Executable file
View File

@@ -0,0 +1,247 @@
#!/bin/bash
set -e -o pipefail
: "${REMOVE_OLD_MODS:=false}"
: "${MODS_FILE:=}"
: "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar}"
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
# CURSE_URL_BASE used in manifest downloads below
CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects}
# Remove old mods/plugins
if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
removeOldMods /data/mods
removeOldMods /data/plugins
fi
# If packwiz url passed, bootstrap packwiz and update mods before other modpack processing
if [[ "${PACKWIZ_URL}" ]]; then
# Ensure we have the latest packwiz bootstrap installer
latestPackwiz=$(curl -fsSL https://api.github.com/repos/comp500/packwiz-installer-bootstrap/releases/latest)
if [[ -z "${latestPackwiz}" ]]; then
log "WARNING: Could not retrieve Packwiz bootstrap installer release information"
else
isDebugging && log "Latest packwiz ${latestPackWiz}"
latestPackwizVer=$(echo ${latestPackwiz} | jq --raw-output '.tag_name')
latestPackwizUrl=$(echo ${latestPackwiz} | jq --raw-output '.assets[] | select(.name | match("packwiz-installer-bootstrap.jar")) | .url')
: "${PACKWIZ_JAR:=packwiz-installer-bootstrap_${latestPackwizVer}.jar}"
if [[ ! -e $PACKWIZ_JAR ]]; then
log "Downloading Packwiz ${latestPackwizVer}"
curl -H "Accept:application/octet-stream" -o "$PACKWIZ_JAR" -fsSL ${latestPackwizUrl}
ln -sf "${PACKWIZ_JAR}" packwiz-installer-bootstrap.jar
fi
fi
if [[ ! -e packwiz-installer-bootstrap.jar ]]; then
log "ERROR: Packwiz not available or could not be downloaded from Github!"
exit 1
fi
if isURL "${PACKWIZ_URL}"; then
log "Running packwiz against URL: ${PACKWIZ_URL}"
java -jar packwiz-installer-bootstrap.jar -g -s server "${PACKWIZ_URL}"
fi
fi
# If supplied with a URL for a modpack (simple zip of jars), download it and unpack
if [[ "$MODPACK" ]]; then
if isURL "${MODPACK}"; then
log "Downloading mod/plugin pack"
if ! get -o /tmp/modpack.zip "${MODPACK}"; then
log "ERROR: failed to download from ${MODPACK}"
exit 2
fi
elif [[ "$MODPACK" =~ .*\.zip ]]; then
if ! cp "$MODPACK" /tmp/modpack.zip; then
log "ERROR: failed to copy from $MODPACK"
exit 2
fi
else
log "ERROR Invalid URL or Path given for MODPACK: $MODPACK"
exit 1
fi
if [ "$TYPE" = "SPIGOT" ]; then
mkdir -p /data/plugins
if ! unzip -o -d /data/plugins /tmp/modpack.zip; then
log "ERROR: failed to unzip the modpack from ${MODPACK}"
fi
else
mkdir -p /data/mods
if ! unzip -o -d /data/mods /tmp/modpack.zip; then
log "ERROR: failed to unzip the modpack from ${MODPACK}"
fi
fi
rm -f /tmp/modpack.zip
elif [[ "$MODS" ]]; then
if [ "$TYPE" = "SPIGOT" ]; then
out_dir=/data/plugins
else
out_dir=/data/mods
fi
mkdir -p "$out_dir"
for i in ${MODS//,/ }
do
if isURL "$i"; then
log "Downloading mod/plugin $i ..."
if ! get -o "${out_dir}" "$i"; then
log "ERROR: failed to download from $i into $out_dir"
exit 2
fi
elif [[ -f "$i" && "$i" =~ .*\.jar ]]; then
log "Copying plugin located at $i ..."
out_file=$(basename "$i")
if ! cp "$i" "${out_dir}/$out_file"; then
log "ERROR: failed to copy from $i into $out_dir"
exit 2
fi
elif [[ -d "$i" ]]; then
log "Copying plugin jars from $i ..."
cp "$i"/*.jar "${out_dir}"
else
log "ERROR Invalid URL or path given in MODS: $i"
exit 2
fi
done
elif [[ "$MODS_FILE" ]]; then
if [ ! -f "$MODS_FILE" ]; then
log "ERROR: given MODS_FILE file does not exist"
exit 2
fi
if [ "$TYPE" = "SPIGOT" ]; then
out_dir=/data/plugins
else
out_dir=/data/mods
fi
mkdir -p "$out_dir"
args=(
-o "${out_dir}"
--log-progress-each
--skip-existing
--uris-file "${MODS_FILE}"
)
if isTrue "${REMOVE_OLD_MODS}"; then
args+=(
--prune-others "${REMOVE_OLD_MODS_INCLUDE}"
--prune-depth "${REMOVE_OLD_MODS_DEPTH}"
)
fi
if ! get "${args[@]}" ; then
log "ERROR: failed to retrieve one or more mods"
exit 1
fi
fi
if [[ "$MANIFEST" ]]; then
if [[ -e "$MANIFEST" ]]; then
EFFECTIVE_MANIFEST_FILE=$MANIFEST
elif isURL "$MANIFEST"; then
EFFECTIVE_MANIFEST_FILE=/tmp/manifest.json
EFFECTIVE_MANIFEST_URL=$(curl -Ls -o /dev/null -w %{effective_url} $MANIFEST)
curl -Ls -o $EFFECTIVE_MANIFEST_FILE "$EFFECTIVE_MANIFEST_URL"
else
log "MANIFEST='$MANIFEST' is not a valid manifest url or location"
exit 2
fi
case "X$EFFECTIVE_MANIFEST_FILE" in
X*.json)
if [ -f "${EFFECTIVE_MANIFEST_FILE}" ]; then
MOD_DIR=${FTB_BASE_DIR:-/data}/mods
if [ ! -d "$MOD_DIR" ]
then
log "Creating mods dir $MOD_DIR"
mkdir -p "$MOD_DIR"
fi
log "Starting manifest download..."
cat "${EFFECTIVE_MANIFEST_FILE}" | jq -r '.files[] | (.projectID|tostring) + " " + (.fileID|tostring)'| while read -r p f
do
if [ ! -f $MOD_DIR/${p}_${f}.jar ]
then
redirect_url="$(curl -Ls -o /dev/null -w %{effective_url} ${CURSE_URL_BASE}/${p})"
url="$redirect_url/download/${f}/file"
log Downloading curseforge mod $url
# Manifest usually doesn't have mod names. Using id should be fine, tho
curl -sSL "${url}" -o $MOD_DIR/${p}_${f}.jar
fi
done
else
log "Could not find manifest file, insufficient privileges, or malformed path."
fi
;;
*)
log "Invalid manifest file for modpack. Please make sure it is a .json file."
;;
esac
fi
: "${GENERIC_PACKS:=${GENERIC_PACK}}"
if [[ "${GENERIC_PACKS}" ]]; then
IFS=',' read -ra packs <<< "${GENERIC_PACKS}"
packFiles=()
for pack in "${packs[@]}"; do
if isURL "$pack"; then
mkdir -p /data/packs
if ! outfile=$(get -o /data/packs --output-filename --skip-existing "$pack"); then
log "ERROR: failed to download $pack"
exit 2
fi
packFiles+=("$outfile")
else
packFiles+=("$pack")
fi
done
sum_file=/data/.generic_pack.sum
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
if ! sha256sum -c "${sum_file}" --status 2> /dev/null; then
base_dir=/tmp/generic_pack_base
mkdir -p ${base_dir}
for pack in "${packFiles[@]}"; do
isDebugging && ls -l "${pack}"
unzip -q -d ${base_dir} "${pack}"
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)
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'
exit 1
fi
if [ -f /data/manifest.txt ]; then
log "Manifest exists from older generic pack, cleaning up ..."
while read -r f; do
rm -rf "/data/${f}"
done < /data/manifest.txt
# prune empty dirs
find /data -mindepth 1 -depth -type d -empty -delete
rm -f /data/manifest.txt
fi
log "Writing generic pack manifest ... "
find "${base_dir}" -type f -printf "%P\n" > /data/manifest.txt
log "Applying generic pack ..."
cp -R -f "${base_dir}"/* /data
rm -rf /tmp/generic_pack_base
sha256sum "${packFiles[@]}" > "${sum_file}"
isDebugging && cat "$sum_file"
fi
fi
exec "${SCRIPTS:-/}start-setupModconfig" "$@"

69
scripts/start-setupMounts Executable file
View File

@@ -0,0 +1,69 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
: ${SYNC_SKIP_NEWER_IN_DESTINATION:=${PLUGINS_SYNC_UPDATE:-true}}
: ${REPLACE_ENV_DURING_SYNC:=true}
: ${REPLACE_ENV_SUFFIXES:=yml,yaml,txt,cfg,conf,properties,hjson,json,tml,toml}
: ${REPLACE_ENV_VARIABLE_PREFIX:=${ENV_VARIABLE_PREFIX:-CFG_}}
: ${REPLACE_ENV_VARIABLES_EXCLUDES:=}
: ${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS:=}
: ${DEBUG:=false}
set -e
isDebugging && set -x
if isTrue ${SYNC_SKIP_NEWER_IN_DESTINATION}; then
updateArg="--skip-newer-in-destination"
fi
if isTrue ${REPLACE_ENV_DURING_SYNC}; then
subcommand=sync-and-interpolate
else
subcommand=sync
fi
if [ -d /plugins ]; then
case ${TYPE} in
SPIGOT|BUKKIT|PAPER|MAGMA)
mkdir -p /data/plugins
log "Copying plugins over..."
mc-image-helper \
--debug=${DEBUG} ${subcommand} $updateArg \
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
--replace-env-prefix=${REPLACE_ENV_VARIABLE_PREFIX} \
/plugins /data/plugins
;;
esac
fi
# If any modules have been provided, copy them over
: ${COPY_MODS_DEST:="/data/mods"}
if [ -d /mods ]; then
log "Copying any mods over..."
mc-image-helper \
--debug=${DEBUG} ${subcommand} $updateArg \
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
--replace-env-prefix=${REPLACE_ENV_VARIABLE_PREFIX} \
/mods "${COPY_MODS_DEST}"
fi
: ${COPY_CONFIG_DEST:="/data/config"}
if [ -d /config ]; then
log "Copying any configs from /config to ${COPY_CONFIG_DEST}"
mc-image-helper \
--debug=${DEBUG} ${subcommand} $updateArg \
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
--replace-env-prefix=${REPLACE_ENV_VARIABLE_PREFIX} \
/config "${COPY_CONFIG_DEST}"
fi
exec ${SCRIPTS:-/}start-setupServerProperties $@

View File

@@ -0,0 +1,233 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
: "${SERVER_PROPERTIES:=/data/server.properties}"
# FUNCTIONS
function setServerPropValue {
local prop=$1
local value=$2
# normalize booleans
case ${value^^} in
TRUE|FALSE)
value=${value,,} ;;
esac
if grep "${prop}" "$SERVER_PROPERTIES" > /dev/null; then
log "Setting ${prop} to '${value}' in ${SERVER_PROPERTIES}"
sed -i "/^${prop}\s*=/ c ${prop}=${value//\\/\\\\}" "$SERVER_PROPERTIES"
else
log "Adding ${prop} with '${value}' in ${SERVER_PROPERTIES}"
echo "${prop}=${value}" >> "$SERVER_PROPERTIES"
fi
}
function setServerProp {
local prop=$1
local varName=$2
if [ -v $varName ]; then
setServerPropValue "$prop" "${!varName}"
fi
}
function customizeServerProps {
# Whitelist processing
if [ -n "$WHITELIST" ] || [ -n "$WHITELIST_FILE" ] || isTrue "${ENABLE_WHITELIST:-false}"; then
log "Enabling whitelist functionality"
setServerPropValue "white-list" "true"
else
log "Disabling whitelist functionality"
setServerPropValue "white-list" "false"
fi
setServerProp "enforce-whitelist" ENFORCE_WHITELIST
if [[ $(grep "enforce-whitelist" $SERVER_PROPERTIES) != *true ]]; then
log "WARNING: whitelist enabled but not enforced. Set ENFORCE_WHITELIST=TRUE or update 'enforce-whitelist' in server.properties to enforce the whitelist."
fi
# If not provided, generate a reasonable default message-of-the-day,
# which shows up in the server listing in the client
if [ -z "$MOTD" ]; then
# snapshot is the odd case where we have to look at version to identify that label
if [[ ${ORIGINAL_TYPE} == "VANILLA" && ${VERSION} == "SNAPSHOT" ]]; then
label=SNAPSHOT
else
label=${ORIGINAL_TYPE}
fi
# Convert label to title-case
label=${label,,}
label=${label^}
MOTD="A ${label} Minecraft Server powered by Docker"
fi
setServerProp "server-name" SERVER_NAME
setServerProp "server-ip" SERVER_IP
setServerProp "server-port" SERVER_PORT
setServerProp "allow-nether" ALLOW_NETHER
setServerProp "announce-player-achievements" ANNOUNCE_PLAYER_ACHIEVEMENTS
setServerProp "enable-command-block" ENABLE_COMMAND_BLOCK
setServerProp "spawn-animals" SPAWN_ANIMALS
setServerProp "spawn-monsters" SPAWN_MONSTERS
setServerProp "spawn-npcs" SPAWN_NPCS
setServerProp "spawn-protection" SPAWN_PROTECTION
setServerProp "generate-structures" GENERATE_STRUCTURES
setServerProp "view-distance" VIEW_DISTANCE
setServerProp "hardcore" HARDCORE
setServerProp "snooper-enabled" SNOOPER_ENABLED
setServerProp "max-build-height" MAX_BUILD_HEIGHT
setServerProp "force-gamemode" FORCE_GAMEMODE
setServerProp "max-tick-time" MAX_TICK_TIME
setServerProp "enable-query" ENABLE_QUERY
setServerProp "query.port" QUERY_PORT
setServerProp "enable-rcon" ENABLE_RCON
setServerProp "rcon.password" RCON_PASSWORD
setServerProp "rcon.port" RCON_PORT
setServerProp "max-players" MAX_PLAYERS
setServerProp "max-world-size" MAX_WORLD_SIZE
setServerProp "level-name" LEVEL
setServerProp "level-seed" SEED
setServerProp "pvp" PVP
setServerProp "generator-settings" GENERATOR_SETTINGS
setServerProp "online-mode" ONLINE_MODE
setServerProp "allow-flight" ALLOW_FLIGHT
setServerProp "resource-pack" RESOURCE_PACK
setServerProp "resource-pack-sha1" RESOURCE_PACK_SHA1
setServerProp "require-resource-pack" RESOURCE_PACK_ENFORCE
setServerProp "player-idle-timeout" PLAYER_IDLE_TIMEOUT
setServerProp "broadcast-console-to-ops" BROADCAST_CONSOLE_TO_OPS
setServerProp "broadcast-rcon-to-ops" BROADCAST_RCON_TO_OPS
setServerProp "enable-jmx-monitoring" ENABLE_JMX
setServerProp "sync-chunk-writes" SYNC_CHUNK_WRITES
setServerProp "enable-status" ENABLE_STATUS
setServerProp "entity-broadcast-range-percentage" ENTITY_BROADCAST_RANGE_PERCENTAGE
setServerProp "function-permission-level" FUNCTION_PERMISSION_LEVEL
setServerProp "network-compression-threshold" NETWORK_COMPRESSION_THRESHOLD
setServerProp "op-permission-level" OP_PERMISSION_LEVEL
setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS
setServerProp "use-native-transport" USE_NATIVE_TRANSPORT
setServerProp "simulation-distance" SIMULATION_DISTANCE
setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)"
[[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}"
if [ -n "$DIFFICULTY" ]; then
case ${DIFFICULTY,,} in
peaceful|0)
if versionLessThan 1.13; then
DIFFICULTY=0
else
DIFFICULTY=peaceful
fi
;;
easy|1)
if versionLessThan 1.13; then
DIFFICULTY=1
else
DIFFICULTY=easy
fi
;;
normal|2)
if versionLessThan 1.13; then
DIFFICULTY=2
else
DIFFICULTY=normal
fi
;;
hard|3)
if versionLessThan 1.13; then
DIFFICULTY=3
else
DIFFICULTY=hard
fi
;;
*)
log "DIFFICULTY must be peaceful, easy, normal, or hard."
exit 1
;;
esac
setServerPropValue "difficulty" "$DIFFICULTY"
fi
if [ -n "$MODE" ]; then
log "Setting mode"
case ${MODE,,} in
su*|0)
if versionLessThan 1.13; then
MODE=0
else
MODE=survival
fi
;;
c*|1)
if versionLessThan 1.13; then
MODE=1
else
MODE=creative
fi
;;
a*|2)
if versionLessThan 1.13; then
MODE=2
else
MODE=adventure
fi
;;
sp*|3)
if versionLessThan 1.13; then
MODE=3
else
MODE=spectator
fi
;;
*)
log "ERROR: Invalid game mode: $MODE"
exit 1
;;
esac
setServerPropValue "gamemode" "$MODE"
fi
}
# Deploy server.properties file
if [[ ${TYPE} == "CURSEFORGE" ]]; then
export SERVER_PROPERTIES="${FTB_DIR}/server.properties"
log "detected FTB, changing properties path to ${SERVER_PROPERTIES}"
fi
if ! isTrue "${SKIP_SERVER_PROPERTIES:-false}"; then
if [ ! -e "$SERVER_PROPERTIES" ]; then
log "Creating server.properties in ${SERVER_PROPERTIES}"
cp /tmp/server.properties "$SERVER_PROPERTIES"
customizeServerProps
elif [ -n "${OVERRIDE_SERVER_PROPERTIES}" ]; then
case ${OVERRIDE_SERVER_PROPERTIES^^} in
TRUE|1)
customizeServerProps
;;
*)
log "server.properties already created, skipping"
;;
esac
else
log "server.properties already created, skipping"
fi
else
log "Skipping setup of server.properties"
fi
if isTrue "${ENABLE_AUTOPAUSE}"; then
current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' )
if (( current_max_tick > 0 && current_max_tick < 86400000 )); then
log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled."
log "Warning (cont): Autopause functionality resuming the process might trigger the Watchdog and restart the server completely."
log "Warning (cont): Set the max-tick-time property to a high value (or disable the Watchdog with value -1 for versions 1.8.1+)."
fi
fi
if isDebugging && [ -f "${SERVER_PROPERTIES}" ]; then
log "DEBUG Dumping server.properties"
cat "${SERVER_PROPERTIES}"
fi
exec "${SCRIPTS:-/}start-setupEnvVariables" "$@"

12
start-finalSetupWorld → scripts/start-setupWorld Normal file → Executable file
View File

@@ -1,16 +1,14 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
set -e
isDebugging && set -x
: ${LEVEL:=world}
export LEVEL
if [ $TYPE = "CURSEFORGE" ]; then
worldDest=$FTB_DIR/$LEVEL
worldDest=$FTB_DIR/${LEVEL:-world}
else
worldDest=/data/$LEVEL
worldDest=/data/${LEVEL:-world}
fi
if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] ); then
@@ -71,4 +69,4 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
fi
fi
exec ${SCRIPTS:-/}start-finalSetupModpack $@
exec "${SCRIPTS:-/}start-setupModpack" "$@"

104
scripts/start-spiget Executable file
View File

@@ -0,0 +1,104 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
handleDebugMode
: ${SPIGET_RESOURCES:=}
: ${SPIGET_DOWNLOAD_TOLERANCE:=5} # in minutes
containsJars() {
file=${1?}
pat='\.jar$'
while read -r line; do
if [[ $line =~ $pat ]]; then
return 0
fi
done <<<$(unzip -l "$file")
return 1
}
getResourceFromSpiget() {
resource=${1?}
log "Downloading resource ${resource} ..."
mkdir -p /data/plugins
versionfile="/data/plugins/.${resource}-version.json"
versionfileNew="/tmp/.${resource}-version.json"
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
log "ERROR failed to download resource version meta data '${resource}' from ${urlVersion}"
exit 2
fi
installedVersion=$(jq -r '.name' $versionfile)
newVersion=$(jq -r '.name' $versionfileNew)
if [ "$installedVersion" = "$newVersion" ]; then
log "resource '${resource}' not downloaded because installed version '${installedVersion}' already up to date ('${newVersion}')"
mv "${versionfileNew}" "${versionfile}"
else
if downloadResourceFromSpiget "${resource}"; then
mv "${versionfileNew}" "${versionfile}"
fi
fi
else
log "resource '${resource}' not checked because version meta file newer than '${SPIGET_DOWNLOAD_TOLERANCE}' minutes"
fi
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
log "ERROR failed to download resource version meta data '${resource}' from ${urlVersion}"
exit 2
fi
mv "${versionfileNew}" "${versionfile}"
fi
fi
}
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
fi
if containsJars "${tmpfile}"; then
log "Extracting contents of resource ${resource} into plugins"
unzip -o -q -d /data/plugins "${tmpfile}"
rm "${tmpfile}"
else
log "Moving resource ${resource} into plugins"
mv "${tmpfile}" "/data/plugins/${resource}.jar"
fi
}
if [[ ${SPIGET_RESOURCES} ]]; then
if isTrue ${REMOVE_OLD_MODS:-false}; then
removeOldMods /data/plugins
REMOVE_OLD_MODS=false
fi
log "Getting plugins via Spiget"
IFS=',' read -r -a resources <<<"${SPIGET_RESOURCES}"
for resource in "${resources[@]}"; do
getResourceFromSpiget "${resource}"
done
fi
exec ${SCRIPTS:-/}start-setupWorld $@

46
start-utils → scripts/start-utils Normal file → Executable file
View File

@@ -112,32 +112,7 @@ function normalizeMemSize() {
}
function versionLessThan() {
local activeParts
IFS=. read -ra activeParts <<<"${VANILLA_VERSION}"
local givenParts
IFS=. read -ra givenParts <<<"$1"
if ((${#activeParts[@]} < 2)); then
return 1
fi
if ((${#activeParts[@]} == 2)); then
if ((activeParts[0] < givenParts[0])) ||
((activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1])); then
return 0
else
return 1
fi
else
if ((activeParts[0] < givenParts[0])) ||
((activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1])) ||
((activeParts[0] == givenParts[0] && activeParts[1] == givenParts[1] && activeParts[2] < givenParts[2])); then
return 0
else
return 1
fi
fi
mc-image-helper compare-versions "${VANILLA_VERSION}" lt "${1?}"
}
requireVar() {
@@ -161,7 +136,7 @@ requireEnum() {
fi
done
log "ERROR: $var must be set to one of $@"
log "ERROR: $var must be set to one of $*"
# exit 1
}
@@ -180,3 +155,20 @@ function removeOldMods {
find "$1" -mindepth 1 -maxdepth ${REMOVE_OLD_MODS_DEPTH:-16} -wholename "${REMOVE_OLD_MODS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_MODS_EXCLUDE:-}" -delete
fi
}
function get() {
local flags=()
if isTrue "${DEBUG_GET:-false}"; then
flags+=("--debug")
fi
mc-image-helper "${flags[@]}" get "$@"
}
function isFamily() {
for f in "${@}"; do
if [[ $FAMILY == "$f" ]]; then
return 0
fi
done
return 1
}

View File

@@ -1,123 +0,0 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
export TYPE=FORGE
: ${FORGEVERSION:=RECOMMENDED}
isDebugging && set -x
if [[ -z $FORGE_INSTALLER && -z $FORGE_INSTALLER_URL ]]; then
norm=$VANILLA_VERSION
case $VANILLA_VERSION in
*.*.*)
norm=$VANILLA_VERSION ;;
*.*)
norm=${VANILLA_VERSION}.0 ;;
esac
#################################################################################
log "Checking Forge version information."
case $FORGEVERSION in
RECOMMENDED)
curl -fsSL -o /tmp/forge.json http://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json
FORGE_VERSION=$(cat /tmp/forge.json | jq -r ".promos[\"$VANILLA_VERSION-recommended\"]")
if [ $FORGE_VERSION = null ]; then
FORGE_VERSION=$(cat /tmp/forge.json | jq -r ".promos[\"$VANILLA_VERSION-latest\"]")
if [ $FORGE_VERSION = null ]; then
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
log " Refer to http://files.minecraftforge.net/ for supported versions"
exit 2
fi
fi
;;
*)
FORGE_VERSION=$FORGEVERSION
;;
esac
normForgeVersion=$VANILLA_VERSION-$FORGE_VERSION-$norm
shortForgeVersion=$VANILLA_VERSION-$FORGE_VERSION
FORGE_INSTALLER="/tmp/forge-$shortForgeVersion-installer.jar"
elif [[ -z $FORGE_INSTALLER ]]; then
FORGE_INSTALLER="/tmp/forge-installer.jar"
elif [[ ! -e $FORGE_INSTALLER ]]; then
log "ERROR: the given Forge installer doesn't exist : $FORGE_INSTALLER"
exit 2
else
shortForgeVersion=$VANILLA_VERSION-custom
fi
installMarker="/data/.forge-installed-$shortForgeVersion"
if [ ! -e $installMarker ]; then
if [ ! -e $FORGE_INSTALLER ]; then
if [[ -z $FORGE_INSTALLER_URL ]]; then
log "Downloading $normForgeVersion"
forgeFileNames="
$normForgeVersion/forge-$normForgeVersion-installer.jar
$shortForgeVersion/forge-$shortForgeVersion-installer.jar
END
"
for fn in $forgeFileNames; do
if [ $fn == END ]; then
log "Unable to compute URL for $normForgeVersion"
exit 2
fi
downloadUrl=https://maven.minecraftforge.net/net/minecraftforge/forge/$fn
log "...trying $downloadUrl"
if curl -o $FORGE_INSTALLER -fsSL $downloadUrl; then
break
fi
done
else
log "Downloading $FORGE_INSTALLER_URL ..."
if ! curl -o $FORGE_INSTALLER -fsSL $FORGE_INSTALLER_URL; then
log "Failed to download from given location $FORGE_INSTALLER_URL"
exit 2
fi
fi
fi
log "Installing Forge $shortForgeVersion using $FORGE_INSTALLER"
mkdir -p mods
tries=3
while ((--tries >= 0)); do
java -jar $FORGE_INSTALLER --installServer
if [ $? == 0 ]; then
break
fi
done
if (($tries < 0)); then
log "Forge failed to install after several tries." >&2
exit 10
fi
# NOTE $shortForgeVersion will be empty if installer location was given to us
log "Finding installed server jar..."
unset -v latest
for file in *forge*.jar; do
if ! [[ $file =~ installer ]]; then
if [[ -z $latest ]] || [[ $file -nt $latest ]]; then
latest=$file
fi
fi
done
if [[ -z $latest ]]; then
log "Unable to derive server jar for Forge"
exit 2
fi
export SERVER=$latest
log "Using server $SERVER"
echo $SERVER > $installMarker
else
export SERVER=$(cat $installMarker)
fi
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,18 +0,0 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
export SERVER="/data/magma-server-${VANILLA_VERSION}.jar"
# Always download since new updates of each base version are published frequently
if ! curl -o /data/magma-server-${VANILLA_VERSION}.jar -fsSL \
https://api.magmafoundation.org/api/resources/Magma/${VANILLA_VERSION}/stable/latest/download; then
log "ERROR unable to download version ${VANILLA_VERSION} of Magma"
log " Check https://magmafoundation.org/ for available versions"
exit 1
fi
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,26 +0,0 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
if [ "${VERSION}" != "LATEST" ]; then
log "ERROR: Tuinity server type only supports VERSION=LATEST"
exit 1
fi
: ${TUINITY_BUILD:=lastSuccessfulBuild}
export SERVER=tuinity-${VANILLA_VERSION}-${TUINITY_BUILD}.jar
if [ ! -f "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
downloadUrl="https://ci.codemc.io/job/Spottedleaf/job/Tuinity/${TUINITY_BUILD}/artifact/tuinity-paperclip.jar"
log "Downloading Tuinity (build $TUINITY_BUILD) from $downloadUrl ..."
curl -fsSL -o "$SERVER" "$downloadUrl"
if [ ! -f "$SERVER" ]; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -1,49 +0,0 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
set -o pipefail
export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar"
if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
log "Downloading $SERVER ..."
debug "Finding version manifest for $VANILLA_VERSION"
versionManifestUrl=$(curl -fsSL '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)"
exit 1
fi
if [ $versionManifestUrl = "null" ]; then
log "ERROR couldn't find a matching manifest entry for $VANILLA_VERSION"
exit 1
fi
debug "Found version manifest at $versionManifestUrl"
serverDownloadUrl=$(curl -fsSL ${versionManifestUrl} | jq --raw-output '.downloads.server.url')
result=$?
if [ $result != 0 ]; 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"
exit 1
fi
debug "Downloading server from $serverDownloadUrl"
if isDebugging; then
verbose=-v
fi
curl $verbose -fsSL -o $SERVER $serverDownloadUrl
result=$?
if [ $result != 0 ]; then
log "ERROR failed to download server from $serverDownloadUrl ($result)"
exit 1
fi
fi
isDebugging && ls -l
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,30 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
: ${VANILLA_VERSION:?}
: ${RELEASE:=latest}
: ${FORCE_REDOWNLOAD:=false}
requireEnum RELEASE stable latest
export SERVER="yatopia-${RELEASE}-${VANILLA_VERSION}.jar"
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
downloadUrl="https://api.yatopiamc.org/v2/${RELEASE}Build/download?branch=ver/${VANILLA_VERSION}"
log "Downloading Yatopia from $downloadUrl ..."
if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,51 +0,0 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
: ${ENV_VARIABLE_PREFIX:=CFG_}
if isTrue "${REPLACE_ENV_VARIABLES}"; then
log "Replacing env variables in configs that match the prefix $ENV_VARIABLE_PREFIX ..."
# File excludes
fileExcludes=
for f in ${REPLACE_ENV_VARIABLES_EXCLUDES}; do
fileExcludes="${fileExcludes} -not -name $f"
done
# Directory excludes (recursive)
dirExcludes=$(join_by " -o -path " ${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS})
if [[ $dirExcludes ]]; then
dirExcludes=" -type d ( -path ${dirExcludes} ) -prune -o"
fi
isDebugging && echo "Using find file exclusions: $fileExcludes"
isDebugging && echo "Using find directory exclusions: $dirExcludes"
for name in $(compgen -v $ENV_VARIABLE_PREFIX); do
# check if name of env variable matches the prefix
# sanity check environment variables to avoid code injections
# Read content from file environment
if [[ $name = *"_FILE" ]]; then
value=$(<${!name})
name="${name%_FILE}"
else
value=${!name}
fi
log "Replacing $name with $value ..."
value=${value//\\/\\\\}
value=${value//#/\\#}
find /data/ \
$dirExcludes \
-type f \
\( -name "*.yml" -or -name "*.yaml" -or -name "*.txt" -or -name "*.cfg" \
-or -name "*.conf" -or -name "*.properties" -or -name "*.hjson" -or -name "*.json" \) \
$fileExcludes \
-exec sed -i 's#${'"$name"'}#'"$value"'#g' {} \;
done
fi
exec ${SCRIPTS:-/}start-minecraftFinalSetup $@

View File

@@ -1,188 +0,0 @@
#!/bin/bash
set -e -o pipefail
. ${SCRIPTS:-/}start-utils
if isDebugging; then
set -x
fi
# CURSE_URL_BASE used in manifest downloads below
CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects}
# Remove old mods/plugins
if isTrue ${REMOVE_OLD_MODS:-false}; then
removeOldMods /data/mods
removeOldMods /data/plugins
fi
# If supplied with a URL for a modpack (simple zip of jars), download it and unpack
if [[ "$MODPACK" ]]; then
if isURL "${MODPACK}"; then
if [[ "${MODPACK}" == *.zip ]]; then
downloadUrl="${MODPACK}"
else
downloadUrl=$(curl -Ls -o /dev/null -w %{effective_url} $MODPACK)
if ! [[ $downloadUrl == *.zip ]]; then
log "ERROR Invalid URL given for MODPACK: $downloadUrl resolved from $MODPACK"
log " Must be HTTP, HTTPS or FTP and a ZIP file"
exit 1
fi
fi
log "Downloading mod/plugin pack"
log " from $downloadUrl ..."
if ! curl -sSL -o /tmp/modpack.zip "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl"
exit 2
fi
elif [[ "$MODPACK" =~ .*\.zip ]]; then
if ! cp $MODPACK /tmp/modpack.zip; then
log "ERROR: failed to copy from $MODPACK"
exit 2
fi
else
log "ERROR Invalid URL or Path given for MODPACK: $MODPACK"
exit 1
fi
if [ "$TYPE" = "SPIGOT" ]; then
mkdir -p /data/plugins
if ! unzip -o -d /data/plugins /tmp/modpack.zip; then
log "ERROR: failed to unzip the modpack from $downloadUrl"
fi
else
mkdir -p /data/mods
if ! unzip -o -d /data/mods /tmp/modpack.zip; then
log "ERROR: failed to unzip the modpack from $downloadUrl"
fi
fi
rm -f /tmp/modpack.zip
fi
# If supplied with a URL for a plugin download it.
if [[ "$MODS" ]]; then
if [ "$TYPE" = "SPIGOT" ]; then
out_dir=/data/plugins
else
out_dir=/data/mods
fi
mkdir -p "$out_dir"
for i in ${MODS//,/ }
do
if isURL $i; then
log "Downloading mod/plugin $i ..."
if isValidFileURL jar "$i"; then
if ! curl -fsSL -o "${out_dir}/$(getFilenameFromUrl "${i}")" "${i}"; then
log "ERROR: failed to download from $i into $out_dir"
exit 2
fi
else
effective_url=$(resolveEffectiveUrl "$i")
if isValidFileURL jar "${effective_url}"; then
out_file=$(getFilenameFromUrl "${effective_url}")
if ! curl -fsSL -o "${out_dir}/$out_file" "${effective_url}"; then
log "ERROR: failed to download from $i into $out_dir"
exit 2
fi
else
log "ERROR: $effective_url resolved from $i is not a valid jar URL"
exit 2
fi
fi
elif [[ -f "$i" && "$i" =~ .*\.jar ]]; then
log "Copying plugin located at $i ..."
out_file=$(basename "$i")
if ! cp "$i" "${out_dir}/$out_file"; then
log "ERROR: failed to copy from $i into $out_dir"
exit 2
fi
elif [[ -d "$i" ]]; then
log "Copying plugin jars from $i ..."
cp "$i"/*.jar "${out_dir}"
else
log "ERROR Invalid URL or path given in MODS: $i"
exit 2
fi
done
fi
if [[ "$MANIFEST" ]]; then
if [[ -e "$MANIFEST" ]]; then
EFFECTIVE_MANIFEST_FILE=$MANIFEST
elif isURL "$MANIFEST"; then
EFFECTIVE_MANIFEST_FILE=/tmp/manifest.json
EFFECTIVE_MANIFEST_URL=$(curl -Ls -o /dev/null -w %{effective_url} $MANIFEST)
curl -Ls -o $EFFECTIVE_MANIFEST_FILE "$EFFECTIVE_MANIFEST_URL"
else
log "MANIFEST='$MANIFEST' is not a valid manifest url or location"
exit 2
fi
case "X$EFFECTIVE_MANIFEST_FILE" in
X*.json)
if [ -f "${EFFECTIVE_MANIFEST_FILE}" ]; then
MOD_DIR=${FTB_BASE_DIR:-/data}/mods
if [ ! -d "$MOD_DIR" ]
then
log "Creating mods dir $MOD_DIR"
mkdir -p "$MOD_DIR"
fi
log "Starting manifest download..."
cat "${EFFECTIVE_MANIFEST_FILE}" | jq -r '.files[] | (.projectID|tostring) + " " + (.fileID|tostring)'| while read -r p f
do
if [ ! -f $MOD_DIR/${p}_${f}.jar ]
then
redirect_url="$(curl -Ls -o /dev/null -w %{effective_url} ${CURSE_URL_BASE}/${p})"
url="$redirect_url/download/${f}/file"
log Downloading curseforge mod $url
# Manifest usually doesn't have mod names. Using id should be fine, tho
curl -sSL "${url}" -o $MOD_DIR/${p}_${f}.jar
fi
done
else
log "Could not find manifest file, unsufficient privs, or malformed path."
fi
;;
*)
log "Invalid manifest file for modpack. Please make sure it is a .json file."
;;
esac
fi
if [[ "${GENERIC_PACK}" ]]; then
if isURL "${GENERIC_PACK}"; then
log "Downloading generic pack ..."
curl -fsSL -o /tmp/generic_pack.zip "${GENERIC_PACK}"
GENERIC_PACK=/tmp/generic_pack.zip
fi
sum_file=/data/.generic_pack.sum
if ! sha256sum -c ${sum_file} -s 2> /dev/null; then
base_dir=/tmp/generic_pack_base
mkdir -p ${base_dir}
isDebugging && ls -l "${GENERIC_PACK}"
unzip -q -d ${base_dir} "${GENERIC_PACK}"
if [ -f /data/manifest.txt ]; then
log "Manifest exists from older generic pack, cleaning up ..."
while read f; do
rm -rf "/data/${f}"
done < /data/manifest.txt
find /data/* -type d -exec rmdir --ignore-fail-on-non-empty {} +
rm -f /data/manifest.txt
fi
log "Writing generic pack manifest ... "
find ${base_dir} -type f -print0 | xargs -0 -I {} echo "{}" | sed "s#${base_dir}/##" > /data/manifest.txt
log "Applying generic pack ..."
IFS='
'
set -f
for d in $(find ${base_dir} -type d); do mkdir -p "$(sed "s#${base_dir}#/data#" <<< $d)"; done
for f in $(find ${base_dir} -type f); do cp -f "$f" "$(sed "s#${base_dir}#/data#" <<< $f)"; done
rm -rf ${base_dir}
sha256sum "${GENERIC_PACK}" > ${sum_file}
fi
fi
exec ${SCRIPTS:-/}start-finalSetupModconfig $@

View File

@@ -1,40 +0,0 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
: ${PLUGINS_SYNC_UPDATE:=true}
isDebugging && set -x
if [ -d /plugins ]; then
case ${TYPE} in
SPIGOT|BUKKIT|PAPER|MAGMA)
mkdir -p /data/plugins
log "Copying plugins over..."
if isTrue ${PLUGINS_SYNC_UPDATE}; then
updateArg="--update"
fi
# Copy plugins over using rsync to allow deeply nested updates of plugins
rsync -a --out-format="update:%f:Last Modified %M" --prune-empty-dirs $updateArg /plugins /data
;;
esac
fi
# If any modules have been provided, copy them over
: ${COPY_MODS_DEST:="/data/mods"}
if [ -d /mods ]; then
log "Copying any mods over..."
mkdir -p "${COPY_MODS_DEST}"
rsync -a --out-format="update:%f:Last Modified %M" "${rsyncArgs[@]}" --prune-empty-dirs --update /mods/ "${COPY_MODS_DEST}"
fi
: ${COPY_CONFIG_DEST:="/data/config"}
if [ -d /config ]; then
log "Copying any configs from /config to ${COPY_CONFIG_DEST}"
mkdir -p "${COPY_CONFIG_DEST}"
rsync -a --out-format="update:%f:Last Modified %M" "${rsyncArgs[@]}" --prune-empty-dirs --update /config/ "${COPY_CONFIG_DEST}"
fi
exec ${SCRIPTS:-/}start-finalSetupServerProperties $@

View File

@@ -1,220 +0,0 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
: ${SERVER_PROPERTIES:=/data/server.properties}
# FUNCTIONS
function setServerProp {
local prop=$1
local var=$2
if [ -n "$var" ]; then
# normalize booleans
case ${var^^} in
TRUE|FALSE)
var=${var,,} ;;
esac
if grep "${prop}" "$SERVER_PROPERTIES" > /dev/null; then
log "Setting ${prop} to '${var}' in ${SERVER_PROPERTIES}"
sed -i "/^${prop}\s*=/ c ${prop}=${var//\\/\\\\}" "$SERVER_PROPERTIES"
else
log "Adding ${prop} with '${var}' in ${SERVER_PROPERTIES}"
echo "${prop}=${var}" >> "$SERVER_PROPERTIES"
fi
else
isDebugging && log "Skip setting ${prop}"
fi
}
function customizeServerProps {
if [ -n "$WHITELIST" ] || isTrue ${ENABLE_WHITELIST:-false}; then
log "Creating whitelist"
setServerProp "whitelist" "true"
setServerProp "white-list" "true"
else
log "Disabling whitelist"
setServerProp "whitelist" "false"
setServerProp "white-list" "false"
fi
# If not provided, generate a reasonable default message-of-the-day,
# which shows up in the server listing in the client
if [ -z "$MOTD" ]; then
# snapshot is the odd case where we have to look at version to identify that label
if [[ ${ORIGINAL_TYPE} == "VANILLA" && ${VERSION} == "SNAPSHOT" ]]; then
label=SNAPSHOT
else
label=${ORIGINAL_TYPE}
fi
# Convert label to title-case
label=${label,,}
label=${label^}
MOTD="A ${label} Minecraft Server powered by Docker"
fi
setServerProp "server-name" "$SERVER_NAME"
setServerProp "server-ip" "$SERVER_IP"
setServerProp "server-port" "$SERVER_PORT"
setServerProp "motd" "$MOTD"
setServerProp "allow-nether" "$ALLOW_NETHER"
setServerProp "announce-player-achievements" "$ANNOUNCE_PLAYER_ACHIEVEMENTS"
setServerProp "enable-command-block" "$ENABLE_COMMAND_BLOCK"
setServerProp "spawn-animals" "$SPAWN_ANIMALS"
setServerProp "spawn-monsters" "$SPAWN_MONSTERS"
setServerProp "spawn-npcs" "$SPAWN_NPCS"
setServerProp "spawn-protection" "$SPAWN_PROTECTION"
setServerProp "generate-structures" "$GENERATE_STRUCTURES"
setServerProp "view-distance" "$VIEW_DISTANCE"
setServerProp "hardcore" "$HARDCORE"
setServerProp "snooper-enabled" "$SNOOPER_ENABLED"
setServerProp "max-build-height" "$MAX_BUILD_HEIGHT"
setServerProp "force-gamemode" "$FORCE_GAMEMODE"
setServerProp "max-tick-time" "$MAX_TICK_TIME"
setServerProp "enable-query" "$ENABLE_QUERY"
setServerProp "query.port" "$QUERY_PORT"
setServerProp "enable-rcon" "$ENABLE_RCON"
setServerProp "rcon.password" "$RCON_PASSWORD"
setServerProp "rcon.port" "$RCON_PORT"
setServerProp "max-players" "$MAX_PLAYERS"
setServerProp "max-world-size" "$MAX_WORLD_SIZE"
setServerProp "level-name" "$LEVEL"
setServerProp "level-seed" "$SEED"
setServerProp "pvp" "${PVP}"
setServerProp "generator-settings" "$GENERATOR_SETTINGS"
setServerProp "online-mode" "$ONLINE_MODE"
setServerProp "allow-flight" "$ALLOW_FLIGHT"
setServerProp "level-type" "${LEVEL_TYPE^^}"
setServerProp "resource-pack" "$RESOURCE_PACK"
setServerProp "resource-pack-sha1" "$RESOURCE_PACK_SHA1"
setServerProp "player-idle-timeout" "$PLAYER_IDLE_TIMEOUT"
setServerProp "broadcast-console-to-ops" "$BROADCAST_CONSOLE_TO_OPS"
setServerProp "broadcast-rcon-to-ops" "$BROADCAST_RCON_TO_OPS"
setServerProp "enable-jmx-monitoring" "$ENABLE_JMX"
setServerProp "sync-chunk-writes" "$SYNC_CHUNK_WRITES"
setServerProp "enable-status" "$ENABLE_STATUS"
setServerProp "entity-broadcast-range-percentage" "$ENTITY_BROADCAST_RANGE_PERCENTAGE"
setServerProp "function-permission-level" "$FUNCTION_PERMISSION_LEVEL"
setServerProp "network-compression-threshold" "$NETWORK_COMPRESSION_THRESHOLD"
setServerProp "op-permission-level" "$OP_PERMISSION_LEVEL"
setServerProp "prevent-proxy-connections" "$PREVENT_PROXY_CONNECTIONS"
setServerProp "use-native-transport" "$USE_NATIVE_TRANSPORT"
setServerProp "enforce-whitelist" "$ENFORCE_WHITELIST"
if [ -n "$DIFFICULTY" ]; then
case $DIFFICULTY in
peaceful|0)
if versionLessThan 1.13; then
DIFFICULTY=0
else
DIFFICULTY=peaceful
fi
;;
easy|1)
if versionLessThan 1.13; then
DIFFICULTY=1
else
DIFFICULTY=easy
fi
;;
normal|2)
if versionLessThan 1.13; then
DIFFICULTY=2
else
DIFFICULTY=normal
fi
;;
hard|3)
if versionLessThan 1.13; then
DIFFICULTY=3
else
DIFFICULTY=hard
fi
;;
*)
log "DIFFICULTY must be peaceful, easy, normal, or hard."
exit 1
;;
esac
setServerProp "difficulty" "$DIFFICULTY"
fi
if [ -n "$MODE" ]; then
log "Setting mode"
MODE_LC=$( echo $MODE | tr '[:upper:]' '[:lower:]' )
case $MODE_LC in
su*|0)
if versionLessThan 1.13; then
MODE=0
else
MODE=survival
fi
;;
c*|1)
if versionLessThan 1.13; then
MODE=1
else
MODE=creative
fi
;;
a*|2)
if versionLessThan 1.13; then
MODE=2
else
MODE=adventure
fi
;;
sp*|3)
if versionLessThan 1.13; then
MODE=3
else
MODE=spectator
fi
;;
*)
log "ERROR: Invalid game mode: $MODE"
exit 1
;;
esac
setServerProp "gamemode" "$MODE"
fi
}
# Deploy server.properties file
if [[ ${TYPE} == "CURSEFORGE" ]]; then
export SERVER_PROPERTIES="${FTB_DIR}/server.properties"
log "detected FTB, changing properties path to ${SERVER_PROPERTIES}"
fi
if [ ! -e "$SERVER_PROPERTIES" ]; then
log "Creating server.properties in ${SERVER_PROPERTIES}"
cp /tmp/server.properties "$SERVER_PROPERTIES"
customizeServerProps
elif [ -n "${OVERRIDE_SERVER_PROPERTIES}" ]; then
case ${OVERRIDE_SERVER_PROPERTIES^^} in
TRUE|1)
customizeServerProps
;;
*)
log "server.properties already created, skipping"
;;
esac
else
log "server.properties already created, skipping"
fi
if isTrue "${ENABLE_AUTOPAUSE}"; then
current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' )
if (( $current_max_tick > 0 && $current_max_tick < 86400000 )); then
log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled."
log "Warning (cont): Autopause functionality resuming the process might trigger the Watchdog and restart the server completely."
log "Warning (cont): Set the max-tick-time property to a high value (or disable the Watchdog with value -1 for versions 1.8.1+)."
fi
fi
if isDebugging; then
log "DEBUG Dumping server.properties"
cat "${SERVER_PROPERTIES}"
fi
exec ${SCRIPTS:-/}start-finalSetupEnvVariables $@

View File

@@ -1,69 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
handleDebugMode
: ${SPIGET_RESOURCES:=}
containsJars() {
file=${1?}
pat='\.jar$'
while read -r line; do
if [[ $line =~ $pat ]]; then
return 0
fi
done <<<$(unzip -l "$file")
return 1
}
getResourceFromSpiget() {
resource=${1?}
log "Downloading resource ${resource} ..."
mkdir -p /data/plugins
if [ -f /data/plugins/.${resource} ]; then
log "Resource '${resource}' already downloaded"
else
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
fi
if containsJars "${tmpfile}"; then
log "Extracting contents of resource ${resource} into plugins"
unzip -o -q -d /data/plugins "${tmpfile}"
touch "/data/plugins/.${resource}"
rm "${tmpfile}"
else
log "Moving resource ${resource} into plugins"
mv "${tmpfile}" "/data/plugins/${resource}.jar"
touch "/data/plugins/.${resource}"
fi
fi
}
if [[ ${SPIGET_RESOURCES} ]]; then
if isTrue ${REMOVE_OLD_MODS:-false}; then
removeOldMods /data/plugins
REMOVE_OLD_MODS=false
fi
log "Getting plugins via Spiget"
IFS=',' read -r -a resources <<<"${SPIGET_RESOURCES}"
for resource in "${resources[@]}"; do
getResourceFromSpiget "${resource}"
done
fi
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld $@

View File

@@ -1,18 +0,0 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
if ! [[ -v CURSE_INSTANCE_JSON ]]; then
log "ERROR: CURSE_INSTANCE_JSON needs to be set"
exit 2
elif ! [ -f "${CURSE_INSTANCE_JSON}" ] && [ -f "${CURSE_INSTANCE_JSON}/minecraftinstance.json" ]; then
CURSE_INSTANCE_JSON="${CURSE_INSTANCE_JSON}/minecraftinstance.json"
elif ! [ -f "${CURSE_INSTANCE_JSON}" ]; then
log "ERROR: CURSE_INSTANCE_JSON file does not exist: ${CURSE_INSTANCE_JSON}"
exit 2
fi
log "Resolved CURSE_INSTANCE_JSON as ${CURSE_INSTANCE_JSON}"
# Continue to Final Setup
exec ${SCRIPTS:-/}start-finalSetupWorld "$@"

View File

@@ -1,20 +0,0 @@
version: "3.8"
services:
sut:
depends_on:
- mc
image: itzg/mc-monitor:0.6.0
command: status --host mc --retry-interval 1s --retry-limit 120
mc:
restart: "no"
build:
context: ..
args:
TARGETOS: linux
TARGETARCH: amd64
cache_from:
- itzg/minecraft-server:latest
environment:
EULA: "TRUE"

15
tests/docker-compose.yml Normal file
View File

@@ -0,0 +1,15 @@
version: "3.8"
services:
monitor:
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
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}

View File

@@ -0,0 +1,15 @@
version: "3"
services:
mc:
image: itzg/minecraft-server
environment:
EULA: "true"
GENERIC_PACKS: https://github.com/itzg/mc-image-helper/releases/download/v1.9.5/mc-image-helper-1.9.5.zip,/packs/testing.zip
DEBUG: "true"
volumes:
- ./packs:/packs
- data:/data
volumes:
data: {}

Binary file not shown.

View File

@@ -1,17 +1,22 @@
#!/bin/bash
cd $(dirname $0)
cd "$(dirname "$0")" || exit 1
failed=false
args="-f docker-compose.test.yml"
docker-compose $args run sut || failed=true
down() {
docker-compose down -v
}
docker-compose run monitor || failed=true
echo "
Result: failed=$failed"
$failed && docker-compose $args logs mc
docker-compose $args down -v
if $failed; then
docker-compose logs mc
down
exit 1
else
down
fi