Shortly after I first got my own domain I decided to run all the services myself. It was a good experience but eventually got old, so I’ve been migrating everything to hosted services. Free hosted services if possible.
DNS went first. When I first registered my domain the registrar would only register my nameservers, which I then had to manage. But now they (and apparently all registrars) will manage my nameservers for me through a simple web dashboard. Step one was done and it was free as part of my domain registration.
Next came e-mail. Before I ran my own mail servers I had a mail hosting provider, which cost $25 per month back then. But now I can get mail hosting for free from Google Apps. It’s easy to use and works great. If you don’t have your own domain name, you can also register one through them for just $10 per year.
I’d been running my own Movable Type installation for my blog. I considered moving to hosted TypePad, but I’d heard good things about WordPress. WordPress.com now hosts my blog, also for free, but I decided to pay $10 per year to have it at my own domain name. I love their service.
And now I’d migrated everything but my core web site, which is very minimal. All I’ve got is a home page and a small number of other pages, because I’d already migrated my photos to Picasa web albums and my presentation files to Google Docs (which is also available as part of Google Apps), all for free. There is one hitch, though: when I moved to a hosted blog all my old URLs changed, so my main web site has to redirect requests for the old URLs to the correct new ones. But still, I didn’t want to pay for full web hosting for what is essentially just a starting point.
First, register an application name for AppEngine. You’ll need a regular Google Mail account for this, but that’s easy to get. It doesn’t matter what you call it; mine was engelkeweb.
Next, create a local folder on your machine to hold your application. Put a folder inside that containing all your web pages. It can be called anything, but the AppEngine examples always call it static, so that’s what I’ll do. If your application folder is at C:\MyAppEngine then this folder will be C:\MyAppEngine\static, and the main home page would probably be C:\MyAppEngine\static\index.html.
Now create a text file called app.yaml in the main folder (in this example, at C:\MyAppEngine\app.yaml) with the following contents (change the engelkeweb entry to the name you registered):
application: engelkeweb version: 1 runtime: python api_version: 1 handlers: - url: (.*)/ static_files: static\1/index.html upload: static/index.html - url: / static_dir: static
Now upload your application (actually, just the static pages and the app.yaml file) using the command:
appcfg.py update C:\MyAppEngine
Voila! You’ve got a simple static web site. The second handler specification (for url: /, handled by static_dir: static) means that AppEngine will serve the page static\folder\xyz.ext whenever a user requests http://engelkeweb.appspot.com/folder/xyz.ext. That’s 95% of a static web site. And the first handler specification (for url: (.*)/) says that any request to a URL ending with a slash should return the index.html page in that folder. So a request to http://engelkeweb.appspot.com/folder/ would return the file static\folder\index.html.
Note that the order of the handler specifications matter, since the first one matched is what is returned.
You can use your Google Apps settings page to make this site available at your domain’s normal address, too (so in my case, that same page is returned for http://www.engelke.com/folder/xyz.ext and http://engelke.com/folder/xyz.ext). You have to set up some DNS entries for that, but the Google Apps pages give clear explanations of what to do.
That’s how I’m now serving up engelke.com. But what about the redirection for my blog pages? Every URL of the form http://engelke.com/blog/something should now be redirected to https://blog.engelke.com/something. Doing that requires actually writing a very simple Python handler for the site, just 20 lines long, and adding another handler specification in the app.yaml file. I’ll cover that in my next post.