- Dockerfile 51.7%
- Shell 48.3%
| _content | ||
| bashrc | ||
| docker-java-home | ||
| Dockerfile | ||
| entrypoint.sh | ||
| hytale.json | ||
| java.sh | ||
| LICENSE | ||
| README.md | ||
Hytale
Docker image using GraalVM 25 and specific Java arguments to run Hytale under Pterodactyl.
Egg
Use from this source: Pterodactyl Eggs
You can also use provided: hytale.json.
This one contain a modified version of this egg to include docker image and jvm arguments by default.
Docker image
- Hytale requires Java 25 (included in the Docker image)
- Server resource usage depends heavily on player count and view distance
- Higher view distances significantly increase RAM usage
- Hytale uses QUIC over UDP (not TCP) on port 5520
Files used:
- Dockerfile : file to use to build the Docker image
- bashrc : copied to container home
- docker-java-home : to get Java home path
- entrypoint.sh : image main entrypoint (download installer and get settings)
- java.sh : launch server using Java
First-Time Setup: Authentication Required
On first startup, you'll need to authenticate via your browser. The server will display a URL in the console - just visit it and log in with your Hytale account. You will then need to authorize again from the link that appears once the server has started.
Docker Compose
services:
hytale:
image: hytale:latest
restart: unless-stopped
container_name: hytale
stop_grace_period: 30s
ports:
- 5520:5520/udp
stdin_open: false
tty: false
Port Configuration
Hytale uses the QUIC protocol over UDP (not TCP). Make sure to:
- Open UDP port 5520 (or your custom port) in your firewall
- Forward UDP port 5520 in your router if hosting from home
- Configure firewall rules for UDP only
JVM ARGS
Default Service Start Command
These are default egg settings:
java $( ((USE_AOT_CACHE)) && printf %s "-XX:AOTCache=Server/HytaleServer.aot" ) -Xms128M $( ((SERVER_MEMORY)) && printf %s "-Xmx${SERVER_MEMORY}M" ) -jar Server/HytaleServer.jar $( ((HYTALE_ALLOW_OP)) && printf %s "--allow-op" ) $( ((HYTALE_ACCEPT_EARLY_PLUGINS)) && printf %s "--accept-early-plugins" ) $( ((DISABLE_SENTRY)) && printf %s "--disable-sentry" ) --auth-mode ${HYTALE_AUTH_MODE} --assets Assets.zip --bind 0.0.0.0:${SERVER_PORT}
Startup Command
Tuning arguments:
G1GC version (for server below 32GB allocated heap)
--add-modules=jdk.incubator.vector -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=28 -XX:G1MaxNewSizePercent=50 -XX:G1HeapRegionSize=16M -XX:G1ReservePercent=15 -XX:G1MixedGCCountTarget=3 -XX:InitiatingHeapOccupancyPercent=20 -XX:G1MixedGCLiveThresholdPercent=90 -XX:SurvivorRatio=32 -XX:G1HeapWastePercent=5 -XX:MaxTenuringThreshold=1 -XX:+PerfDisableSharedMem -XX:G1SATBBufferEnqueueingThresholdPercent=30 -XX:G1ConcMarkStepDurationMillis=5 -XX:G1RSetUpdatingPauseTimePercent=0 -XX:+UseNUMA -XX:-DontCompileHugeMethods -XX:MaxNodeLimit=240000 -XX:NodeLimitFudgeFactor=8000 -XX:ReservedCodeCacheSize=400M -XX:NonNMethodCodeHeapSize=12M -XX:ProfiledCodeHeapSize=194M -XX:NonProfiledCodeHeapSize=194M -XX:NmethodSweepActivity=1 -XX:+UseFastUnorderedTimeStamps -XX:+UseCriticalJavaThreadPriority -XX:AllocatePrefetchStyle=3 -XX:+AlwaysActAsServerClassMachine -XX:+UseTransparentHugePages -XX:LargePageSizeInBytes=2M -XX:+UseLargePages -XX:+EagerJVMCI -XX:+UseStringDeduplication -XX:+UseAES -XX:+UseAESIntrinsics -XX:+UseFMA -XX:+UseLoopPredicate -XX:+RangeCheckElimination -XX:+OptimizeStringConcat -XX:+UseCompressedOops -XX:+UseThreadPriorities -XX:+OmitStackTraceInFastThrow -XX:+RewriteBytecodes -XX:+RewriteFrequentPairs -XX:+UseFPUForSpilling -XX:+UseFastStosb -XX:+UseNewLongLShift -XX:+UseVectorCmov -XX:+UseXMMForArrayCopy -XX:+UseXmmI2D -XX:+UseXmmI2F -XX:+UseXmmLoadAndClearUpper -XX:+UseXmmRegToRegMoveAll -XX:+EliminateLocks -XX:+DoEscapeAnalysis -XX:+AlignVector -XX:+OptimizeFill -XX:+EnableVectorSupport -XX:+UseCharacterCompareIntrinsics -XX:+UseCopySignIntrinsic -XX:+UseVectorStubs -XX:UseAVX=2 -XX:UseSSE=4 -XX:+UseFastJNIAccessors -XX:+UseInlineCaches -XX:+SegmentedCodeCache -Djdk.nio.maxCachedBufferSize=262144 -Djdk.graal.UsePriorityInlining=true -Djdk.graal.Vectorization=true -Djdk.graal.OptDuplication=true -Djdk.graal.DetectInvertedLoopsAsCounted=true -Djdk.graal.LoopInversion=true -Djdk.graal.VectorizeHashes=true -Djdk.graal.EnterprisePartialUnroll=true -Djdk.graal.VectorizeSIMD=true -Djdk.graal.StripMineNonCountedLoops=true -Djdk.graal.SpeculativeGuardMovement=true -Djdk.graal.TuneInlinerExploration=1 -Djdk.graal.LoopRotation=true -Djdk.graal.CompilerConfiguration=enterprise
Source: MeowIce's Flags
Input this startup command to take advantage of GraalVM:
- replace [TUNING ARGS] with the above arguments
java [TUNING ARGS] $( ((USE_AOT_CACHE)) && printf %s "-XX:AOTCache=Server/HytaleServer.aot" ) -Xms128M $( ((SERVER_MEMORY)) && printf %s "-Xmx${SERVER_MEMORY}M" ) -jar Server/HytaleServer.jar $( ((HYTALE_ALLOW_OP)) && printf %s "--allow-op" ) $( ((HYTALE_ACCEPT_EARLY_PLUGINS)) && printf %s "--accept-early-plugins" ) $( ((DISABLE_SENTRY)) && printf %s "--disable-sentry" ) --auth-mode ${HYTALE_AUTH_MODE} --assets Assets.zip --bind 0.0.0.0:${SERVER_PORT}
DNS
If you want to selfhost Hytale and you have a domain name with complete control over it, you may want to be able to use a specific subdomain to join your server.
To do this, you need to
Create 2 DNS entries
Name: ht (you may want to name it hytale :p)
- Type: A
- TTL: 86400 (or whatever number)
- Data: your public ip address
Name: _hytale._udp.ht _(adjust ht with the previous name entry)_
- Type: SRV
- TTL: should be the same as previous
- Data: 0 5 port number ht.domainname
Keep in mind that :
- port number : is the port number to access Hytale
- domainname : is you main domain name
And you also may need to open you firewall port: port number.
Refer to your firewall documentation to apply this :p
Mods
Recommanded mods
Website template
I recommand this one :
Changelog
2026-05-02
- Update to GraalVM 25.0.3 (from 25.0.2)
2026-03-26
- Add asset folder cleanup before extracting new assets
2026-02-14
- Rework egg variables, and adjust scripts
2026-02-09
- Update egg to include Assets path variable ASSETS_PATH (where assets get extracted)
- Update java.sh to change version display order
- Update entrypoint.sh to add coloring, verbosity and handle ASSETS*PATH *(automatic extract of assets)_
2026-02-03
- Update to GraalVM 25.0.2 (from 25.0.1)
- Update startup update logic
- Add website template link
2026-01-20
- Add UPDATE_ON_START parameter to allow to skip downlading new patchline server
2026-01-19
- Update displaying GraalVM version in java.sh
- Update to GraalVM 25.0.1 (from 25)
- Added dns settings informations (I know it's lite :p)
2026-01-18
- Docker image pushed to Docker Hub, so update the Egg
2026-01-17
- Add Pterodactyl egg hytale.json
- Add section: recommanded mods
- Update Egg to enable backup managment
- Update Docker image entrypoint to enable 'backups' folder if missing
2026-01-15
- Update the Java flags with MeowIce's Flags
2026-01-14
- Initial commit
