HTML5 and Docker

Summary

If you’ve ever messed with UI programming that utilized the ‘hash’ URL technique for invoking UI actions, it’s time to go html5 native!

This blog post will describe how to setup an apache docker container with the pieces enabled for URL Rewriting. This allows html5 ‘pushState’ to be utilized instead of hash operations. Some advantages HTML5 pushState offers over hash:

  • Cleaner looking for sharing URLs (http://…/#/employees/list vs http://…/employees/list)
  • Search Engine Optimized (SEO) due to being able to pre-generate/crawl your site and return things server-side whereas hash always needs to process on the client and is not SEO friendly

The major disadvantage is that it requires the server being involved .. that’s where this post comes in.

NOTE: For angular2, there is a debate going on for what the default should be, hash or html5. You can read about it here.

Setup

I have a little toy project I have been using for a few years for Spring Boot and angular to help me prove out concepts. I won’t go into any detail on the UI itself (I recently converted from angular1 -> angular2 and that’s what drove this blog post, but it’s applicable for any UI tech that utilizes hash URLs).

NOTE: All code is in the my git repo.

To try everything out you’ll need a recent version of docker installed. If you are using an ubuntu/debian based distro you can install it with:

$ curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -
$ sudo apt-get install -y nodejs

From here you need a Dockerfile like-so:

# Pull base apache image
# ---------------
FROM httpd:2.4
 
# Maintainer
# ----------
MAINTAINER Jim Basilio <jim.basilio@gmail.com>
 
# Copy file in as daemon user
USER daemon
 
# httpd.conf turns on rewrite module and rewrites 404 errors to load index.html then redirect client
COPY ./httpd.conf /usr/local/apache2/conf/httpd.conf
 
USER root
 
# Define default command to start bash. 
CMD [ "httpd-foreground" ]

What this does is build a docker image and copy in httpd.conf that turns on the urlrewrite module and configures the rewrites when a 404 is encountered.

For example, when a user goes to your app at http://awesomeapp.com that allows index.html to load angular (or whatever UI framework you are running) and then angular takes over managing client routing. On a later session when a user ‘direct links’ to your app at http://awesomeapp.com/users/list, this is making a server request to apache (in this case) to serve the ‘users/list’ folder (looking for an index.html normally). However, we don’t have that folder on our server since it really was a UI route so a 404 would be returned from apache.

The urlrewrite rule is

    Options +FollowSymLinks
    IndexIgnore */*
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (.*) index.html

I didn’t originally write the above, I took it from this SO gist. When the above is read by apache, any 404 errors that are found will rewrite the URL so index.html is served and then angular will perform the routing it needs. From the users perspective all of this is seamless and it just “does the right thing”. Without this in place, the users direct link would result in a “404 not found” and a very confused user. To start the container you can run:

$ sudo docker run -d -v <span class="pl-s"><span class="pl-pds">$(</span><span class="pl-c1">pwd</span><span class="pl-pds">)</span></span>:/usr/local/apache2/htdocs --name=html5-apache -p 8080:80 -t html5-apache

Be sure to customize the ‘$(pwd)’ with whatever the root is for your application.

That’s it! You now have a docker image you can use for any app that requires html5 pushState routing. This is a good alternative to using ‘lightweight’ dev http servers as seen with angular2 development stacks. You can start the container and let it run, adjusting the shared volume with your source code (i.e. delete the files, change the files, whatever) and when you reload your site everything will instantly update.

I’m using this setup for my hiit-frontend project which is working great. I can run an ‘npm run build’ and it’ll recompile all my typescript and move my site to the ‘dist’ folder. The dist folder is my shared volume to docker which I just leave running all the time (I intend on writing more about angular2 and the build stack I’m using there in another blog post).

Leave a Reply

Your email address will not be published. Required fields are marked *