Ghost

I was arguing with myself whether I should post this or not. For one, it is the second Linux-related tutorial I write, and that strays from the main topic of my site (my awesome self and iOS development). But because installing Ghost was a big hassle on my current setup, I decided to write this for those who are struggling with the same thing as me. After all, I have said this before – one of the reasons I decided to start blogging was so I could also start documenting things for myself. Most, if not all, of my tutorials, have been things I have written shortly after having learned about them. So I know that my own site is a good go-to reference when I need to use those topics again.

At the time of this writing, Ghost 0.5 has just been released to the public. There are many changes, and there aren’t too many sources you can find to help you install Ghost on Ubuntu, using Virtualmin (Webmin, in case you only have access to that – this tutorial should work for both). In fact, in all my searches, the total amount of resources I found that talked about Ghost and Virtualmin or Webmin in the same page was a grand total of zero.

For this reason, I will document how I managed to install Ghost on my server, which is running Ubuntu server with a Virtualmin setup. If you are like me, you just hate to do server administration by hand using the Terminal and sending off the commands, and installed Virtualmin to make your life easier.

Most Ghost related tutorials use NGinx. But personally I am an Apache guy, so for me it’s important to make this work in Apache.

In short, this tutorial assumes that you have access to Virtualmin (or Webmin), and are using Apache.

Finally, this is not a tutorial for beginners. Even when using Webmin, you need to know the command line, and know your way around virtual sites.

With all that said, I will try to make this as easy as possible.

1. Preparing Your Web Server For Ghost.

The first thing you will probably want to do is to set up a subdomain using Virtualmin for your Ghost Blog. If you are using a shared host that has Webmin and can’t do that, don’t worry, you can set Ghost up in your main domain as well.

(Virtualmin only) Go to Virtualmin, click Create Virtual Server. At this point, the settings of the server are irrelevant so just configure it as you need it. The Ghost blog I created is located at http://linguist.andyibanez.com

Grab your username and password for FTP and SSH purposes.

2. Installed The Packages Required for Ghost

After you have your site created, go to Webmin > System > Software Packages.

2.1 Build Essentials and NPM

Select the radio button that says “Package from APT”. Then click the button that says “Search Apt…”. Type in build-essentials, select the only package that shows up, and install it. This package is needed because it includes a few useful development tools, including g++, which is needed to compile the other tools needed for Ghost.

APT

Do the exact same thign with NPM, writing “npm” instead of build-essentials.

2.2 node.js

Sadly, I lied. Sorta. We will need to access our site SSH after all to install the remaining component to install Ghost. I, too, thought it was a bummer when I realised I had to do that.

Technically, you can install node.js installed build-essentials and PM, but at the time of this writing, the APT packages for node.js are outdated. Ghost needs nose.js 0.10.x to work, and at the time of this writing it installs 0.6.x. So we have no other option but to download them and compile it from source.

Virtualmin Users

If you have access to Virtualmin because you have full access over your VPS, follow these instructions.

1. Login to your root account via SSH in the terminal (this is NOT the username and password you created above – you should have gotten this when you created your VPS).
2. Once logged in, type in the following commands *:

cd /usr/src
wget http:/nodejs.org/dist/v0.10.18/node-v0.10.18.tar.gz
tar zxf node-v0.10.18.tar.gz
cd node-v0.10.18
./configure
make
make install

The moment you send the make command, your server will be doing a big task. It can take a while to complete (in my case, it took 8 – 10 minutes).

Once that is done, verify node.js is installed by typing this command:

node -v

It should print the node.js version you’re running.

If you are using a shared hosting and don’t have access to Virtualmin but only to Webmin, you may need to ask the manage of the server to install that version of node.js, npm, and build-settings.

3. Installing Ghost

Once all data is done, everything we have left is to install Ghost itself. Go to http://ghost.org/download and download the package to your computer. Next, grab the SSH details we obtained in the first step.

Once Ghost is downloaded, open your favorite FTP program and login with the credentials. Navigate to the public_html folder, unzip the Ghost package, and upload it (you can also upload the zip as it is, or even download it directly there with wget and unzip with more command line commands).

Once that is uploaded via FTP, we need to log in via SSH again, but this time using the credentials from the first step instead of root. Do that and navigate to the place where you just uploaded the Ghost files. Once you are there, run the following command to install Ghost:

npm install --production

And watch out for any possible errors. If we are doing everything correctly, everything you will see at most are a few warnings.

4. Configuring Ghost

We are nearing the end of this process.

Ghost has a file called “config.js”. If you don’t see it, you may see the example “config.example.js” file. You can just copy the latter one and rename it to config.js. Open it with your favorite editor (I do all my FTP operations with Cyberduck, so I can download the files locally and open them with TextMate – But this is just personal preference.

The config file is here, you can also just steal this one.

// # Ghost Configuration
// Setup your Ghost install for various environments
// Documentation can be found at http://support.ghost.org/config/

var path = require('path'),
    config;

config = {
    // ### Development **(default)**
    development: {
        // The url to use when providing links to the site, E.g. in RSS and email.
        url: 'http://my-ghost-blog.com',

        // Example mail config
        // Visit http://support.ghost.org/mail for instructions
        // ```
        //  mail: {
        //      transport: 'SMTP',
        //      options: {
        //          service: 'Mailgun',
        //          auth: {
        //              user: '', // mailgun username
        //              pass: ''  // mailgun password
        //          }
        //      }
        //  },
        // ```

        database: {
            client: 'sqlite3',
            connection: {
                filename: path.join(__dirname, '/content/data/ghost-dev.db')
            },
            debug: false
        },
        server: {
            // Host to be passed to node's `net.Server#listen()`
            host: '127.0.0.1',
            // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
            port: '2368'
        },
        paths: {
            contentPath: path.join(__dirname, '/content/')
        }
    },

    // ### Production
    // When running Ghost in the wild, use the production environment
    // Configure your URL and mail settings here
    production: {
        url: 'http://my-ghost-blog.com',
        mail: {},
        database: {
            client: 'sqlite3',
            connection: {
                filename: path.join(__dirname, '/content/data/ghost.db')
            },
            debug: false
        },
        server: {
            // Host to be passed to node's `net.Server#listen()`
            host: '127.0.0.1',
            // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
            port: '2368'
        }
    },

    // **Developers only need to edit below here**

    // ### Testing
    // Used when developing Ghost to run tests and check the health of Ghost
    // Uses a different port number
    testing: {
        url: 'http://127.0.0.1:2369',
        database: {
            client: 'sqlite3',
            connection: {
                filename: path.join(__dirname, '/content/data/ghost-test.db')
            }
        },
        server: {
            host: '127.0.0.1',
            port: '2369'
        },
        logging: false
    },

    // ### Testing MySQL
    // Used by Travis - Automated testing run through GitHub
    'testing-mysql': {
        url: 'http://127.0.0.1:2369',
        database: {
            client: 'mysql',
            connection: {
                host     : '127.0.0.1',
                user     : 'root',
                password : '',
                database : 'ghost_testing',
                charset  : 'utf8'
            }
        },
        server: {
            host: '127.0.0.1',
            port: '2369'
        },
        logging: false
    },

    // ### Testing pg
    // Used by Travis - Automated testing run through GitHub
    'testing-pg': {
        url: 'http://127.0.0.1:2369',
        database: {
            client: 'pg',
            connection: {
                host     : '127.0.0.1',
                user     : 'postgres',
                password : '',
                database : 'ghost_testing',
                charset  : 'utf8'
            }
        },
        server: {
            host: '127.0.0.1',
            port: '2369'
        },
        logging: false
    }
};

// Export config
module.exports = config;

Search for the line that says “// ### Production” near line 47 and do a few edits.

  • Edit url to be the URL that will be used to visit your blog.
  • (Optionally) change the port number (only do this if you’re installing a second instance of Ghost).

Finally, go back to Webmin, select your server, and go to Configure Website > Edit Directies. You will be greeted with a bunch of directives.

Paste in these three lines, right before the first “Directory” directive:

ProxyRequests off
ProxyPass / http://127.0.0.1:2368/
ProxyPassReverse / http:/127.0.0.1:2368/

If you are installing a second instance of Ghost, you would need to change the port number to match the port of the instance.

Now you need to start the service (Ghost runs as a service instead of an actual website).

npm start --production > output.log &

Please note you will need to do this again if you restart your server. There are ways to keep Ghost “Alive forever”, but none of them have worked for me so I am omitting them from this tutorial.

That’s a Wrap

You can now visit the URL of your Ghost website. visit it’s /ghost page to create the first user and start blogging!

You can install various instances of Ghost with this method. Simply change the port number in both the configuration and proxy settings when you do.

Enjoy!

Positive SSL