Ghost is a new open source blogging platform which is developed solely for blogging purpose. Ghost is developed using Node.js, which makes it fast, scalable and efficient. You can easily publish your blog using Ghost as it uses Markdown syntax in editor unlike the other CMS which uses WYSIWYG editor. It lets you see how your blog will look like on live site while you are writing the blog. It is very easy to migrate from WordPress, Joomla or other content management system. Ghost is only focused on blogging, not for creating complex websites or ecommerce sites. Themes which are designed for Ghost are also focused on blogging only. Currently there are thousands of website running Ghosts as it is a very popular blogging platform due to its simplicity.
In this tutorial you will learn how to install Ghost on a CentOS 7.x server. We will also learn to setup the environment required for installing and managing Ghost, which includes the setup of Node.js, PM2 and nginx.
Requirements
Ghost does not require any special hardware requirements as it is a lightweight web application. You will only need a CentOS 7.x server with root or sudo access on it. In this tutorial we will use root user account to execute the commands, if you are logged in as non root user, run sudo -i
command to switch to root user or you can add sudo
command at the start of all the administrative commands.
Installing Node.js
Before installing any package in our system it is recommended to update the system and packages. Run the following command for same.
yum -y update
Once all the packages are updated, you will need to install Node.js in your system, we can install Node.js using many methods, but in this tutorial we will install Node.js using NodeSource Binary Distributions Repository. Ghost only supports LTS version of Node.js, which are 0.12.*
, >=4.2 =6.9 =4.2 <5.*
. To install Node.js version 4.x LTS, you will need to add NodeSource repository in your system, run the following command for same.
curl --silent --location https://rpm.nodesource.com/setup_4.x | bash -
You will see following output
[root@ip-172-31-2-60 ~]# curl --silent --location https://rpm.nodesource.com/setup_4.x | bash -
## Installing the NodeSource Node.js v4.x LTS Argon repo...
## Inspecting system...
+ rpm -q --whatprovides redhat-release || rpm -q --whatprovides centos-release || rpm -q --whatprovides cloudlinux-release || rpm -q --whatprovides sl-release
+ uname -m
## Confirming "el7-x86_64" is supported...
+ curl -sLf -o /dev/null 'https://rpm.nodesource.com/pub_4.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'
## Downloading release setup RPM...
+ mktemp
+ curl -sL -o '/tmp/tmp.iAJEdWUDH5' 'https://rpm.nodesource.com/pub_4.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'
## Installing release setup RPM...
+ rpm -i --nosignature --force '/tmp/tmp.iAJEdWUDH5'
## Cleaning up...
+ rm -f '/tmp/tmp.iAJEdWUDH5'
## Checking for existing installations...
+ rpm -qa 'node|npm' | grep -v nodesource
XNode.js v4.x LTS Argon == XNode.js v5.x
## Run `yum install -y nodejs` (as root) to install Node.js v4.x LTS Argon and npm.
You may also need development tools to build native addons:
`yum install -y gcc-c++ make`
Now you can install Node.js using the following command.
yum -y install nodejs
The above command will install any supported Node.js 4.x LTS version. You can check the version of Node.js using the following command.
node -v
You will see the version of the Node.js.
[root@ip-172-31-2-60 ~]# node -v
v4.6.2
When installing Node.js, NPM or Node Package Manager is automatically installed. You can verify its installation by running the following command.
npm help
You should see following output.
[root@ip-172-31-2-60 ~]# npm help
Usage: npm
where is one of:
access, add-user, adduser, apihelp, author, bin, bugs, c,
cache, completion, config, ddp, dedupe, deprecate, dist-tag,
dist-tags, docs, edit, explore, faq, find, find-dupes, get,
help, help-search, home, i, info, init, install, issues, la,
link, list, ll, ln, login, logout, ls, outdated, owner,
pack, ping, prefix, prune, publish, r, rb, rebuild, remove,
repo, restart, rm, root, run-script, s, se, search, set,
show, shrinkwrap, star, stars, start, stop, t, tag, team,
test, tst, un, uninstall, unlink, unpublish, unstar, up,
update, upgrade, v, version, view, whoami
npm -h quick help on
npm -l display full usage info
npm faq commonly asked questions
npm help search for help on
npm help npm involved overview
Specify configs in the ini-formatted file:
/root/.npmrc
or on the command line via: npm --key value
Config info can be viewed via: npm help config
npm@2.15.11 /usr/lib/node_modules/npm
Installing Ghost
Now that we have Node.js installed, we can proceed with the installation of Ghost. To download the latest version Ghost run the following command.
mkdir -p /var/www/
cd /var/www/
wget https://ghost.org/zip/ghost-latest.zip
The above command will create a directory to install Ghost in it. Then after moving into newly created directory, it will download the latest version of Ghost. If you don’t have wget
installed you can run yum -y install wget
to install it.
Now unzip the compressed file into ghost directory using the following command.
unzip -uo ghost-latest.zip -d /var/www/ghost
Now move into the new ghost directory and install Ghost using the following commands.
cd /var/www/ghost
npm install --production
The above command will install production dependencies only. If you don’t include --production
attribute during install, it will only install some extra dependencies, which are only required for development of the Ghost core. Installation of Ghost is now finished.
Starting Ghost
Before you can start Ghost blog, you will need to make a small change in Configuration to allow everyone to connect to the web server. By default Ghost listens to port number 2368 and can only be accessed through localhost. To allow everyone to access Ghost on port 2368, edit the configuration file using your favorite editor. In this tutorial we will be using nano editor. If you do not have nano installed, you can install it using yum -y install nano
.
nano /var/www/ghost/config.example.js
In production
block find host: '127.0.0.1',
. Change the host to host: '0.0.0.0',
. Save and exit from editor.
Now you can start your Ghost blog, run the following command.
cd /var/www/ghost
npm start --production
You should see following output.
[root@ip-172-31-2-60 ghost]# npm start --production
> ghost@0.11.3 start /var/www/ghost
> node index
WARNING: Ghost is attempting to use a direct method to send email.
It is recommended that you explicitly configure an email service.
Help and documentation can be found at http://support.ghost.org/mail.
Migrations: Creating tables...
Migrations: Creating table: posts
Migrations: Creating table: users
Migrations: Creating table: roles
Migrations: Creating table: roles_users
Migrations: Creating table: permissions
Migrations: Creating table: permissions_users
Migrations: Creating table: permissions_roles
Migrations: Creating table: permissions_apps
Migrations: Creating table: settings
Migrations: Creating table: tags
Migrations: Creating table: posts_tags
Migrations: Creating table: apps
Migrations: Creating table: app_settings
Migrations: Creating table: app_fields
Migrations: Creating table: clients
Migrations: Creating table: client_trusted_domains
Migrations: Creating table: accesstokens
Migrations: Creating table: refreshtokens
Migrations: Creating table: subscribers
Migrations: Running fixture populations
Migrations: Creating owner
Ghost is running in production...
Your blog is now available on http://my-ghost-blog.com
Ctrl+C to shut down
Now use your favorite browser to access your Ghost blog on the following web address.
http://your-server-ip:2368
Replace your-server-ip
with the IP address of your server. You should see following screen.
HP_NO_IMG/data/uploads/users/1a010430-e647-458e-a84e-ec55c6ef8793/2069542009.png” alt=”” />
To create your administrative account go to the following web address.
http://your-server-ip:2368/ghost
You will be greeted by a welcome screen, click on Create new account button. You will be now taken to a new interface where you need to provide your Name, email address, password and name of the Blog.
HP_NO_IMG/data/uploads/users/1a010430-e647-458e-a84e-ec55c6ef8793/1995252924.png” alt=”” />
Finally click on the button saying Last Step: Invite your team. You can use this interface to invite your team members to your new blog, or you can click on I’ll do this later, take me to my blog link. You will be now taken to the administrative dashboard of your Ghost Blog.
HP_NO_IMG/data/uploads/users/1a010430-e647-458e-a84e-ec55c6ef8793/868824333.png” alt=”” />
You can use this interface to manage your Blog and to add new posts in it.
Configure Ghost
When running Ghost on server, whenever the terminal session is ended, Ghost is also stopped. We can keep Ghost running with many different methods like PM2, forever or init script. In this tutorial we will learn about running Ghost with PM2.
Keep Ghost running using PM2
PM2 is a advanced, production process manager for Node.js. PM2 helps running Ghost indefinitely until you do not stop it manually. Installation and setup of PM2 is very easy. Run the following command to install PM2.
cd /var/www/ghost
npm install -g pm2
Once PM2 is installed, run the following command to change the environment variables so that Ghost always starts in production mode.
echo "export NODE_ENV=production" >> ~/.profile
source ~/.profile
Now start the process using the following command.
pm2 start index.js --name ghost
Once you execute the above command, you will see following output.
[root@ip-172-31-2-60 ghost]# pm2 start index.js --name ghost
[PM2] Spawning PM2 daemon with pm2_home=/root/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /var/www/ghost/index.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤
│ ghost │ 0 │ fork │ 8912 │ online │ 0 │ 0s │ 6% │ 13.0 MB │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
Use `pm2 show ` to get more details about an app
To get more details about the running Ghost process, run the following command.
pm2 show ghost
You will see output similar to the following.
[root@ip-172-31-2-60 ghost]# pm2 show ghost
Describing process with id 0 - name ghost
┌───────────────────┬───────────────────────────────────┐
│ status │ online │
│ name │ ghost │
│ restarts │ 0 │
│ uptime │ 2m │
│ script path │ /var/www/ghost/index.js │
│ script args │ N/A │
│ error log path │ /root/.pm2/logs/ghost-error-0.log │
│ out log path │ /root/.pm2/logs/ghost-out-0.log │
│ pid path │ /root/.pm2/pids/ghost-0.pid │
│ interpreter │ node │
│ interpreter args │ N/A │
│ script id │ 0 │
│ exec cwd │ /var/www/ghost │
│ exec mode │ fork_mode │
│ node.js version │ 4.6.2 │
│ watch & reload │ ✘ │
│ unstable restarts │ 0 │
│ created at │ 2016-11-10T18:24:32.514Z │
└───────────────────┴───────────────────────────────────┘
Code metrics value
┌────────────┬────────┐
│ Loop delay │ 1.26ms │
└────────────┴────────┘
Add your own code metrics: http://bit.ly/code-metrics
Use `pm2 logs ghost [--lines 1000]` to display logs
Use `pm2 monit` to monitor CPU and Memory usage ghost
Now you will need to create the startup script so that whenever the server restarts, PM2 also restarts along with the process it is running. Run the following commands for the same.
pm2 startup centos
pm2 save
pm2 save
command saves the the current process list in a file. You will the following output.
[root@ip-172-31-2-60 ghost]# pm2 startup centos
[PM2] Writing startup script in /etc/init.d/pm2-init.sh
[PM2] Making script booting at startup...
[PM2] /var/lock/subsys/pm2-init.sh lockfile has been added
[PM2] -centos- Using the command:
su -c "chmod +x /etc/init.d/pm2-init.sh; chkconfig --add pm2-init.sh"
[PM2] Done.
[PM2] Now you can type
$ pm2 save
[PM2] To save the current process list at reboot or via pm2 update
[root@ip-172-31-2-60 ghost]# pm2 save
[PM2] Saving current process list...
[PM2] Successfully saved in /root/.pm2/dump.pm2
To check the current status of PM2, you can run the following command.
pm2 status
To stop Ghost process, run the following command.
pm2 stop ghost
You should see following output.
[root@ip-172-31-2-60 ghost]# pm2 stop ghost
[PM2] Applying action stopProcessId on app [ghost](ids: 0)
[PM2] [ghost](0) ✓
┌──────────┬────┬──────┬─────┬─────────┬─────────┬────────┬─────┬────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────┼────┼──────┼─────┼─────────┼─────────┼────────┼─────┼────────┼──────────┤
│ ghost │ 0 │ fork │ 0 │ stopped │ 0 │ 0 │ 0% │ 0 B │ disabled │
└──────────┴────┴──────┴─────┴─────────┴─────────┴────────┴─────┴────────┴──────────┘
Use `pm2 show ` to get more details about an app
You can now use the following command to restart the Ghost process.
pm2 start ghost
To check the logs of PM2, run the following command.
pm2 logs
You should see following output.
[root@ip-172-31-2-60 ghost]# pm2 logs
[TAILING] Tailing last 10 lines for [all] processes (change the value with --lines option)
/root/.pm2/pm2.log last 10 lines:
PM2 | 2016-11-10 18:33:59: Concurrent actions : 2
PM2 | 2016-11-10 18:33:59: SIGTERM timeout : 1600
PM2 | 2016-11-10 18:33:59: ===============================================================================
PM2 | 2016-11-10 18:33:59: Starting execution sequence in -fork mode- for app name:ghost id:0
PM2 | 2016-11-10 18:33:59: App name:ghost id:0 online
PM2 | 2016-11-10 18:36:47: Stopping app:ghost id:0
PM2 | 2016-11-10 18:36:47: App [ghost] with id [0] and pid [1531], exited with code [0] via signal [SIGINT]
PM2 | 2016-11-10 18:36:47: pid=1531 msg=process killed
PM2 | 2016-11-10 18:38:12: Starting execution sequence in -fork mode- for app name:ghost id:0
PM2 | 2016-11-10 18:38:12: App name:ghost id:0 online
/root/.pm2/logs/ghost-error-0.log last 10 lines:
0|ghost | Help and documentation can be found at http://support.ghost.org/mail.
0|ghost |
0|ghost | WARNING: Ghost is attempting to use a direct method to send email.
0|ghost | It is recommended that you explicitly configure an email service.
0|ghost | Help and documentation can be found at http://support.ghost.org/mail.
0|ghost |
0|ghost | WARNING: Ghost is attempting to use a direct method to send email.
0|ghost | It is recommended that you explicitly configure an email service.
0|ghost | Help and documentation can be found at http://support.ghost.org/mail.
0|ghost |
0|ghost |
0|ghost | Ghost has shut down
0|ghost |
0|ghost | Your blog is now offline
0|ghost | Ghost is running in production...
0|ghost | Your blog is now available on http://my-ghost-blog.com
0|ghost | Ctrl+C to shut down
[STREAMING] Now streaming realtime logs for [all] processes
Configure Ghost to run on port 80 using nginx
By default Ghost runs on port 2368, we can use nginx to run Ghost on port number 80on which normal HTTP request listen to. We will configure Nginx to proxy all the requests for port 80 to 2368. Finally when we will have our blog running on port 80 we will disable its accessibility on 2368 for security purposes. To install nginx, run the following commands.
yum -y install epel-release
yum -y update
yum -y install nginx
As we have nginx ready we will now create a virtual host or server block file to forward all the request from port 80 to port 2368. Create a new configuration file in /etc/nginx/conf.d/
directory. To use nginx virtual host you must have a domain name configured and pointing towards your server. To create a new configuration file, run the following command.
nano /etc/nginx/conf.d/your-domain.com.conf
In above command replace your-domain.com
with your actual domain name.
Paste the following lines in the file.
server {
listen 80;
server_name your-domain.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
}
}
Change your-domain.com
with your actual domain. Save the file and exit from editor. You will also need to adjust your SELinux configuration to allow network connections. Run the following command for same.
setsebool -P httpd_can_network_connect true
Now you can start your nginx server using the following command.
systemctl start nginx
To enable nginx to start automatically at boot time, run the following command.
systemctl enable nginx
You can now access the domain name in your favorite web browser to browse the website.
As we have access to our website through port 80, we can disable port 2368 for everyone else except the localhost. To make this configuration simply edit the configuration file of Ghost using the following command.
nano /var/www/ghost/config.example.js
Revert the change which we made during the start of the tutorial. In production
block find host: '0.0.0.0',
. Change the host to host: '127.0.0.1',
. Save and exit from editor.
Conclusion
In this tutorial we have successfully installed Ghost Blogging system on our CentOS VPS. We also learnt about the process management by PM2. You can now successfully deploy Ghost Blogging system along with Node.js, PM2 and nginx to set up a lightweight but powerful professional blog.