Preparing the operating system
First of there are some things in the operating system that improve security and separation from the rest of the server. As a first step we create a dedicated linux user for minecraft:
root# groupadd -r minecraft
root# useradd -r -g minecraft -d "/var/minecraft" -s "/bin/bash" minecraft
The created user has his home directory in /var/minecraft
which will be the directory of most of the files that will be installed. The user has no password so you cannot login with it. To change to the minecraft user you have to use su minecraft
as root.
This will create the four directories backup
, build/spigot
, build/mcrcon
and server
in /var/minecraft
.
- The build directory will contain the build environment for spigot and mcrcon since it is not possible to download the binary servers anymore.
- The
server
directory will contain the actual server and maps. - The
backup
directory is something I use to backup old server binaries should an upgrade fail.
The server
For the server update and initial download I created a small bash script:
#!/bin/env bash
# Download
wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar &> lastdl.log && echo "Download Successful"
# Build
# use --rev version to overwrite latest with given argument else use latest
java -jar BuildTools.jar --rev ${1:-latest} &> lastbuild.log && echo "Build Successful"
# Backup
mv ../../server/spigot.jar ../../backup/server/`date +"%Y-%m-%H-spigot.jar"` && echo "Backup Successful"
# Install
mv spigot-1.*.jar ../../server/spigot.jar && echo "Install Successful"
So simply copy and paste that script into the file /var/minecraft/build/spigot/update.sh
and make it executable and change group and owner to the minecraft user.
root# vim /var/minecraft/build/spigot/update.sh # and paste the script
root# chmod +x /var/minecraft/build/spigot/update.sh
root# chown minecraft.minecraft -R /var/minecraft/
Now java has to be installed since otherwise the build does not run:
Next we download and build the server to do so we first change to the minecraft user and the build/spigot
directory. Then we execute the update.sh
script. The first time the script is run it shows that it can't move the old server binary wich is expected.
After that step you should have a nice binary /var/minecraft/server/spigot.jar
. If you want to check if you are up to date with the tutorial you can try to execute it with java -jar spigot.jar
. It will then create all the config files.
Downloading and building mcrcon
Mcrcon is a very small tool that allows to connect to a running minecraft server instance and issue some commands. Since the binary is only available in 32bit for linux I compiled it from source which works like a charm:
root# su minecraft
minecraft> cd ~/build/mcrcon
minecraft> git clone git://git.code.sf.net/p/mcrcon/code mcrcon-code
minecraft> cd mcrcon-code
minecraft> gcc mcrcon.c -o mcrcon
minecraft> cp mcrcon ~/
If your server is already running you can try the mcrcon
tool by executing:
Replace the port and password with the values specified in the server.properties
file.
In this howto the next step is to create a systemd minecraft.service file.
The systemd service file
The systemd service file took quite some time for me to create but I think it is quite nice. So here it is (a line by line explanation follows):
[Unit]
Description=Minecraft Server
Documentation=
Wants=network.target
After=network.target
[Service]
User=minecraft
Group=minecraft
Nice=5
EnvironmentFile=-/var/minecraft/unit.conf
KillMode=none
SuccessExitStatus=0 1
ProtectHome=true
ProtectSystem=full
PrivateDevices=true
NoNewPrivileges=true
PrivateTmp=true
InaccessibleDirectories=/root /sys /srv -/opt /media -/lost+found
ReadWriteDirectories=/var/minecraft/server
WorkingDirectory=/var/minecraft/server
ExecStart=/usr/bin/java -Xmx1024M -Xms1024M -jar spigot.jar --noconsole
ExecStop=/var/minecraft/mcrcon -H localhost -P $port -p $password stop
[Install]
WantedBy=multi-user.target
First the easy things: line 2 and 3 contain descriptive information you can fill in anything you like. Line 5 and 6 say that this service likes to have network available.
The Service
section is the one that gets more interesting. lines 9, 10 and 11 restrict the minecraft server so that it is run as minecraft user and group with a nice level of 5 meaning that it has a lower priority than most other things that run on the server. I do that because my server hosts other services besides the minecraftserver that are more important to me.
With line 12 I import a unit.conf file that can be used to set various environment variables. I thought it might be usefull but actually I didn't use it.
Line 13 and 14 are more important again KillMode=none
says that the server is not killed when the service is stoped but instead the ExecStop
command is used to gracefully stop the server. The next line marks the service as sucessfully exited.
The following lines regulate the access of the server. So if the server should be compromised in any way it should not be able to acess anything outside the /var/minecraft/server
directory.
ExecStart
specifies the command that fires up the server. If you want to pass more advanced options to the server then this is most probably the place to do so.
ExecStop
specifies the command that is issued to stop the server. you have to replace $port and $password with the actual values you specify in the server.properties
file of the minecraft server.
The Install
section specifies how to enable this service so that it is started every boot.
Create the file in the directory /etc/systemd/system/minecraft.service
and paste the contents from above.
Note on CentOS
As CentOS has a quite old systemd Version there are some features missing. So on CentOS you have to drop the ProtectHome, ProtectSystem and PrivateDevices otherwise you will probably get warnings in the log because those options were introduced in Systemd v214.
Setting up the server
First of all you have to accept the eula to do so you have to add the line eula=true
to /var/minecraft/server/eula.txt
. This file should be generated when you first run the server.
Now you are ready to set up your server. This is done in the file /var/minecraft/server/server.properties
most of the setings do have good default values but everything can be changed as you like see: server.properties
The following 3 properties are important for the systemd minecraft.service
file to work properly. They enable the rcon protokoll of the minecraft server. You can connect to a running instance and execute commands using rcon. the systemd service uses this in its ExecStop
part to gracefully shut down the server.
The following settings have to be changed in /var/minecraft/server/server.properties
for this setup to work(keep replacing $port and $password with your own values):
There are a lot of additional options in /var/minecraft/server/bukkit.yml
and /var/minecraft/server/spigot.yml
change anything you like to change.
Securing the server
Since Fedora uses Firewalld I created a nice little firewalld service file in /etc/firewalld/services/Minecraft.xml
with the following contents:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Minecraft</short>
<description>The Minecraftserver that runs on this host. This service has a customized Port.</description>
<port protocol="tcp" port="$minecraftport"/>
</service>
remember to change the portnumber to the one you specified in server.properties
Now we need to reload the firewall so that it sees the new servicefile and then enable it permanently with:
Running the server
Now comes the big time where you can start your nicely setup server for the first time. First systemd might not be aware of your new minecraft.service so reload it quickly then start the server.
it should return promtly to the promt and then you can read all the log entries with:
root# journalctl -u minecraft -f # To see an updating log
root# journalctl -u minecraft # To see all logs in a less like viewer.
Somewhere when the logs stop scrolling you should see something like Done (4.406s)! For help, type "help" or "?"
indicating that the server has started successfully. If not try to consult the journal-log what might be missing.
You can then stop the server with systemctl stop minecraft
and go then check if the server was nicely shut down without being killed in mid shutdown. More specifically you should see for every world a message in the journal that it is being saved.
If the shutdown is not working correctly then you should first try that the rcon connection is working by manually executing the rcon command from ExecStop
.
Finally when everything is working as expected you can enable the service with:
If you want to update the server try the following commands:
root# su minecraft
minecraft> cd ~/build/spigot/
minecraft> ./update.sh
Download Successful
Build Successful
Backup Successful
Install Successful
minecraft> exit
root# systemctl restart minecraft
Play and profit
Whenver you reboot now the minecraft server is automatically started the appropriate ports are open and everything should be set up for a happy gaming experience.
Comments
LOAS
This article was exactly what I needed to very quickly get a minecraft server running on my centos 7 server. I had to modify the minecraft.service file a bit, which may have reduced the process isolation a bit.
Thanks a bunch!
Brandon Zylstra
The script fails in a couple of places.
../../backup/server/ doesn't exist and must first be created.
spigot-1.*.jar doesn't exist either, but I'm not clear on the purpose of this line.
Also, didn't you mean to use cp instead of mv for the backup?
enaut
Hey Brandon, I added the directory in the mkdir statement. so that should be fixed. As for the Spigot-1.*.jar this file should be created by the build process during the build step in line 7. If it does not exist please check the build log in lastbuild.log.
Also note that this script is customized and pretty much hardcoded for my system. I just added it for others to edit it for their needs.
hope that helped.
Rob
LOAS could you post the modifications you made? I'm getting Failed at step NAMESPACE spawning /usr/bin/java: Operation not permitted and similar errors when trying to start the process.
enaut
Hey Rob, I never got that error so I cannot guess what went wrong. However I can try to help you debug the issue. First of is java there? What happens if you execute /usr/bin/java. Next I'd try to run the command from the ExecStart line in the systemd service. Next I'd try to change the user using su to the minecraft user and run the same command again - Carful to change all the permissions of previously generated files accordingly! last run the service and see what happens in the journal.
Duke
I'm getting the same error on Centos 7. Failed at step NAMESPACE spawning /usr/bin/java: Operation not permitted
note: I do have SE linux enabled 8)and if possibleI'd like to keep it that way.
Randell Jesup
Thanks! For Fedora 22, java was in /bin/java instead of /usr/bin/java, and /var/minecraft/unit.conf has to exist or it will fail to start the service
wolfgang dragunov
i'm having the same problem as Rob. i can start the server manually with the command from the service file as root. i have checked file permissions. i have a vanilla minecraft server running to test with but stop it when trying to get this permanent solution running.
enaut
Sorry for not responding... :( I will look into your problem when I find time. And I really have to add some formatting to the comments... The fact that wolfgangs post looks so ugly is really all my fault! - why do I allways have to use my own software I can only blame myself :P
ise
For me, to solve the NAMESPACE issue, i just had to remove certain configurations from the systemd script... I used this as the basis: http://linuxrackers.com/doku.php?id=creating_a_custom_systemd_service_script_for_minecraft
I modified the systemd config SERVICE section to use only User, Group, WorkingDirectory, ExecStart and ExecStop
(merged two comments to one by enaut)
enaut
I now enabled SELinux on my Fedora 23 server and I did not hit any issue with NAMESPACE.It might be some issue with the older Version of Systemd in CentOS?
wolfgang dragunov
i managed to get the server working following ise's suggestions. i am using centos 7. the only other change i made was to the firewall. after creating the firewalld service the port still wasn't open, so i just added through add-port.
enaut
Thanks to your help I tracked the issue down. - at least I think so as I cannot test it.
The ProtectHome, ProtectSystem and PrivateDevices options have been added with systemd v214 while CentOS uses 208 I think.
I hope that solved some of the problems and I added a note to the article :).
bajr
Running CentOS 7 here and systemd v208. I encountered the same problem with the Namespace error. I was able to resolve it completely by removing /lost+found from the InaccessibleDirectories directive. (Even better, prepend it with a '-' so the directory's presence is optional.)
After I did this, I don't encounter the error, even when I include the ProtectHome, ProtectSystem, etc directives that aren't supposed to be supported by v208... interesting.
Hope this helps.
enaut
@ bajr
Thanks for solving the issue! I adjusted the article to use the - prefix and modified the note for CentOS. According to documentation systemd throws a warning on unknown Variables but does run without problem.
bipsen
I tried to use the description to set up systemd file on a debian jessie on raspberry Pi ... When trying to start, I get:
But the java binary exists:
Any clue on how to fix iy ?
enaut
Mhm I can only guess there!
The thing that confuses me is the
No such process
part.Do you happen to use Variables in lines besides execstart?
You could try removing the "sandboxing" for testing purposes (in my file line 16 to 21 - note that in line 21 /opt/ is explicitly set to be invisible but I thought that this is only for the running processes).
Oh and did you double check that the user and group specified in the systemd service file exist?
goober
I'm using Centos 6, 64-bit, and It's ydying in the BuildTools.jar:
angrymoose
Thanks for sharing!
When using
minecraft_server.jar
instead ofspigot.jar
in combination with:The java process did not actually exit after
systemctl stop minecraft.service
Java apparently exits with status 143 on sucess when receiving
SIGTERM
. So you can ommit theKillMode
option and setHere is my version of minecraft.service:
enaut
@goober
This sounds like an issue with permissions to me. so probably you have no write permissions for the directory/or there are files in the directory that you do not have write permissions for. Also is the git binary executable?
@angrymoose
If I recall correctly I added the
KillmodeNone
because I shut the server down with rcon see theExecStop
line. Without that gracefull shutdown I was never seeing theSaving worlds
line which got me suspicious. So my approach is to log into rcon and shutdown gracefully and do not let systemd interfere no matter how long the server needs to shut down. So withExecStop
set correctly the server should be shutting down.docsen
ough hi... first problem is that i cant user "localhost" nor "127...." for rcon, therefore i used the real broadcast IP. Yes i am trying to find the fault.. guess its portforwarding...
anyway:
I tried to restart from INGAME the MCinstance by using /restart in chat.. after a while i had a sniff into the journal and found this:
any clue? can you push me in the right direction please? thanks a bunch :) doc
enaut
Hey docsen,
first of... rcon is unencrypted (even password transmission)... so this should be really an exception...
So if you do a restart from within minecraft minecraft exits with an exitcode bigger than
255
(which is limited to255
) this causes systemd to think that it did not exit cleanly. You can tell systemd that255
is perfectly fine by adding255
to the line that saysSuccessExitStatus=0 1
in theminecraft.service
file.That however only hides the error. You can make the server restart, by adding
Restart=always
see https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart=Now your server should restart after you entered the restart command. I don't have enough information on your rcon issue - I just don't know what to look for.
thundercrack
This saved me a ton of time, thank you!
TinfoilSubmarine
Arch user here, had to modify the InaccessibleDirectories directive so that /media was optional, as suggested by bajr (i.e., changing from /media to -/media). Thanks for the work you did here so that I didn't have to!
FlyingMongoose
Latest version of CentOS 7 has systemd 219
I'm running on Centos 7.3
The only modification I had to make was to comment/remove
ProtectHome
, but ONLY because I actually install my stuff onto the user, and ifProtectHome
is enabled it prevents the functions from being accessible.madhartigan
Are the three lines found in the code window of the Setting up the Server section supposed to be added to the file
minecraft.service
or are they intended to be executed from the command line?There's no command prompt in front of them, so I'm assuming they're additional lines to be added to
minecraft.service
, but that's not clear.Let me know.
Thanks!!
enaut
@madhartigan
No those three lines are settings of the minecraft server they are intended for the
/var/minecraft/server/server.properties
settings file (if you stick to the paths used here). Usually they already exist and only need to be changed.I made that more clear.
madhartigan
You completely exceeded my expectations for response time. Thank you SO much. Sincere credit for maintaining your page properly. Thank you so much!!!
Jwguy
Worked one time, and now no longer starts the server. Keeps procing the following:
enaut
There seems to be some issue with your
minecraft.service
file. The command posted inExecStart
is not correct. You can simply copy and paste that command to a terminal and try executing it there. It will probably print an error.When you fixed the command you can readd it to your service file - careful with paths as they might be different.
gcarvelli
I've set up a minecraft server to work with systemd before but this solution is a lot more complete than what I came up with. The ExecStop mcrcon call to stop the server is a cool idea and way more elegant than just killing it outright.
Great post!
enaut
Thank you!
I have even further improved this by adding socket activation...
I will need some quiet hours to document this though.
merry xmas
Doug
Great guide for setting up a Minecraft server. There are also other options such as using a minecraft server hosting company [Spam removed]
Gidfiddle
Thanks for your excellent work.
I'm on Fedora 27, and everything works except for
systemctl stop minecraft
. In the journal there appears the following:However, running the contents of
ExecStop
directly on the command line (as userminecraft
) properly shuts down the server.The "Permission denied" error indicates a permissions problem, but
ls -l ~minecraft
shows that the permissions formcrcon
areI'm scratching a hole in my head. Any ideas?
enaut
Sorry for not replying for so long. I have currently very limited time... did you solve the issue? I did not see any obvious errors.
you could try executing the
who
command instead of themcrcon
command just to see if it is actually executed as minecraft... - Another thing might be SELinux or similar blocking the execution...Gidfiddle
Following your suggestion, I tried changing the SELinux context using the following command:
(Originally, the type was
var_t
) Nowsystemd
has permission to runmcrcon
.dryans
Wonderful guide! I'd been trying off and on to get Minecraft running as a service for a LONG time but this writeup and the added explanation is what finally got me there.
Also think I learned a lot more about linux from this. Thanks!
enaut
Thank you so much I am happy to have helped you!
Randell Jesup
I have Fedora 28 (also; soon to be 29). I had to disable the
ProtectHome
line to get it to start. Clearly it was looking for something there to start java... The error is totally opaque unfortunately. I haven't figured out why yet; it's not really safe - before I disabled some automatic updating of the server (or mcrcon?) it installed a crypto miner(!) and stored it in the~minecraft/.ccache
directory to try to hide it. Needless to say I disabled auto-updates, but it points out minecraft needs to be sandboxed (and the server itself may be exposed to the web, and subject to malicious clients trying to crack the server.Another suggestion stolen from the Minecraft wiki
https://minecraft.gamepedia.com/Tutorials/Server_startup_script
: use/var/minecraft/server/%i
(and aoppropriate other tweaks) to allow running multiple servers viasystemctl start minecraft@vanilla
orsystemctl start minecraft@hardcore
etc. Before I noticed that trick I had to clone the service file and tweak it.enaut
Hey Randell Jesup,
thanks for your comment. I was using F28 and I am using F29 and so far the
ProtectHome
did work without problem. Could it be that theminecraft
user has hishome
in the home directory or that the maps are somewhere in the home directory?The crypto miner seems worrying - do you care to elaborate how you found it and how you identified it? I'd be very curious to see if there is something similar in my server. - Though first thing I'd suspect is mods. The mcrcon is very tiny and I read most of it. This should not be the Problem. Though when the mcrcon port is open to the internet that will be a massive problem, as rcon is a very unsecure protocol.
I'm using the service instantiation for other services too but I never needed it for minecraft as this is one single server. I dislike the use of screen in the tutorial given.
Randell Jesup
home:
/var/minecraft
maps:
/var/minecraft/server
andserver2
The crypto miner was some time ago; and appeared to be installed as part of something run from
update.sh
(I presume). No ports tominecraft/mcrcon
were ever open to the internet (local lan play only). It clearly hid itself using.ccache
. No mods to the server (some player mods; perhaps one of them infected the server.I keep the minecraft user very locked down, of course.
I noticed it because it was using 100% of one core all the time
Also: Due to selinux, there are various things that have to be done, like after update.sh was run I had to change the permission for mcrcon:
Kevdog
I understand this is a Fedora forum, however for the most part these instructions worked for an Ubuntu installation. bash is located in /usr/bin/env bash. systemd startup files work. JDK package names differed but I managed to installed with openjdk11.
Nice job on the writeup.
JMD
The mcrcon command in the
systemd
file doesn't actually stop thejava
process in your example. The systemd file calls java to start up the daemon, shouldn't it also stop the JVM to stop the service as well?Otherwise you have a bunch of PIDs still running on your system in parallel.
enaut
@JMD thanks for the remark. The mcrcon script does not kill the process instead it tries to shut down the server gracefully meaning to use minecrafts own
\stop
command. So minecraft shuts itself down and after it exits usually the jvm also exits. - At least I never noticed any lost jvm processes. - However if the mcrcon command is not setup correctly the minecraft server will not be shut down. So test if the mcrcon command does in fact shut down the minecraft server.hibobjr
I have completed everything outlined in your guide but my server does not have permission to write to files and thus causes many errors and eventually crashes. For example, the console outputs something like this: java.io.FileNotFoundException: spigot.yml (Permission Denied)
I have made sure my WorkingDirectory path and ReadWriteDirectories path are correct and I don't know what to do from here. I'm still fairly new to linux so I'm sorry if this is a stupid question. I'm running on Ubuntu-Server 18.04.3.
enaut
No worries for asking! It seems to be a permission issue. Most probably you created and tested the server as root once so the files do not belong to the minecraft user.
To fix this you go to your minecraft directory and change the owner and group of all the files to minecraft. Make sure you understand what you are doing because it can be really hard to fix if you mess up the permissions of your system.
mindavi
Hey, just want to thank you for the guide. It was useful in setting up my server and it seems to be happily running now.
I've used the mcrcon created by Tiiffi https://github.com/Tiiffi/mcrcon. Might be nice to add an url to the repository page (I think it's hosted on both sourceforge and github).
See also https://bukkit.org/threads/admin-rcon-mcrcon-remote-connection-client-for-minecraft-servers.70910/
eve
great guide, might add that you have to download git. got some errors on first (and second) start but after that I've "updated" a last time with update.sh and all errors were gone, logs looks okay
Alien
Thanks for the great guide! It really helped me along with getting a couple of servers purring along and I learned a ton along the way.
The one issue I've run into is that you need to fix mcrcon's context in SELinux in order for systemd to properly use it to stop the server. A symptom of this is that the server never stops when you tell it to with `systemctl stop minecraft´ even though systemd will say it exited successfully. (At least on CentOS 8)
To do so, run:
then
Then you should be in business.
Cheers!
Add a new comment
Note that all comments are moderated - so your post will not appear till I find time to accept it.
The comments do use markup syntax.