Creating your own Docker Images
All Pterodactyl containers must have a user named container
, and the user home must be /home/container
This guide explains how to create a custom Docker image for use with Pterodactyl eggs, using a modern base example from the Ptero-Eggs yolks repository.
Docker images define the environment in which a server runs—what software is installed, what versions are used, and how everything is launched. Custom images allow you to add packages or modify behavior beyond what official yolks provide.
Dockerfile Example
Here’s a full Dockerfile example using Java 21 as the base image:
FROM --platform=$TARGETOS/$TARGETARCH eclipse-temurin:21-jdk-jammy
LABEL author="Michael Parker" maintainer="[email protected]"
LABEL org.opencontainers.image.source="https://github.com/pterodactyl/yolks"
LABEL org.opencontainers.image.licenses=MIT
RUN apt update -y \
&& apt install -y \
curl \
lsof \
ca-certificates \
openssl \
git \
tar \
sqlite3 \
fontconfig \
tzdata \
iproute2 \
libfreetype6 \
tini \
zip \
unzip
RUN useradd -m -d /home/container -s /bin/bash container
USER container
ENV USER=container HOME=/home/container
WORKDIR /home/container
COPY --chown=container:container ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/usr/bin/tini", "-g", "--"]
CMD ["/entrypoint.sh"]
Breakdown of the Dockerfile
Base Image
FROM --platform=$TARGETOS/$TARGETARCH eclipse-temurin:21-jdk-jammy
Uses Eclipse Temurin Java 21 JDK on Ubuntu Jammy. The --platform
flag ensures compatibility with different system architectures.
Metadata Labels
LABEL author="..."
Provides metadata such as author, source, and license. Useful for documentation.
Dependencies
RUN apt update -y && apt install -y [...]
Installs useful server packages:
curl
,lsof
,openssl
: Common CLI tools.fontconfig
,libfreetype6
: Support Java-based GUI rendering.tini
: Handles signal forwarding and zombie reaping.
User Setup
RUN useradd -m -d /home/container -s /bin/bash container
Creates a non-root user container
to enhance security.
Switch User & Set Environment
USER container
ENV USER=container HOME=/home/container
Switches to the new user and sets key environment variables.
Working Directory
WORKDIR /home/container
Sets the default working directory.
Entrypoint Setup
COPY --chown=container:container ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
Copies the startup script and ensures it’s executable.
Entry Command
ENTRYPOINT ["/usr/bin/tini", "-g", "--"]
CMD ["/entrypoint.sh"]
Uses tini
to launch the container and execute the custom startup script.
Example entrypoint.sh
In order to complete this Dockerfile, we will need an entrypoint.sh file which tells Docker how to run this specific server type.
These entrypoint files are actually fairly abstracted, and the Daemon will pass in the start command as an environment variable before processing it and then executing the command.
This script pairs with the Dockerfile above:
#!/bin/bash
# Default the TZ environment variable to UTC.
TZ=${TZ:-UTC}
export TZ
# Set environment variable that holds the Internal Docker IP
INTERNAL_IP=$(ip route get 1 | awk '{print $(NF-2);exit}')
export INTERNAL_IP
# Switch to the container's working directory
cd /home/container || exit 1
# Print Java version
printf "\033[1m\033[33mcontainer@pterodactyl~ \033[0mjava -version\n"
java -version
# Convert all of the "{{VARIABLE}}" parts of the command into the expected shell
# variable format of "${VARIABLE}" before evaluating the string and automatically
# replacing the values.
PARSED=$(echo "${STARTUP}" | sed -e 's/{{/${/g' -e 's/}}/}/g' | eval echo "$(cat -)")
# Display the command we're running in the output, and then execute it with the env
# from the container itself.
printf "\033[1m\033[33mcontainer@pterodactyl~ \033[0m%s\n" "$PARSED"
# shellcheck disable=SC2086
eval ${PARSED}
Breakdown
- Navigates to the working directory.
- Outputs the Java version for confirmation.
- Processes and expands the Pterodactyl
STARTUP
variable. - Executes the startup command.
Final Notes
- User home must be
/home/container
- All Pterodactyl containers must have a user named
container
- Always run as a non-root user in Pterodactyl containers.
- Build and test locally with:
docker build -t my-image .
- Push images to Docker Hub or private registry and specify them in the egg under Docker Image, or run the image locally first if you want to ensure it functions as expected
Creating a custom Docker image lets you fully control the server for uncommon games or special dependencies.