Overhaul of start.sh and Dockerfiles
This project is a great public resource, and I wanted to give back by putting some effort into giving things a facelift.
I have tested this new image repeatedly against a couple of my test instances in kubernetes that use this project. The changes have worked well for me, there is a caveat here. The image has been running as root for a long time, and recently start.sh was updated to have execution switch over to a new minecraft user after changing ownership of all files to the new user.
[!WARNING] The changes here are not breaking (as far as I can tell) if people have already been running that most recent image with the
root->minecraftuser. However, if users have not previously launched with this more recent image, then all their files will still be owned byroot, and images build from this PR will not be able to change ownership (since it runs as a non-root user, it cannot change ownership of files owned byroot).There is a workaround for this: run the container once as
root. That will trigger the current (and retained) conditional block at the beginning of the script to change ownership of all files and then rerun the start script as theminecraftuser. Alternatively, users could go in and manually set ownership of everything in the/minecraftdirectory to theminecraftuser/group (uid:gid 999:999).This is easily done in a compose file by adding
user: rootto the minecraft container service. For example:... services: minecraftbe: image: 05jchambers/legendary-minecraft-geyser-floodgate:latest user: root ...Run it that way once, then afterwards you can remove that additional line.
In kubernetes, the same thing can be accomplished by defining the
spec.template.spec.securityContextfor the Deployment/StatefulSet. For example:... spec: ... template: ... spec: securityContext: runAsUser: 0 runAsGroup: 0 ...
[!IMPORTANT] This branch is based on the other PR I submitted (#42) to update
start.shto work with the new endpoint for PaperMC's API. That one should be merged before this one.
There are a lot of changes here, but I'll do my best to summarize/explain them here:
- Dockerfiles
- amd64
- Removed the unneeded builder stage since nothing from it is copied over to the main stage
- non-amd64
- Added the platform to the builder stage. Note that this way of doing multiarch images (hardcoding the platform inside the Dockerfile) is discouraged by Docker now, and generates warnings when building the images.
- All
- Removed the
sudopackage, since it isn't needed anymore - Alphabetized the package installs and broke up the main one to one package per line for better visibility and easier auditing
- Changed the
apt updateto the preferredapt-get updatefor scripting - Create the
minecraftuser and group - Create the
/minecraftdirectory (so that we can set it as the WORKDIR) and set its permissions - Set the default USER to
minecraft - Set the WORKDIR to
/minecraftso when we exec into the container, it drops us right into that directory
- Removed the
- amd64
-
start.sh- Made a lot of tweaks to the logging/echos in the script to make the log output more informative, clear, and easier to parse.
- Changed the logic for respecting the
QuietCurloverride so that each command using it is not duplicated. Duplication like that is an easy way to introduce bugs by forgetting to make a change to both commands. Replicated this same approach to similar command duplication in the script as well. - Made changes to resolve with a handful of bash linting (ShellCheck) warnings (unused variables,
findvsls -1tr, double quotes on variables to prevent globbing,||conditions when changing directories, checking for variable/env var existence before use, etc.) - Broke up long commands with lots of flags into multi-line commands for readability and auditability.
- Changed the backup tar command to not be verbose. It makes the logs SO long when dumping them from Docker or Kubernetes and I didn't see the value in listing every single file that is put into the backup. I messed around a while with tar checkpoints, but some of our backups are going to be pretty big with large enough maps, so in the end I opted to just omit all of that.
- Reworked the command to delete old backups primarily based on ShellCheck suggestions. I did test the new logic and it consistently worked. Note that setting
BackupCountto 0 will delete all backups. - Consolidated the Paper build
jqlogic to automatically fall back to check the latest experimental channel build if no default channel builds are found for the desired version. This was done to, again, remove the need for a duplicated command that could lead to bugs over time. - Abstracted away the common
curlarguments/flags into an array so they didn't clutter up the script as much. - Moved the port variable checks down to where the port values are set in the config files.
I think that about covers it. I am happy to discuss anything that seems confusing or why I made some of the choices I did.
Fixes #41, which is what lead me down this path anyway, since you can't actually run the container as the minecraft user in its current state, which, in my opinion, is the "better" way to do this vs obfuscating it within the entrypoint script.
I cannot seem to view the results of the failed tests from Docker Hub. If you can tell me why they failed, I'll gladly make adjustments.
As a test, I ran the arm64v8 build locally and it seemed to build fine, so I do not have any signal as to the cause of the test failures.
Here is sample log output from a run targeting server 1.21.4 without QuietCurl:
################################################################################################################
Paper Minecraft Java Server Docker + Geyser/Floodgate script by James A. Chambers
################################################################################################################
Latest version always at https://github.com/TheRemote/Legendary-Java-Minecraft-Geyser-Floodgate
Don't forget to set up port forwarding on your router! The default port is 25565 and the Bedrock port is 19132.
************************************************************************
Prepare Environment
************************************************************************
Checking volume mount ...
Volume mount found for /minecraft
Checking network interface status ...
Network interface is up.
Checking ownership of all server files/folders in /minecraft for user:group - 'minecraft:minecraft' ...
Ownership check complete. Any errors above could indicate an issue.
Running backup ...
Backing up server (all cores) to /minecraft/backups folder...
Total bytes written: 370677760 (354MiB, 23MiB/s)
Updating to most recent Paper server version ...
Found latest Paper build 72 for version 1.21.4
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 48.9M 100 48.9M 0 0 39.0M 0 0:00:01 0:00:01 --:--:-- 39.0M
Updating Floodgate ...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 10.9M 100 10.9M 0 0 17.6M 0 --:--:-- --:--:-- --:--:-- 17.6M
Updating Geyser ...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 20.9M 100 20.9M 0 0 36.9M 0 --:--:-- --:--:-- --:--:-- 36.9M
Updating ViaVersion ...
Checking the latest version of ViaVersion ...
ViaVersion is up to date: ViaVersion-5.2.1.jar
Accepting EULA ...
Setting server ports ...
Java port used: 25565
Bedrock port used: 19132
************************************************************************
Launch Minecraft
************************************************************************
Starting Minecraft server ...
...
Here is sample log output from a run targeting server 1.21.3 with QuietCurl and a few NoBackups:
################################################################################################################
Paper Minecraft Java Server Docker + Geyser/Floodgate script by James A. Chambers
################################################################################################################
Latest version always at https://github.com/TheRemote/Legendary-Java-Minecraft-Geyser-Floodgate
Don't forget to set up port forwarding on your router! The default port is 25565 and the Bedrock port is 19132.
************************************************************************
Prepare Environment
************************************************************************
Checking volume mount ...
Volume mount found for /minecraft
Checking network interface status ...
Network interface is up.
Checking ownership of all server files/folders in /minecraft for user:group - 'minecraft:minecraft' ...
Ownership check complete. Any errors above could indicate an issue.
Running backup ...
Excluding the following extra items from backups: ./bluemap,./testing
Backing up server (all cores) to /minecraft/backups folder...
Total bytes written: 358983680 (343MiB, 23MiB/s)
Updating to most recent Paper server version ...
Found latest Paper build 82 for version 1.21.3
Updating Floodgate ...
Updating Geyser ...
Updating ViaVersion ...
Checking the latest version of ViaVersion ...
ViaVersion is up to date: ViaVersion-5.2.1.jar
Accepting EULA ...
Setting server ports ...
Java port used: 25565
Bedrock port used: 19132
************************************************************************
Launch Minecraft
************************************************************************
Starting Minecraft server ...
Here is sample log output from a run with the user for the container overridden as root:
Script is running as 'root', switching to 'minecraft' user ...
Changing ownership of all files in /minecraft to 'minecraft:minecraft' ...
Restarting script as 'minecraft' user.
################################################################################################################
Paper Minecraft Java Server Docker + Geyser/Floodgate script by James A. Chambers
################################################################################################################
Latest version always at https://github.com/TheRemote/Legendary-Java-Minecraft-Geyser-Floodgate
Don't forget to set up port forwarding on your router! The default port is 25565 and the Bedrock port is 19132.
************************************************************************
Prepare Environment
************************************************************************
Checking volume mount ...
Volume mount found for /minecraft
Checking network interface status ...
Network interface is up.
Checking ownership of all server files/folders in /minecraft for user:group - 'minecraft:minecraft' ...
Ownership check complete. Any errors above could indicate an issue.
Running backup ...
Backing up server (all cores) to /minecraft/backups folder...
Total bytes written: 440944640 (421MiB, 23MiB/s)
Updating to most recent Paper server version ...
Found latest Paper build 72 for version 1.21.4
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 48.9M 100 48.9M 0 0 43.1M 0 0:00:01 0:00:01 --:--:-- 43.1M
Updating Floodgate ...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 10.9M 100 10.9M 0 0 18.3M 0 --:--:-- --:--:-- --:--:-- 18.3M
Updating Geyser ...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 20.9M 100 20.9M 0 0 28.1M 0 --:--:-- --:--:-- --:--:-- 56.2M
Updating ViaVersion ...
Checking the latest version of ViaVersion ...
ViaVersion is up to date: ViaVersion-5.2.1.jar
Accepting EULA ...
Setting server ports ...
Java port used: 25565
Bedrock port used: 19132
************************************************************************
Launch Minecraft
************************************************************************
Starting Minecraft server ...
I'll try removing the --platform flags I added to the builder phase in the non-amd64 files and push up that commit to see if it resolves the test failures.
Edit - well, that's closer. I wish I could see what the test failure logs are. Please let me know why that one remaining test is failing. Are these tests flaky?