Tutorials/Server startup script

This is an example of possible Minecraft server startup and maintenance script for GNU/Linux distros.

Pre-Requisites
Screen package must be installed. On CentOs and Red Hat-based distributions: yum install screen On Debian based systems such as Ubuntu: apt-get install screen

Download
To download the script with wget, run the following (WATCH OUT SCRIPT NEEDS WORK - change the WORLD, MCPATH and BACKUPPATH variables. Important: If you use the wget method and the first character of every line is an empty space, the script won't work and update-rc.d outputs errors. If so, you have to remove the leading empty spaces from each line. Be careful not to delete anything else than empty space though!) wget -O minecraft "http://minecraft.gamepedia.com/Tutorials/Server_startup_script/Script?action=raw"

# SERVICE='minecraft_server.jar' SCREENNAME='minecraft_server' OPTIONS='nogui' USERNAME='minecraft' WORLD='world' MCPATH='/home/minecraft' BACKUPPATH='/media/remote.share/minecraft.backup' MAXHEAP=2048 MINHEAP=1024 HISTORY=1024 CPU_COUNT=1 INVOCATION="java -Xmx${MAXHEAP}M -Xms${MINHEAP}M -XX:+UseConcMarkSweepGC \ -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=$CPU_COUNT -XX:+AggressiveOpts \ -jar $SERVICE $OPTIONS" ME=`whoami` as_user { if [ "$ME" = "$USERNAME" ] ; then bash -c "$1" else su - "$USERNAME" -c "$1" fi } mc_start { if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then echo "$SERVICE is already running!" else echo "Starting $SERVICE..." cd $MCPATH as_user "cd $MCPATH && screen -h $HISTORY -dmS ${SCREENNAME} $INVOCATION" sleep 7 if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then echo "$SERVICE is now running." else echo "Error! Could not start $SERVICE!" fi fi } mc_saveoff { if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then echo "$SERVICE is running... suspending saves" as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'" as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-off\"\015'" as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-all\"\015'" sync sleep 10 else echo "$SERVICE is not running. Not suspending saves." fi } mc_saveon { if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then echo "$SERVICE is running... re-enabling saves" as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-on\"\015'" as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'" else echo "$SERVICE is not running. Not resuming saves." fi } mc_stop { if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then echo "Stopping $SERVICE" as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'" as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-all\"\015'" sleep 10 as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"stop\"\015'" sleep 7 else echo "$SERVICE was not running." fi if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then echo "Error! $SERVICE could not be stopped." else echo "$SERVICE is stopped." fi } mc_update { if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then echo "$SERVICE is running! Will not start update." else as_user "cd $MCPATH && wget -q -O $MCPATH/versions --no-check-certificate https://launchermeta.mojang.com/mc/game/version_manifest.json " if [ "$1" == "snapshot" ] ; then JSONVERSION=`cd $MCPATH && cat versions | python -c "exec(\"import json,sys\nobj=json.load(sys.stdin)\nversion=obj['latest']['snapshot']\nfor v in obj['versions']:\n  if v['id']==version:\n    print v['url']\")"` else JSONVERSION=`cd $MCPATH && cat versions | python -c "exec(\"import json,sys\nobj=json.load(sys.stdin)\nversion=obj['latest']['release']\nfor v in obj['versions']:\n  if v['id']==version:\n    print v['url']\")"` fi     as_user "cd $MCPATH && wget -q -O $MCPATH/versions --no-check-certificate $JSONVERSION" MC_SERVER_URL=`cd $MCPATH && cat versions | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["downloads"]["server"]["url"]'` as_user "rm $MCPATH/versions" as_user "cd $MCPATH && wget -q -O $MCPATH/minecraft_server.jar.update --no-check-certificate $MC_SERVER_URL" if [ -f $MCPATH/minecraft_server.jar.update ] ; then if `diff $MCPATH/$SERVICE $MCPATH/minecraft_server.jar.update >/dev/null` ; then echo "You are already running the latest version of $SERVICE." else as_user "mv $MCPATH/minecraft_server.jar.update $MCPATH/$SERVICE" echo "Minecraft successfully updated." fi     else echo "Minecraft update could not be downloaded." fi   fi  } mc_backup { mc_saveoff NOW=`date "+%Y-%m-%d_%Hh%M"` BACKUP_FILE="$BACKUPPATH/${WORLD}_${NOW}.tar" echo "Backing up minecraft world..." #as_user "cd $MCPATH && cp -r $WORLD $BACKUPPATH/${WORLD}_`date "+%Y.%m.%d_%H.%M"`" as_user "tar -C \"$MCPATH\" -cf \"$BACKUP_FILE\" $WORLD" echo "Backing up $SERVICE" as_user "tar -C \"$MCPATH\" -rf \"$BACKUP_FILE\" $SERVICE" #as_user "cp \"$MCPATH/$SERVICE\" \"$BACKUPPATH/minecraft_server_${NOW}.jar\"" mc_saveon echo "Compressing backup..." as_user "gzip -f \"$BACKUP_FILE\"" echo "Done." } mc_command { command="$1"; if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then pre_log_len=`wc -l "$MCPATH/logs/latest.log" | awk '{print $1}'` echo "$SERVICE is running... executing command" as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"$command\"\015'" sleep .1 # assumes that the command will run and print to the log file in less than .1 seconds # print output tail -n $[`wc -l "$MCPATH/logs/latest.log" | awk '{print $1}'`-$pre_log_len] "$MCPATH/logs/latest.log" fi } case "$1" in start)    mc_start    ;;  stop) mc_stop ;; restart)    mc_stop    mc_start    ;;  update) mc_stop mc_backup mc_update $2 mc_start ;; backup)    mc_backup    ;;  status) if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then echo "$SERVICE is running." else echo "$SERVICE is not running." fi   ;; command)   if [ $# -gt 1 ] ; then      shift      mc_command "$*"    else      echo "Must specify server command (try 'help'?)"    fi    ;;  *) echo "Usage: $0 {start|stop|update|backup|status|restart|command \"server command\"}" exit 1 ;; esac exit 0
 * 1) !/bin/bash
 * 2) /etc/init.d/minecraft
 * 3) version 0.4.2 2016-02-09 (YYYY-MM-DD)
 * 1) BEGIN INIT INFO
 * 2) Provides:   minecraft
 * 3) Required-Start: $local_fs $remote_fs screen-cleanup
 * 4) Required-Stop:  $local_fs $remote_fs
 * 5) Should-Start:   $network
 * 6) Should-Stop:    $network
 * 7) Default-Start:  2 3 4 5
 * 8) Default-Stop:   0 1 6
 * 9) Short-Description:    Minecraft server
 * 10) Description:    Starts the minecraft server
 * 11) END INIT INFO
 * 1) Settings
 * 1) Start-Stop here

Requirements

 * screen
 * python (apt-get install python)

Installation
Use your favorite editor to create file called minecraft in /etc/init.d/ and paste the script above in that file.

Edit the USERNAME and MCPATH -variables according to your setup. If you use a wrapper script, change INVOCATION to start it instead of starting the server directly.

Make sure the newly created file has required permissions You can set the permissions by running: chmod a+x /etc/init.d/minecraft

Then run (on Debian-based distributions) update-rc.d minecraft defaults

Starting with Debian 6.0, the insserv command is used instead, if dependency-based booting is enabled. insserv will produce no output if everything went OK. Examine the error code in $? if you want to be sure. insserv minecraft

On CentOs and RHEL(Redhat enterprise Linux) You will need to add the process into the chkconfig list chkconfig manages startup scripts under systemd chkconfig --add minecraft To check if the process is done correctly use the ntsysv command keep scrolling until you see the minecraft process if you don't repeat the chkconfig command. to add required symbolic links. Note: your system will most likely warn you that the script does not meet all requirements. The script will however work.

You can also setup an entry in your crontab to backup the server. A sample crontab to backup every half hour on the hour, and 30 minutes into the hour:

crontab -e and add this 0,30 * * * * /etc/init.d/minecraft backup
 * Using the user account you want the work done under, run:

If the above attempt went poorly because you do not know how to use vi, try: VISUAL=/usr/bin/nano crontab -e

Uninstall
(In debian based GNU/Linux distribution) update-rc.d -f minecraft remove (In CentOs/RHEL) chkconfig --del minecraft

Usage
The script may be invoked via the following command on most systems, where "(command)" will be "stop", "start", "restart", or any of the other options it supports. /etc/init.d/minecraft (command) On most RedHat- or Debian-based distribution where the `service` command is available, it should be invoked as: service minecraft (command) To view the screen, use: screen -r

To exit the screen, use: CTRL+a+d

Extra information
If you still want to view the live log file, use this command in the server directory. tail -f logs/latest.log

Alternative Startup Scripts
The following scripts offer the same functions as the above script but contain more useful features:
 * mcwrapper


 * &#91;Multi World&#93; Minecraft Server Control Script
 * Run multiple Minecraft worlds.
 * Start, stop, and restart single or multiple worlds.
 * Create, delete, disable, and enable worlds.
 * Supports CraftBukkit in addition to the standard Mojang server distribution.
 * Users automatically notified of important server events.
 * Uses the Minecraft Query protocol to keep track of current server conditions.
 * LSB and systemd compatible init script, allows for seamless integration with your server's startup and shutdown sequences.
 * Map worlds using the Minecraft Overviewer mapping software.
 * Backup worlds, and remove backups older than X days.
 * Update the server software and installed addons.
 * Send commands to a world server from the command line.


 * minecraftd
 * Start, stop, and restart the server using either systemd or the script directly
 * Send commands to a server from the command line
 * Backup server (world, plugins, configuration, etc.), and purge old ones (configurable)
 * Suspend server if no player is logged in and bring it up as soon as one tries to join to maximazie efficiency
 * Purely written in bash and condensed features in about 500 lines of code to keep the foorprint small
 * Flexible configuration: support for e.g. spigot/craftbukkit, adjustable threads and RAM usage, etc.
 * Full systemd support with init and backup script
 * Secure resource usage: run script as different user and drop permissions if not requiered
 * Very similiar to the script described in this article: It as well uses screen and tar but offers more advanced features
 * Excellent Arch Linux support


 * MC Sheller


 * Minecraft Systemd Service A nice systemd service that features:
 * safe shutdown using rcon
 * protection of the system by making most of the system readonly
 * uses systemd journal to log
 * can be combined with a nice commandcenter script
 * is fully integrated in the systemd-toolchain


 * minecraft init
 * modification of this script with a lot more features like multiworld


 * Minecraft Service


 * Dagmar d'Surreal's Sysv init script


 * Setsuna-Xero's OpenRC(Gentoo) compatible init script, with conf.d defaults


 * Mineserv Perl Init Script
 * A very simple automatic start/stop script with backup and cleanup functions and the ability to pass commands to the server console.