Scott Hanselman

How to install the nodejs Ghost blogging software on Azure Websites

October 24, '13 Comments [26] Posted in Azure | nodejs | Open Source
Sponsored By
The Ghost Admin running in Azure

UPDATE - These instructions are out of date!

GO HERE for a one-click installation of Ghost to Azure technique.

Like many folks, I watched the recent Kickstarter for the nodejs-based Ghost Blogging Platform with great interest. There are lots of folks, myself included, who believe that WordPress has jumped from blog to complete and complex CMS, and there's value in a simple platform for "just blogging."

SIDE NOTE: Every time a post something I get at least 4 emails from well-meaning readers about how my spelling and grammar sucks. And I appreciate you all. For a few posts, I'm trying an online service called Grammarly that promises to be 10x better than word processors in proofreading. 10x is like 9 x's more than 1 x and it's clearly a much more bigger number. We shall be seeing how it do. ;)
(Of course, Grammarly HATED this paragraph.)

Ghost is very minimal, evocative of Medium in style and essence. Ghost is basic and clean publishing, plus it's open source and being very actively developed on GitHub. As of the time of this writing, it's version 0.3.3, and I will do my best to keep this blog post up to date. Things are moving fast.

It'd be nice to get Ghost running on Azure, and since it's a reasonably complex node application, it's good exercise for everyone. Jeremiah Billmann and a number of others have been working on some of the small compatibility issues (like image uploads and pathing), and soon we'll be able to get Ghost up and running in just a few commands. Jeremiah has a great writeup here. He and I spent part of the afternoon Skyping and pairing and trying alternate ways to get Ghost running. My instructions are different and not meant to take away from his. There's more than one way to deploy a site.

I'll point out workarounds, and again, remove them (strike them out) as Ghost takes PRs. (BTW, the Ghost Team is SO NICE. So nice.)

Installing Ghost on Azure Web Sites

I'm using Windows, but these commands should also work on Macs.

IMPORTANT CHOICE: You can just go download Ghost at https://ghost.org/download/ and everything comes pre-built.
If you download it, you can SKIP getting Grunt, Ruby, Sass, below. Just get node, and move to the Configuring Ghost before you Deploy section further down!
Otherwise, if you "git clone" like I did, you're doing stuff manually, certainly more than is needed, but perhaps learning more about node.
So, want it prebuilt and ready to go? Download Ghost.
Learning, hacking? git clone https://github.com/TryGhost/Ghost.git.

Prerequisites

To start, you'll want these things locally:

  • nodejs - Get 0.10 or above. Install from http://nodejs.org
    • Then get the node Azure command line
      • npm install azure-cli --g
  • Git - Get it from http://git-scm.com/downloads
  • Get Grunt
    • npm install grunt-cli --g
  • ruby - Get 2.0 or above. Install from https://www.ruby-lang.org
  • Bourbon and Sass. Bourbon brings in Sass.
    • gem install bourbon
  • Get an Azure Trial if you don't have one.
    • You get 10 websites free and can run whatever you want, node, php, ASP.NET, etc.

Setup the Azure Command Line

Connect the Azure CLI (command line interface) to your account like this:

  • azure account download
    • launches browser, sign in, get cert
  • azure account  import
  • [optional] azure account set "account name"

Getting Ghost

You can either download Ghost prebuilt or get the source and build it. Here's both ways. The Source is harder, but I learned some things.

Getting Ghost from Download

Download Ghost and unzip it into a folder.

> azure site create [Site Name] --location "West US" --git
# note that this line setups the "git remote add..." and you can confirm with "git remote show"
> azure site config add NODE_ENV=production
# sets an env var for node, up in azure
> npm install
# get all the modules locally, only needed if you are running locally
> copy con server.js
var GhostServer = require('./index');
CTRL-Z, ENTER
# Ghost uses index.js, not server.js. Make a server.js.

Now, skip over this to the Configuring section. The --git switch above set up your remote git repo in Azure.

Getting Ghost from Source

Now, run these commands from the command line. Read carefully, and think. You can change Site Name, Location. You can confirm the git remote. Things with # are my comments, don't type them. Note the copy con. Don't like it? Use a text editor.

> git clone https://github.com/TryGhost/Ghost.git
> azure site create [Site Name] --location "West US" --git
# note that this line setups the "git remote add..." and you can confirm with "git remote show"
> azure site config add NODE_ENV=production
# sets an env var for node, up in azure
> npm install
# get all the modules locally
> grunt init
> grunt prod
#preps your CSS and JS
> copy con server.js
var GhostServer = require('./index');
CTRL-Z, ENTER
# Ghost uses index.js, not server.js. Make a server.js.

At this point, you have a site running in Azure with nothing in it.

You currently have a local Git repo with a Git Remote pointing to Azure.

Configuring Ghost before you Deploy

Your cloned Ghost includes a config.example.js. I renamed it to config.js and made a few changes.

production: {
url: 'http://YOURSITE.azurewebsites.net/',
mail: {
transport: 'SMTP',
options: {
auth: {
user: 'poop',
pass: 'alsopoop'
}
}
},
database: {
client: 'sqlite3',
connection: {
filename: path.join(__dirname, '/content/data/ghost.db')
},
debug: false
},
server: {
host: '127.0.0.1',
port: process.env.PORT
}
}

Go to the production section, check your URL, your user/pass for mail (mine is invalid, I'll do it later), and check the port: section. Make it "process.env.PORT" which is what Azure uses to get the Port number.

Now open your .gitignore, comment out these lines. enabling you to check in these files and directories.

# /core/client/assets/css
# /core/built
# /core/client/assets/fonts
# config.js

When you ran grunt prod earlier, it built files into /core/built, that's why we need that checked in.

NOTE: Of course, we are using Git for deployment. If you don't want to use Git, you can just FTP the files into Azure.

Deploy

Now, add, commit, push.

> git add .
> git commit -m "hope this works"
> git push azure master

Azure (specifically the Kudu subsystem) will run npm install, so this deployment may take a while. You can watch it live in the Azure Portal if you like.

There's my deployment in the Azure Portal

You can also look at deployments from the command line:

C:\Ghost>azure site deployment list hanselmanghost
info: Executing command site deployment list
+ Getting deployments
data: Time Commit id Status Author Message
data: ------------------- ---------- ------ --------------- ----------------
data: 2013-10-23 15:59:38 783746f6a1 Active Scott Hanselman adding server.js
info: site deployment list command OK

OK. It's deployed...except, today...there's a bug.

The Big Hack as of October 23rd...THIS HAS BEEN CLOSED AND MERGED!

Here's the hack/workaround. There's a node module called Express-HBS that is a handlebars template engine that supports partials. It has a caching bug, but there's been a Pull Request opened for express-hbs with the fix. As soon as that fix gets merged in, this whole workaround just goes away.

But, for now, you need to patch the express-hbs/lib/hbs.js with this version (link to RAW file)

How do you patch this in Azure? You can either FTP it, or use this super-secret Azure Kudu DebugConsole that is public but no one has noticed it yet.

Visit https://YOURSITEHERE.scm.azurewebsites.net/DebugConsole/ in your browser. The name and password are the same as your Git Deployment name and password.

Kudu DebugConsole

Navigate to site/wwwroot/node_modules/express-hbs/lib by clicking folders. Click the Edit button, which brings you to a live multiline textbox. Copy paste the patched hbs.js into the textbox, and click Save.

Once you've patched hbs.js, you're all good. Go hit http://YOURSITE.azurewebsites.net/ghost and sign in.

My ghost blog works

Where are the images for my posts stored? They are right there on the file system where Ghost put them. Here's me remoted into the Azure WebSite with the Kudu Debug Console. There's the images.

Images in Ghost in the Azure Kudu Debug Console

You might not want to scale this website out to more than once instance, as you'll have file contention, but you could certainly scale it up. Since it does so little, I don't see Ghost having much trouble scaling to the average blog's traffic.

Myself, Jeremiah, and lots of other folks are going to work on getting Ghost up and running even easier. Once that hack is gone, there's about 2 or 3 steps could be removed and this will be really quite streamlined. I've got some ideas about using Custom Azure Websites Deployment Scripts to move the Grunt build steps into Azure. They would happen after the push. We'll see!

Have fun, I am! Also, check out http://friday.azure.com, my new show where I learn Azure from the folks that built it...coming soon!

UPDATE: Felix Rieseberg built an Azure Ghost Updater! Try using it to update your Ghost installations on Azure!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Make a Windows 8.1 Pinned Live Tile for YOUR website in minutes

October 21, '13 Comments [34] Posted in Win8
Sponsored By

imageI actually set this up on my site a few months back when Windows 8.1 preview showed up, but I didn't mention it. If you've got Windows 8.1, you've likely figured out that the most fun apps are ones that have active live tiles.

I'm a web guy and I like web sites, though. Certainly there's no reason or need for a "Hanselman" app anymore than there's a need for an app for, say, The Verge.com. We have perfectly lovely sites today and work just fine. We also have RSS feeds that contain our content and let folks know when a site has been updated.

You can add some HTML META markup to your site now and have a multi-size automatically updating Live Tile for Windows 8.1 in minutes. It's very cool.

Pin a Site to your Windows 8.1 Start Screen

  • Open Full Screen IE (that's the big blue IE from the Start Screen, not the one on your Desktop).
  • Visit the site you want to pin, like http://hanselman.com/blog.
  • Click the Star to Favorite the site, then the Pin to Pin it as a Live Tile
    • Before you finally pin the site, you can click the arrows left or right to pick the size of the Tile.
    • You can change the size whenever from your Start Screen by right clicking the Tile and clicking Resize.

Don't worry about my creepy eyes staring at you. My RSS feed will start coming in soon and the Live Tile will flip over.

Get a Large Live Tile for Your Site

The easiest way to make one of these is to visit http://buildmypinnedsite.com as they have a wizard that helps you make four file sizes and setup notifications from your RSS feed, as well as pick the background color for your Tile.

ASIDE: Back when IE9 came out, I added Site Pinning support to my site in a similar way. You can still do that for your Windows Taskbar, in fact, and get a nice right-click context menu with lots of quick access to my site, archives and podcasts. View Source or visit the link there for details.

There's a very detailed API on MSDN if you'd like to understand all the little details of Pinned SItes with IE9, 10 and 11. It's literally minutes of work on the low end, and maybe an hour if you go nuts with JavaScript.

You can put all your META tags in the HEAD and just have a pile of them if you want, which is fine:







More on that crazy notification one in a second.

Or, if you want a tidy META area, just move this stuff into a static XML file:



And that file, is predictably similar. Again, it's not needed, but you can either put the stuff in META tags, or in a file.









#83382b



360
1


Now, let's look at those notifications. The service above is speeding things up by making the little Tile Notifications XML file for me. This is similar to Facebook's open graph stuff or Twitter Cards, where you want an image (if available) plus the title of a post to show up as a "card" or in this case, a Tile.

ASIDE: You can do similar type things in other browsers with nice custom PNGs and Icons, like Opera's Speed Dial, or iPhone Home Screen icons. I've done all those for my site. There's a lot, but it's minutes each and then it's done.

You get some amount of control as to text and images that can appear in your live tile if you make the notification yourself. The BuildMyPinnedSite service, as you can see in the URL above, takes your RSS feed and makes it WAY smaller (mine is too large to poll, for example) and pulls out prominent images. I set my Frequency at a few hours, since I'm a blog, not a news site. No need to poll me every 30 minutes!

Here's a Wide title generated by a recent post:

image

Or a Large tile:

image

The site will generate those, but if you're a really high-traffic site you might just write a little handler to make these Notification Tile Files from your RSS feed.




CollectionViewSource is crazy useful for binding to filtered Observable Collections on Windows Phone 8



CollectionViewSource is crazy useful for binding to filtered Observable Collections on Windows Phone 8


CollectionViewSource is crazy useful for binding to filtered Observable Collections on Windows Phone 8
SCREENCASTS: What's New in Visual Studio 2013 - learn over lunch!
IE10 and IE11 and Windows 8.1 and __doPostBack


I wonder how hard it would be to write a WordPress, Drupal, Ghost, or MiniBlog plugin to make these notification files? Not hard I think.

UPDATE: Looks like Nick Halsey has already crated a Windows Pinned Sites Plugin for WordPress. Nice job, Nick!

UPDATE: Drupal has Pinned Sites also!

I'm looking forward to seeing tiles like this for sites I visit like LifeHacker, The Verge, CNN, etc. I'll be more likely to pin a site to the home screen if it also shows me updated headlines.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

CollectionViewSource is crazy useful for binding to filtered Observable Collections on Windows Phone 8

October 21, '13 Comments [8] Posted in WinPhone
Sponsored By

I've been working on this Windows Phone 8 app on the side (it's a news app, but mark my words, it's gonna be huge). 

For the initial development I've been binding to a Pivot to a basic ObservableCollection of type "FeedItem," so basically my XAML was like this.

Really, the only thing you care about here is that FIRST line...ItemsSource=""

<phone:Pivot Title="MAGICAL FREAKING NEWS" x:Name="MainPivot" 
ItemsSource="{Binding Path=NewsData.Feeds}" >
<phone:Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=key}"/>
</DataTemplate>
</phone:Pivot.HeaderTemplate>

<phone:Pivot.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock Text="{Binding Path=title}" Style="{StaticResource PhoneTextTitle2Style}" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding Path=updated_at, StringFormat=F}" HorizontalAlignment="Center" TextWrapping="Wrap" />
<Button x:Name="PlayButton" Margin="0,40,0,0" HorizontalAlignment="Center" Style="{StaticResource PlayStyle}" Click="Play_Click">
<Button.RenderTransform>
<!-- Changes to .5 when in Landscape -->
<ScaleTransform x:Name="OrientationScale" ScaleX="1" ScaleY="1" CenterX="60" CenterY="0"/>
</Button.RenderTransform>
</Button>
</StackPanel>

...snip...you get the idea.

As an aside, I really like the idea of Design Time Data, meaning that I can layout my page in Visual Studio and it will actually LOOK like my app using static data that happens at Design Time. For this, I just add this at the PhoneApplicationPage level:

 d:DataContext="{d:DesignData Content/NewsDataSample.xaml}"

And that sample XAML file just looks like a "XAML-shaped" version of my Object Model, which is actually fed by JSON at runtime:

<vm:AppViewModel
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:toawesometolive_portable.Data;assembly=icantstandit-portable"
    OperationInProgress="True"
    >
    <vm:AppViewModel.NewsData Force="False">
        <vm:NewsData>
            <vm:NewsData.Feeds>
                <vm:Feed id="0" key="NPR" subtitle="National Public Radio"
...snip...

Fast forward some and requirements changed. Now I needed to be able to individually enable and disable new sources, as well as reorder sources on the fly.

image

That means, if a source is not enabled, it shouldn't be in the first page's pivot. The Sources page and the Main Pivot both bind to the same ObservableCollection, except I need a filter of some kind of the Pivot for "where enabled == true."

I tried lots of stuff things like other sub-collections, properties that returned filtered collections, IQueryable this and that, then discovered the (not really well documented) CollectionViewSource.

Turns out, though, that WPF folks have been using this for YEARS. Here's Beth Massi talking about CollectionViewSource in 2008, for crying out loud (as I discover it a half-decade later on the phone.)

You can have more than one CollectionViewSource on your page. You can use them with Master/Detail forms, for Pathing and for Filtering, which is what I'm interested in. It's also nice because any controls that you bind to the same CollectionViewSource will always have the same current item.

I put one in my Phone Page's Resources like this:

<phone:PhoneApplicationPage.Resources>
    <CollectionViewSource x:Key="src" Source="{Binding Path=NewsData.Feeds}"/>
</phone:PhoneApplicationPage.Resources>

Later, my Pivot binds to the CollectionViewSource by name:

ItemsSource="{Binding Source={StaticResource src}}"

I know folks love to do EVERYTHING in their XAML, but that's not how I roll. (Nor do I have any idea what I'm doing.)

In my page's code behind I set a filter:

collectionView.Source = App.ViewModel.NewsData.Feeds;
collectionView.View.Filter = item =>
{
Feed f = item as Feed;
if (f == null) return false;
if (!f.enabled) return false;
return true;
};

That's it. Now I can enable and disable my items in my source view and the Pivot updates nicely only showing those news sources that are enabled.

Ideally I would have been able to express this somehow in XAML with some kind of where clause as an attribute, but once I figured this solution out it worked famously. I suspect there's actually a LOT of depth to CollectionViewSource and I may end up using it in other parts of my app.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

SCREENCASTS: What's New in Visual Studio 2013 - learn over lunch!

October 21, '13 Comments [65] Posted in ASP.NET | Screencasts | VS2013
Sponsored By

I could write a whole epic post about what's new in VS2013 for Web folks and front-end developers, but this time instead I did some videos. I'm proud of them and I think they really show some of the cool new features in a very clear way.

These are short, clear and to the point. I did them on my own and there's no marketing-speak, just "here's what we built." Here's the full release notes for ASP.NET and Web Tools for you to check out if you really like reading.

Otherwise, take about 30 minutes total, perhaps over lunch, and watch these short videos with live demos of what's new in Visual Studio for Web Developers and Front End Devs.

HTML5 in VS2013

CSS in VS2013

BrowserLink in VS2013

Page Inspector in VS2013

JavaScript in VS2013

Publishing in VS2013

If you've been paying attention over the last year, you may have seen some of these features. I realize that these may not ALL feel like "amazing new surprises." That's the price for being open, eh? If you'd prefer we hide out for a year and make stuff then appear and DROP it on you, let me now. Otherwise, we're sticking with a more Open Web.

Hope you enjoy the tools and the direction.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

IE10 and IE11 and Windows 8.1 and __doPostBack

October 19, '13 Comments [50] Posted in ASP.NET | Blogging
Sponsored By

A while back there was a bug in the old browser definition files that shipped with .NET 2 and .NET 4. Fast forward to today and these older ASP.NET’s will mis-detect IE10 and IE11. If you have this, you'll see __doPostBack JavaScript errors in your sites when IE10 or IE11 hit them.

However, I'm still getting email from folks who are seeing this, which means they've got very unpatched installations.

Aside: If you don't have this two year old patch, be sure to check out what other updates your server is missing. Again, rollups like .NET 4.5 and "hotfix rollups" get you the latest in one swoop.

Here’s all the internal details for this fix across every combo of framework and OS if you can’t get .NET 4.5. You may want to run "aspnet_regbrowsers -i" after installing the fix if you're having trouble.

  • 2836939 .NET 4 - Win7SP1/Win2K3SP2/Win2K8R2SP1/Win2K8SP2/VistaSP2/WinXPSP3
  • 2836940 .NET 3.5 SP1 - Win2K3SP2/Win2K8SP2/VistaSP2/WinXPSP3
  • 2836941 .NET 2.0 SP2 - Win2K3SP2/WinXPSP3
  • 2836942 .NET 3.5 SP1 - Win7SP1/Win2K8R2SP1
  • 2836943 .NET 2.0 SP2 - Win7SP1/Win2K8R2SP1
  • 2836945 .NET 2.0 SP2 - Win2K8SP2/VistaSP2
  • 2836946 .NET 2.0 SP2 - Win8RTM/WinRTRTM/Win2K12RTM
  • 2836947 .NET 3.5 SP1 - Win8RTM/WinRTRTM/Win2K12RTM

You really shouldn’t be "sniffing" browsers, you should check for the existence of features in your browser. There have been a number "mobile browser" files, including one I used 4 years ago.

If you are using a custom browser definition file (and perhaps forgotten about it) you may STILL see a problem with IE10 or IE11 because you've got your own overriding custom browser sniffing regexes in there. Either remove the need for a browser definition file (ideal) or open up your custom file and remote the IE portion.

TL;DR Version

  • DO - Keep your Web Servers patched.
  • DO - Upgrade to ASP.NET 4.5 if you can.
  • DON'T - Use old Custom Browser Definition Files from years ago and expect them to work

Hope this helps.


Sponsor: Thanks to Red Gate for sponsoring the feed this week! Check out a simpler way to deploy with Red Gate’s Deployment Manager. It can deploy your .NET apps, services, and databases in a single, repeatable process. Get your free Starter edition now.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.