Ghost Setup

I have thus far explained why a blog, and why DigitalOcean. The following is a step-by-step guide to launch a VPS with Ghost pre-installed (it is assumed that you have signed up for a DigitalOcean account - I generally prepay using PayPal):

Create a droplet with the Ghost installed as part of the one-click application with the following specifications:

  • $5/mo: 512MB; 1 CPU; 20GB SSD; 1TB Transfers
  • Location: Amsterdam 2 or 3 (chosen as I also plan on using OpenVPN on this VPS, and I've generally had the best experience in terms of speed and reliability with the Dutch data centre)
  • SSH Keys: Your choice - for security purposes, I use only one device so that there is no set root password. Will never log in remotely as root in any case, as a new user will be set up with cloud-init.
  • Hostname: Enter desired hostname. I generally use
  • Tick the user data box. Sample cloud-init data:

# Add user 'admin' to the system, and allow ssh access. Include the user in the sudo group, and do not require a password for every sudo command.

  - name: admin
      - ssh-rsa ... MacBookPro.local
      - ssh-rsa ... MacMini.local
      - ssh-rsa ... iPhone.serverAuditor
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash

# Run the update and upgrade commands. 
# Install sed to make changes to the sshd_config file (do not permit root login, and allow SSH login for admin. 
# Install tcptrack, my preferred network monitoring tool. 
# Install OpenVPN and EasyRSA, and copy the example configuration file - I wanted to save a little time.

  - apt-get update
  - apt-get upgrade
  - apt-get install sed
  - apt-get install tcptrack
  - sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config
  - sed -i -e '$aAllowUsers admin' /etc/ssh/sshd_config
  - restart ssh
  - apt-get -y install open-vpn easy-rsa
  - gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf

Note, the OpenVPN commands in the runcmd section does not always seem to work for some reason

Initial Server Configuration

Once the droplet has been created, the domain name needs to be set-up, followed by making a few minor changes to the nginx & Ghost configuration files.

In my circumstance, my domain was purchased through GoDaddy. I first needed to change the name servers to DigitalOcean's:  

Once this is done, the domain needs to be added to DigitalOcean (click Networking at the top of the page, followed by Domains on the bar to the left). Fairly straightforward process, so I'm not going to go into it in detail here.

Next, the nginx configuration has to be updated to reflect the domain name. Enter nano /etc/nginx/sites-available/ghost to open the nginx config file for editing in the nano editor (my preferred Linux editor). Change the current server_name from to the relevant domain name. In my circumstance, this would look like server_name ;

This is followed by an edit to the Ghost configuration file. Enter nano /var/www/ghost/config.js to open the Ghost configuration file for editing.

Move to the production mode section and change the url to Also worth including the forceAdminSSL line here, as the SSL certificate is going to be installed in the next section immediately.

It would look like the following in my circumstance:

production: {  
        url: '',
        forceAdminSSL: true,

Side-note: DigitalOcean automatically configures Ghost to run in Production mode.

There are several other options in this file which can be configured, see the Ghost usage documentation for more information. We will also return to this file shortly, to configure the mail section.

Securing the Admin Interface

The Ghost server is now running, however I believe it is a good idea to secure the admin interface immediately, before proceeding any further.

I hope to include a separate post on SSL certificates as whole at some point, however to give a brief outline:

  • Create a directory to save the certificate files, for example: sudo mkdir /etc/nginx/ssl

  • Create a private key and CSR using the following as an example: openssl req -new -newkey rsa:2048 -nodes -keyout /etc/nginx/ssl/ -out /etc/nginx/ssl/

  • Answer all relevant questions. Note: enter the domain name you want associated with the certificate under "Common Name".

  • Save the private key in a safe and secure place on the VPS.

  • Submit the CSR to a certificate authority. In the case of, I used Comodo.

  • Once the certificate if received from the authority, copy the certificate to your server, using your preferred method. For example: simply copy the text and paste it using nano, or using SFTP and CyberDuck.

  • Update the nginx configuration: sudo nano /etc/nginx/sites-available/ghost. Include the SSL certificate details so that configuration looks something like this:

server {  
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;
    listen 443 ssl;
    ssl_certificate        path-to-cert/;
    ssl_certificate_key    path-to-key/;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

Note: ssl_protocols included to protect the server against the POODLE SSLv3 Vulnerability

Note to self: update to include ssl_ciphers for Perfect Forward Secrecy

  • Restart nginx: sudo service restart nginx

The admin area of the blog should only be accessible using a secure HTTPS connection now (particularly since we already included the forceAdminSSL lines in the Ghost config.js.

Ghost Initial Setup

Browse to your-ghost-url/ghost ( in my circumstance). You'll see the Ghost sign up screen. Enter your details to create your admin user account. You'll be automatically logged in when you're done.

Once logged in, you will be able to start your first blog entry.

One of the things you will notice as soon as the Ghost blog is ready and you have created an account, is a bar at the top of the screen referring to Ghost's mail server. I am copying the following verbatim from Ghost's support documentation:

Most other other blogging platforms are based on a scripting language called PHP. If you’ve used those platforms before, you’re probably used to having email just magically work. Ghost is based on Node.js. Node is shiny and new, and still a little rough around the edges. It requires some configuration to get email working.

At the moment, the only thing Ghost uses email for is sending you an email with a new password if you forget yours. It’s not much, but don’t underestimate how useful that feature is if you ever happen to need it.

The support document goes on to describe how to set up a Mailgun account, using the auto-generated sandbox domain, however I'd preferably like to receive my password reset emails from a postmaster account from my domain.

It's a simple enough process...

  • Head along to and sign up for an account. It’s free to use up to 10,000 emails per month.

  • The registering process should take you right to the domain entry page. If it doesn't just go to the control panel and click on Add Domain. Enter the domain name. Mailgun will ask you to enter a sub-domain such as, however I did not have much success with this, and instead added as the domain name.

  • Now Mailgun should have directed you to the DNS settings page. To find it manually, go to the Domains tab and select your domain. Enter these details into DigitalOcean's Networking configuration. Sample for domain_info Note the following:

    • The txt details need to be in inverted commas: "v=spf...".
    • DigitalOcean will make you include dots at the end of domain values
    • The v=spf part needs an @ in front, not your domain, as Mailgun instructs.
  • It should take about 24 hours for the DNS records to update, however you can spam the "Check DNS..." button to speed things up.

  • Next, you will need to update Ghost's config.js file so that the SMTP information is saved. To do so, open up the file on nano (sudo nano /var/www/ghost/config.js) and update the mail block under the production mode section, so that it looks similar to the following:

        mail: {
            transport: 'SMTP',
            from: '"Nakul Natarajan" <>'
            options: {
                service: 'Mailgun',
                auth: {
                    user: '',
                    pass: 'PASSWORD_FROM_MAILGUN_CP',

1. How to use the DigitalOcean Ghost Application
2. Getting Started with Ghost
3. How to setup SSL for self-hosted Ghost
4. Configuring Ghost
5. Mail Configuration on self-hosted version of Ghost
6. Mailgun + DigitalOcean
7. How-to: Install SSL certificate, nginx with spdy and Perfect Forward Secrecy (PFS) on Debian Wheezy
8. An Introduction to Cloud-Config Scripting
9. How To Create an SSL Certificate on Nginx for Ubuntu 14.04
10. How To Protect your Server Against the POODLE SSLv3 Vulnerability