Minimal repo for running All the Mods 10 on a Hetzner VPS with Docker Compose.
The repository currently runs Minecraft only, with a reserved services/discord-bot/ directory for a future bot.
.
├── compose.yml
├── .env.example
├── scripts/
│ ├── bootstrap-ubuntu.sh
│ └── provision-ubuntu.sh
├── services/
│ ├── minecraft/
│ └── discord-bot/
└── volumes/
└── minecraft/
compose.yml: shared Docker orchestration for the reposcripts/bootstrap-ubuntu.sh: Ubuntu bootstrap script for Docker + first deployscripts/provision-ubuntu.sh: fresh-server provisioner with dedicated user + clone + bootstrapservices/minecraft/: docs and files related to the Minecraft serverservices/discord-bot/: reserved location for the future botvolumes/minecraft/: persistent server data
- a Hetzner VPS
- a CurseForge API key
On a fresh Ubuntu server, after cloning the repo:
chmod +x scripts/bootstrap-ubuntu.sh
./scripts/bootstrap-ubuntu.shThe script will:
- install Docker Engine and the Compose plugin if needed
- create
.envfrom.env.exampleif missing - ask for
CF_API_KEYandRCON_PASSWORDif they are not already set - create
./volumes/minecraft - pull the image and start the stack
You can also run it non-interactively:
CF_API_KEY='your_token' RCON_PASSWORD='your_password' ./scripts/bootstrap-ubuntu.shOptional overrides:
CF_API_KEY='your_token' \
RCON_PASSWORD='your_password' \
MEMORY=20G \
INIT_MEMORY=4G \
VIEW_DISTANCE=6 \
SIMULATION_DISTANCE=4 \
MOTD="Eternia ATM10" \
./scripts/bootstrap-ubuntu.shIf you also want the script to open Minecraft in UFW, set OPEN_UFW=1.
If you want the server to:
- create a dedicated system user
- clone or update the repo
- run the bootstrap automatically
use scripts/provision-ubuntu.sh.
With a public repo, the shortest path on a fresh server is:
curl -fsSL https://raw.githubusercontent.com/Asgarrrr/hetzner-minecraft/main/scripts/provision-ubuntu.sh -o provision-ubuntu.sh
sudo env CF_API_KEY='your_token' \
RCON_PASSWORD='your_password' \
APP_USER=minecraft \
APP_HOME=/opt/hetzner-minecraft \
bash provision-ubuntu.shIf your CurseForge key starts with $2a$10$..., keep the single quotes exactly as shown above. On the current version of this repo, that is enough: the key is passed to the container through env_file, so you do not need to double the dollar signs in .env.
The default REPO_URL already points to https://github.com/Asgarrrr/hetzner-minecraft.git, so you only need to override it if you fork or rename the repository.
If you ever switch back to a private repo, use either:
sudo REPO_URL=git@github.com:Asgarrrr/hetzner-minecraft.git bash provision-ubuntu.shor:
sudo GITHUB_TOKEN=your_token bash provision-ubuntu.shUseful options:
APP_USER: dedicated Linux user, defaultminecraftAPP_USER_HOME: Linux home directory for that user, default/home/minecraftAPP_HOME: target directory, default/opt/hetzner-minecraftREPO_REF: git branch/tag, defaultmainUPDATE_REPO=1: fetch and fast-forward an existing checkoutRUN_BOOTSTRAP=0: stop after clone/update- all bootstrap variables such as
CF_API_KEY,RCON_PASSWORD,MEMORY,MOTD,OPEN_UFW
- Copy
.env.exampleto.env - Set
CF_API_KEYandRCON_PASSWORD - Start the server:
docker compose up -d- Open port
25565/tcpin the VPS firewall - Follow the logs during first boot:
docker compose logs -f minecraftThe first boot can take a while: the container downloads the image, then the ATM10 modpack.
Main variables in .env:
CF_API_KEY: required to download the CurseForge modpackRCON_PASSWORD: RCON passwordALLOW_FLIGHT: set totrueto avoid kicks when modded flight is detectedMEMORY: Java max heap,16Gby defaultINIT_MEMORY: Java initial heap,4Gby defaultCF_FILENAME_MATCHER: ATM10 version to install,6.6by default
All persistent data is stored in ./volumes/minecraft.
If you want to migrate an existing world later, place the world files in that directory before restarting the container.