Skip to content

Overhaul of start.sh and Dockerfiles #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

cyberops7
Copy link

@cyberops7 cyberops7 commented Jan 4, 2025

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 -> minecraft user. However, if users have not previously launched with this more recent image, then all their files will still be owned by root, 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 by root).

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 the minecraft user. Alternatively, users could go in and manually set ownership of everything in the /minecraft directory to the minecraft user/group (uid:gid 999:999).

This is easily done in a compose file by adding user: root to 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.securityContext for 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.sh to 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 sudo package, 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 update to the preferred apt-get update for scripting
      • Create the minecraft user and group
      • Create the /minecraft directory (so that we can set it as the WORKDIR) and set its permissions
      • Set the default USER to minecraft
      • Set the WORKDIR to /minecraft so when we exec into the container, it drops us right into that directory
  • 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 QuietCurl override 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, find vs ls -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 BackupCount to 0 will delete all backups.
    • Consolidated the Paper build jq logic 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 curl arguments/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.

… This includes cleaning up the version extraction from the JSON response by using jq. Adding jq to the Dockerfiles to support this. Also adding vim to the Dockerfiles so that users have a choice between nano and vim.
…inecraft, the USER to minecraft, changing apt to apt-get, and removing unused build stage from the amd64 Dockerfile; shart.sh - lots and lots of changes to streamline some logic (e.g. around QuietCurl), fix bash linting warnings, logging tweaks, consolidating common curl args, suppressing verbose file output for backups, other miscellaneous tweaks
… removed sudo from the install list since we are now running as the minecraft user (which cannot sudo, that's kind of the point), alphabetizing the apt-get install lists to make auditing/checking easier, breaking the long apt-get installs into one package per line to make auditing/checking much easier, making MaxMemory= instead of just = is explicit and makes IDEs happier (plus bash doesn't have variable types, so it isn't like this was an int and now is a string), adding new minecraft user changes to all Dockerfiles
…g more things, reverting some logs from printf because they end up delayed flushing to stdout, tweaking some more logs/echos
…output during backups...it'll just be noisy and clutter the logs (albeit much less than the previous highly verbose backup logging)
@cyberops7
Copy link
Author

cyberops7 commented Jan 4, 2025

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.

@cyberops7 cyberops7 changed the title [DRAFT] Overhaul of start.sh and Dockerfiles Overhaul of start.sh and Dockerfiles Jan 4, 2025
@cyberops7 cyberops7 marked this pull request as ready for review January 4, 2025 06:52
@cyberops7
Copy link
Author

cyberops7 commented Jan 4, 2025

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 ...
...

@cyberops7
Copy link
Author

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 ...

@cyberops7
Copy link
Author

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 ...

@cyberops7
Copy link
Author

cyberops7 commented Jan 4, 2025

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?

… stages to see if that change is what broke the failing tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Script cannot start as user minecraft (999)
1 participant