Ms
Gaming AWS

Mindustry Server 160.7 on AWS User Guide

| Product: Mindustry Server 160.7 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the Mindustry Server 160.7 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg game server listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

Mindustry is an open source factory building tower defence game. Players mine resources, lay conveyor and power networks, automate production and defend what they have built against waves of enemies. It is at its best in multiplayer, where a group builds one factory together on a shared, persistent map, and that is what a dedicated server is for.

This image ships the dedicated server, not the game client. Each Mindustry release publishes several files and only server-release.jar is a server; Mindustry.jar is the desktop client. The build checks that the installed file really is the server (it carries mindustry/server/ServerLauncher.class, its manifest Main-Class is mindustry.server.ServerLauncher, and it carries no desktop client classes) before the image is captured. Your players install Mindustry normally on their own computers and use Join Game, Add Server with this instance's address.

The cloudimg image adds:

  • A closed administration console. Upstream's remote console (socketInput) has no authentication at all: anyone who reaches it can grant admin, ban players and stop the server. This image leaves it off, and the server refuses to start if it is ever switched on. Administration goes through a cloudimg console bridge bound only to 127.0.0.1:6859 that forwards nothing without this instance's console token, driven by the root only mindustryctl command.
  • A token unique to your instance. First boot generates the console token on your instance. No token, world, save, admin list or ban list is baked into the image, and a committed secret guard refuses to start the server if the token is missing or weak.
  • A contained service. The server runs as the mindustry system account (no shell, no password) under a sandboxed systemd unit. The jar is owned by root, so the service cannot change its own code.
  • Loopback only outbound connections. A Mindustry server does not need to reach the internet: players connect in. A firewall rule keyed to the mindustry account lets it open new connections only to the instance itself, on IPv4 and IPv6, so a map script, plugin or mod running inside the server cannot reach the instance metadata service, your VPC or the internet. Replies to players are not affected. The server units are also denied the metadata and link local addresses by systemd, and the AMI requires IMDSv2.
  • Anti-abuse defaults. A player limit of 30, chat rate limiting, strict mode, spam kicks and modified client rejection are configured instead of upstream's defaults, several of which are off.
  • Saves that persist. Autosave every five minutes keeping the five most recent (upstream ships autosave off), and a reboot resumes the most recent autosave by itself.
  • A self audit you can run. mindustry-roundtrip-check.sh proves the console refuses a wrong token, that a real Mindustry protocol client can join, that malformed clients are refused and that the world survives a full restart.
  • Exactly the ports players need. TCP and UDP 6567 for players and TCP 22 for SSH.
  • A pinned, checked download. The unmodified upstream server-release.jar from the v160.7 release, verified against a recorded sha256.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: Mindustry server 160.7 (/opt/mindustry/server-release.jar), OpenJDK 21 runtime (Ubuntu package, no compiler), Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.

Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet.
  • A public IPv4 address on the instance (auto assigned or an Elastic IP), so players on the internet can reach it.
  • A security group that allows TCP 6567 and UDP 6567 from your players (usually anywhere) and TCP 22 (SSH) from your own networks only. Mindustry needs both protocols on 6567.
  • Your players need the Mindustry game at the same version, 160.7.

Do not open port 6859. That is the administration console; it is bound to loopback and reached over SSH.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Mindustry Server 160.7 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair and a security group as above. The server itself is modest: it used about 162 MB of memory with a world hosted and a player connected, and the Java heap is capped at 1024 MB.

With the AWS CLI (replace the values in angle brackets):

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --associate-public-ip-address \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=mindustry}]'

The security group rules, from the AWS CLI:

aws ec2 authorize-security-group-ingress --group-id <your-security-group> \
  --ip-permissions 'IpProtocol=tcp,FromPort=6567,ToPort=6567,IpRanges=[{CidrIp=0.0.0.0/0}]' \
                   'IpProtocol=udp,FromPort=6567,ToPort=6567,IpRanges=[{CidrIp=0.0.0.0/0}]' \
                   'IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges=[{CidrIp=<your-mgmt-cidr>}]'

Step 2: Connect to your instance

Version SSH user
Mindustry Server 160.7 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: Check first boot and read your credentials

On first boot the instance generates its own console token, prepares a clean state directory, starts the server, applies the shipped configuration, hosts the Ancient_Caldera map and then proves a real Mindustry protocol client can join before it declares itself ready. Give it two or three minutes after the instance reports running, then check it:

systemctl is-active mindustry-firstboot.service mindustry.service mindustry-console.service cloudimg-mindustry-egress.service

All four should report active. Then read this instance's credentials:

sudo cat /root/mindustry-credentials.txt

The file is 0600 root:root and was written on your instance. It holds the console token, the instance's addresses (read with IMDSv2) and the address players connect to:

MINDUSTRY_CONSOLE_TOKEN=<console-token>
MINDUSTRY_CONSOLE_ENDPOINT=127.0.0.1:6859
MINDUSTRY_PRIVATE_IP=<private-ip>
MINDUSTRY_PUBLIC_IP=<server-ip>
MINDUSTRY_GAME_ADDRESS=<server-ip>:6567
MINDUSTRY_VERSION=160.7

Keep the token as you would any other secret. It is not a player password: Mindustry has no player login, and the game port is meant to be public. If the instance has no public IPv4, the public and game addresses show the private address, which only works inside your VPC or VPN.

Then check the server is hosting a world:

sudo mindustryctl status

You should see the map being played, the wave, the time until the next wave and the connected players. If it says server closed, no world is hosted; see Step 6.

Step 4: Connect from the game

  1. Open Mindustry on your own computer (Steam, itch.io or the official build) at version 160.7.
  2. Choose Play, Join Game, Add Server.
  3. Enter MINDUSTRY_GAME_ADDRESS from the credentials file: the public IP with :6567.
  4. The server appears with its name, map and player count. Select it to join.

The server refuses clients on a different build, by design, so worlds do not desynchronise. It also refuses modified clients, because allowCustomClients is false in this image.

Step 5: Administer the server

mindustryctl drives the server's own console through the token checked bridge. It is root only (0750 root:root):

sudo mindustryctl help

Everyday commands:

sudo mindustryctl status          # what is hosted, wave, players
sudo mindustryctl players         # who is connected, with their IDs
sudo mindustryctl maps all        # the built in maps you can host
sudo mindustryctl playerlimit     # the current player cap

Admins are granted by player ID, shown by players while the player is connected. Take the value after ID: and run the following (the player should reconnect afterwards to pick up the new status; admin remove <id> reverses it):

sudo mindustryctl admin add <their-player-id>
sudo mindustryctl admins

To deal with a griefer:

sudo mindustryctl kick <player-name>
sudo mindustryctl ban id <their-player-id>
sudo mindustryctl unban <id-or-ip>
sudo mindustryctl bans

Vote kick is on, so your players can remove a griefer themselves, and strict mode corrects positions and rejects duplicate player IDs.

A wrong token is refused with a fixed one second delay and deliberately no lockout, so a typo never locks you out of your own server.

Step 6: Host a map

The game port only exists while a world is hosted: Mindustry opens the listener when you host and closes it when you stop.

sudo mindustryctl maps all
sudo mindustryctl host Ancient_Caldera survival

Loading a large map can take a minute or two. Then confirm it with sudo mindustryctl status. Other modes are attack, pvp, sandbox and editor. To end the current world run sudo mindustryctl stop and host another; to start the next wave now run sudo mindustryctl runwave.

Step 7: Saves, restarts and logs

  • Autosave is on every 300 seconds and keeps the five most recent, so saves cannot fill the disk.
  • A reboot resumes the most recent autosave, and hosts the default map if there is nothing to resume.
  • Named saves are yours to make and keep:
sudo mindustryctl save my-world
sudo mindustryctl saves

Saves live in /var/lib/mindustry/config/saves as .msav files. Copy them off the instance with scp for a backup you control, and bring one back with sudo mindustryctl load my-world. To resume the latest autosave by hand, run sudo mindustryctl loadautosave.

The server log is /var/log/mindustry/mindustry.log, rotated daily or at 32 MB and keeping seven compressed generations for at most 30 days:

sudo tail -20 /var/log/mindustry/mindustry.log

mindustryctl strips Mindustry's colour codes; the raw log keeps them, which less -R renders.

Step 8: Tune the server

Configuration is the plain text file /etc/mindustry/server-commands.conf, which the service replays into the server console on every start. Mindustry's own settings.bin is a binary file that also holds the admin list, ban list and player database, so the image ships none and configuration stays readable as text.

sudo cat /etc/mindustry/server-commands.conf
Setting This image Upstream default
playerlimit 30 no limit
messageRateLimit 2 seconds 0 (chat rate limiting off)
messageSpamKick 3 3
allowCustomClients false true on desktop builds
autosave true, 5 kept false
socketInput false false (and unauthenticated when on)

To change a setting, edit the file and restart:

sudoedit /etc/mindustry/server-commands.conf
sudo systemctl restart mindustry.service

A setting changed live with sudo mindustryctl config <name> <value> reverts to the file on the next restart. For an invite only server, add config whitelist true to the file, have each player connect once, then run sudo mindustryctl whitelist add <their-player-id>.

The Java heap is capped at 1024 MB in /usr/local/sbin/mindustry-run.sh. If a very large map with many players needs more, raise -Xmx there and move to a larger instance type.

Step 9: Security checks

Only SSH (TCP 22) and the game port (TCP and UDP 6567) listen on the network. The console bridge listens on loopback only:

sudo ss -H -tulnp | grep -E ':(22|6567|6859) '

The administration console answers only on 127.0.0.1:6859, and the kernel only lets root open a connection to it. The server account can open new connections only to the instance itself. Both rules are loaded by cloudimg-mindustry-egress.service before the server starts, and the server refuses to start without them. To see them:

sudo mindustry-egress-apply --print

The server units are also denied the instance metadata service and link local addresses:

systemctl show mindustry.service -p User -p NoNewPrivileges -p PrivateTmp -p IPAddressDeny

Java's temporary directory is private to the service (/var/lib/mindustry/.tmp, mode 0700), and the console token is never written to the logs or the journal.

ubuntu and root keep normal access to the instance metadata service with IMDSv2, so the AWS CLI and the SSM agent work as usual.

If you add a plugin or mod that needs to reach the internet (for example a chat bridge), the outbound rule refuses it. That is deliberate: run such integrations as their own service under a different account rather than loosening the game server.

Step 10: Verify your deployment

The image carries its own audit. It takes a few minutes because it really restarts the server and reconnects a client:

sudo /usr/local/sbin/mindustry-roundtrip-check.sh

It proves, in order:

  • the console token is required, and a wrong or empty one executes nothing (the real one is proven again straight after, so the refusal is not a lockout);
  • the console answers on loopback and not on the instance's private address, while the game port on that same address does;
  • a real Mindustry protocol client completes the handshake and the server lists the connected player;
  • malformed clients (wrong build, wrong client type, empty name) are refused;
  • the world survives a full service restart with the same map and wave;
  • logrotate really rotates.

It ends with MINDUSTRY_ROUNDTRIP_OK and exits non-zero if anything failed.

Step 11: Server components

Component Version Location
Mindustry server 160.7 (unmodified upstream server-release.jar) /opt/mindustry/server-release.jar (root owned)
OpenJDK 21 runtime (Ubuntu package, security updates via unattended upgrades) /usr/lib/jvm
State, saves and maps /var/lib/mindustry/
Configuration /etc/mindustry/server-commands.conf
Console token /etc/mindustry/console.token (0640 root:mindustry)
Log /var/log/mindustry/mindustry.log
Admin command /usr/local/sbin/mindustryctl
Self audit /usr/local/sbin/mindustry-roundtrip-check.sh
First boot mindustry-firstboot.service, credentials in /root/mindustry-credentials.txt
Licence and source offer /usr/share/doc/mindustry/

Step 12: Security recommendations

  • Allow TCP 22 only from your own networks; only TCP and UDP 6567 need to be open to players.
  • Never open 6859 and never switch socketInput on. The server refuses to start with it on.
  • Keep /root/mindustry-credentials.txt and /etc/mindustry/console.token private.
  • Use the whitelist (Step 8) if the server is for a known group of players.
  • Copy saves off the instance regularly (Step 7).
  • Unattended upgrades keep Ubuntu and OpenJDK patched; update Mindustry when your players move to a new release.

Troubleshooting

  • Players cannot find or join the server. Check a world is hosted: sudo mindustryctl status must not say server closed. Then check the security group allows TCP and UDP 6567; opening only TCP is the most common cause of "it shows up but will not connect".
  • A player is refused. Almost always a version mismatch: the client must be on 160.7. Modified clients are refused by design. sudo tail -20 /var/log/mindustry/mindustry.log shows the reason.
  • mindustryctl says the console is unreachable. Check the units with systemctl is-active mindustry.service mindustry-console.service cloudimg-mindustry-egress.service. If the server is not active, run sudo /usr/local/sbin/mindustry-secret-guard.sh: it explains why it refused to start (a missing or weak token, socketInput switched on, or the outbound rule not loaded).
  • The world is gone after a restart. Run sudo mindustryctl loadautosave, or load a named save.

Support and licensing

cloudimg provides 24/7 technical support for this image by email and live chat at support@cloudimg.co.uk. Include the output of sudo /usr/local/sbin/mindustry-roundtrip-check.sh and the last lines of /var/log/mindustry/mindustry.log with a request. For gameplay, mods and map making, the Mindustry project and its community are the right place.

Mindustry is free software under the GNU General Public License, version 3, and cloudimg does not modify it. The server jar also contains the Arc framework (Apache-2.0), a fork of Mozilla Rhino (MPL-2.0), lz4-java (Apache-2.0, with the LZ4 C library under BSD-2-Clause) and JLine (BSD-3-Clause), and it runs on OpenJDK 21 (GPL-2.0 with the Classpath Exception). The image ships the GPL text and a written offer for the corresponding source:

ls /usr/share/doc/mindustry/ && head -12 /usr/share/doc/mindustry/SOURCE.txt

SOURCE.txt names the exact upstream tag and the sha256 of the installed jar, and links to the source tree at that tag. cloudimg's own additions (the console bridge, first boot, the protocol probe and the audit scripts) are separate files under /usr/local, also GPL-3.0-or-later, and the protocol probe's source ships next to its compiled classes.

Mindustry is a trademark of its authors. cloudimg is not affiliated with or endorsed by the Mindustry project.