Part 3 in starting with Hexo: how to deploy to an IIS server for hosting
For all posts in the series, check the Hexo-Bootstrap-Series tag.
As Hexo is entirely static content, hosting is streight forward. There are no special server requirements to worry about.
I’m hosting on IIS because that’s what I am used to and what I have available. But any other web server will work just as well. There may have been significant differences hosting static content between Apache, IIS, nginX and others back in the 90s, but those days are long gone.
First thing we need is a place to store the generated files.
Create a folder to store your public Hexo files:
blog.ligos.net. I name my folders based on the domain of the site they host.
Set permissions on your folder. I only give IIS (via the
IIS_IUSRS group) read permission, to reduce the impact of any security breach. But also gave ordinary users write access, so I can maintain the site.
Share the folder so I can update the site. This was via an SMB share on the
inetpub folder, but on Linux would probably be via ssh / sftp / scp.
Next part is to configure IIS to serve requests.
Create an IIS app pool. I already had one for static content, so I used it, but otherwise I name them the same as the domain its hosting. I’ve got a few more details on app pools below.
Then create a new web site.
I name my sites based on their domain. Make sure you choose the app pool you just created. And the folder. Finally, add an HTTP binding.
If you’re not familiar with app pools, they determine a bunch of low level settings for your site
IIS hosts websites in a process called
w3wp.exe (or www worker process), and your app pool drives some key attributes of that process.
Things like what user does the website run as (the w3wp.exe process runs as that user), or what bit-ness the process is (32 or 64).
Putting different websites in different app pools will isolate them from one another.
There are also a bunch of IIS specific settings like when an app pool is recycled, what happens when its idle.
A couple of useful changes to app pool defaults:
- Enable 32-bit applications:
true- causes the hosting process to be 32 bit, which keeps memory usage down (and you really don’t need more than 2GB of RAM to serve static content).
- Start Mode:
AlwaysRunning- starts the hosting process when IIS starts, which makes things a bit faster for your first visitor.
- Idle Timeout:
60 min- time before IIS says the site is idle and kills it.
- Idle Timeout Action:
Suspend- pages the IIS process to disk on idle, which is faster than killing the process (only on IIS 8.5 and higher).
- Recycling Regular Time Interval:
10000- static content processes shouldn’t need to be recycled, so make this number large.
- Recycling Specific Times:
none- again, static content processes shouldn’t need to be recycled.
Setting ACLs on your folders based on an
ApplicationPoolIdentity is a bit tricky, ServerFault has a helpful answer.
Now we have a site ready to go, but no files.
Hexo makes this process very easy.
We previously used
hexo generate to create all the files needed in the
Now all we need is to copy that content to the folder we created.
With a simple batch file, I’m generating then using robocopy to mirror the
public folder to my
blog.ligos.net folder on my server.
Note that on Windows, you need to use the
call command to run Hexo, as hexo is actually a batch file on Windows.
Yet another quirk of scripting on Windows (sigh).
You need to tell the internet that your blog’s domain name points to an IP address before it will work.
This will vary between DNS hosting providers, but you’ll either need to create an A record (which says blog.ligos.net points to my IP address; I also have a AAAA record which does the same for IPv6), or a CNAME record (which says blog.ligos.net points to some.server.ligos.net).
I went for the CNAME option, because I have several domains all on the one server.
If you don’t have a DNS provider (or you’re sick of your current one) I’ll recommend DNSimple as a simple, hassle free, reasonably priced DNS provider.
At this point, everything should be working. You can point your web browser to your domain name and you should see your site!
At this point, we’re almost finished.
Next step is to serve the site over HTTPS. You’ll need an appropriate certificate before you can do this. I’m using StartSSL, which will issue free SSL certificates for domains using email based validation.
Once you have your certificate installed on your server, you add another binding to your site. I’m using SNI so I can host multiple HTTPS based sites behind my one IP address.
Note that you need to be on IIS 8.5 or newer to use SNI (Windows 8.1 / Server 2012 R2).
Once saved, you can browse to your HTTPS site and get a nice padlock.
And, even better than that, because I’m on Windows 10 and IIS 10, I get HTTP/2 support. Yay for being on the cutting edge!
I want the site to be secure and encrypted by default, so we need to add a redirect from HTTP -> HTTPS. You can do this in the IIS configuration, but the GUI isn’t great. So I prefer to drop a web.config in.
web.config becomes part of my Hexo content, in the
As far as Hexo is concerned, its just a file to publish.
But IIS picks it up and issues an appropriate 301 permanent redirect whenever someone visits the site via unencrypted HTTP.
You also need to install the IIS URL Rewrite Module before this will work.
The Hueman theme had a reference to load jQuery using HTTP, which browsers refused to load from my shiny HTTPS site. Basically, if you have a secure site, everything needs to be loaded via the secure HTTPS url scheme. If you generated code using PHP or ASP or whatever, you could dynamiclly generate the scheme. But there’s a better way, which works entirely in the browser:
- This only works on unencrypted sites (HTTP):
- This only works on secure sites (HTTPS):
- This works on either, which I what I want:
Now the site was public, I registered it with Google and Bing’s webmin tools. They need you to add a magic file to prove you really own the site (otherwise you could just claim you owned Google itself and muck with things).
Bing gives you an XML file, which I added to the
source folder and deployed without problem.
Google gives you an HTML file, which I added to the
source folder and deployed.
Only, when I published my site, I found that Hexo thought the site auth file was content, and wrapped it in the usual header, sidebar and footer.
Needless to say, Google webmin wasn’t impressed.
I needed to explicitly tell Hexo not to render Google’s magic file:
OK, I’d actually noticed this much earlier in the process.
I’d test my site using the local
hexo server command.
And images wouldn’t load.
After much checking of HTML source, it turns out that Hexo’s internal web server is case sensitive.
My-Image.PNG are treated as different things.
IIS (and pretty much every other web server I’m aware of) is case insensitive, so all three images would mean the same thing.
So now, all my snipping tool generated images need to have their all caps PNG changed to lower case
Serving static content isn’t hard. So hosting Hexo is nice and easy too. And once I’ve worked through a few gotchas, all was working well.
Next time: how authoring works in Hexo