About

Professional software developer / technical lead / architect / engineering director. Java-focused background.

Cross-industry experience in organizations ranging from VC-backed startups to publicly traded behemoths.

Evaluating whether Golang lives up to its expectation as being ideally suited for the modern web. Based in the greater (much greater) DC metro region.

Reach out to me via email at andrew@m0d3rnc0ad.com

This site

This site itself is created with Hugo, a static site generator written in Go.

Github repo for this site is in Bitbucket and the content is hosted by Firebase.

Why this stack was chosen

Editing the site's content is a matter of updating Markdown and committing to a Git repo, two activities with which I'm well-versed. Moreover, working on a Git repo nicely suits my use-case, as my time for this site mainly comes while I'm commuting on the train with spotty internet connectivity. A WYSIWYG site, such as Wordpress, runs the risk of dropping a connection at an inopportune time and losing work.

Hugo is written in Go meshes well with my desire to learn Go. Wordpress being in PHP does nothing for me. With Hugo, the option exists to extend any functionality as desired.

Moreover, I maintain complete control of all content without paying a dime thanks to Firebase's and Bitbucket's free tiers.

Free control includes no hosting platform-inserted banner advertisements, as well as the ability to easily migrate to a new hosting provider, which has already happened once as a result of Aerobatic ditching support of custom domains on their free tier. When that happened, I switched to Firebase.

Latest: Simple Nginx site in Docker

Docker provides the ability to package software applications inside lightweight containers.

Docker images only need to contain the built code artifacts / configuration / dependencies they require as a result of Docker using the host machine’s underlying operating system with resource isolation features.

This tutorial covers building a basic Nginx image for Docker to host a simple static site.

Prerequisites

The only prerequisite is to have Docker installed. Instructions are here for all operating systems.

As of March 2, 2017, Docker offers 2 flavors: the free “Community Edition” (CE) and “Enterprise Edition” (EE). We’re using the CE edition.

Static site to host

All code for this demo (simple static site and Dockerfile) is in this Github repo.

The site directory contains 2 simple HTML files, /index.html and /another.html, which shows a pair of messages suitable for our demo.

The layout of the code appears as so:

demo-nginx-site> tree -a
.
├── Dockerfile
└── site
    ├── another.html
    ├── css
    │   ├── normalize.css
    │   └── skeleton.css
    ├── images
    │   └── favicon.png
    └── index.html

Docker configuration

The configuration of our Docker image rests in Dockerfile:

FROM nginx
COPY site /usr/share/nginx/html

This file instructs Docker to use the public nginx image. Docker will go out and download this image if you don’t have it already, else will cache it on your machine.

The next line instructs Docker to add a layer to the image containing the content of our static site folder into the /usr/share/nginx/html directory, the default hosted location for the Nginx image.

Code organization

The location of our site directory as a sibling to the Dockerfile is more than convenience.

Docker’s context stipulates that:

path must be inside the context of the build; you cannot ADD ../something /something, because the first step of a docker build is to send the context directory (and subdirectories) to the docker daemon

In a production scenario, the Docker build script should execute after all code artifacts are tested/deployed to an artifact repository.

A tool like Ansible would then typically download the artifacts and unpack them to an isolated location to be built by Docker before running the image in a new container.

Build Docker image

The Docker ‘image’ is the snapshot of configured layers which can be executed. A running image is termed the ‘container’.

From the parent directory containing the Dockerfile and site folders, create a Docker image:

docker build -t blog-content-nginx .

You’ll see output similar to this, where Docker downloads (or uses the local cache of) the Nginx image, then copies the static site as an additional layer:

Sending build context to Docker daemon 32.77 kB
Step 1/2 : FROM nginx
 ---> 6b914bbcb89e
Step 2/2 : COPY site /usr/share/nginx/html
 ---> e4db7110e91b
Removing intermediate container f149a78a0052
Successfully built e4db7110e91b

Run Docker container

Now we can run the image as its own Docker container. Execute:

docker run --name blog-nginx -d -p 8080:80 blog-content-nginx

The above command tells Docker to run the blog-content-nginx image as a container named blog-nginx.

The command also maps port 8080 on the host machine to port 80 of the Docker container.

Now you can go to http://localhost:8080 and you should see our sample site: Screenshot of index.html

Voila! You’ve got a static website running in Docker!

To stop the Docker container, execute:

docker stop blog-nginx

Wrapup

In Dockerfile we configured layers in our Docker image which was built and run as a Docker container.

This covers the basic scenario for working in Docker.

Images can be built as part of a development build (integrated with a build system, such as Gradle) or a more enterprise DevOps environment such as Ansible.

Images can also be more complex, such as full-on microservices containing a persistence layer, web API interface, and service registration such as with Spring Boot and Netflix’s Eureka, or orchestrated with Kubernetes.