Ghost and Node.js on Windows IIS
Ghost is a simple, powerful publishing platform, developed in Node.js. Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
After reading about installing and running node.js applications within IIS on Windows, I wanted to run Ghost on IIS. Tomasz Janczuk developed the iisnode module for IIS to run node.js on IIS, so this should work for Ghost too... Guess we need to install iisnode in IIS then :)
Getting and installing Node.js, iisnode and Ghost on IIS - step 1
First you need all the software:
- Grab a copy of
node-v0.10.26.x86.msi
(node-v0.10.26.x64.msi
) - Grab a copy of
iisnode-full-iis7-v0.2.7-x86.msi
(iisnode-full-iis7-v0.2.7-x64.msi
- choose the right flavor for your architecture - Grab a copy of
ghost-0.4.1.zip
from https://ghost.org - Install the software on your IIS web server and verify iisnode is registered as a module.
- Unzip
ghost-0.4.1.zip
and place it in your webroot. Ghost cannot be installed in a subdirectory called 'ghost', be aware of that.
Set 2 - Set up and configure iisnode and Ghost Rewrites
Create a web.config
file to configure iisnode. It needs to contain a handler for iisnode:
<handlers>
<add name="iisnode"
path="index.js"
verb="*"
modules="iisnode"
/>
</handlers>
Add an URL Rewrite Module Rewrite directive for Ghost in your web.config:
<rewrite>
<rules>
<rule name="Ghost">
<match url="/*" />
<conditions>
<add input="{PATH_INFO}" pattern=".+\.js\/debug\/?" negate="true" />
</conditions>
<action type="Rewrite" url="index.js" />
</rule>
</rules>
</rewrite>
In the web.config file, you need to configure iisnode too:
<iisnode node_env="%node_env%"
loggingEnabled="true"
debuggingEnabled="true"
devErrorsEnabled="true"
nodeProcessCommandLine="c:\path\to\node.exe"
/>
Depending on your web server security and configuration, you might need to add or tweak NTFS file permissions. The node.exe
process needs some read permissions starting from the partition drive (C:, D:, or E: for example).
Set up and configure Ghost - step 3
Important: you need to configure Ghost locally on your development machine.
- copy config.example.js to config.js
- edit your Production environment:
url: 'http://www.example.com'
host: 'http://www.example.com'
port: process.env.PORT // this one is important!
- edit
core\index.js
for production:
// process.env.NODE_ENV = process.env.NODE_ENV || 'development';
process.env.NODE_ENV = process.env.NODE_ENV || 'production';
- make sure files and folders are writeable
- install necessary node.js modules for production, run from within your Ghost directory:
npm install --production
- dry run, run the following command from within your Ghost directory:
node.exe index.js
, and fix any errors that may occure.
Now everything should run fine when you upload Ghost to your webroot. The logfiles iisnode creates are placed in $webroot/iisnode/*.txt
Troubleshooting Node.js-, iisnode- and Ghost errors
Incorrect configured file permissions: How to fix Application has thrown an uncaught exception and is terminated
:
As stated earlier in this article, the nodejs.exe
process requires read permissions starting from the partition drive for the IUSR user, or group under which the web site and application runs. The special permission needed are Traverse folder / execute file, List folder / read data, Read attributes. This may be a security concern. If file permissions are set up wrong, you can expect the following exception:
Application has thrown an uncaught exception and is terminated:
Error: EPERM, operation not permitted 'd:\'
at Object.fs.lstatSync (fs.js:679:18)
at start (fs.js:1240:10)
at Object.realpathSync (fs.js:1228:3)
at tryFile (module.js:142:15)
at Function.Module._findPath (module.js:181:18)
at Function.Module._resolveFilename (module.js:336:25)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (C:\Program Files (x86)\iisnode\interceptor.js:210:1)
Correcting the file permissions resolves this error.
Node.js Hello World example
A small hello world node.js application comes in handy to debug node.js or iisnode configuration issues. Here's one:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello, world!');
}).listen(process.env.PORT);
console.log("Node.js running!");
Important to note is the .listen(process.env.PORT)
line: Using iisnode, you cannot let your node.js app listen to other TCP-ports than the default HTTP and HTTPS ports; 80 and 443.
Errors during WordPress JSON import into Ghost
WordPress export to Ghost: errors will happen.
Are you trying to import WordPress content into Ghost and that's giving you a hard time? See my post how to import posts from WordPress in Ghost for a solution to the HTTP 500 Internal Server error:
A problem was encountered while importing new content to your blog. Error: unknown
Protip: One thing you must not forget is that IIS acts as a reverse proxy, utilizing the iisnode module, for Node.js web applications like Ghost. You may find out the "hard" way, for example when you get too many redirect errors after setting up an SSL certificate.