Deployment guide

Mindustry Server 160.7

Overview

Mindustry is an open-source factory-building tower defence game. Players mine resources, lay conveyor and power networks, automate production and defend their base 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 SecureAnyCloud image runs Mindustry Server 160.7 on Ubuntu 24.04 on Amazon EC2. It is one version of the SecureAnyCloud game server listing on AWS Marketplace, and you pick it as the software version when you subscribe and launch.

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.

Before the image is captured, 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. Your players install Mindustry normally on their own computers and use Join Game, Add Server with this instance's address.

What you get:

  • 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 SecureAnyCloud console bridge bound only to 127.0.0.1:6859, which forwards nothing without this instance's console token. The root-only mindustryctl command drives it.
  • 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. A 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, because 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. A map script, plugin or mod running inside the server therefore cannot reach the instance metadata service, your VPC or the internet. Replies to players are not affected. systemd also denies the server units the metadata and link-local addresses, and the AMI requires IMDSv2.
  • Anti-abuse defaults. A player limit of 30, chat rate limiting, strict mode, spam kicks and modified-client rejection replace upstream's defaults, several of which are off.
  • Saves that persist. Autosave runs every five minutes and keeps the five most recent saves (upstream ships autosave off). A reboot resumes the most recent autosave by itself.
  • A self-audit you can run. mindustry-roundtrip-check.sh proves that the console refuses a wrong token, a real Mindustry protocol client can join, malformed clients are refused and 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 patched at build time, with unattended security upgrades switched on.
  • What is on the image: Mindustry server 160.7 (/opt/mindustry/server-release.jar), an OpenJDK 21 runtime (Ubuntu package, no compiler), Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
  • Defaults: the default user is ubuntu, the architecture is x86_64 and the recommended instance type is 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.
  • Players running the Mindustry game at the same version, 160.7.

Do not open port 6859. It is the administration console, which is bound to loopback and reached over SSH.

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, choose your Region, then choose Launch through EC2. Select m5.large, your key pair and a security group as described 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.

To launch with the AWS CLI instead, 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}]'

Create the security group rules with 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>}]'
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>
3

Check first boot and read your credentials

On first boot, the instance generates its own console token and prepares a clean state directory. It then starts the server, applies the shipped configuration and hosts the Ancient_Caldera map. Before it declares itself ready, it proves that a real Mindustry protocol client can join.

Wait two or three minutes after the instance reports running, then check the services:

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

All four 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 that 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 secret, as you would any other credential. 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 address, the public and game addresses show the private address. That address works only inside your VPC or VPN.

Then check that the server is hosting a world:

sudo mindustryctl status

The output shows 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.

4

Connect from the game

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

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

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

Grant admin rights by player ID. The players command shows the ID while the player is connected. Take the value after ID: and run the following command. The player should reconnect afterwards to pick up the new status, and admin remove <id> reverses it:

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

To deal with a griefer, kick or ban the player and review the ban list:

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. 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.

6

Host a map

The game port exists only 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.

7

Saves, restarts and logs

  • Autosave runs every 300 seconds and keeps the five most recent saves, so saves cannot fill the disk.
  • A reboot resumes the most recent autosave. If there is nothing to resume, it hosts the default map.
  • 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. 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. It is rotated daily or at 32 MB, 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, and less -R renders them.

8

Tune the server

Configuration is the plain-text file /etc/mindustry/server-commands.conf. The service replays it 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. The image ships none, so 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 the service:

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 and 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.

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. Confirm the listeners:

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

The administration console answers only on 127.0.0.1:6859, and the kernel lets only root open a connection to it. The server account can open new connections only to the instance itself.

sac-mindustry-egress.service loads both rules before the server starts, and the server refuses to start without them. To see the rules, run:

sudo mindustry-egress-apply --print

systemd also denies the server units the instance metadata service and link-local addresses. To see the setting, run:

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). 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 instead of loosening the game server.

10

Verify your deployment

The image carries its own audit. Run it as follows. It takes a few minutes, because it restarts the server and reconnects a client for real:

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

The audit proves, in order, that:

  • the console token is required, and a wrong or empty token executes nothing (the real token is proven again straight afterwards, 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. If anything fails, it exits non-zero.

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/

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 that a world is hosted: sudo mindustryctl status must not say server closed. Then check that 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. This is almost always a version mismatch, because 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 sac-mindustry-egress.service. If the server is not active, run sudo /usr/local/sbin/mindustry-secret-guard.sh. It explains why the server 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

SecureAnyCloud provides 24/7 technical support for this image by email and live chat at sales@secureanycloud.com. Include the output of sudo /usr/local/sbin/mindustry-roundtrip-check.sh and the last lines of /var/log/mindustry/mindustry.log with your 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 SecureAnyCloud 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). 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.

SecureAnyCloud's own additions are the console bridge, first boot, the protocol probe and the audit scripts. They 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. SecureAnyCloud is not affiliated with or endorsed by the Mindustry project.

Deploy on AWS

Launch Mindustry Server 160.7 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS