You are not logged in.

#1 2011-02-24 19:25:58

PIMPinator
Member
From: Queensland, Australia
Registered: 2010-03-14
Posts: 85

Minecraft server script (run minecraft server as a daemon in Arch)

Hey all, I just finished editing and setting up a nice script to run a Minecraft server at boot in Arch. This is based on the original script on the minecraft wiki here. I've edited it to be suitable to place in your /etc/rc.d/ folder with the name "minecraft" (/etc/rc.d/minecraft).

This requires a user "minecraft" with the home directory /home/minecraft to work by default.

I decided I wanted to run the server entirely in RAM so I store all my files in /home/minecraft/backup while the server is offline. When it starts up it makes a tmpfs mount at /home/minecraft/minecraft and copies all the files there and runs from there. It makes an hourly backup using /etc/rc.d/backup stored in /home/minecraft/onlinebackup, first erasing the current backup and creating a new one. This is simply to save space. In the event of a crash without proper stopping of the daemon you will have a backup from your previous reboot (or restart of your minecraft server) in /home/minecraft/backup and one from within the previous hour in /home/minecraft/onlinebackup which I figure ought to be enough. You can manually backup at any time by restarting the daemon.

All paths can be altered. You can run this game under your normal user if you wish, just change the Settings section at the top of the file. RAM amounts may need to be increased for both the server and for the tmpfs, depending on how large your files are (mine are tiny and I have not heard of over 48MB for a game world, but you never know). Just check up on df -h every now and again to make sure your tmpfs has plenty of space, or just increase the allocated maximum size from the start. If you have low RAM you can always change the script to simply not use tmpfs.

If anyone wants, just ask and I can put up a version without tmpfs (should be easy enough to remove yourself but if you're not sure I'll do it for you)

All you need to start off with (if starting your server for the first time, using the scrip as is) is the user minecraft created, with the folders backup, onlinebackup and minecraft in the folder /home/minecraft, your minecraft_server.jar file in /home/minecraft/backup and your oninebackup file in /home/minecraft/backup.

NOTE: onlinebackup file runs from /home/minecraft/minecraft so that if your system crashes, the cron job to run the backups will fail because the link will point to a non-existant file until server is started again.

You can use these commands to with the server: /etc/rc.d/minecraft {start|stop|restart|update|backup}

The backup system is designed to wipe all previous sessions' backups upon starting the server, so do not set it to start the server at boot.

/etc/rc.d/minecraft

#!/bin/bash
# /etc/rc.d/minecraft

. /etc/rc.conf
. /etc/rc.d/functions

#Uncomment line below if using Sun JRE
#. /etc/profile

#Settings
SERVICE='minecraft_server.jar'
USERNAME="minecraft"
MCPATH='/home/minecraft/minecraft'
MCOFFLINEPATH='/home/minecraft/backup'
INVOCATION='java -Xmx768M -Xms768M -jar minecraft_server.jar nogui'
BACKUPPATH='/home/minecraft/onlinebackup'


ME=`whoami`
as_user() {
  if [ "$ME" == "$USERNAME" ] ; then
    bash -c "$1"
  else
    su -c - $USERNAME "$1"
  fi
}

mc_start() {
  stat_busy "Starting Minecraft Server"
  
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "Tried to start but $SERVICE was already running!"
  else
    echo "$SERVICE was not running... starting."
    
    #Move minecraft from backup folder to ram
    mount -t tmpfs tmpfs -o size=50m $MCPATH
    cp -a $MCOFFLINEPATH/* $MCPATH
    echo "Files moved to RAM."
    
    cd $MCPATH
    as_user "cd $MCPATH && screen -dmS minecraft $INVOCATION"
    sleep 7
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
      echo "$SERVICE is now running."
      
      #Create hourly backups while running
      ln -s $MCPATH/onlinebackup /etc/cron.hourly/minecraftonlinebackup
      echo "Hourly backups initiated."
    else
      echo "Could not start $SERVICE."
      umount $MCPATH
    fi
  fi
    
  add_daemon minecraft
  stat_done
}

mc_saveoff() {
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
    echo "$SERVICE is running... suspending saves."
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
    sync
    sleep 10
  else
    echo "$SERVICE was not running. Not suspending saves."
  fi
}

mc_saveon() {
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "$SERVICE is running... re-enabling saves."
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
  else
    echo "$SERVICE was not running. Not resuming saves."
  fi
}

mc_stop() {
  stat_busy "Stopping Minecraft Server"
  
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "$SERVICE is running... stopping."                
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
    sleep 10
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
    sleep 7
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
      echo "$SERVICE could not be shut down... still running."
    else
      echo "$SERVICE is shut down."
      
      #Stop hourly backups
      rm /etc/cron.hourly/minecraftonlinebackup
      echo "Hourly backup halted."
      
      #Unmount tmpfs
      cp -a $MCPATH/* $MCOFFLINEPATH
      umount $MCPATH
      echo "Files copied to HDD."
    fi
  else
    echo "$SERVICE was not running."
  fi
  
  rm_daemon minecraft
  stat_done
}


mc_update() {
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "$SERVICE is running! Will not start update."
  else
    MC_SERVER_URL=http://minecraft.net/`wget -q -O - http://www.minecraft.net/download.jsp | grep minecraft_server.jar\</a\> | cut -d \" -f 2`
    as_user "cd $MCPATH && wget -q -O $MCPATH/minecraft_server.jar.update $MC_SERVER_URL"
    if [ -f $MCPATH/minecraft_server.jar.update ]
    then
      if `diff $MCPATH/minecraft_server.jar $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/minecraft_server.jar"
        echo "Minecraft successfully updated."
      fi
    else
      echo "Minecraft update could not be downloaded."
    fi
  fi
}

mc_backup() {
   echo "Backing up minecraft world"
   if [ -d $BACKUPPATH/world_`date "+%m.%d.%Y"` ]
   then
     for i in 1 2 3 4 5 6
     do
       if [ -d $BACKUPPATH/world_`date "+%m.%d.%Y"`-$i ]
       then
         continue
       else
         as_user "cd $MCPATH && cp -r world $BACKUPPATH/world_`date "+%m.%d.%Y"`-$i"
         break
       fi
     done
   else
     as_user "cd $MCPATH && cp -r world $BACKUPPATH/world_`date "+%m.%d.%Y"`"
     echo "Backed up world"
   fi
   echo "Backing up the minecraft server executable"
   if [ -f "$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`.jar" ]
   then
     for i in 1 2 3 4 5 6
     do
       if [ -f "$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`-$i.jar" ]
       then
         continue
       else
         as_user "cd $MCPATH && cp minecraft_server.jar \"$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`-$i.jar\""
         break
       fi
     done
   else
     as_user "cd $MCPATH && cp minecraft_server.jar \"$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`.jar\""
   fi
   echo "Backup complete"
}


#Start-Stop here
case "$1" in
  start)
    mc_start
    ;;
  stop)
    mc_stop
    ;;
  restart)
    mc_stop
    mc_start
    ;;
  update)
    mc_stop
    mc_backup
    mc_update
    mc_start
    ;;
  backup)
    mc_saveoff
    mc_backup
    mc_saveon
    ;;
  status)
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
      echo "$SERVICE is running."
    else
      echo "$SERVICE is not running."
    fi
    ;;

  *)
  echo "Usage: /etc/rc.d/minecraft {start|stop|update|backup|status|restart}"
  exit 1
  ;;
esac


exit 0

/home/minecraft/backup/onlinebackup

#!/bin/bash
# /home/minecraft/backup/onlinebackup
rm -rf /home/minecraft/onlinebackup/*
/etc/rc.d/minecraft backup

UPDATE:

rationalOgre has created an alternate script with a different backup system, which will keep compressed copies of your world indefinitely, along with a working update function. https://bbs.archlinux.org/viewtopic.php … 97#p944797

Last edited by PIMPinator (2011-06-08 14:00:54)

Offline

#2 2011-03-01 07:13:07

Splex
Member
Registered: 2009-03-09
Posts: 33

Re: Minecraft server script (run minecraft server as a daemon in Arch)

I have been using aur/bukkit. but i actually want to run the original server.  Will try out your script. Thanks PIMPinator!

Nice that you added the backup script...  I have lost 'chunks' of my map including the seed file on a crash.. fortunately i had a backup from a couple weeks before... was able to merge the (old) missing chunks... and seed.  All is good now smile

Definitely plan on running cron backup.

Last edited by Splex (2011-03-01 07:15:22)

Offline

#3 2011-03-01 14:21:39

PIMPinator
Member
From: Queensland, Australia
Registered: 2010-03-14
Posts: 85

Re: Minecraft server script (run minecraft server as a daemon in Arch)

Cleaned up script (in first post), changed where backups and things execute, just stop your current script and overwrite with this one then start again.

Offline

#4 2011-03-01 16:01:09

jollysnowman
Member
From: Austin, TX
Registered: 2010-12-08
Posts: 35

Re: Minecraft server script (run minecraft server as a daemon in Arch)

Nice script! I'll have to give it a shot. Mine is much simpler; its only functionality is to start the server via screen. I perform the backups manually.

Offline

#5 2011-04-06 18:07:51

phekno
Member
Registered: 2011-04-06
Posts: 1

Re: Minecraft server script (run minecraft server as a daemon in Arch)

I'm having trouble getting this to work.  When I run the daemon, it moves the files to RAM and then says that it "Could not start minecraft_server.jar".  After that it complains that /home/minecraft/minecraft is busy.  I guess my question is; did you give the user "minecraft" a password when you created it?  Is that why I'm having trouble (i.e. because I gave mine a password).

Edit:  I deleted the minecraft user's password and it's still complaining about not being able to start minecraft_server.jar.  I'm not really sure why.  I don't get any kind of output in the server.log or anything like that.  I've tried running each of the commands in the script individually and I can get it started that way.

Last edited by phekno (2011-04-06 18:37:19)

Offline

#6 2011-04-12 11:09:22

PIMPinator
Member
From: Queensland, Australia
Registered: 2010-03-14
Posts: 85

Re: Minecraft server script (run minecraft server as a daemon in Arch)

The minecraft user has a password on my server.

EDIT: Ignore that, make sure you have java installed correctly. I'm using jre but I see no reason that you can't use openjdk

Last edited by PIMPinator (2011-04-12 11:12:03)

Offline

#7 2011-04-12 13:44:43

Stebalien
Member
Registered: 2010-04-27
Posts: 1,239
Website

Re: Minecraft server script (run minecraft server as a daemon in Arch)

To be consistent with other rc.d scripts, you should consider putting the settings in /etc/conf.d/minecraft and sourcing this file in your script.


Steven [ web : git ]
GPG:  327B 20CE 21EA 68CF A7748675 7C92 3221 5899 410C

Offline

#8 2011-05-23 23:58:57

rationalOgre
Member
Registered: 2011-05-23
Posts: 4

Re: Minecraft server script (run minecraft server as a daemon in Arch)

phekno wrote:

I'm having trouble getting this to work.  When I run the daemon, it moves the files to RAM and then says that it "Could not start minecraft_server.jar".  After that it complains that /home/minecraft/minecraft is busy.  I guess my question is; did you give the user "minecraft" a password when you created it?  Is that why I'm having trouble (i.e. because I gave mine a password).

Edit:  I deleted the minecraft user's password and it's still complaining about not being able to start minecraft_server.jar.  I'm not really sure why.  I don't get any kind of output in the server.log or anything like that.  I've tried running each of the commands in the script individually and I can get it started that way.

I know it's been awhile since this was asked but I recently ran into this issue while attempting to set up my own minecraft server using this code. It took the better part of forever (ok, 2 hours really but hey, this is my first time in Arch) but I finally spotted the issue. Below, for your perusal, the patch...

--- minecraft    2011-05-23 14:51:38.434887236 -0400
+++ minecraft-fix    2011-05-23 19:50:12.813208175 -0400
@@ -18,7 +18,7 @@
   if [ "$ME" == "$USERNAME" ] ; then
     bash -c "$1"
   else
-    su - $USERNAME -c "$1"
+    su -c - $USERNAME "$1"
   fi
 }

All is now working perfectly fine. Hope that helps!

EDIT: Oh and I almost forgot, I had to add ". /etc/profile" to the sourcing section of the file at the top. (This is because I use the sun JRE instead of OpenJDK.)

Last edited by rationalOgre (2011-05-24 02:43:18)

Offline

#9 2011-05-28 16:44:24

froli
Member
From: Germany
Registered: 2008-06-17
Posts: 455

Re: Minecraft server script (run minecraft server as a daemon in Arch)

How could I use this script for my bukkit server?

I didn't install bukkit from aur, if you need to know...


archlinux on Macbook Pro 10,1

Offline

#10 2011-06-01 16:51:03

PIMPinator
Member
From: Queensland, Australia
Registered: 2010-03-14
Posts: 85

Re: Minecraft server script (run minecraft server as a daemon in Arch)

rationalOgre wrote:

I know it's been awhile since this was asked but I recently ran into this issue while attempting to set up my own minecraft server using this code. It took the better part of forever (ok, 2 hours really but hey, this is my first time in Arch) but I finally spotted the issue. Below, for your perusal, the patch...

All is now working perfectly fine. Hope that helps!

EDIT: Oh and I almost forgot, I had to add ". /etc/profile" to the sourcing section of the file at the top. (This is because I use the sun JRE instead of OpenJDK.)

I changed the line in the script, although I haven't tested this yet and I don't really see what difference it would make, as it was working as is for me. I'll trust you on this one wink

@froli
I'm sorry, I don't even know what bukkit is.

Stebalien wrote:

To be consistent with other rc.d scripts, you should consider putting the settings in /etc/conf.d/minecraft and sourcing this file in your script.

I would, but since I haven't bothered making this an installer or anything, creating and editing the one file for now is easier.

Last edited by PIMPinator (2011-06-01 16:53:20)

Offline

#11 2011-06-05 18:37:55

rationalOgre
Member
Registered: 2011-05-23
Posts: 4

Re: Minecraft server script (run minecraft server as a daemon in Arch)

@PIMPinator - To be fair, I'm not sure why. The man pages for SU on my server box says that -c is an option, instead of an argument. However, on my laptop (Ubuntu) the man page for SU says that -c can come after the {username}. All I know is when I tried changing that, it suddenly spurred to life where before it was refusing to do so.

Also, Bukkit is a minecraft_server.jar modification that provides addon support and some other stuff.

@froli - There would be a couple things you would have to change. You might just find & replace through the file for all instances of minecraft_server.jar and replace them with craftbukkit-0.0.1-SNAPSHOT.jar. Also you probably would want to change the INVOCATION='blahblahblah' line to use whatever invocation of craftbukkit you want

Offline

#12 2011-06-05 23:27:18

froli
Member
From: Germany
Registered: 2008-06-17
Posts: 455

Re: Minecraft server script (run minecraft server as a daemon in Arch)

Then maybe some of you guys can help me. I don't really want the server to be started by a daemon. I am more interested by the tempfs part. I want a script that would launch my minecraft (bukkit) server in RAM and the backup script, like in the OP.

The command to launch the server would be something like:

tmux new-window -n bukkit /home/froli/Minecraft/minecraft.sh

Where /home/froli/Minecraft/ is my minecraft folder

ls /home/froli/Minecraft/:

banned-ips.txt      bukkit_update  craftbukkit-0.0.1-SNAPSHOT.jar  minecraft.sh  nether         ops.txt  RUN.bat     server.log.1       userdata        world
banned-players.txt  bukkit.yml     lib                             mmCfg.txt     onlinebackup~  plugins  server.log  server.properties  white-list.txt  world_nether

and minecraft.sh is the script from the bukkit wiki that really starts the server. I want to use tmux to launch it because I could acces to the server console whenever I want.

cat minecraft.sh: (if you want to see it)

#! /bin/sh 
BINDIR="$(dirname "$(readlink -fn "$0")")"
cd "$BINDIR"
java -Xincgc -Xmx1G -jar craftbukkit-0.0.1-SNAPSHOT.jar

I hope some of you can help me! I have absolutely zero coding skills tongue ... Thanks in advance!


archlinux on Macbook Pro 10,1

Offline

#13 2011-06-07 12:31:11

PIMPinator
Member
From: Queensland, Australia
Registered: 2010-03-14
Posts: 85

Re: Minecraft server script (run minecraft server as a daemon in Arch)

@froli: You should be able to access the server by simply logging in as the user minecraft (or just doing a "su minecraft" in a terminal) then "screen -R" (assuming you use the minecraft user for nothing else, it will be the only screen running). Other than that I'll take a look at running it with bukkit, I haven't reinstalled minecraft since I migrated servers last week.

@rationalOgre: I just realised I was running minecraft with Sun JRE and not OpenJDK and did not have ./etc/profile at the start of the script.

Offline

#14 2011-06-07 22:38:32

rationalOgre
Member
Registered: 2011-05-23
Posts: 4

Re: Minecraft server script (run minecraft server as a daemon in Arch)

@PIMPinator - Weird. On mine, if I don't source /etc/profile it won't work. No clue what the difference is. I tested it after I got it up and running, removing different elements to see if one or the other was the problem. Without it all in place it just didn't work.

I made some modifications to your script today. Fixed "update" so it works properly. (You had it running mc_backup after mc_stop, which never worked on my system.) I basically reworked it so it runs the backup, then stops the server and performs the update in the ~/backup directory, then restarts the server. I also completely overhauled the "backup" system. (for this to work you have to comment out the rm -rf ~/onlinebackup/* directive in the onlinebackup script.) Now, it creates 4 rolling backups of the server, in tar.gz format. What this means is that over time, you will accumulate the last 4 backups for each day in your ~/onlinebackup folder. I thought about creating a cleanup function to cull anything over 2 days old but to be honest, even if your world was > 50MB, zipped up it's going to be about ~20mb which means you can have 50 of them and only be taking up a gig of server space. Anyway, here's the code if you are interested.

#!/bin/bash
# /etc/init.d/minecraft

. /etc/rc.conf
. /etc/rc.d/functions
#Comment out the following if using OpenJDK
. /etc/profile

#Settings
SERVICE='minecraft_server.jar'
USERNAME="minecraft"
MCPATH='/home/minecraft/minecraft'
MCOFFLINEPATH='/home/minecraft/backup'
INVOCATION='java -Xmx768M -Xms768M -jar minecraft_server.jar nogui'
BACKUPPATH='/home/minecraft/onlinebackup'


ME=`whoami`
as_user() {
  if [ "$ME" == "$USERNAME" ] ; then
    bash -c "$1"
  else
    su -c - $USERNAME "$1"
  fi
}

mc_start() {
  stat_busy "Starting Minecraft Server"
  
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "Tried to start but $SERVICE was already running!"
  else
    echo "$SERVICE was not running... starting."
    
    #Move minecraft from backup folder to ram
    mount -t tmpfs tmpfs -o size=50m $MCPATH
    cp -a $MCOFFLINEPATH/* $MCPATH
    echo "Files moved to RAM."
    
    cd $MCPATH
    as_user "cd $MCPATH && screen -dmS minecraft $INVOCATION"
    sleep 7 
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
      echo "$SERVICE is now running."
      
      #Create hourly backups while running
      ln -s $MCPATH/onlinebackup /etc/cron.hourly/minecraftonlinebackup
      echo "Hourly backups initiated."
    else
      echo "Could not start $SERVICE."
      umount $MCPATH
    fi
  fi
    
  add_daemon minecraft
  stat_done
}

mc_saveoff() {
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
    echo "$SERVICE is running... suspending saves."
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
    sync
    sleep 10
  else
    echo "$SERVICE was not running. Not suspending saves."
  fi
}

mc_saveon() {
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "$SERVICE is running... re-enabling saves."
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
  else
    echo "$SERVICE was not running. Not resuming saves."
  fi
}

mc_stop() {
  stat_busy "Stopping Minecraft Server"
  
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "$SERVICE is running... stopping."                
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
    sleep 10
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
    sleep 7
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
      echo "$SERVICE could not be shut down... still running."
    else
      echo "$SERVICE is shut down."
      
      #Stop hourly backups
      rm /etc/cron.hourly/minecraftonlinebackup
      echo "Hourly backup halted."
      
      #Unmount tmpfs
      cp -a $MCPATH/* $MCOFFLINEPATH
      umount $MCPATH
      echo "Files copied to HDD."
    fi
  else
    echo "$SERVICE was not running."
  fi
  
  rm_daemon minecraft
  stat_done
}


mc_update() {
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "$SERVICE is running! Will not start update."
  else
    MC_SERVER_URL=http://minecraft.net/`wget -q -O - http://www.minecraft.net/download.jsp | grep minecraft_server.jar\</a\> | cut -d \" -f 2`
    as_user "cd $MCOFFLINEPATH && wget -q -O $MCOFFLINEPATH/minecraft_server.jar.update $MC_SERVER_URL"
    if [ -f $MCOFFLINEPATH/minecraft_server.jar.update ]
    then
      if `diff $MCOFFLINEPATH/minecraft_server.jar $MCOFFLINEPATH/minecraft_server.jar.update >/dev/null`
      then 
        echo "You are already running the latest version of $SERVICE."
        rm $MCOFFLINEPATH/minecraft_server.jar.update
      else
        as_user "mv $MCOFFLINEPATH/minecraft_server.jar.update $MCOFFLINEPATH/minecraft_server.jar"
        echo "Minecraft successfully updated."
      fi
    else
      echo "Minecraft update could not be downloaded."
    fi
  fi
}

mc_backup() {
   echo "Backing up minecraft world"
   local COUNTER=
   if [ -f $BACKUPPATH/co ]
   then
       COUNTER=`cat $BACKUPPATH/co`
       if [ $COUNTER -gt 4 ]
       then
           #Loop back to 1 if greater than the max number of desired saves (4 hardcoded)
           as_user "echo 1 > $BACKUPPATH/co"
           COUNTER=1
       fi
   else
       COUNTER=1
       as_user "echo 1 > $BACKUPPATH/co"
   fi
   if [ -f $BACKUPPATH/world_`date "+%m.%d.%Y"`-$COUNTER.tar.gz ]
   then
       as_user "rm $BACKUPPATH/world_`date "+%m.%d.%Y"`-$COUNTER.tar.gz"
   fi
   as_user "cd $MCPATH && tar -czf $BACKUPPATH/world_`date "+%m.%d.%Y"`-$COUNTER.tar.gz world"
   #now to update the counter
   as_user "echo $(($COUNTER + 1)) > $BACKUPPATH/co"
   echo "Backup complete..."
}


#Start-Stop here
case "$1" in
  start)
    mc_start
    ;;
  stop)
    mc_stop
    ;;
  restart)
    mc_stop
    mc_start
    ;;
  update)
    mc_saveoff
    mc_backup
    mc_saveon
    mc_stop
    mc_update
    mc_start
    ;;
  backup)
    mc_saveoff
    mc_backup
    mc_saveon
    ;;
  status)
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
      echo "$SERVICE is running."
    else
      echo "$SERVICE is not running."
    fi
    ;;

  *)
  echo "Usage: /etc/rc.d/minecraft {start|stop|update|backup|status|restart}"
  exit 1
  ;;
esac


exit 0

I hope you don't mind.

EDIT: Made a small change later that I came back and put in. If you are currently at the latest release it removes the .update file it created.

Last edited by rationalOgre (2011-06-07 23:05:58)

Offline

#15 2011-06-08 13:52:26

PIMPinator
Member
From: Queensland, Australia
Registered: 2010-03-14
Posts: 85

Re: Minecraft server script (run minecraft server as a daemon in Arch)

Hey that's pretty nice. I prefer only having the previous hour's backup and one from the last start up, but personal preference I guess. Is there any chance you can throw up a version with just the auto-update fixed? big_smile I'd look through what's wrong but I'm a bit tired atm. Also, I tend to update manually anyway. I'll merge your fixed update with my script then and link yours in the top post.

Also, I reinstalled the server, and once again it works fine with Sun JRE and without . /etc/profile in the script. Just a straight default install of java etc with no changes.

Offline

#16 2011-06-08 16:23:27

rationalOgre
Member
Registered: 2011-05-23
Posts: 4

Re: Minecraft server script (run minecraft server as a daemon in Arch)

#!/bin/bash
# /etc/rc.d/minecraft

. /etc/rc.conf
. /etc/rc.d/functions

#Uncomment line below if using Sun JRE
#. /etc/profile

#Settings
SERVICE='minecraft_server.jar'
USERNAME="minecraft"
MCPATH='/home/minecraft/minecraft'
MCOFFLINEPATH='/home/minecraft/backup'
INVOCATION='java -Xmx768M -Xms768M -jar minecraft_server.jar nogui'
BACKUPPATH='/home/minecraft/onlinebackup'


ME=`whoami`
as_user() {
  if [ "$ME" == "$USERNAME" ] ; then
    bash -c "$1"
  else
    su -c - $USERNAME "$1"
  fi
}

mc_start() {
  stat_busy "Starting Minecraft Server"
  
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "Tried to start but $SERVICE was already running!"
  else
    echo "$SERVICE was not running... starting."
    
    #Move minecraft from backup folder to ram
    mount -t tmpfs tmpfs -o size=50m $MCPATH
    cp -a $MCOFFLINEPATH/* $MCPATH
    echo "Files moved to RAM."
    
    cd $MCPATH
    as_user "cd $MCPATH && screen -dmS minecraft $INVOCATION"
    sleep 7
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
      echo "$SERVICE is now running."
      
      #Create hourly backups while running
      ln -s $MCPATH/onlinebackup /etc/cron.hourly/minecraftonlinebackup
      echo "Hourly backups initiated."
    else
      echo "Could not start $SERVICE."
      umount $MCPATH
    fi
  fi
    
  add_daemon minecraft
  stat_done
}

mc_saveoff() {
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
    echo "$SERVICE is running... suspending saves."
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
    sync
    sleep 10
  else
    echo "$SERVICE was not running. Not suspending saves."
  fi
}

mc_saveon() {
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "$SERVICE is running... re-enabling saves."
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
  else
    echo "$SERVICE was not running. Not resuming saves."
  fi
}

mc_stop() {
  stat_busy "Stopping Minecraft Server"
  
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "$SERVICE is running... stopping."                
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
    sleep 10
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
    sleep 7
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
      echo "$SERVICE could not be shut down... still running."
    else
      echo "$SERVICE is shut down."
      
      #Stop hourly backups
      rm /etc/cron.hourly/minecraftonlinebackup
      echo "Hourly backup halted."
      
      #Unmount tmpfs
      cp -a $MCPATH/* $MCOFFLINEPATH
      umount $MCPATH
      echo "Files copied to HDD."
    fi
  else
    echo "$SERVICE was not running."
  fi
  
  rm_daemon minecraft
  stat_done
}


mc_update() {
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
  then
    echo "$SERVICE is running! Will not start update."
  else
    MC_SERVER_URL=http://minecraft.net/`wget -q -O - http://www.minecraft.net/download.jsp | grep minecraft_server.jar\</a\> | cut -d \" -f 2`
    as_user "cd $MCOFFLINEPATH && wget -q -O $MCOFFLINEPATH/minecraft_server.jar.update $MC_SERVER_URL"
    if [ -f $MCOFFLINEPATH/minecraft_server.jar.update ]
    then
      if `diff $MCOFFLINEPATH/minecraft_server.jar $MCOFFLINEPATH/minecraft_server.jar.update >/dev/null`
      then 
        echo "You are already running the latest version of $SERVICE."
        rm $MCOFFLINEPATH/minecraft_server.jar.update
      else
        as_user "mv $MCOFFLINEPATH/minecraft_server.jar.update $MCOFFLINEPATH/minecraft_server.jar"
        echo "Minecraft successfully updated."
      fi
    else
      echo "Minecraft update could not be downloaded."
    fi
  fi
}

mc_backup() {
   echo "Backing up minecraft world"
   if [ -d $BACKUPPATH/world_`date "+%m.%d.%Y"` ]
   then
     for i in 1 2 3 4 5 6
     do
       if [ -d $BACKUPPATH/world_`date "+%m.%d.%Y"`-$i ]
       then
         continue
       else
         as_user "cd $MCPATH && cp -r world $BACKUPPATH/world_`date "+%m.%d.%Y"`-$i"
         break
       fi
     done
   else
     as_user "cd $MCPATH && cp -r world $BACKUPPATH/world_`date "+%m.%d.%Y"`"
     echo "Backed up world"
   fi
   echo "Backing up the minecraft server executable"
   if [ -f "$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`.jar" ]
   then
     for i in 1 2 3 4 5 6
     do
       if [ -f "$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`-$i.jar" ]
       then
         continue
       else
         as_user "cd $MCPATH && cp minecraft_server.jar \"$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`-$i.jar\""
         break
       fi
     done
   else
     as_user "cd $MCPATH && cp minecraft_server.jar \"$BACKUPPATH/minecraft_server_`date "+%m.%d.%Y"`.jar\""
   fi
   echo "Backup complete"
}


#Start-Stop here
case "$1" in
  start)
    mc_start
    ;;
  stop)
    mc_stop
    ;;
  restart)
    mc_stop
    mc_start
    ;;
  update)
    mc_saveoff
    mc_backup
    mc_saveon
    mc_stop
    mc_update
    mc_start
    ;;
  backup)
    mc_saveoff
    mc_backup
    mc_saveon
    ;;
  status)
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
    then
      echo "$SERVICE is running."
    else
      echo "$SERVICE is not running."
    fi
    ;;

  *)
  echo "Usage: /etc/rc.d/minecraft {start|stop|update|backup|status|restart}"
  exit 1
  ;;
esac


exit 0

There's the file without the changes to mc_backup. As for why you aren't having to source etc profile, I have no clue. I just know that I do. That is what resolved one of the errors I was getting.

I prefer having multiple days worth of backups because if my server reboots due to power failure or whatever and it comes back up, it could potentially overwrite my online backup if it goes on for an hour without me noticing it rebooted. (ex. I'm away from home for the day and the power goes out.) Then I'd end up with a corrupted backup and or a backup of the server from several days ago.

Last edited by rationalOgre (2011-06-08 16:27:22)

Offline

#17 2011-07-13 06:26:41

PIMPinator
Member
From: Queensland, Australia
Registered: 2010-03-14
Posts: 85

Re: Minecraft server script (run minecraft server as a daemon in Arch)

rationalOgre wrote:

I prefer having multiple days worth of backups because if my server reboots due to power failure or whatever and it comes back up, it could potentially overwrite my online backup if it goes on for an hour without me noticing it rebooted. (ex. I'm away from home for the day and the power goes out.) Then I'd end up with a corrupted backup and or a backup of the server from several days ago.

I'm not autostarting is why it doesn't matter to me, I just start it when I boot.

Offline

#18 2011-12-17 08:41:50

CaseMonster
Member
Registered: 2011-06-17
Posts: 10

Re: Minecraft server script (run minecraft server as a daemon in Arch)

#!/bin/bash
# /etc/rc.d/minecraft

. /etc/rc.conf
. /etc/rc.d/functions
. /etc/profile

ME=`whoami`
as_user() {
  if [ "$ME" == "root" ] ; then
    bash -c "$1"
  else
    su -c - root "$1"
  fi
}

mc_start() {
  stat_busy "Starting Minecraft Server"
  
  if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
  then
    echo "Tried to start but Minecraft was already running!"
    stat_fail
  else
    echo "Minecraft was not running... starting."
    
    #Move minecraft from backup folder to ram
    mount -t tmpfs tmpfs -o size=250m /mnt/minecraft
    cp -a /srv/minecraft/current/* /mnt/minecraft
    echo "Files moved to RAM."
    
    cd /mnt/minecraft
    as_user "cd /mnt/minecraft && screen -dmS minecraft java -Xmx2048M -Xms2048M -jar minecraft_server.jar nogui"
    sleep 3
    if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
    then
      echo "Minecraft is now running."
      
      #Create daily maps"
      cp /srv/minecraft/minecraft-map.sh /etc/cron.daily/
      echo "Daily map generation initiated."
      
      #Create hourly backups while running
      cp /srv/minecraft/minecraft-backup.sh /etc/cron.hourly/
      echo "Hourly backups initiated."
      
      #Create daily backup compression
      cp /srv/minecraft/minecraft-compress.sh /etc/cron.daily/
      echo "Daily backup compression initiated."
      
      add_daemon minecraft
      stat_done "Minecraft Server Stated"
      
    else
      echo "Could not start Minecraft."
      echo "Unmounting /mnt/minecraft."
      umount /mnt/minecraft
      stat_fail
    fi
  fi
}

mc_stop() {
  stat_busy "Stopping Minecraft Server"
  
  if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
  then
    echo "Minecraft is running... stopping."                
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
    sleep 10
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
    sleep 7
    if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
    then
      echo "Minecraft could not be shut down... still running."
      stat_fail
    else
      echo "Minecraft is shut down."
      
      #Stop map gens
      rm /etc/cron.daily/minecraft-map.sh
      echo "Daily map gen halted."
      
      #Stop hourly backups
      rm /etc/cron.hourly/minecraft-backup.sh
      echo "Hourly backup halted."
      
      #Stop map compression
      rm /etc/cron.daily/minecraft-compress.sh
      echo "Daily backup compression halted."
      
      #Unmount tmpfs
      cp -a /mnt/minecraft/* /srv/minecraft/current
      umount /mnt/minecraft
      echo "Files copied to HDD."
      
      rm_daemon minecraft
      stat_done "Minecraft Server stopped"
      
    fi
  else
    echo "Minecraft was not running."
    stat_fail
  fi
}

mc_update() {
  stat_busy "Updating up minecraft_server.jar"
  if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
  then
    echo "Minecraft is running! Can't start update."
    stat_fail
  else
    #MC_SERVER_URL=http://minecraft.net/`wget -q -O - http://www.minecraft.net/download.jsp | grep minecraft_server.jar\</a\> | cut -d \" -f 2`
    
    as_user "cd /srv/minecraft/current && wget -O /srv/minecraft/current/minecraft_server.jar.update "https://s3.amazonaws.com/MinecraftDownload/launcher/minecraft_server.jar""
    if [ -f /srv/minecraft/current/minecraft_server.jar.update ]
    then
      if `diff /srv/minecraft/current/minecraft_server.jar /srv/minecraft/current/minecraft_server.jar.update >/dev/null`
      then 
        echo "Minecraft is already up to date."
        rm /srv/minecraft/current/minecraft_server.jar.update
        stat_done
      else
        as_user "mv /srv/minecraft/current/minecraft_server.jar.update /srv/minecraft/current/minecraft_server.jar"
        echo "Minecraft has been updated."
        rm /srv/minecraft/current/minecraft_server.jar.update
        stat_done
      fi
    else
      echo "Minecraft update could not be downloaded."
      stat_fail
    fi
  fi
}

mc_backup() {
   stat_busy "Backing up minecraft world"
   
  if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
    then
    echo "Setting server to readonly."
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
    sync
    sleep 10
    echo "Server ready to backup."
  fi
   
   if [ -d /srv/minecraft/backup/world_`date "+%m.%d.%Y_%H"` ]
   then
     for i in 1 2 3 4 5 6
     do
       if [ -d /srv/minecraft/backup/world_`date "+%m.%d.%Y_%H"`-$i ]
       then
         continue
       else
         as_user "cd /mnt/minecraft && cp -r world /srv/minecraft/backup/world_`date "+%m.%d.%Y_%H"`-$i"
         break
       fi
     done
   else
     as_user "cd /mnt/minecraft && cp -r world /srv/minecraft/backup/world_`date "+%m.%d.%Y_%H"`"
     echo "Backed up world."
   fi
   
  if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
  then
    echo "Setting server to read-write."
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"
    as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
  fi
  
   echo "Backup complete."
   stat_done
}

mc_map() {
  stat_busy "Mapping Minecraft Server"
  echo "Running c10t..."
  as_user "c10t -w /mnt/minecraft/world -o /srv/minecraft/map/map_`date "+%m.%d.%Y_%H"`.png" > /dev/null
  echo "Map generated."
  stat_done
}

mc_status() {
    if ps ax | grep -v grep | grep -v -i SCREEN | grep minecraft_server.jar > /dev/null
    then
      echo "Minecraft is running."
    else
      echo "Minecraft is not running."
    fi
}

mc_compress(){
   stat_busy "Compressing save..."
   as_user "7z a -mx9 /srv/minecraft/backup.7z /srv/minecraft/backup/ > /dev/null"
   echo "Backup folder compressed."
   stat_done
}

case "$1" in
  start)
    mc_start
    ;;
  stop)
    mc_stop
    ;;
  restart)
    mc_stop
    mc_start
    ;;
  update)
    mc_update
    ;;
  backup)
    mc_backup
    ;;
  map)
    mc_map
    ;;
  status)
    mc_status
    ;;
  compress)
    mc_compress
    ;;
    
  *)
  echo "Usage: /etc/rc.d/minecraft {start|stop|update|backup|status|map|compress|restart}"
  exit 1
  ;;
esac


exit 0

I edited your script.  I set 7zip to compress saves into an archive because i like to hold on to the saves for a bit, just in case.  The daily and hourly cron scripts just call the daemon script.
This one uses
/srv/minecraft/ , main directory (source for cron scripts, backup archive, log file for c10t)
/srv/minecraft/current/ , main source dir for minecraft
/srv/minecraft/backup/ , hourly backup dir
/mnt/minecraft/ , mount location for the running copy of minecraft (from /srv/minecraft/current/)

Offline

#19 2012-03-03 02:21:48

IgnisFatuus85
Member
Registered: 2008-01-20
Posts: 9

Re: Minecraft server script (run minecraft server as a daemon in Arch)

Hey all.  I'm looking at implementing this startup script on my server and I had a couple of questions:

EDIT: I figured out the "sceen ... -X eval 'stuff ...'" part after (more than) a bit of research, so you can skip this part:
First off (this is more of a basic bash question), in trying to understand the script, everything makes sense with the exception of the mc_saveoff() and mc_saveon() functions.
I'm not very familiar with screen + eval, but from what I can gather, this is sending commands to the tty that's running minecraft? ...This makes sense... but the 'stuff \" part before the command is what's confusing me.
Would someone mind giving me the quick version?

Second, I was curious as to why the hourly backup seems to save only the map and the server jar file.  I could see maybe only saving the map since the map is the only thing that will be modified during runtime, but in that case, why save the server jar?  Also, my world name isn't world, so with the setup I would have to modify the script, where I wouldn't if it just backed up the entire directory recursively like in the stop function.

I can of course make these changes myself, I was just curious if there was a particular reason you choose to do it this way.


And finally, an idea:

Since the server needs to be stopped in order for an update to be applied anyways, why not modify the update function to simply download the update into the offline backup dir, then modify the start function to look for the updated jar and swap it out at next startup if present?  This way you could call update while the server was running, and the next time the server was restarted, the update would be applied seamlessly?

Let me know what you think.


Thanks a lot for this script, it's pretty awesome.  Looking forward to getting it running on my box smile

Last edited by IgnisFatuus85 (2012-03-04 02:42:59)

Offline

Board footer

Powered by FluxBB