Amazon Web Services, nginx, Docker, Hugo and a Raspberry Pi

Hosting a static webiste on a Raspberry Pi (RPi from now on) is quite straight forward. Serving that same website from a Dockerized Nginx HTTP server -on that same RPi- is a bit more interesting. Sure.

But what if the RPi decides to take the day off?

This post is mainly for students who attended one of my Architecting on AWS or System Operations on AWS sessions. It contains instructions, links to templates, tools and scripts to get started with Amazon Route 53 DNS failover between a primary site hosted on a RPi and a secondary site hosted on Amazon S3 & Amazon CloudFront. It is however not an exhaustive list of all the steps required for such a setup: use it at your own risk.

Raspberry Pi

First you may want to give your RPi some HypriotOS love. There are other Linux distributions available for the Raspberry Pi but HypriotOS has, in my opinion, the best Docker support at the moment.

Web

The page you’re reading right now (the whole fourteenislands.io domain for that matter) is written in Markdown and converted to a static site (HTML) with Hugo. Please go (no pun intended) have a look and come back here when you’ve written that novel of yours. I’ll wait.

Done? Good. You now want to serve the site you’ve generated directly from your RPi. We’ll do that with Nginx running in a Docker container. I’ve prepared some for you.

From a terminal on your RPi open your favorite text editor and save the following as docker-compose.yml

# docker-compose.yml
# Assumes your generated/copied static site is in /home/pi/volumes/nginx
nginx:
  container_name: nginx
  image: lroguet/rpi-nginx:latest
  ports:
    - "80:80"
  volumes:
    - /home/pi/volumes/nginx:/var/www/html

Start the Nginx container with the following command

$ docker-compose run -d --service-ports nginx

Amazon Route 53

In this section I assume you already have created an S3 bucket to store a copy of your static website and set up a CloudFront distribution to distribute that content (see Using CloudFront with Amazon S3 for instructions). I also assume you have the AWS CLI installed and configured.

Create DNS records and an health check with CloudFormation

First we want to create a primary record, an health check for that record and a secondary record to failover to when the primary record is not available.

Create a CloudFormation stack from that template directly in the AWS console or save the template locally, hit the terminal and run the following script(replace the ParameterValue values with your own):

#!/bin/bash
aws cloudformation create-stack \
  --stack-name fourteenislands-dns-failover \
  --template-body file://route53-dns-failover.json \
  --parameters \
    ParameterKey=PrimaryRecord,ParameterValue=1.2.3.4 \
    ParameterKey=SecondaryRecord,ParameterValue=abc123.cloudfront.net \
    ParameterKey=DomainName,ParameterValue=example.com \
    ParameterKey=HealthCheckPath,ParameterValue=/index.html \
    ParameterKey=HostedZoneId,ParameterValue=Z23ABC4XYZL05B

Update health check and primary DNS record

Once the health check, primary and secondary records have been created using the above CloudFormation template, the health check IPAddress and the primary record ResourceRecords should be automatically (hourly job on the RPi for example) updated with the following script.

#!/bin/bash
# To update https://github.com/lroguet/amazon-web-services/blob/master/cloudformation/templates/route53-dns-failover.json

PRIMARY_RECORD_IP_ADDRESS=`dig +short myip.opendns.com @resolver1.opendns.com`
STACK_NAME_OR_ID="fourteenislands-dns-failover"

aws cloudformation update-stack --stack-name $STACK_NAME_OR_ID \
  --use-previous-template \
  --parameters \
    ParameterKey=PrimaryRecord,ParameterValue=$PRIMARY_RECORD_IP_ADDRESS \
    ParameterKey=DomainName,UsePreviousValue=true \
    ParameterKey=HealthCheckPath,UsePreviousValue=true \
    ParameterKey=HostedZoneId,UsePreviousValue=true \
    ParameterKey=SecondaryRecord,UsePreviousValue=true 

Have fun and if you have any questions, please leave a comment.

Update. fourteenislands.io is not currently served from a Raspberry Pi but from an Amazon S3 bucket.

Comments