NewHalo Edge 3 is here: HTTP/3 everywhere and 42 edge locations.Learn more
Docs / Game servers

Run Minecraft as a systemd service

Game servers8 min readUbuntu 24.04 LTS

Running the server in a terminal means it stops the moment your SSH session closes. systemd, the service manager built into Ubuntu, can keep the server running in the background, start it on boot, restart it after a crash, and stop it cleanly when you ask. This article creates that service.

Before you begin

  • The Minecraft Java server installed in /opt/minecraft, with the EULA accepted and one successful start (see the Minecraft Java Edition article).
  • The minecraft system user, which owns that folder.
  • A sudo user on the server (this guide uses alex).

Step 1: Confirm the start command works

A service runs one command without a terminal, so first confirm that the exact command works. Find the Java program's path, which is /usr/bin/java on Ubuntu when you install the headless package:

which java
/usr/bin/java

Make sure the memory settings in your command match your plan, since the service will use them every time it starts.

Step 2: Write the service file

A service is described in a small text file under /etc/systemd/system. Create one named minecraft.service:

sudo nano /etc/systemd/system/minecraft.service

Paste the following, then save with Ctrl+O and exit with Ctrl+X:

[Unit]
Description=Minecraft Java server
After=network-online.target
Wants=network-online.target

[Service]
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft
ExecStart=/usr/bin/java -Xms1G -Xmx2G -jar server.jar nogui
Restart=on-failure
RestartSec=10
TimeoutStopSec=90

[Install]
WantedBy=multi-user.target

Here is what the settings do. [Unit] says the server should start after the network is up. User and Group run it as the unprivileged account. WorkingDirectory makes the world save into /opt/minecraft. ExecStart is the start command, and it must match the memory settings you chose. Restart=on-failure restarts the server after a crash but not after a normal stop. TimeoutStopSec=90 gives the server up to 90 seconds to save the world before systemd forces it to close. WantedBy enables the service at boot.

Step 3: Load the service and start it

Tell systemd to read the new file, enable the service so it starts on boot, and start it now:

sudo systemctl daemon-reload
sudo systemctl enable --now minecraft
sudo systemctl status minecraft --no-pager

The status output should include Active: active (running). Follow the server's own log, which systemd collects in the journal:

sudo journalctl -u minecraft -n 30 --no-pager

Look for the Done line that means the world has loaded. Lines in the journal show the server's own console output, including players joining and leaving.

Step 4: Stop, start and restart the server

Use these commands from now on, rather than running Java by hand:

sudo systemctl stop minecraft
sudo systemctl start minecraft
sudo systemctl restart minecraft

A stop sends the server a standard termination signal. Minecraft listens for that signal, announces the shutdown, and saves the world before exiting. Watch the journal during a stop with sudo journalctl -u minecraft -f to see the save messages. Press Ctrl+C to stop following the log.

Step 5: Test the automatic restart

To prove that crash recovery works, simulate a crash by killing the server forcibly. This is not a normal stop, so systemd treats it as a failure and restarts the server after the 10-second delay you set:

sudo systemctl kill --signal=SIGKILL minecraft
sleep 15
sudo systemctl status minecraft --no-pager

The status should show that the server is running again, with a new start time. Forced kills can lose recent changes, so use this test only on a quiet server, and never as a normal way to stop it.

Tip: To check that the service will come back after a reboot, run sudo reboot, wait a minute, reconnect over SSH, and run sudo systemctl status minecraft --no-pager.

Troubleshooting

  • status shows "failed" right after start: read the journal with sudo journalctl -u minecraft -n 50 --no-pager. A common cause is a wrong path, a missing eula=true, or a memory setting larger than the server has.
  • The service keeps restarting every 10 seconds: the server is crashing on startup. The journal shows the error, often a port already in use. Check with sudo ss -tlnp | grep 25565.
  • Changes to the service file have no effect: run sudo systemctl daemon-reload and then restart the service.
  • Stop takes a long time: a large world may need more than 90 seconds to save. Raise TimeoutStopSec in the file, then run daemon-reload again.

Next steps

Your server now runs as a managed service. Next, the allowlist article controls who may join and who has operator rights, and the backup article protects your world with scheduled copies. Both work well with a service that stops cleanly.

Something not working? Chat or email our support team and we will help you get unstuck.

Contact support