Ghost 0.x on SmartOS

This article has been superceeded by a newer version.

Running and maintaining a blog on SmartOS is simple and easy.  Today we're going to go over setting up Ghost on SmartOS, configuring an Nginx front-end, as well as configuring SMF to boot it up on zone startup.

Why Ghost?

To be completely honest, I'm not the biggest fan of Ghost.  It can be somewhat clunky at times, but that's true of most all software, especially version 0 software.  Despite that, it's overall fairly easy to use, and definitely quite pretty, oh yes, it isn't WordPress.

Quite possibly the biggest appreciation I have for ghost is its side-by-side source/rendered view editor.  It's quite rewarding to see your blog form in real time on one side of the screen as you're writing it's markdown source on the other side.  A close second is that it's quite easy to install and configure, allowing me to maximize my time in other pursuits.

Note: This guide applied to the 0.x versions of ghost and not the 1.x, which will be the subject of a future blog post.

Prerequisites

To fully install and configure ghost, you will need a few additional packages to decompress ghost and compile some of its extensions.

# pkgin in gmake gcc49 unzip

Getting Ghost

Downloading and configuring Ghost is pretty straightforward.  Switch to the directory you want to run it out of and do the following:

$ curl -LOk https://ghost.org/zip/ghost-latest.zip
$ unzip ghost-latest.zip -d ./

Edit config.js to your liking and run the following commands to configure your environment and initialize ghost for the first time, preferably as the user which will be running the blog:

$ npm install --production

Then start the blog.

$ npm start --production

If everything goes well, you should have a fully functional blog.  Create your account and shut down the node.js server with ctrl-c, we're next going to setup Nginx as a front-end.

Upgrading Ghost

Upgrading Ghost is an admittedly manual process right now.  I recommend following the instructions at http://support.ghost.org/how-to-upgrade/, with some additional steps.

If you can, take a snapshot of the ZFS dataset containing ghost before you start sawing at your current installation.  If something goes wrong, you can just rollback to the snapshot and none will be the wiser.

Configuring Nginx

For this section, we're going to assume you've already installed and preconfigured Nginx.  Add the following to /opt/local/etc/nginx/nginx.conf or a file included by that configuration file:

server {
  listen 80;
  listen [::];
  server_name <blog_hostname>;

  location / {
    proxy_pass http://127.0.0.1:2368;
    proxy_http_version 1.1;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
  }
}

The set_header directives aren't necessary but will make the logs a bit more usable.  Restart Nginx to re-read the configuration directives.

# svcadm restart nginx

Configuring SMF

Service Management Facility (SMF) has an unfortunately steep learning curve, which is a real shame, given how it excels at managing services on a running host.  Without going into too much depth, We will define a service manifest that will facilitate starting and stopping and restarting the service, basically in the same way that Solaris starts stops and restarts any of its other services.

Save the following into /root/ghost.xml:

Customize everything that needs to be changed in the instance tag and descendants, namely the following:

  • name parameter of instance tag.
  • working_directory parameter of method_context tag.
  • user and (optionally) group parameter of method_credential tag.
  • value parameter of envvar tag with the name parameter set to HOME.

Once those changes have been made, import the service into SMF.  Because enabled='true' was set under the instance tag, this instance will automatically start.

# svccfg import /root/ghost.xml

Enable User Management with RBAC

This is great and all, but what happens when we're changing something as our user and we need to restart the blogging software?

$ svcadm restart ghost
svcadm: svc:/application/ghost:blog-brianewell: Permission denied.

Nothing good.  Fortunately, Role-Based Access Control (RBAC) really shines with SMF.  First of all, define an authorization description under /etc/security/auth_attr:

solaris.smf.manage.ghost.blog-brianewell:::Manage Brian's Ghost Blog::

Next, we authorize our user with this description.

# usermod -A solaris.smf.manage.ghost.blog-brianewell brian

And finally, we tell SMF what to allow with that authorization description.  Specifically, we want SMF to allow a user with the solaris.smf.manage.ghost.blog-brianewell authorization to be able to take the application down for maintenance and restart it (action_authorization) as well as enable or disable its starting during boot (value_authorization).  Since we've been as specific as naming our blog, we should also grant this permission to this specific instance, and not all ghost instances which could be on the server.

# svccfg -s ghost:blog-brianewell setprop \
general/action_authorization=astring: 'solaris.smf.manage.ghost.blog-brianewell'
# svccfg -s ghost:blog-brianewell setprop \
general/value_authorization=astring: 'solaris.smf.manage.ghost.blog-brianewell'

Now you can use svcadm from your user account to control your blogging software in a stable and secure manner, much better than is possible using cron, init.d, or pretty much any other alternative.

Stay tuned for another blog post on SMF, since it's incredibly useful to understand while using Solaris or SmartOS.