Self-Hosted Blog Part 5 - Container

2/12/2021 2-minute read

In part 4 we picked a blog framework and built a static site. Now that we can build our static site, we need to create a container which contains bits for hosting that site. For simplicity’s sake, I decided to build the static site and build the contents of the static site into the container. Then, in Kubernetes, everything we need to host the site is distributed by pulling the Docker image.

I found a set of Docker images for running Hugo that were incredibly helpful. The one I’m using in the Dockerfile will build the Hugo site as part of the Docker image build process, which we can use in a multi-stage Docker image build. Docker multi-stage builds are very helpful to be able to build an artifact in one stage that can be copied into another image without needing to include all of that image.

Here’s the very simple Dockerfile:

FROM klakegg/hugo:0.92.1-ext-ubuntu-onbuild AS hugo

FROM nginx
COPY --from=hugo /target /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf

We use the Docker image I found to build the artifact and then we use the COPY command from the multi-stage build to include the static site into the stock Nginx container. We’re running the stock nginx container and overriding nginx.conf so we can disable access logging. I disabled access logging because I was concerned we’d create more writes on the SD cards than we needed. nginx.conf looks like:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/;

events {
    worker_connections  1024;

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  off;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;

This is the same as the stock configuration except for access_log off. Locally, I run a build and run and now my blog is hosted in Docker.

docker build -t clintsharp/blog .
docker run -p 8000:80 -it clintsharp/blog

Now, I point my browser at my machine on port 8000 and I see my blog running.

Next, we will setup a CI/CD pipeline to build our site on every git push.

Posts in this Series