This blog is running my fork of Ghost. I decided to use Ghost for this blog because datememe is also written in nodejs so I've got some experience with it.
While Ghost is missing some basic features like scheduling posts, commenting and proper SSL support this functionality shouldn't be too hard to add myself. I really like the markdown editor and the code is pretty nice to work with so lets get started.
Getting Ghost to work for me
I already had a nodejs app running on my root domain so I wanted to run Ghost using the same runtime and in the directory blog from my root domain. There were a few issues I needed to work out to get ghost working for me:
production install from git
setup in a directory
using unix domain sockets
let's encrypt ssl all the things
add commenting
setup with upstart
same runtime as datememe
use Bugsnag for error reporting
Installing Ghost from git
Here are the steps i used to install ghost on my production box from git.
git clone https://github.com/radiofrequency/Ghost /var/www/dm_blog
cd /var/www/dm_blog
npm install -g grunt-cli
I'm using Node 5.5 in my production environment so i needed to make some changes to package.json to get everything working correctly. Just change engines to include your Node version.
engines: {
node: "~0.10.0 || ~0.12.0 || ^4.2.0 || ^5.5.0"
}
In my environment NODE_ENV=production so i needed:
npm install --dev
Now you can run finish the install
grunt init
grunt prod
cp config.example.js config.js
Your blog is ready to be started once you edit the config.js file with your url etc.
Install in a directory
You don't want your blog on a subdomain. Throwing it in a directory will increase your search rankings. Here is the config required for nginx to load your ghost blog in a directory:
location ^~ /blog {
proxy_read_timeout 600s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-forwarded-for $remote_addr;
proxy_set_header X-Queue-Start "t=${msec}000";
proxy_set_header X-NginX_Proxy true;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://dm_blog;
proxy_redirect off;
}
Unix Domain Sockets
I like to always run nodejs apps using domain sockets rather than binding to ports as unix domain sockets are much faster and less risky from a security standpoint. Here is the relevant nginx config that defines the upstream to the ghost domain socket:
upstream dm_blog {
server unix:/var/run/dm_blog.sock;
}
Modify your config.js and change:
server: {
socket: '/var/run/dm_blog.sock'
}
Your ghost blog is configured to listen on a domain socket.
Commenting
While building out my own commenting would be trivial lots of sites use Disqus and it looks good with the default ghost theme so I just added that using the installation instructions for ghost here.
Upstart Script
I run ubuntu on VPS Dime and it uses upstart scripts found in /etc/init. Here is the upstart script i use for my blog.
description "dm blog"
start on started redis
stop on shutdown
expect fork
setuid www
env NODE_ENV="production"
env SPIN_SLEEP_TIME="60000"
chdir /var/www/dm_blog
script
exec /var/www/dm_blog/node_modules/forever/bin/forever start --spinSleepTime 30000 --pidFile /var/run/dm-blog.pid -l /var/log/dm-blog.log -a -d /var/www/dm_blog/index.js
end script
Save this file as /etc/init/dm_blog.conf.
You will need to add forever for this to work:
npm install forever --save
Now you can start your blog with:
sudo start dm_blog
When your VPS reboots it will wait for redis to start then start your blog.
SSL
Really there is little excuse for not using SSL, it's free and easy to provide basic encryption protecting your users from malicious service providers or governments that would like to change your content before its delivered to the client.
Let's Encrypt
Setting up SSL is so easy with Let's Encrypt. I followed this tutorial to auto regenerate certificates every 60 days and configure nginx to use them.
Nginx
To force my sites to use ssl I use nginx to redirect any http traffic to https with a directive like this:
server {
listen 80;
server_name datememe.com www.datememe.com;
return 301 https://$server_name$request_uri;
}
Ghost
The setup for SSL on Ghost is weird. If you set your url in config.js to use https it puts the blog in a redirect loop. After digging through the code i found you are supposed to specify urlSSL in your config like so:
url: 'http://www.datememe.com/blog',
urlSSL: 'https://www.datememe.com/blog',
This will allow the software to work but Ghost will still use the http url for meta tags like canonical url etc. To fix that you need to modify the code in:
core/server/data/meta/canonical_url.js
Just change:
return config.urlJoin(config.getBaseUrl(false),
getUrl(data, false));
to:
return config.urlJoin(config.getBaseUrl(true),
getUrl(data, false));
Passing true to getBaseURL will return the https url instead of the http url.
Now when your articles are shared you will not have a costly redirect from http to https slowing your blog load time.
Bugsnag
What good is your blog if it doesn't work? I need to install bugsnag on the client and server to make sure stuff is working and to be notified if any unhandled exceptions happen. So here are the steps to set it up on the client and server.
Client Side
If your new to Ghost you might not have a clue where to add the bugsnag code to the ghost project to get it to work. You want to add your bugsnag cdn script to the head:
The file you want to modify is:
content/templates/casper/default.hbs
Add your bugsnag cdn script tag:
<script
src="//d2wy8f7a9ursnm.cloudfront.net/bugsnag-2.min.js"
data-apikey="YOURAPIKEY">
</script>
Before {{ghost_head}} around Line 21.
Server Side
First you'll need to install the bugsnag module.
npm install bugsnag --save
Now you'll need to modify some code:
core/server/index.js
To the very top of the file add the line:
var bugsnag = require("bugsnag");
In the init function on Line 63 add the following:
bugsnag.register("YOURAPIKEY", {
releaseStage: process.env,
notifyReleaseStages: ["production"]
});
Restart your blog:
sudo restart dm_blog
Build your Blog
I hope these tips help you out when setting up your blog. If you haven't decided on a host for your blog I recommend VPS Dime. A VPS with 6GB of ram for 7$ a month is more than enough to host your Ghost blog and handle lots of traffic. This setup is also easy to move to Amazon or Google if you want to use auto scaling.
Up Next
I'm still not finished with modifying my ghost blog. A few issues i'd like to tackle in future blog posts are:
Scheduling Posts
Accelerated Mobile Pages
Better Structured Data
Address bugs found by Bugsnag
Develop a plugin
Theme creation
If your struggling with something on your own Ghost blog let me know in the comments and maybe i can help.