1

I'm running ubuntu 20.04 server on a home server, and I have a self-hosted minecraft instance, located at /opt/minecraft/server, owned by the user minecraft. I can activate the server manually just fine. However, I would like to have the server run the process constantly and on startup, but I'm having trouble getting the systemd script working. I'll post that below, but here's a few preliminaries

Here's me verifying that minecraft:minecraft owns everything:

albert@mfs:/opt/minecraft$ ls -l survival
total 37108
-rw-r--r--  1 minecraft minecraft        2 Nov 26 01:04 banned-ips.json
-rw-r--r--  1 minecraft minecraft        2 Nov 26 01:04 banned-players.json
-rw-r--r--  1 minecraft minecraft      180 Nov 25 23:16 eula.txt
drwxr-xr-x  2 minecraft minecraft     4096 Nov 26 01:04 logs
-rw-r--r--  1 minecraft minecraft      136 Nov 26 01:04 ops.json
-rw-r--r--  1 minecraft minecraft 37961464 Nov 25 23:16 server.jar
-rw-r--r--  1 minecraft minecraft     1073 Nov 26 01:04 server.properties
-rw-r--r--  1 minecraft minecraft      323 Nov 26 03:30 usercache.json
-rw-r--r--  1 minecraft minecraft        2 Nov 25 23:16 whitelist.json
drwxr-xr-x 11 minecraft minecraft     4096 Nov 26 04:36 world

After starting the service and checking the status:

albert@mfs:~$ sudo systemctl status minecraft@survival
● minecraft@survival.service - Minecraft Server survival
     Loaded: loaded (/etc/systemd/system/minecraft@.service; enabled; vendor preset: enabled)
     Active: activating (auto-restart) (Result: exit-code) since Thu 2020-11-26 21:13:11 UTC; 5s ago
    Process: 99802 ExecStart=/bin/sh -c /usr/bin/screen -DmS mc-survival /usr/bin/java -server -Xms512M -Xmx2048M -XX:+UseG1GC -XX:+CMSIncrementalPacing -XX:+CMSClassUnloadi>
    Process: 99820 ExecStop=/usr/bin/screen -p 0 -S mc-survival -X eval stuff "say SERVER SHUTTING DOWN. Saving map..."\015 (code=exited, status=1/FAILURE)
   Main PID: 99802 (code=exited, status=0/SUCCESS)

After checking journalctl

    albert@mfs:~$ journalctl -u minecraft@survival
    -- Logs begin at Wed 2020-06-03 18:13:36 UTC, end at Thu 2020-11-26 20:59:45 UTC. --
    Nov 25 23:18:34 my.freakin.server systemd[1]: Started Minecraft Server: survival.
    Nov 25 23:18:34 my.freakin.server screen[78218]: No screen session found.
    Nov 25 23:18:34 my.freakin.server systemd[1]: minecraft@survival.service: Control process exited, code=exited, status=1/FAILURE
    Nov 25 23:18:34 my.freakin.server systemd[1]: minecraft@survival.service: Failed with result 'exit-code'.
    Nov 25 23:18:34 my.freakin.server systemd[1]: minecraft@survival.service: Scheduled restart job, restart counter is at 1. 
    
    [and so on, four more times]

I've tried a few different config files, and have noticed no change in this problem (can confirm I've been daemon-reload'ing). (Should I be enabling Forking?). This is my current systemd file:

albert@mfs:~$ cat /etc/systemd/system/minecraft@.service    
# source: https://github.com/agowa338/MinecraftSystemdUnit/
# License: MIT
[Unit]
Description=Minecraft Server %i
After=network.target

[Service]
WorkingDirectory=/opt/minecraft/%i
PrivateUsers=true 
# Users Database is not available for within the unit, only root and minecraft is available, everybody else is nobody
User=minecraft
Group=minecraft
ProtectSystem=full 
# Read only mapping of /usr /boot and /etc
ProtectHome=true 
# /home, /root and /run/user seem to be empty from within the unit. It is recommended to enable this setting for all long-running services (in particular network-facing ones).
ProtectKernelTunables=true 
# /proc/sys, /sys, /proc/sysrq-trigger, /proc/latency_stats, /proc/acpi, /proc/timer_stats, /proc/fs and /proc/irq will be read-only within the unit. It is recommended to turn this on for most services.
# Implies MountFlags=slave
ProtectKernelModules=true 
# Block module system calls, also /usr/lib/modules. It is recommended to turn this on for most services that do not need special file systems or extra kernel modules to work
# Implies NoNewPrivileges=yes
ProtectControlGroups=true 
# It is hence recommended to turn this on for most services.
# Implies MountAPIVFS=yes
# ExecStart=/bin/strace -o /tmp/s -f screen -dm -S me bash -c 'sleep 999'
ExecStart=/bin/sh -c '/usr/bin/screen -DmS mc-%i /usr/bin/java -server -Xms512M -Xmx2048M -XX:+UseG1GC -XX:+CMSIncrementalPacing -XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -jar $(ls -v | grep -i "FTBServer.*jar\|minecraft_server.*jar" | head -n 1) nogui'

#ExecReload=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "reload"\\015'

ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say SERVER SHUTTING DOWN. Saving map..."\\015'
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "save-all"\\015'
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "stop"\\015'
ExecStop=/bin/sleep 10

Restart=on-failure
RestartSec=60s

[Install]
WantedBy=multi-user.target

#########
# HowTo
#########
#
# Create a directory in /opt/minecraft/XX where XX is a name like 'survival'
# Add minecraft_server.jar into dir with other conf files for minecraft server
#
# Enable/Start systemd service
#    systemctl enable minecraft@survival
#    systemctl start minecraft@survival
#
# To run multiple servers simply create a new dir structure and enable/start it
#    systemctl enable minecraft@creative
# systemctl start minecraft@creative

Just above the ExecStart command, you can see a commented-out command with an strace on it. I researched enough to figure out how to put it in, but I'm having a nearly impossible time reading it. The trace is very long, so I'll refrain from adding it unless someone requests it; that said, here are all results from the trace that threw some kind of error.

81270 arch_prctl(0x3001 /* ARCH_??? */, 0x7ffc8a212000) = -1 EINVAL (Invalid argument)
81270 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
81270 access("/opt/minecraft/.nethackrc", F_OK) = -1 ENOENT (No such file or directory)
81270 access("/opt/minecraft/.nethackrc", F_OK) = -1 ENOENT (No such file or directory)
81270 connect(3, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
81270 connect(3, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
81270 openat(AT_FDCWD, "/etc/shadow", O_RDONLY|O_CLOEXEC) = -1 EACCES (Permission denied)
81270 openat(AT_FDCWD, "/etc/shadow", O_RDONLY|O_CLOEXEC) = -1 EACCES (Permission denied)
81271 connect(3, {sa_family=AF_UNIX, sun_path="/run/screen/S-minecraft/81271.me"}, 34) = -1 ENOENT (No such file or directory)
81271 unlink("/run/screen/S-minecraft/81271.me") = -1 ENOENT (No such file or directory)
81271 ioctl(1, TCGETS, 0x7ffc8a210800)  = -1 ENOTTY (Inappropriate ioctl for device)
81271 stat("/opt/minecraft/.terminfo", 0x564c0619b900) = -1 ENOENT (No such file or directory)
81271 access("/etc/terminfo/s/screen", R_OK) = -1 ENOENT (No such file or directory)
81271 ioctl(2, TCGETS, 0x7ffc8a210800)  = -1 ENOTTY (Inappropriate ioctl for device)
81271 ioctl(2, TCGETS, 0x7ffc8a210790)  = -1 ENOTTY (Inappropriate ioctl for device)
81271 openat(AT_FDCWD, "/opt/minecraft/.screenrc", O_RDONLY) = -1 ENOENT (No such file or directory)
81271 stat("bash", 0x7ffc8a2107f0)      = -1 ENOENT (No such file or directory)
81271 openat(AT_FDCWD, "/dev/ptmx", O_RDWR) = 4
81271 connect(5, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
81271 connect(5, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
81271 chown("/dev/pts/1", 995, 5)       = -1 EINVAL (Invalid argument)
81272 access("/etc/terminfo/s/screen", R_OK) = -1 ENOENT (No such file or directory)
81272 execve("/usr/local/sbin/bash", ["bash", "-c", "sleep 999"], 0x564c0619ff10 /* 12 vars */) = -1 ENOENT (No such file or directory)
81272 execve("/usr/local/bin/bash", ["bash", "-c", "sleep 999"], 0x564c0619ff10 /* 12 vars */) = -1 ENOENT (No such file or directory)
81272 execve("/usr/sbin/bash", ["bash", "-c", "sleep 999"], 0x564c0619ff10 /* 12 vars */) = -1 ENOENT (No such file or directory)
81272 arch_prctl(0x3001 /* ARCH_??? */, 0x7ffede633760) = -1 EINVAL (Invalid argument)
81272 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
81272 ioctl(-1, TIOCGPGRP, 0x7ffede6335b4) = -1 EBADF (Bad file descriptor)
81272 stat("/usr/local/sbin/bash", 0x7ffede633220) = -1 ENOENT (No such file or directory)
81272 stat("/usr/local/bin/bash", 0x7ffede633220) = -1 ENOENT (No such file or directory)
81272 stat("/usr/sbin/bash", 0x7ffede633220) = -1 ENOENT (No such file or directory)
81272 getpeername(0, 0x7ffede6335b0, [16]) = -1 ENOTSOCK (Socket operation on non-socket)
81272 stat("/usr/local/sbin/sleep", 0x7ffede633110) = -1 ENOENT (No such file or directory)
81272 stat("/usr/local/bin/sleep", 0x7ffede633110) = -1 ENOENT (No such file or directory)
81272 stat("/usr/sbin/sleep", 0x7ffede633110) = -1 ENOENT (No such file or directory)
81272 arch_prctl(0x3001 /* ARCH_??? */, 0x7ffc09151430) = -1 EINVAL (Invalid argument)
81272 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)

Anyone have ideas? I'm unclear about what the screen session issue is or how to go about solving it. Thank you all very much for your time and thoughts.

2
  • Try ExecStart=/bin/sh -c '/usr/bin/screen -DmS mc-%i /usr/bin/java -server -Xms512M -Xmx2048M -XX:+UseG1GC -XX:+CMSIncrementalPacing -XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -jar server.jar nogui' and see if the result is any different. – user535733 Nov 26 '20 at 22:58
  • THIS WORKED! This worked! It's incredible. thank you so much. if you post this as a reply, would be more than happy to vote it up and such! – person Nov 26 '20 at 23:19
0

On your ExecStart line,

  • The service is looking for $(ls -v | grep -i "FTBServer.*jar\|minecraft_server.*jar" | head -n 1)

  • But the server name is server.jar...which that grep won't find.

One easy solution is to substitute that long expression, replacing it with the simple, real file name.

2
  • of course of course.... thank you so much – person Nov 26 '20 at 23:55
  • Such things are obvious ONLY in hindsight. Took a good 10 minutes of comparing to my own Minecraft .service file and several blind alleys before discovering it. – user535733 Nov 26 '20 at 23:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.