Script for managing puma in server
Fri 05 Oct 2018

Firstly, we create puma.sh file and define crucial paths which are used in functions we will develop later.

#!/bin/bash
PUMA_WORKING_DIRECTORY=/var/www/willapp/current
PUMA_CONFIG_FILE=/var/www/willapp/shared/puma.rb
PUMA_PID_FILE=/var/www/willapp/shared/tmp/pids/puma.pid
PUMA_SOCKET_FILE=/var/www/willapp/shared/tmp/sockets/willapp-puma.sock
PUMA_USER=willnguyen
CMD="cd $PUMA_WORKING_DIRECTORY && bundle exec puma -C $PUMA_CONFIG_FILE --daemon" 

Don't forget to add #!/bin/bash at the top of file. We call it shebang. It is interpreted by the kernel when handling the executable system call - kernel convention.

Checking if puma is running.

puma_is_running() {
  if [ -S $PUMA_SOCKET_FILE ] ; then
    if [ -e $PUMA_PID_FILE ] ; then
      if cat $PUMA_PID_FILE | xargs kill -0 > /dev/null ; then
        return 0
      else
	echo "No puma process found"
      fi
    else
      echo "No puma pid file found"
    fi
  else
    echo "No puma socket found"
  fi

  return 1
}

Run an argument as command in shell using eval function.

run () {
  if [ "$(id -un)" = "$PUMA_USER" ]; then
    eval $1
  else
    su -c "$1" - $PUMA_USER
  fi
}

Checking arguments and performing the proper behaviours.

case "$1" in
  start)
  if puma_is_running; then
    echo "Already running"
  else
  run "$CMD"
  fi
  ;;
  stop)
    if puma_is_running; then
      run "kill -9 `cat $PUMA_PID_FILE`"
      rm -f $PUMA_PID_FILE
      rm -f $PUMA_SOCKET_FILE
      echo "Puma stopped"
    else
      echo "Puma is not running"
    fi
  ;;
  restart)
    if puma_is_running; then
      run "kill -9 `cat $PUMA_PID_FILE`"
      echo "Puma restarted"
    else
      echo "Puma is not running"
    fi
    run "$CMD"
  ;;
  status)
    if puma_is_running; then
      echo "Puma is running"
      exit 0
    else
      echo "Puma is not running"
      exit 1
    fi
  ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}"
    exit 1
  ;;
esac

In fact, we used two actions in above code.

  • Stop puma by killing port.
  • Start puma by bundle command.

We always can do it manually. But developing a file like this will save our time in case you put multiple web applications in the same server.

Below is full code of this file.

#!/bin/bash
PUMA_WORKING_DIRECTORY=/var/www/willapp/current
PUMA_CONFIG_FILE=/var/www/willapp/shared/puma.rb
PUMA_PID_FILE=/var/www/willapp/shared/tmp/pids/puma.pid
PUMA_SOCKET_FILE=/var/www/youapp/shared/tmp/sockets/willapp-puma.sock
PUMA_USER=willnguyen
CMD="cd $PUMA_WORKING_DIRECTORY && bundle exec puma -C $PUMA_CONFIG_FILE --daemon" 

puma_is_running() {
  if [ -S $PUMA_SOCKET_FILE ] ; then
    if [ -e $PUMA_PID_FILE ] ; then
      if cat $PUMA_PID_FILE | xargs kill -0 > /dev/null ; then
        return 0
      else
	echo "No puma process found"
      fi
    else
      echo "No puma pid file found"
    fi
  else
    echo "No puma socket found"
  fi

  return 1
}

run () {
  if [ "$(id -un)" = "$PUMA_USER" ]; then
    eval $1
  else
    su -c "$1" - $PUMA_USER
  fi
}

case "$1" in
  start)
  if puma_is_running; then
    echo "Already running"
  else
  run "$CMD"
  fi
  ;;
  stop)
    if puma_is_running; then
      run "kill -9 `cat $PUMA_PID_FILE`"
      rm -f $PUMA_PID_FILE
      rm -f $PUMA_SOCKET_FILE
      echo "Puma stopped"
    else
      echo "Puma is not running"
    fi
  ;;
  restart)
    if puma_is_running; then
      run "kill -9 `cat $PUMA_PID_FILE`"
      echo "Puma restarted"
    else
      echo "Puma is not running"
    fi
    run "$CMD"
  ;;
  status)
    if puma_is_running; then
      echo "Puma is running"
      exit 0
    else
      echo "Puma is not running"
      exit 1
    fi
  ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}"
    exit 1
  ;;
esac

We can put it to PATH to involve anywhere and make it executable as well.

chmod +x puma.sh

Happy devopts :)