How to deploy Etherpad as a service

JohnMcLear edited this page Nov 19, 2014 · 1 revision

General

Resources

For Developers

How to's

Set up

Advanced steps

Integrating Etherpad in your web app

for Developers

Clone this wiki locally

Ubuntu 10.04, Debian 6 (sysvinit)

  1. Create a user called etherpad-lite
  2. Create a log folder for the service /var/log/etherpad-lite
  3. Ensure the etherpad-lite user have full access to the log and the git folder
  4. Copy following script to /etc/init.d/ and configure the variables. You might want also configure the runSafe script in your git folder to ensure you get email notifications if there are problems with the applications
  5. Make sure the script is marked as executable: chmod +x /etc/init.d/etherpad-lite
  6. If etherpad-lite is not installed in /usr/share/etherpad-lite create a link with ln -s /your-path-to/etherpad-lite /usr/share/etherpad-lite
  7. Enable it with update-rc.d etherpad-lite defaults
  8. start with service etherpad-lite start
#!/bin/sh

### BEGIN INIT INFO
# Provides:          etherpad-lite
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts etherpad lite
# Description:       starts etherpad lite using start-stop-daemon
### END INIT INFO

PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/node/bin"
LOGFILE="/var/log/etherpad-lite/etherpad-lite.log"
EPLITE_DIR="/usr/share/etherpad-lite"
EPLITE_BIN="bin/safeRun.sh"
USER="etherpad-lite"
GROUP="etherpad-lite"
DESC="Etherpad Lite"
NAME="etherpad-lite"

set -e

. /lib/lsb/init-functions

start() {
  echo "Starting $DESC... "

    start-stop-daemon --start --chuid "$USER:$GROUP" --background --make-pidfile --pidfile /var/run/$NAME.pid --exec $EPLITE_DIR/$EPLITE_BIN -- $LOGFILE || true
  echo "done"
}

#We need this function to ensure the whole process tree will be killed
killtree() {
    local _pid=$1
    local _sig=${2-TERM}
    for _child in $(ps -o pid --no-headers --ppid ${_pid}); do
        killtree ${_child} ${_sig}
    done
    kill -${_sig} ${_pid}
}

stop() {
  echo "Stopping $DESC... "
  if test -f /var/run/$NAME.pid; then
    while test -d /proc/$(cat /var/run/$NAME.pid); do
      killtree $(cat /var/run/$NAME.pid) 15
      sleep 0.5
    done
    rm /var/run/$NAME.pid
  fi
  echo "done"
}

status() {
  status_of_proc -p /var/run/$NAME.pid "" "etherpad-lite" && exit 0 || exit $?
}

case "$1" in
  start)
      start
      ;;
  stop)
    stop
      ;;
  restart)
      stop
      start
      ;;
  status)
      status
      ;;
  *)
      echo "Usage: $NAME {start|stop|restart|status}" >&2
      exit 1
      ;;
esac

exit 0

Ubuntu 10.04 (upstart)

  1. Create a user called etherpad-lite
  2. Create a log folder for the service /var/log/etherpad-lite
  3. Ensure the etherpad-lite user have full access to the log and the git folder
  4. Save the following script to /etc/init/etherpad-lite.conf
  5. Set EPHOME and EPUSER to the proper values
  6. Run sudo start etherpad-lite
description "etherpad-lite"

start on started networking
stop on runlevel [!2345]

env EPHOME=/usr/local/etherpad-lite
env EPLOGS=/var/log/etherpad-lite
env EPUSER=etherpad-lite

respawn

pre-start script
    cd $EPHOME
    mkdir $EPLOGS                              ||true
    chown $EPUSER:admin $EPLOGS                ||true
    chmod 0755 $EPLOGS                         ||true
    chown -R $EPUSER:admin $EPHOME/var         ||true
    $EPHOME/bin/installDeps.sh >> $EPLOGS/error.log || { stop; exit 1; }
end script

script
  cd $EPHOME/
  exec su -s /bin/sh -c 'exec "$0" "$@"' $EPUSER -- node node_modules/ep_etherpad-lite/node/server.js \
                        >> $EPLOGS/access.log \
                        2>> $EPLOGS/error.log
end script

Mac OS-X (launchd)

  1. Create a user and a group called etherpad
  2. Create a log folder for the service /var/log/etherpad-lite
  3. Ensure the etherpad user has full access to the log and the git folder
  4. Copy following property list file as org.etherpad.etherpad-lite.plist to /Library/LaunchDaemons/. You might want to edit the paths and also configure the runSafe script in your git folder to ensure you get email notifications if there are problems with the applications
  5. Load into launchd: sudo launchctl load /Library/LaunchDaemons/org.etherpad.etherpad-lite.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>org.etherpad.etherpad-lite</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/etherpad-lite/bin/safeRun.sh</string>
        <string>/var/log/etherpad-lite/etherpad.log</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/var/log/etherpad-lite/etherpad.log</string>
    <key>StandardErrorPath</key>
    <string>/var/log/etherpad-lite/etherpad-error.log</string>
    <key>UserName</key>
    <string>etherpad</string>
    <key>GroupName</key>
    <string>etherpad</string>
</dict>
</plist>

Windows (nssm)

  1. Download and extract nssm, the non-sucking service manager. This application allows you to host an executable as a Windows service. Put the nssm binary into a folder that is set in your PATH IE \windows\system32
  2. Install the service: nssm.exe install etherpad C:\etherpad-location\start.bat. Nssm creates the service under the Local System account, so you might want to consider changing this afterwards. You will need to be running command prompt as the administrator to do this.
  3. Launch it: Run net start etherpad.

CentOS 6 (SysV Init)

  1. Create a user called etherpad-lite
  2. Install etherpad-lite under /srv/etherpad-lite (or where ever you want)
  3. Ensure the etherpad-lite user have full access to the git folder
  4. Copy following script to /etc/init.d/ and configure the variables.
  5. Make sure the script is marked as executable: chmod +x /etc/init.d/etherpad-lite
  6. Enable it with chkconfig etherpad-lite on
  7. After a update the script "bin/run.sh" must be run once manual as root.
#!/bin/bash
# chkconfig: 2345 90 90
# description: program_name
### BEGIN INIT INFO# Provides: program_name
# Required-Start: network
# Required-Stop: network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6# Description: Start the program
### END INIT INFO

START_CMD="/home/etherpad-lite-dev/bin/run.sh > /var/log/etherpad.log 2>&1 &"
NAME="etherpad"
PGREP_STRING="/home/etherpad-lite-dev/bin/run.sh"
PGREP_NODE_STRING="node /home/etherpad-lite-dev/node_modules/ep_etherpad-lite/node/server.js"
PID_FILE="/var/run/etherpad/etherpad-dev.pid"
USER="etherpad-lite"

### No further muckin' about needed!

CUR_USER=`whoami`

killproc() {
  pkill -u $USER -f $PGREP_STRING
  pkill -u $USER -f $PGREP_NODE_STRING
}

killproc_node(){
  pkill -u $USER -f "$PGREP_NODE_STRING"
}

start_daemon() {
  eval "$*"
}

log_success_msg() {
  echo "$*"
  logger "$_"
}

log_failure_msg() {
  echo "$*"
  logger "$_"
}

check_proc() {
  pgrep -u $USER -f $PGREP_STRING >/dev/null
}

check_proc_node(){
  pgrep -u $USER -f $PGREP_NODE_STRING >/dev/null
}

start_script() {
  if [ "${CUR_USER}" != "root" ] ; then
    log_failure_msg "$NAME can only be started as 'root'."
    exit -1
  fi

  check_proc
  if [ $? -eq 0 ]; then
    log_success_msg "$NAME is already running."
    exit 0
  fi

  [ -d /var/run/$NAME ] || (mkdir /var/run/$NAME )

   # make go now
    start_daemon /bin/su - $USER -c $START_CMD

  # Sleep for a while to see if anything cries
  sleep 5
  check_proc

  if [ $? -eq 0 ]; then
    log_success_msg "Started $NAME."
  else
    log_failure_msg "Error starting $NAME."
    exit -1
  fi
}

stop_script() {
  if [ "${CUR_USER}" != "root" ] ; then
    log_failure_msg "You do not have permission to stop $NAME."
    exit -1
  fi

  check_proc
  if [ $? -eq 0 ]; then
    killproc -p $PID_FILE >/dev/null

    # Make sure it's dead before we return
    until [ $? -ne 0 ]; do
      sleep 1
      check_proc
    done

    check_proc
    if [ $? -eq 0 ]; then
      log_failure_msg "Error stopping $NAME."
      exit -1
    else
      log_success_msg "Stopped $NAME."
    fi
  else
    log_failure_msg "$NAME is not running or you don't have permission to stop it"
  fi

  check_proc_node
  if [ $? -eq 0 ]; then
    killproc_node -p $PID_FILE >/dev/null

    # Make sure it's dead before we return
    # until [ $? -ne 0 ]; do
    #  sleep 1
    #  check_proc_node
    # done

    #check_proc_node
    #if [ $? -eq 0 ]; then
    #  log_failure_msg "Error stopping $NAME."
    #  exit -1
    #else
    #  log_success_msg "Stopped $NAME."
    #fi
  else
    log_failure_msg "$NAME is not running or you don't have permission to stop it"
  fi

}

check_status() {
  check_proc
  if [ $? -eq 0 ]; then
    log_success_msg "$NAME is running."
  else
    log_failure_msg "$NAME is stopped."
    exit -1
  fi
}

case "$1" in
  start)
    start_script
    ;;
  stop)
    stop_script
    ;;
  restart)
    stop_script
    start_script
    ;;
  status)
    check_status
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}"
    exit 1
esac

exit 0

Arch Linux

Ok, this script can be made better, but it's a cleaner way than the old way that was mentioned in the wiki. Feel free to provide better suggestions / improve this script.

  1. Create a user for etherpad and set up a "homefolder" from git.
  2. Paste the script below in to /etc/rc.d/etherpad-lite
  3. Edit the variables HOME and USER in the script to match your configuration.
  4. chmod +x /etc/rc.d/ethterpad-lite
  5. That's it! You should have a basic functioning script to start and stop Etherpad-Lite with. The commands are rc.d start etherpad-lite, rc.d stop etherpad-lite, and rc.d restart etherpad-lite.
  6. If you want Etherpad-Lite to start automatically at boot, place the string etherpad-lite in the DAEMONS section in /etc/rc.conf, like this: DAEMONS=(syslog-ng network netfs ntpd sshd crond httpd mysqld nginx etherpad-lite)
#!/bin/sh

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

USER="etherpad-lite"
HOMEDIR="/opt/etherpad-lite"
PID=/run/etherpad-lite.pid
LOG=/var/log/etherpad-lite.log

case "$1" in
        'start')
                # Start Etherpad.
                cd $HOMEDIR
                exec nohup sudo -u $USER bin/run.sh > $LOG 2>$1 < /dev/null &

                # Wait five seconds for the node.js server to start up.
                sleep 5

                # Store the PID in a file.
                ps ax | grep [s]erver.js | awk '{print $1}' > $PID
                ;;
        'stop')
                # Terminate Etherpad-Lite.
                kill `cat $PID`
                rm -f $PID

                ;;
        'status')
                ps ax | grep [n]ode
                ;;
        *)
                echo "USAGE: $0 {start|stop|status}"
                exit 0
        esac                                                                                                                                                                                                                                                                                      

Gentoo

  1. Create a user 'etherpad-lite'
  2. Copy this initscript into directory /etc/init.d
#!/sbin/runscript
# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $

depend() {
        need net mysql
        after apache2
}

start() {
        ebegin "Starting ${RC_SVCNAME}"
                start-stop-daemon -S -m --pidfile ${PIDFILE} -x ${NODE} -u ${USER} -d "${ETHERPATH}" -b -- ${ARGS}
        eend $?
}

stop() {
        ebegin "Stopping ${RC_SVCNAME}"
                start-stop-daemon -K -x ${NODE} -u ${USER} -d "${ETHERPATH}" 
        eend $?
}
  1. chmod 0755 /etc/init.d/etherpad-lite

  2. Copy this File into Directory /etc/conf.d/ (Change as necessary)

ETHERPATH="/local/etherpad-lite/"
ARGS="node_modules/ep_etherpad-lite/node/server.js"
ETHERLOG="${ETHERPATH}/log/error.log"
USER="etherpad-lite"
PIDFILE="/var/run/etherpad-lite.pid"
NODE="/usr/bin/node"
  1. rc-update add etherpad-lite default
  2. rc-service etherpad-lite start

Slackware Linux/Porteus Linux/Byzantium Linux/You like to do things manually.

  1. Create a user 'etherpad-lite'
  2. Copy this initscript into the directory /etc/rc.d: https://github.com/Byzantium/Byzantium/blob/master/porteus/etherpad-lite/rc.etherpad-lite
  3. Edit the script, change the username the 'pad instance will run as. Also change the value of the $HOMEDIR variable to be wherever Etherpad-Lite was installed to.
  4. chmod 0755 /etc/rc.d/rc.etherpad-lite
  5. Add the command /etc/rc.d/rc.etherpad-lite start to the /etc/rc.d/rc.local script if you prefer.

openSUSE and/or SLES (sysvinit)

  1. Create a user and a group called etherpad-lite (using the yast2 users module as example) with /srv/etherpad-lite as home directory
  2. Install etherpad-lite under /srv/etherpad-lite (or where ever you want - if etherpad-lite is not installed in /srv/etherpad-lite either create a link with ln -s /your-path-to/etherpad-lite /srv/etherpad-lite or adapt the path in the init script)
  3. Ensure the etherpad-lite user has full access to the git folder (/srv/etherpad-lite) and logfile (/var/log/etherpad-lite)
  4. Copy the following script to /etc/init.d/ and configure the variables. You might want also configure the runSafe script in your git folder to ensure you get email notifications if there are problems with the applications
  5. Make sure the script is marked as executable: chmod +x /etc/init.d/etherpad-lite
  6. Create a rc-Symlink if you like: ln -s /etc/init.d/etherpad-lite /usr/sbin/rcetherpad-lite
  7. Enable it with chkconfig etherpad-lite on
  8. start with /etc/init.d/etherpad-lite start or rcetherpad-lite start
#!/bin/bash
#
#     Template LSB system startup script for example service etherpad-lite
#     Copyright (C) 1995--2005  Kurt Garloff, SUSE / Novell Inc.
#          
#     This library is free software; you can redistribute it and/or modify it
#     under the terms of the GNU Lesser General Public License as published by
#     the Free Software Foundation; either version 2.1 of the License, or (at
#     your option) any later version.
#                             
#     This library is distributed in the hope that it will be useful, but
#     WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#     Lesser General Public License for more details.
#      
#     You should have received a copy of the GNU Lesser General Public
#     License along with this library; if not, write to the Free Software
#     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
#     USA.
#
# /etc/init.d/etherpad
# LSB compatible service control script; see http://www.linuxbase.org/spec/
# Please send feedback to http://www.suse.de/feedback/
# 
# Note: This template uses functions rc_XXX defined in /etc/rc.status on
# UnitedLinux/SUSE/Novell based Linux distributions. However, it will work
# on other distributions as well, by using the LSB (Linux Standard Base) 
# or RH functions or by open coding the needed functions.
# Read http://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/ if you prefer not 
# to use this template.
#
# chkconfig: 345 99 00
# description: Start etherpad lite
# 
### BEGIN INIT INFO
# Provides:          etherpad
# Required-Start:    $syslog $remote_fs $time
# Should-Start:      $time smtp
# Required-Stop:     $syslog $remote_fs
# Should-Stop:       smtp
# Default-Start:     3 4 5
# Default-Stop:      0 1 2 6
# Short-Description: Starts etherpad lite
# Description:       Start etherpad lite using startproc
### END INIT INFO

PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/node/bin"
LOGFILE="/var/log/etherpad-lite/etherpad-lite.log"
EPLITE_DIR="/srv/etherpad-lite"
EPLITE_BIN="bin/safeRun.sh"
USER="etherpad-lite"
GROUP="etherpad-lite"
DESC="Etherpad Lite"
NAME="etherpad-lite"

test -x "$EPLITE_DIR/$EPLITE_BIN" || { echo "$EPLITE_DIR/$EPLITE_BIN not installed";
        if [ "$1" = "stop" ]; then exit 0;
        else exit 5; fi; } 

test -d $(dirname "$LOGFILE") || mkdir -p $(dirname "$LOGFILE")
chown -R $USER:$GROUP $(dirname "$LOGFILE")

# Shell functions sourced from /etc/rc.status
. /etc/rc.status

# Reset status of this service
rc_reset

case "$1" in
    start)
        echo -n "Starting $DESC "
        ## Start daemon with startproc(8). If this fails
        ## the return value is set appropriately by startproc.
        /sbin/startproc -p "/var/run/$NAME.pid" -u $USER -g $GROUP -l "$LOGFILE"  "$EPLITE_DIR/$EPLITE_BIN" "$LOGFILE"
        # Remember status and be verbose
        rc_status -v
        ;;
    stop)
        echo -n "Shutting down $DESC "
        ## Stop daemon with killproc(8) and if this fails
        ## killproc sets the return value according to LSB.
        /sbin/killproc -TERM -p "/var/run/$NAME.pid" "$EPLITE_DIR/$EPLITE_BIN"
        # Remember status and be verbose
        rc_status -v
        ;;
    try-restart|condrestart)
        ## Do a restart only if the service was active before.
        ## Note: try-restart is now part of LSB (as of 1.9).
        ## RH has a similar command named condrestart.
        if test "$1" = "condrestart"; then
                echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
        fi
        $0 status
        if test $? = 0; then
                $0 restart
        else
                rc_reset        # Not running is not a failure.
        fi
        # Remember status and be quiet
        rc_status
        ;;
    restart)
        ## Stop the service and regardless of whether it was
        ## running or not, start it again.
        $0 stop
        $0 start
        # Remember status and be quiet
        rc_status
        ;;
    force-reload)
        ## Signal the daemon to reload its config.
        $0 try-restart
        rc_status
        ;;
    reload)
        ## Like force-reload, but if daemon does not support
        ## signaling, do nothing (!)
        rc_failed 3
        rc_status -v
        ;;
    status)
        echo -n "Checking for service $DESC "
        ## Check status with checkproc(8), if process is running
        ## checkproc will return with exit status 0.
        # NOTE: checkproc returns LSB compliant status values.
        /sbin/checkproc -p "/var/run/$NAME.pid" "$EPLITE_DIR/$EPLITE_BIN"
        # NOTE: rc_status knows that we called this init script with
        # "status" option and adapts its messages accordingly.
        rc_status -v
        ;;
    *)
        echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload}"
        exit 1
        ;;
esac
rc_exit

Fedora 15 or later (systemd)

Create codepad.service in /usr/lib/systemd/system

[Unit]
Description=Run Etherpad-lite, the collaborative editor.
After=syslog.target network.target

[Service]
Type=simple
ExecStart=/home/etherpad-user/etherpad-lite/bin/run.sh 2>$1 < /dev/null &

[Install]
WantedBy=multi-user.target