itzg / docker-minecraft-server

Docker image that provides a Minecraft Server that will automatically download selected version at startup
https://docker-minecraft-server.readthedocs.io/
Apache License 2.0
9.23k stars 1.52k forks source link

Docker Compose Not Handling JVM_XX_OPTS in Quotes #1311

Closed coryjreid closed 2 years ago

coryjreid commented 2 years ago

Describe the problem

I'm trying to convert my Docker command into a Docker Compose file (admittedly I am new to this). As far as I can tell I've done it correctly, but when attempting to start the container I receive the error: Error: Could not find or load main class '-XX:+UseG1GC.

I did remove the quotes and that rectified the problem.

Container definition

version: '3'
services:
  <omitted>:
    container_name: '<omitted>'
    image: 'itzg/minecraft-server:java8-openj9'
    environment:
      - UID=1000
      - GID=1000
      - EULA=TRUE
      - VERSION=1.16.5
      - TYPE=FORGE
      - FORGEVERSION=36.2.23
      - DIFFICULTY=hard
      - ENFORCE_WHITELIST=true
      - WHITELIST=<omitted>
      - OPS=<omitted>
      - FORCE_GAMEMODE=true
      - ALLOW_FLIGHT=true
      - ENABLE_COMMAND_BLOCK=true
      - SNOOPER_ENABLED=false
      - MAX_TICK_TIME=-1
      - ENABLE_RCON=true
      - RCON_PASSWORD=<omitted>
      - GUI=FALSE
      - TUNE_VIRTUALIZED=TRUE
      - TUNE_NURSERY_SIZES=TRUE
      - MEMORY=8G
      - JVM_XX_OPTS='-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true'
    volumes:
      - '<omitted>:/data'
    ports:
      - '25100:25565'
      - '26100:25575'
    restart: unless-stopped
    cap_add:
      - SYS_ADMIN
    tty: true
    stdin_open: true

Container logs

Paste logs here
shotah commented 2 years ago

The formatting looks a little strange. I'm sure it's working but maybe you can try using a more yaml'fied version like so.

    environment:
      EULA: "TRUE"
      TYPE: FABRIC
      VERSION: "1.18.1"
      INIT_MEMORY: 4G
      MAX_MEMORY: 8G
      JVM_DD_OPTS: >
        sun.rmi.dgc.server.gcInterval=2147483646
        fml.readTimeout=180
      JVM_OPTS: >
        -XX:+UseG1GC
        -XX:+UnlockExperimentalVMOptions
        -XX:G1NewSizePercent=20
        -XX:G1ReservePercent=20
        -XX:MaxGCPauseMillis=50
        -XX:G1HeapRegionSize=32M
        -Dlog4j2.formatMsgNoLookups=TRUE
      # NOTE: Change this if going back
      HARDCORE: "TRUE"
      PVP: "FALSE"     
itzg commented 2 years ago

Agreed on the suggestion.

BTW Aikars flags is already supported with one variable

https://github.com/itzg/docker-minecraft-server#enable-aikars-flags

coryjreid commented 2 years ago

Fair suggestions. However I still think it should be considered that wrapping arguments in single/double quotes breaking the launch command shouldn't happen.

Having one of the docker-compose.yml examples show to not use the quotes could also potentially alleviate the issue for other noobs. Just a thought. :)

coryjreid commented 2 years ago

Also, not to be totally pedantic - but I was following Docker's own style guide for Docker Compose.

https://docs.docker.com/compose/compose-file/compose-file-v3/#environment

itzg commented 2 years ago

Now I'm confused. Is there something wrong with this repo's documentation, examples, or something else?

itzg commented 2 years ago

...did you provide the right link? That's not a style guide from what I can tell. Besides, the quotes weren't the problem. It was the line breaks in the middle of the quoted string.

FWIW https://learnxinyminutes.com/docs/yaml/

itzg commented 2 years ago

...and https://stackoverflow.com/questions/3790454/how-do-i-break-a-string-in-yaml-over-multiple-lines/21699210

coryjreid commented 2 years ago

I'm sorry - I feel like I have upset you. That was not my intent.

Yes, I provided the correct link to Docker's documentation which shows how to define services in a docker-compose.yml file, showing the dashes are fine. My point there was to show formatting wasn't the issue.

The link to learnxinyminutes says "Notice that strings don't need to be quoted. However, they can be.", which to me implies there shouldn't have been anything wrong with wrapping that string. Maybe I'm wrong - and that's fine.

Looking at the original error message I provided maybe wasn't clear enough. Here's the full command which shows how the quotes are improperly handled:

exec mc-server-runner --stop-duration 60s --named-pipe /tmp/minecraft-console-in java '"-XX:+UseG1GC' -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs '-Daikars.new.flags=true"' -Xmx8G -Xms8G -Dlog4j2.formatMsgNoLookups=true -jar forge-1.16.5-36.2.23.jar nogui

You can see how the quotes escaped improperly. Whether that's Docker's fault or a script within this container I do not know.

I also didn't break the string across multiple lines (and didn't want to), so I fail to see the point of the SO link other than a means of avoiding an issue that exists.

I didn't see an example compose file which showed using JVM_XX_OPTS (or other) and splitting it into multiple lines, is why I suggested "maybe an example could help".

Still - appreciate the work you put into maintaining this container. Been using it for a very long time and plan to despite this being a rough interaction. I hadn't seen the new AIKARS flag, which sidesteps the issue for me. But if someone used different flags though, and they're quoting them, they'll have the same issue.

Again, I advised I'm new to using Docker Compose (and in turn YML), so I'm not trying to be rude. It's quite unclear that quotes could be so problematic since examples interchange, for example: TRUE, 'true', "true", etc. But now I know!

Take care! :)

itzg commented 2 years ago

Aha! The snippet you provided reveals a whole lot of clarity. This might be something handled incorrectly by the script since bash quoting of arguments is bizarre. I'll re-open now that I understand the root problem.

exec mc-server-runner --stop-duration 60s --named-pipe /tmp/minecraft-console-in java '"-XX:+UseG1GC' -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs '-Daikars.new.flags=true"' -Xmx8G -Xms8G -Dlog4j2.formatMsgNoLookups=true -jar forge-1.16.5-36.2.23.jar nogui
itzg commented 2 years ago

...I added the bug label, but that's tentative since I need to try this out to see if it's YAML or argument quoting at play.

wertercatt commented 2 years ago

Chiming in to note that this repository's README.md uses quotes when giving an example of using the JVM_XX_OPTS environment variable.

https://github.com/itzg/docker-minecraft-server/blob/6d27ce8461f5ee9fd8d55bcc10dbe7df0c9995c1/README.md#L1415

itzg commented 2 years ago

I finally made my way through the todo list to take a look at this one. It turns out it's a yaml/docker thing but confusingly acts differently than the docker run command line.

So, when using the list-style declaration of environment, the string following the equal sign is used exactly.

This doesn't work:

    environment:
      - EULA=TRUE
      - JVM_XX_OPTS='-XX:+UseG1GC -XX:+ParallelRefProcEnabled'

and double quotes also don't work:

    environment:
      - EULA=TRUE
      - JVM_XX_OPTS="-XX:+UseG1GC -XX:+ParallelRefProcEnabled"

This does work without the quotes:

    environment:
      - EULA=TRUE
      - JVM_XX_OPTS=-XX:+UseG1GC -XX:+ParallelRefProcEnabled

Now @wertercatt 's comment brings up a confusing difference. On the docker run command line the quotes are required or else the shell will think that a new argument starts at the space:

docker run -e JVM_XX_OPTS=-XX:+UseG1GC -XX:+ParallelRefProcEnabled
                                      ^
                                      |
        Without quotes, the shell thinks this is the start of a new argument

This ambiguity is one of many reasons I prefer the object style declaration of environment in compose files:

You can do with quotes:

    environment:
      EULA: TRUE
      JVM_XX_OPTS: "-XX:+UseG1GC -XX:+ParallelRefProcEnabled"

without quotes

    environment:
      EULA: TRUE
      JVM_XX_OPTS: -XX:+UseG1GC -XX:+ParallelRefProcEnabled

line wrapping

    environment:
      EULA: TRUE
      JVM_XX_OPTS: -XX:+UseG1GC 
        -XX:+ParallelRefProcEnabled

and block text

    environment:
      EULA: TRUE
      JVM_XX_OPTS: >
        -XX:+UseG1GC 
        -XX:+ParallelRefProcEnabled