- Root access to your server or have access to an account that has sudo powers on your servers – Instructions here.
npminstalled – Instructions here.
ghostinstalled and a ghost user made to run ghost – Instructions here.
What is supervisor
From the official
Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems.
It shares some of the same goals of programs like launchd, daemontools, and runit. Unlike some of these programs, it is not meant to be run as a substitute for init as â€œprocess id 1â€. Instead it is meant to be used to control processes related to a project or a customer, and is meant to start like any other program at boot time.
An important note here is it is meant to start like any other program at boot time. That means once supervisor is running our app we don’t have to worry about it surviving a reboot. It turns out that we accomplish that using an init script.
Do not use the package manager to install. The version they currently have is waaay behind:
[root@amayem supervisor]# yum list | grep supervisor supervisor.noarch 2.1-8.el6 @epel nodejs-supervisor.noarch 0.5.2-5.el6 epel
Instead let’s install using
In order to start we need to have python installed. Supervisor’s github page says,
Supervisor is known to work with Python 2.4 or later but will not work under any version of Python 3.
Let’s check if we have python installed to begin with and if it installed, which version it is:
[ahmed@amayem ~]$ python --version Python 2.6.6
Looks like I’m good. However if you find that you don’t have python installed then you can install it using
[ahmed@amayem ~]$ sudo yum install python
Make sure the version is acceptable (between 2.4 and 3). If you don’t see the right version number then enter
n at the prompt and try this:
[ahmed@amayem ~]$ sudo yum install python 2.6.6-29.el6_3.3
Installing setup_tools (which has easy_install)
Next we need to install
setup_tools as follows:
[ahmed@amayem ~]$ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | sudo python
Now we can finally install supervisor.
[ahmed@amayem ~]$ sudo easy_install supervisor Searching for supervisor Reading https://pypi.python.org/simple/supervisor/ Best match: supervisor 3.0
Notice the version number of supervisor. 3.0 is the latest stable version so we are good to go.
It should end with the following:
Let’s start using supervisor.
supervisorctl should have been installed in
[ahmed@amayem ~]$ ls /usr/bin | grep supervisor echo_supervisord_conf supervisorctl supervisord
This allows us to use them from anywhere as follows:
[ahmed@amayem ~]$ sudo supervisord
For the sake of education we will also take a look at a lower level way of making it work by using
Let’s go to where supervisor was installed.
[ahmed@amayem ~]$ /usr/lib/python2.6/site-packages/supervisor-3.0-py2.6.egg [ahmed@amayem supervisor-3.0-py2.6.egg]$ ls EGG-INFO supervisor [ahmed@amayem supervisor-3.0-py2.6.egg]$ cd supervisor/ [ahmed@amayem supervisor]$ ls childutils.py dispatchers.py http.py medusa process.pyc socket_manager.pyc supervisord.pyc xmlrpc.py childutils.pyc dispatchers.pyc http.pyc options.py rpcinterface.py states.py tests xmlrpc.pyc confecho.py events.py __init__.py options.pyc rpcinterface.pyc states.pyc ui confecho.pyc events.pyc __init__.pyc pidproxy.py scripts supervisorctl.py version.txt datatypes.py http_client.py loggers.py pidproxy.pyc skel supervisorctl.pyc web.py datatypes.pyc http_client.pyc loggers.pyc process.py socket_manager.py supervisord.py web.pyc
We found the treasure. What we are most interested in is
supervisord.py. Let’s try to run it. It has a
.py extension, which means it needs python to run.
[ahmed@amayem supervisor]$ python ./supervisord.py
Making the configuration file
Whichever way you choose to start you will get this error:
Error: No config file found at default paths (etc/supervisord.conf, supervisord.conf, supervisord.conf, etc/supervisord.conf, /etc/supervisord.conf); use the -c option to specify a config file at a different path For help, use ./supervisord.py -h
Looks like we need to make the configuration file.
We can get a sample configuration file with the following command:
[ahmed@amayem supervisor]$ echo_supervisord_conf
Let’s redirect the output into a config file that supervisor can use:
[ahmed@amayem supervisor]$ sudo echo_supervisord_conf > /etc/supervisord.conf -bash: /etc/supervisord.conf: Permission denied
We need to switch to root.
[ahmed@amayem supervisor]$ sudo su [root@amayem supervisor]# echo_supervisord_conf > /etc/supervisord.conf
Now we give it a try
[root@amayem supervisor]# supervisord usr/lib/python2.6/site-packages/supervisor-3.0-py2.6.egg/supervisor/options.py:295: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security. 'Supervisord is running as root and it is searching '
It seems to be working but we got an annoying warning message. I guess we should use the
-c argument from now on like the following:
[ahmed@amayem supervisor]$ sudo supervisord -c /etc/supervisord.conf
Let’s check the status of supervisor:
[root@amayem supervisor]# supervisorctl supervisor> status supervisor>
That means that supervisor is not supervising any processes at the moment. Time to add our node.js app’s configuration. The following configuration is from ghost’s deployment docs.
[program:ghost] command = node /path/to/ghost/index.js directory = /path/to/ghost user = ghost autostart = true autorestart = true stdout_logfile = /var/log/supervisor/ghost.log stderr_logfile = /var/log/supervisor/ghost_err.log environment = NODE_ENV="production"
We need to append the above to the
supervisord.conf file. You need the
sudo to be able to modify the file. Go to the bottom by pressing
G, enter into insert mode
i and paste the above. On my system the path to ghost is
/var/www/ghost/. Also notice that we are using the
ghost user. This should have been made when installing ghost. Please check these instructions for more information on how to do that. Exit insert mode with
ctrl+c then save with
enter. One way of getting supervisor to read the new configuration is by restarting it.
We can restart using
supervisorctl as follows
[root@amayem supervisor]# supervisorctl supervisor> help default commands (type help <topic>): ===================================== add clear fg open quit remove restart start stop update avail exit maintail pid reload reread shutdown status tail version
restart looks promising:
supervisor> restart Error: restart requires a process name restart <name> Restart a process restart <gname>:* Restart all processes in a group restart <name> <name> Restart multiple processes or groups restart all Restart all processes Note: restart does not reread config files. For that, see reread and update.
Nope! Let’s check some other commands:
supervisor> help shutdown shutdown Shut the remote supervisord down. supervisor> help reload reload Restart the remote supervisord.
Looks like reload is the one I want.
supervisor> reload Really restart the remote supervisord process y/N? y Restarted supervisord supervisor> status ghost RUNNING pid 6215, uptime 0:00:06
Great! Now that we have ghost running, let’s check that it is working properly. Visit your site at port 2368, in my case it was
Making supervisor survive a reboot.
Testing it survive a reboot
First, let’s check if it is running.
[ahmed@amayem supervisor]$ ps aux | grep supervisor root 1488 0.0 0.1 17516 7840 ? Ss 18:26 0:00 python ./supervisord.py -c /etc/supervisord.conf ahmed 1564 0.0 0.0 5508 728 pts/1 S+ 19:14 0:00 grep supervisor
If you don’t see it running then go to the section above to see how to start it. Now we reboot
[ahmed@amayem supervisor]$ sudo reboot
and check again
[ahmed@amayem ~]$ ps aux | grep supervisor ahmed 553 0.0 0.0 5508 728 pts/0 S+ 19:16 0:00 grep supervisor
Argh! It’s not there. To make it survive a reboot we need an
Making the init script
Some community init scripts for supervisor are available here. I am running on CentOS, which is supposed to be upwards compatible with red hat, so I chose to go with
redhat-init-mingalevme, because it was the most comprehensive. Copy all the contents of the file. Now we need to paste it into a new
[ahmed@amayem ~]$ cd /etc/init.d/ [ahmed@amayem init.d]$ sudo vi supervisord
Enter into insert mode with
i and paste. For more about pasting in vi check here. Exit insert mode with
ctrl+c then save with
We have an init file but we have to tell the OS to use it as a service. Let’s compare its permissions with other init scripts.
[ahmed@amayem init.d]$ ls -l -rwxr-xr-x 1 root root 4683 Jun 22 2012 sshd -rw-r--r-- 1 root root 3631 Apr 16 19:57 supervisord
I’ve truncated the output to only two items. Basically I need to add
x or execute permissions to the owner, group and others as follows:
[ahmed@amayem init.d]$ sudo chmod ugo+x supervisord [ahmed@amayem init.d]$ ls -l -rwxr-xr-x 1 root root 4683 Jun 22 2012 sshd -rwxr-xr-x 1 root root 3631 Apr 16 19:57 supervisord
They are exactly the same. Now I need to add the file to
Adding the init script to chkconfig
[ahmed@amayem init.d]$ sudo chkconfig --add supervisord [ahmed@amayem init.d]$ chkconfig --list sshd 0:off 1:off 2:on 3:on 4:on 5:on 6:off supervisord 0:off 1:off 2:off 3:on 4:on 5:on 6:off
Looks like it’s been added and it is set to be start at run levels 3, 4 and 5. This is acceptable. For more about run levels check here. We can see our default run level at
[ahmed@amayem init.d]$ less /etc/inittab
Mine was set at:
So supervisor should run properly. Let’s confirm.
Testing starting on reboot
[ahmed@amayem init.d]$ sudo reboot
After waiting a few seconds login again and check if it is running:
[ahmed@amayem ~]$ ps aux | grep supervisor root 513 0.0 0.1 17500 7768 ? Ss 00:02 0:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf [ahmed@amayem ~]$ sudo supervisorctl ghost RUNNING pid 515, uptime 0:03:25 supervisor>
Looks like it is. Check on your browser that ghost is running. All done!