Pre-requisites
- Root access to your server or have access to an account that has sudo powers on your servers – Instructions here to see how to give a linux user sudo powers.
nodejs
andnpm
installed – Instructions here.ghost
installed and a ghost user made to run ghost – Instructions here
What is forever
From the github forever page we learn that forever is,
A simple CLI tool for ensuring that a given script runs continuously (i.e. forever).
CLI means Command Line Interface tool.
Installing forever
Precursor
As detailed in the instructions for installing ghost we want to run ghost with its own ghost user. Furthermore, the ghost user should have a home directory, i.e. /home/ghost/
should exist. If it doesn’t exist please see this post to see the problem that it would cause and how to fix it. Let’s first switch to the ghost user and go to the ghost install directory.
[ahmed@amayem ~]$ sudo su ghost
[ghost@amayem ahmed]$ cd /var/www/ghost/
First try
Installing is easy.
[ghost@amayem ghost]$ npm install -g forever
npm http GET https://registry.npmjs.org/forever
npm http 200 https://registry.npmjs.org/forever
npm http GET https://registry.npmjs.org/forever/-/forever-0.11.0.tgz
npm http 200 https://registry.npmjs.org/forever/-/forever-0.11.0.tgz
npm ERR! Error: EACCES, mkdir '/usr/lib/node_modules/forever'
npm ERR! { [Error: EACCES, mkdir '/usr/lib/node_modules/forever']
npm ERR! errno: 3,
npm ERR! code: 'EACCES',
npm ERR! path: '/usr/lib/node_modules/forever',
npm ERR! fstream_type: 'Directory',
npm ERR! fstream_path: '/usr/lib/node_modules/forever',
npm ERR! fstream_class: 'DirWriter',
npm ERR! fstream_stack:
npm ERR! [ '/usr/lib/node_modules/fstream/lib/dir-writer.js:36:23',
npm ERR! '/usr/lib/node_modules/mkdirp/index.js:37:53',
npm ERR! 'Object.oncomplete (fs.js:107:15)' ] }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
Argh! I need to sudo
. That’s probably because we included the -g
flag, which indicates that we want the package to be installed globally for everyone to use. As can be seen in the error, the ghost user does not have pemission to write to /usr/lib/node_modules/
. Let’s try installing without the -g
flag. We have two solutions:
- Installing locally
- Switching to an account with
sudo
powers and usingsudo
Installing locally
[ghost@amayem ghost]$ npm install forever
It worked this time. Let’s give forever a try.
[ghost@amayem ghost]$ forever start index.js
bash: forever: command not found
This is the concequence of the local install. We have to actually run the bin that is in the node_modules
directory:
[ghost@amayem ghost]$ ./node_modules/forever/bin/forever start index.js
warn: --minUptime not set. Defaulting to: 1000ms
warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info: Forever processing file: index.js
It worked, but wouldn’t it be much better if we could use forever without having to find it deep in the directory structure. We will need to switch to the sudo
user in that case. Let’s stop the forever process before installing globally.
[ghost@amayem ghost]$ ./node_modules/forever/bin/forever stopall
info: Forever stopped processes:
data: uid command script forever pid logfile uptime
data: [0] RZRV /usr/bin/node index.js 11940 11942 /home/ghost/.forever/RZRV.log 0:0:5:35.759
Switching to an account with sudo powers
Ideally we don’t want the ghost account to have sudo powers. Let’s exit the ghost user shell and install globally.
[ghost@amayem ghost]$ exit
exit
[ahmed@amayem ~]$ sudo npm install -g forever
Notice that I was in the home directory of ahmed
user, as indicated by ~
. It doesn’t matter where I am when I install globally, because it always installs all the packages in the same global directory.
Let’s switch back to the ghost user and run forever again.
[ahmed@amayem ~]$ sudo su ghost
[ghost@amayem ahmed]$ cd /var/www/ghost/
[ghost@amayem ghost]$ NODE_ENV=production forever start index.js
warn: --minUptime not set. Defaulting to: 1000ms
warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info: Forever processing file: index.js
That looks much better! We added the NODE_ENV=production
to tell ghost that we are in production. If you leave it out it will be in devleopment mode. We discuss configuration in the installation guide.
Surviving a reboot: Crontab setup
Forever will now run ghost in the background, but it won’t start it when the server is rebooted. We can remedy that by setting up the crontab
to run cron
, whic is a job-scheduler. Basically it allows users to run programs periodically. We would like to run forever
periodically on startup. As the ghost user type the following
[ghost@amayem ahmed]$ crontab -e
This will allow you to edit the crontab, probably using vi
editor. Enter into insert mode by typing i
and add this line.
@reboot NODE_ENV=production /usr/lib/node_modules/forever/bin/forever start /var/www/ghost/index.js
Notice that we put the full path to forever
even though we had installed it globally. This is because cron
may not be using the bash shell. It’s better to be safe than sorry. Exit insert mode with Esc
or ctrl+c
then save and exit with :x
. You should see the following as the output:
no crontab for ghost - using an empty one
crontab: installing new crontab
Testing cron
Simply reboot your server:
[ghost@amayem ahmed]$ exit
exit
[ahmed@amayem ~]$ sudo reboot
Now simply visit your blog again to see if it’s up. Another way to check is to ssh back in to check the forever process as follows:
[ahmed@amayem ~]$ sudo su ghost
[ghost@amayem ahmed]$ forever list
info: Forever processes running
data: uid command script forever pid logfile uptime
data: [0] 4MOq /usr/bin/node /var/www/ghost/index.js 537 539 /home/ghost/.forever/4MOq.log 0:0:1:17.237
Looks good! It’s only been up for 1 minute and a bit so I know it just came on.