Ghost is a blogging platform. Absurd Tech runs Ghost in a FreeBSD AWS EC2 instance.

The usual steps to deploy include: 1. download ghost, 2. unzip it and 3. run npm install in the ghost dir:

$ curl -O
$ unzip
$ cd ghost-0.7.8
$ npm install
$ npm start --production

Not that easy for us FreeBSD’ers. Especially if you have a somewhat recent version of FreeBSD and its packages.

During the npm install you would probably get this error:

ERROR: Unsupported version of Node
Ghost needs Node version ~0.10.0 || ~0.12.0 || ^4.2.0 you are using version 5.2.0

To work around this issue, you’ll need to downgrade node and npm.

Downgrading Node

If you’re like me you won’t be using nvm to install it or switch between version. At least I couldn’t due to below error:

$ nvm download 4.2.0
tar: Error opening archive: Failed to open '/dev/sa0'
Downloading and unpacking node v4.2.0
      throw er; // Unhandled 'error' event

Error: This socket has been ended by the other party
    at Socket.writeAfterFIN [as write] (net.js:268:12)
    at IncomingMessage.ondata (_stream_readable.js:528:20)
    at emitOne (events.js:77:13)
    at IncomingMessage.emit (events.js:169:7)
    at (_stream_readable.js:360:10)
    at flow (_stream_readable.js:743:26)
    at resume_ (_stream_readable.js:723:3)
    at doNTCallback2 (node.js:441:9)
    at process._tickCallback (node.js:355:17)

You could try and fix nvm on FreeBSD, but who has time for that when you’d like to have your blog up and running?

Not me. Luckily FreeBSD has node4 package:

# pkg install node4

This will install node version 4. It will also remove node and npm.

Downgrading NPM

Now we need npm, but the one you get with pkg install only supports latest node version. Can’t pkg install one that supports node4.

To support node4 backend, we’ll need to use the good ol’ FreeBSD ports system. First upgrade the ports tree:

portsnap fetch
portsnap extract

Now we’re ready to install npm with specific node backend

$ cd /usr/ports/www/npm
$ make                                                                                                                                                                      
┌─────────────────────────────── npm-2.14.7_2 ─────────────────────────────────┐
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │+( ) NODE        Use www/node as backend                                  │ │
│ │+( ) NODE_DEVEL  Use www/node-devel as backend                            │ │
│ │+( ) NODE010     Use www/node010 as backend                               │ │
│ │+( ) NODE012     Use www/node012 as backend                               │ │
│ │+(*) NODE4       Use www/node4 as backend                                 │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│                       <  OK  >            <Cancel>                           │

When the build has finished install it on your system by typing (with sudo or as root):

# make install

And now you should be able to run npm install in ghost dir:

$ npm install

> ghost@0.7.8 preinstall /www_absurdtech
> npm install semver && node -e "require('./core/server/utils/startup-check.js').nodeVersion()"

semver@5.1.0 node_modules/semver

Killed?! I suspect it had to do with my ec2 micro instance so I added a gig of swap space on the box.

In case you got your npm didn’t get killed, you can skip over the next section.

Fix the Killed npm

# dd if=/dev/zero of=/usr/swap0 bs=1m count=64
# chmod 0600 /usr/swap0

Then add to /etc/fstab:

md99	none	swap	sw,file=/usr/swap0	0	0

After that turn on the swap and confirm with swapinfo:

# swapon -aL
swapon: adding /dev/md99 as swap device

# swapinfo
Device          1K-blocks     Used    Avail Capacity
/dev/md99         1048576        0  1048576     0%

Now retry the npm install. If it finishes without errors, great. Mine did.

Start Ghost

As usually in dev or production mode depending on your situation.

npm start [--production]

Next you’ll need to configure a webserver like nginx, set up caching, and maybe configure content to be served from a CDN.

These are all great topics for a blog post, and maybe I’ll write about them later, but right now we’ve at least done a very basic developer installation of Ghost on a FreeBSD box.

That’s all for now!