• Get In Touch
November 14, 2016

How to install Ghost Blogging Platform on CentOS 7

Want your very own server? Get our 1GB memory, Xeon V4, 25GB SSD VPS for £10.00 / month.
Get a Cloud Server

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.

Want your very own server? Get our 1GB memory, Xeon V4, 25GB SSD VPS for £10.00 / month.
Get a Cloud Server

Share this Article!

Related Posts

Node.js Authentication – A Complete Guide with Passport and JWT

Node.js Authentication – A Complete Guide with Passport and JWT

Truth be told, it’s difficult for a web application that doesn’t have some kind of identification, even if you don’t see it as a security measure in and of itself. The Internet is a kind of lawless land, and even on free services like Google’s, authentication ensures that abuses will be avoided or at least […]

Node.js and MongoDB: How to Connect MongoDB With Node

Node.js and MongoDB: How to Connect MongoDB With Node

MongoDB is a document-oriented NoSQL database, which was born in 2007 in California as a service to be used within a larger project, but which soon became an independent and open-source product. It stores documents in JSON, a format based on JavaScript and simpler than XML, but still with good expressiveness. It is the dominant […]

Using MySQL with Node.js: A Complete Tutorial

Using MySQL with Node.js: A Complete Tutorial

Although data persistence is almost always a fundamental element of applications, Node.js has no native integration with databases. Everything is delegated to third-party libraries to be included manually, in addition to the standard APIs. Although MongoDB and other non-relational databases are the most common choice with Node because if you need to scale an application, […]

Node.Js Vs Django: Which Is the Best for Your Project

Node.Js Vs Django: Which Is the Best for Your Project

Django and NodeJs are two powerful technologies for web development, both have great functionality, versatile applications, and a great user interface. Both are open source and can be used for free. But which one fits your project best? NodeJs is based on JavaScript, while Django is written in Python. These are two equally popular technologies […]

Nodejs Vs PHP:  Which Works Best?

Nodejs Vs PHP: Which Works Best?

Before getting into the “battle” between Node.js and PHP we need to understand why the issue is still ongoing. It all started with the increased demand for smartphone applications, their success forcing developers to adapt to new back-end technologies that could handle a multitude of simultaneous requests. JavaScript has always been identified as a client-side […]