Skip to content

Instantly share code, notes, and snippets.

@dotStart
Last active October 29, 2024 08:02
Show Gist options
  • Save dotStart/ea0455714a0942474635 to your computer and use it in GitHub Desktop.
Save dotStart/ea0455714a0942474635 to your computer and use it in GitHub Desktop.
Systemd services for Minecraft Servers
[Unit]
Description=Minecraft Proxy
Wants=network-online.target
After=network-online.target
# If you want to make sure that your servers start along with the proxy, you can append them to the Wants
# parameter. For example:
# Wants=network-online.target lobby.service survival.service
[Service]
# Ensure to set the correct user and working directory (installation directory of your server) here
User=bungeecord
WorkingDirectory=/opt/bungeecord/
# You can customize the maximum amount of memory as well as the JVM flags here
ExecStart=/usr/bin/java -XX:MaxDirectMemorySize=1G -XX:+UseG1GC -Xmx512M -jar BungeeCord.jar --noconsole
# Restart the server when it is stopped or crashed after 30 seconds
# Comment out RestartSec if you want to restart immediately
Restart=always
RestartSec=30
# Alternative: Restart the server only when it stops regularly
# Restart=on-success
StandardInput=null
[Install]
WantedBy=multi-user.target
[Unit]
Description=Minecraft Server
Wants=network-online.target
After=network-online.target
[Service]
# Ensure to set the correct user and working directory (installation directory of your server) here
User=minecraft
WorkingDirectory=/opt/minecraft
# You can customize the maximum amount of memory as well as the JVM flags here
ExecStart=/usr/bin/java -XX:+UseG1GC -Xmx3G -jar server.jar --nojline --noconsole
# Restart the server when it is stopped or crashed after 30 seconds
# Comment out RestartSec if you want to restart immediately
Restart=always
RestartSec=30
# Alternative: Restart the server only when it stops regularly
# Restart=on-success
# Do not remove this!
StandardInput=null
[Install]
WantedBy=multi-user.target bungeecord.service
[Unit]
Description=Minecraft Server
Wants=network-online.target
After=network-online.target
[Service]
# Ensure to set the correct user and working directory (installation directory of your server) here
User=minecraft
WorkingDirectory=/opt/minecraft
# You can customize the maximum amount of memory as well as the JVM flags here
ExecStart=/usr/bin/java -XX:+UseG1GC -Xmx3G -jar server.jar --nojline --noconsole
# Restart the server when it is stopped or crashed after 30 seconds
# Comment out RestartSec if you want to restart immediately
Restart=always
RestartSec=30
# Alternative: Restart the server only when it stops regularly
# Restart=on-success
# Do not remove this!
StandardInput=null
[Install]
WantedBy=multi-user.target

Minecraft systemd Services

This gist contains service descriptors which may be used to automatically start and re-start Minecraft servers using systemd. This allows proper control of your server startup on modern Linux distributions and will automatically manage all required tasks on startup for you.

Requirements

  • A Linux distribution with systemd support
  • A bit of patience

Caveats

These scripts do not expect any user interaction with the server and thus may not be feasible for you. If you wish to interact with the server you may extend the ExecStart properties with a command like screen or tmux. Please refer to other guides for more information on how to setup these tools.

Simple Setup

Note: Not for users of BungeeCord. Single server setups only!

  1. Place the minecraft.service file in your /etc/systemd/system/ directory
  2. Create a user called minecraft with its home pointed to /opt/minecraft
  3. Customize the file according to your requirements as documented within the file
  4. Install the vanilla server or Spigot in /opt/minecraft
  5. (Optional) Enable the service using systemctl enable minecraft
  6. Start the service using systemctl start minecraft

While the step of enabling the service is optional, you should do so to automatically start the server when the machine reboots.

BungeeCord Setup

  1. Place the bungeecord.service file in your /etc/systemd/system/ directory
  2. Create a user called bungeecord with its home pointed to /opt/bungeecord
  3. Customize the file according to your requirements as documented within the file
  4. Install BungeeCord in /opt/bungeecord/
  5. (Optional) Enable the service using systemctl enable bungeecord

For every server you want to add repeat these steps:

  1. Copy the minecraft-bungeecord.service file in your /etc/systemd/system/ directory and give it a descriptive name (lobby.service for example)
  2. Create a user for the server (using the same name as the service is recommended), also give it a dedicated home directory
  3. Customize the file according to your requirements as documented within the file
  4. Install the vanilla server or Spigot in the home directory
  5. (Optional) Add the server to BungeeCord's dependencies in /etc/systemd/systemctl/bungeecord.service

Note: The dependency approach will automatically start your servers when BungeeCord starts and thus you will only need to enable/start the bungeecord service.

@mattwelke
Copy link

mattwelke commented Jul 8, 2021

Reading about the -XX:MaxDirectMemorySize option (https://www.eclipse.org/openj9/docs/xxmaxdirectmemorysize/), it says:

By default, the VM limits the amount of heap memory used for Direct Byte Buffers to approximately 85% of the maximum heap size.

But the settings here have this option set to 200% of the max heap size (-XX:MaxDirectMemorySize=1G and -Xmx512M). Is this intentional?

The example minecraft.service file worked great for me though. I was just using the default "ubuntu" user in Oracle Cloud's Ubuntu image, and I already had a JRE (Microsoft's ARM64 build of Java 16) and the server.jar file downloaded into my home directory. So I edited the service to use those files where they already were, and it worked fine. Minecraft starts automatically when the VM is rebooted.

@dotStart
Copy link
Author

dotStart commented Jul 8, 2021

These service files are about 5 years old by now (in fact I'm surprised that anybody actually stumbled across them after all this time) so take any assumptions in here with a grain of salt.

That being said: I believe MaxDirectMemorySize is deliberately increased in the BungeeCord template as the application didn't use to require any actual heap memory. Generally, it would store everything needed for its job in direct buffers (inbound, outbound, and anything in between uses direct buffers). As a result, you could end up exhausting the direct buffer space (and subsequently drop connections) in deployments with small amounts of heap memory (as would be the case if you just used it as a plain protocol-aware proxy).

I should point out though that I am no longer involved with BungeeCord and/or Spigot (and haven't been in quite a few years) so these statements may no longer hold true (if they were ever truly accurate given that a lot of suggestions back then were just passed along as religious gospel). These files were primarily meant to be simple guides for standard small deployments to cut down on reoccurring support cases we had to deal with back then (mostly from kids who would run these setups on Raspberries and similar low-powered hardware).

@mattwelke
Copy link

in fact I'm surprised that anybody actually stumbled across them after all this time

This was actually the top Google result for "minecraft server systemd service" (or something like that). :P I was too lazy to make one from scratch and knew I'd find examples online. Thanks for putting it out here.

@alvarlagerlof
Copy link

For anyone seeing this, don't use After=syslog.target anymore either (google it)

@adam-currie
Copy link

adam-currie commented Jul 21, 2022

For anyone seeing this, don't use After=syslog.target anymore either (google it)

ty!

@dotStart
Copy link
Author

I've updated the templates since there still seems to be a decent amount of interest here. The services merely depend on network-online.target now.

Additionally, I have replaced the Requires dependency example with Wants as that is probably a slightly better way of dealing with server dependencies (that way the proxy will still come up just fine if a server fails to start up for whatever reason).

@ehrrsn7
Copy link

ehrrsn7 commented Jan 28, 2023

This gist needs more stars! Very straightforward minecraft.service file and good readme explanation for those who know how to follow along. This saved me a lot of potential head-scratching trying to remember how to configure systemctl stuff on the fly.

@ChopsKingsland
Copy link

I just tried using minecraft.service, but it doesn't work... My minecraft.service says the following:


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

[Service]
# Ensure to set the correct user and working directory (installation directory of your server) here
User=minecraft
WorkingDirectory=/opt/minecraft/server

# You can customize the maximum amount of memory as well as the JVM flags here
ExecStart=/usr/bin/java -Xmx10G -Xms10G -jar server.jar nogui

# Restart the server when it is stopped or crashed after 30 seconds
# Comment out RestartSec if you want to restart immediately
Restart=always
RestartSec=30

# Alternative: Restart the server only when it stops regularly
# Restart=on-success

# Do not remove this!
StandardInput=null

[Install]
WantedBy=multi-user.target

and after I start the service, the status says the following:

● minecraft.service - Minecraft Server
   Loaded: loaded (/etc/systemd/system/minecraft.service; disabled; vendor preset: disabled)
   Active: activating (auto-restart) (Result: exit-code) since Wed 2023-03-15 12:10:31 GMT; 8s ago
  Process: 12711 ExecStart=/usr/bin/java -Xmx10G -Xms10G -jar server.jar nogui (code=exited, status=1/FAILURE)
 Main PID: 12711 (code=exited, status=1/FAILURE)
    Tasks: 0 (limit: 70173)
   Memory: 0B
   CGroup: /system.slice/minecraft.service

@dotStart
Copy link
Author

Main PID: 12711 (code=exited, status=1/FAILURE) likely means that it is starting but crashing for some reason.

Check the journal (journalctl -xeu minecraft.service) to get to the actual process output. It should give you more details about why it failed (Maybe you didn't accept the eula? Maybe your working directory isn't quite right so server.jar cannot be found?). systemd can be a bit low on information in the status output since it doesn't include the entire log stream so it's always good to have a look at the journal when a service fails for no obvious reason.

@ChopsKingsland
Copy link

I have tracked it down to this error: Mar 17 18:00:27 minecraft java[692326]: Error: Unable to access jarfile server.jar... the /usr/bin/java -Xmx10G -Xms10G -jar server.jar nogui command works when run by itself, but doesn't seem to work in the service..?

@dotStart
Copy link
Author

Your working directory is likely incorrect then. These service files assume everything is installed in /opt/minecraft and the server jars named server.jar (see instructions).

@ChopsKingsland
Copy link

I modified the working directory slightly to be /opt/minecraft/server, and I also updated that in the minecraft.service file. It is also still called server.jar. Here is what an ls of /opt/minecraft/server has in it:

image

@JustZhenya
Copy link

Hello, just want to know, what benefits of StandardInput=null? My paper & velocity servers work fine without it. Does it increase performance or security?

@JustZhenya
Copy link

@dotStart
Copy link
Author

dotStart commented Jul 7, 2023

The background on StandardInput=null back in the day was that it would essentially cause the server to always disable the interactive command line (since it would not be reachable anyway) which would also definitively sort out any issues with log formatting.

It doesn't improve performance but it's one less resource for systemd to allocate to your processes especially if it is never actually used.

TL;DR: Not strictly required but simply good practice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment