Guru on Rails

if you don’t sacrifice for your dream then your dream becomes your sacrifice.
Sydney, Sat 01 Jun 2019
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 :)