How to Install Ghost Blog Software with Apache and SSL on Ubuntu 16.04

Ghost is a powerful open source publishing and blog platform that is beautifully designed and easy to use. Ghost is written in javascript and uses node.js as runtime environment. The first Ghost version has been released in 2013 under MIT license and gets constantly updated. This tutorial shows the installation of the Ghost Blog software, Node.js and Apache as SSL proxy server on Ubuntu 16.04.

Nodejs is an open source javaScript runtime built on Chrome's V8 JavaScript engine (v4) for developing server-side web applications. Nodejs is a cross-platform runtime that can run on OS X, Microsoft Windows, Linux, and FreeBSD. It provides an event-driven architecture and non-blocking I/O model that makes it lightweight and efficient for real-time web applications. The Node.js project has been started in 2009 by Ryan Dahl and reached version 6.5.0 (LTS) as of today.


  • Ubuntu 16.04
  • root privileges

What we will do in this tutorial:

  • Install Node.js
  • Install Ghost
  • Configure Ghost
  • Install Apache and add the Ghost VirtualHost
  • Enable SSL for Ghost

Step 1- Install Node.js on Ubuntu

For this tutorial, we will use nodejs v4.x. Nodejs can be installed in many different ways like installation from source, or installation from the Ubuntu repository. I will use the nodejs repository of nodesecure for the installation, it contains up to date software and using a repository allows it to update node.js easily later.

Install the nodesource repository key with the command below:

curl -s | apt-key add -

Then add the nodejs repository by executing the comands below:

sudo echo 'deb xenial main' > /etc/apt/sources.list.d/nodesource.list
sudo echo 'deb-src xenial main' >> /etc/apt/sources.list.d/nodesource.list

Update the repository:

sudo apt-get update

Now we can install the "nodejs" package which will install node.js and its dependencies on the server:

sudo apt-get install -y nodejs

Now check nodejs version to ensure that the installation was successful:

node --version

Check npm version:

npm --version

npm is a package manager to install, publish and manage node programs.

Check the node.js and npm version.

Step 2 - Install Ghost Blog

We will install ghost in the directory "/var/www/" and use the latest version of Ghost. Please make a new directory "www" in /var and enter it with "cd":

mkdir -p /var/www/
cd /var/www/

Download Ghost with the wget command, then extract it to a directory called "ghostblog" :

unzip -d ghostblog

NOTE : -d : automatically creates the directory.

Then go to the ghostblog directory and install Ghost with the npm command:

cd ghostblog/
sudo npm install --production

Step 3 - Configure Ghost

Please go to the ghostblog directory and then copy the config sample file to "config.js"

cd /var/www/ghostblog/
cp config.example.js config.js

Next, add a new user "ghost". This user will be sued to run Ghost :

useradd -d /var/www -s /bin/bash ghost
passwd ghost


-d = Defines the home directory for the ghost user in /var/www/.

-s = Defines the shell for the ghost user.

Now change the owner of the ghost installation directory to the user "ghost".

chown -R ghost:ghost /var/www/ghostblog

Test the ghost blog by executing the npm command as ghost user. Please log in to the user ghost:

su - ghost

and go to the installation directory and start Ghost:

cd ghostblog/
npm start --production

Ghost is installed and running on localhost with port 2368. We can check it with the curl command:

curl -I localhost:2368

Check ghost blog with curl

You can see ghost is running - HTTP/1.1 200 OK.

We will run ghost as service to make it easier for us to start ghost. Please go back to sudo/root user by typing "exit" and make a new file called "ghost.service" in the directory "/lib/systemd/system/".

cd /lib/systemd/system/
vim ghost.service

Paste the systemd script below:


# Ghost installation Directory
ExecStart=/usr/bin/npm start --production
ExecStop=/usr/bin/npm stop --production


Next, reload the systemd daemon:

systemctl daemon-reload

Then add ghost to be started at boot time and start ghost with the systemctl command:

systemctl enable ghost
systemctl start ghost

Check that ghost is running by checking the port 2368:

netstat -plntu

Check ghost with netstat

Step 4 - Install Apache and the Ghost VirtualHost

Install apache with the apt-get command:

sudo apt-get install apache2

Once the installation is finished, create a new file for the ghost virtual host in the directory "/etc/apache2/sites-available/".

sudo cd /etc/apache2/sites-available/
sudo vim ghostblog.conf

Paste the configuration below:

<VirtualHost *:80>
    #Domain Name

    #HTTP proxy/gateway server
    ProxyRequests off 
    ProxyPass / 
    ProxyPassReverse / http:/     

Save and exit.

Activate the HTTP proxy module in apache with the command a2enmod as shown below:

sudo a2enmod proxy proxy_http

Finally, we have to activate the Ghost virtual host and then restart apache:

sudo a2ensite ghostblog
sudo systemctl restart apache2

Restart ghost:

sudo systemctl restart ghost

Test by visiting the domain:

Ghost start page

Step 5 - Enable SSL for Ghost

To enable SSL on apache, please make sure the OpenSSL library is installed on the system. We will generate new key and crt file in the directory "/etc/apache2/certs". First, we make new directory certs:

sudo mkdir -p /etc/apache2/certs

And generate the certificate key with the command below :

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/certs/ghostblog.key -out /etc/apache2/certs/ghostblog.crt

Please change the permission of certificate file:

sudo cd /etc/apache2/certs/
sudo chmod 600 *

Next, add the SSL configuration to ghost virtualhost by editing the "ghostblog.conf" file.

sudo cd /etc/apache2/sites-available/
sudo vim ghostblog.conf

Paste the new configuration script below:

<VirtualHost *:80>

    # Force http to https
    Redirect permanent /
#    ProxyRequests off 
#    ProxyPass / 
#    ProxyPassReverse / http:/     

<VirtualHost *:443>


   SSLEngine on
   SSLCertificateFile /etc/apache2/certs/ghostblog.crt
   SSLCertificateKeyFile /etc/apache2/certs/ghostblog.key

   ProxyPass /
   ProxyPassReverse / http:/
   ProxyPreserveHost   On

   RequestHeader set X-Forwarded-Proto "https"


Save the file and exit vim.

Activate the OpenSSL apache module and restart apache :

sudo a2enmod ssl headers
sudo systemctl restart apache2


Visit, and you will be forced to the HTTPS/SSL site of your blog.

Ghost installed with SSL

Ghost with apache and SSL has been successfully installed.


Nodejs is an open source multi-platform javascript runtime to build server-side web applications. It is lightweight and efficient for real-time web applications. Ghost is a blogging platform written in Javascript for Node.js. Ghost is beautifully designed and user-friendly. The intuitive interface makes this blog system easy to use. Ghost can be installed standalone or with a web server like Apache or Nginx. You can secure Ghost with OpenSSL. Configuring Ghost with Apache and OpenSSL is easy, you just have to setup the apache http_proxy module and generate an SSL Certificate.

Share this page:

5 Comment(s)

Add comment

Please register in our forum first to comment.


By: ustoopia

The file location of Ghost doesn't seem to work anymore. I am unable to download it from that location. I'm forced to sign up on the ghost website and am waiting for comfirmation now but if I find a different download link I'll post it here.

By: ustoopia

I see my previous comment still needs to be approved. Also this link to Ghost DOES work at this moment:

By: Andy

This guide is fantastic. Thank you so much. Followed the guide top to bottom and had a working ghost installation in the end. Many, many thanks!

By: Artsiom


I am trying to strup apache2 with ghost and got only apache2 default page.


Could you please take a look on my configuration and, maybe, will give me some advice.


[email protected]:$ sudo netstat -plntu

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name

tcp        0      0*               LISTEN      1967/node

tcp        0      0  *               LISTEN      477/sshd

tcp        0      0    *               LISTEN      1895/apache2

tcp6       0      0 :::22                 :::*                    LISTEN      477/sshd


[email protected]:$ curl -I localhost:2368

HTTP/1.1 200 OK



[email protected]:$ cat ghostblog.conf

<VirtualHost *:80>

    #Domain Name

    ServerName minsk.tld

    ServerAlias www.minsk.tld


    #HTTP proxy/gateway server

    ProxyRequests off

    ProxyPass /

    ProxyPassReverse / http:/



I do not use systemctl

I start ghost from screen

And, finally, it works if i hardcode IP and domain.tld in ghost.js config 



By: Aditya

Thanks a lot, you were a huge help.