A collection of bash scripts for managing a StarMade dedicated server. Handles starting, stopping, backing up, restoring, updating, and scheduled restarts.
Runs via Docker (recommended, all platforms) or natively on Linux with systemd and tmux.
- A StarMade server installation (
StarMade.jarin your server directory) - Docker setup (recommended):
- macOS / Windows: Docker Desktop
- Headless Linux: the installer will install Docker Engine automatically via
get.docker.com
- Native Linux setup: Linux with
sudoaccess — the installer handles everything else
Paste this single command into your terminal. It will download the scripts and walk you through setup interactively — choose Docker or native Linux when prompted:
curl -fsSL https://raw.githubusercontent.com/StarMade-Community/StarMade-Server-Scripts/main/bootstrap.sh | bashOr with wget if you don't have curl:
wget -qO- https://raw.githubusercontent.com/StarMade-Community/StarMade-Server-Scripts/main/bootstrap.sh | bashThe bootstrap script will:
- Install
gitif it isn't already present - Ask where to clone the scripts (default:
~/starmade-scripts) - Clone the repository
- Launch
install.sh, which prompts for Docker (default) or native Linux setup
Skip to the Scripts section when done.
git clone <repo-url> /path/to/scripts
cd /path/to/scripts
chmod +x *.shCopy .env.example to .env and edit it:
cp .env.example .env
nano .env| Variable | Used by | Description | Default |
|---|---|---|---|
STARMADE_DIR |
Both | Absolute path to your StarMade server directory | (must be set) |
UPDATE_BRANCH |
Both | release, dev, or pre |
dev |
JVM_MIN_HEAP |
Both | Minimum JVM heap (e.g. 4g) |
4g |
JVM_MAX_HEAP |
Both | Maximum JVM heap (e.g. 8g) |
16g |
JVM_EXTRA_ARGS |
Both | Extra JVM args — required for pre branch |
(empty) |
JAVA_VERSION |
Docker | Java version for the image — auto-detected (8 for < 0.3, 21 for >= 0.3) |
21 |
SERVER_PORT |
Both | Game port — sets host and in-container port; use a unique value per instance | 4242 |
TMUX_SESSION |
Native Linux | tmux session name | StarMade |
BACKUP_DIR |
Native Linux | Where backup archives are stored | $STARMADE_DIR/backups |
LOG_DIR |
Native Linux | Where log files live | $STARMADE_DIR/logs |
SYSTEMCTL_SERVICE |
Native Linux | systemd service unit name | starmade |
MAX_BACKUPS |
Native Linux | How many backups to keep before pruning | 3 |
Note: Game versions >= 0.3 require Java 21 and additional
--add-opensJVM flags. Both are detected and set automatically based on the installed game version.
- Game versions < 0.3: Java 8 or later
- Game versions >= 0.3: Java 21 or later
# Ubuntu/Debian — Java 8
sudo apt-get install openjdk-8-jre-headless
# Ubuntu/Debian — Java 8
sudo apt-get install openjdk-8-jre-headless
# Fedora/RHEL — Java 8
sudo dnf install java-8-openjdk-headlessIf your distro doesn't carry the required version, install it via SDKMAN:
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install java 21-tem # Eclipse Temurin 21 (for game versions >= 0.3)The backup, restore, update, and scheduled-restart scripts use systemctl to stop and start the server. Create a service unit that calls start.sh:
# /etc/systemd/system/starmade.service
[Unit]
Description=StarMade Game Server
After=network.target
[Service]
Type=forking
User=YOUR_USER
ExecStart=/path/to/scripts/start.sh
ExecStop=/path/to/scripts/stop.sh
Restart=on-failure
[Install]
WantedBy=multi-user.targetEnable and start it:
sudo systemctl daemon-reload
sudo systemctl enable starmade
sudo systemctl start starmadeSo scripts can restart the service without prompting for a password, add a sudoers entry:
sudo visudo -f /etc/sudoers.d/starmadeYOUR_USER ALL=(ALL) NOPASSWD: /bin/systemctl start starmade, /bin/systemctl stop starmade, /bin/systemctl restart starmade
Downloads the latest StarMade build and extracts it to STARMADE_DIR. Asks before overwriting an existing installation. Offers to start the server when done.
./download.sh # uses UPDATE_BRANCH from .env
./download.sh release # force release branch
./download.sh dev # force dev branch
./download.sh pre # force pre branchThe installer calls this automatically if StarMade.jar is not found in your server directory.
Starts the server in a detached tmux session.
./start.shSends the in-game /shutdown command then kills the tmux session.
./stop.shWarns online players, stops the server, creates a timestamped .tar.gz archive of the server directory, then restarts. Automatically prunes archives older than MAX_BACKUPS.
./backup.shExcludes logs/, tmp/, backups/, and *.log files from the archive.
Lists available backups interactively, snapshots the current state first (so you can recover if the restore fails), then restores the selected archive.
./restore.shDownloads the latest build from the official StarMade build server, backs up the current installation, applies the update, and restarts. Uses UPDATE_BRANCH from config.sh by default; pass an argument to override.
./update.sh # uses UPDATE_BRANCH from config.sh
./update.sh release # force release branch
./update.sh dev # force dev branch
./update.sh pre # force pre branchupdate.sh supports an exclusions file that prevents specific files from being overwritten when a new build is applied. Before applying the update, each listed file is copied out of your installation and placed back over the freshly extracted build — so your version wins instead of the default.
Copy the provided example into your server directory and uncomment what you need:
cp update-excludes.example.txt /path/to/starmade/update-excludes.txt
nano /path/to/starmade/update-excludes.txtPaths are relative to STARMADE_DIR, one per line. Lines beginning with # are ignored.
# server settings
server.cfg
# block configs
data/config/BlockTypes.properties
data/config/BlockConfig.xml
# mods
mods/MyMod/config.cfg
Modded servers — block config preservation
StarMade maps block names to numeric IDs locally in data/config/BlockTypes.properties. If an update overwrites this file with the vanilla defaults, every custom or modded block in your world loses its ID mapping and loaded chunks will be corrupted. Always add at minimum these two lines to your exclusions file on a modded server:
data/config/BlockTypes.properties
data/config/BlockConfig.xml
See update-excludes.example.txt in this repository for a fully annotated template covering server settings, block configs, mods, blueprints, and custom content.
Warns players, waits 60 seconds, then restarts the server. Logs activity to $LOG_DIR/restart.log. Intended to be run on a cron schedule.
./scheduled-restart.sh# Daily restart at 5:00 AM
0 5 * * * /path/to/scripts/scheduled-restart.sh
# Weekly backup every Sunday at 3:00 AM
0 3 * * 0 /path/to/scripts/backup.sh
# Check for updates every Monday at 4:00 AM
0 4 * * 1 /path/to/scripts/update.shThe installer automatically configures Docker when run on a non-Linux OS. If you prefer to set it up manually:
# 1. Copy and edit the environment file
cp .env.example .env
nano .env
# 2. Build the image and start the server
docker compose up -d| Command | Description |
|---|---|
docker compose up -d |
Start the server in the background |
docker compose down |
Stop and remove the container |
docker compose restart |
Restart the server |
docker compose logs -f |
Stream server logs |
The server data lives in the directory set as STARMADE_DIR in your .env. To back it up, stop the container and archive that directory:
docker compose down
tar -czf starmade_backup_$(date +%Y%m%d).tar.gz -C "$STARMADE_DIR" .
docker compose up -dThis repo's docker-compose.yml defines a single service, so running two servers
takes a little care. The pitfalls below are what make a second instance unstable.
-
Give each instance its own
.envwith distinct values:STARMADE_DIR— separate server directory. Never share a world/install between live servers: the world database (HSQLDB) is single-writer and will corrupt if two processes open the same files.SERVER_PORT— a distinct port (e.g.4242and4243). This now sets both the published host port and the in-container game port, so it behaves correctly under bridge and host networking.CONTAINER_NAME— a distinct name so the management scripts target the right one.JVM_MAX_HEAP— size so the sum across all instances leaves headroom for the OS. Two servers at16geach will starve a 16–32 GB host into constant GC/swap, which stalls the server tick loop and drops client connections. On a 16 GB box, try6geach.
-
Launch them as separate Compose projects (distinct
-pnames). Runninguptwice from the same folder makes Compose reconcile — it replaces the first server instead of adding a second:docker compose -p sm1 --env-file .env.server1 up -d docker compose -p sm2 --env-file .env.server2 up -d
-
network_mode: hostrequires a uniqueSERVER_PORTper instance. In host mode Docker's port mapping is ignored, so instances stay separated only because each one binds its ownSERVER_PORTdirectly on the host. With the old hardcoded4242this was the classic failure: the second server couldn't bind and threw connection errors.
scripts/
├── .env # Your configuration (gitignored — copy from .env.example)
├── .env.example # Configuration template
├── Dockerfile
├── docker-compose.yml
├── docker-entrypoint.sh
├── install.sh
├── bootstrap.sh
├── download.sh
├── start.sh
├── stop.sh
├── backup.sh
├── restore.sh
├── update.sh
├── scheduled-restart.sh
└── README.md
starmade-server/ # STARMADE_DIR (mounted as /starmade in Docker)
├── StarMade.jar
├── server.cfg
├── update-excludes.txt # optional — copy from update-excludes.example.txt
├── data/config/ # block ID configs — add to update-excludes.txt on modded servers
├── backups/ # created automatically (native Linux)
└── logs/