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