Since 2009, this blog, among other personal projects, was hosted on a VM on Rackspace. The $20 per month I was paying finally got to me, and I decided to migrate it to a new host. I selected Google Cloud Run. To do that, I needed to repackage the site into a Docker Container and migrate the domain.
Previously, I ran the Jekyll commands to build the site and manually uploaded them to the VM with SCP. I thought, if I’m going to migrate to a cloud native, containerized platform I should also replace the old-school techniques that I was using for build/release.
All of the code for this site, including the build/deploy process, is on Github.
Step 1 - Containerize the Build
The old way:
# deploy.sh bundle exec jekyll build scp -r _site/* firstname.lastname@example.org:/vweb/konrness.com/docs/
The new way:
# build.sh export JEKYLL_VERSION=2.5.3 docker run --rm \ --volume="$PWD:/srv/jekyll" \ -it jekyll/jekyll:$JEKYLL_VERSION \ jekyll build
The benefits of containerizing the build process is that I no longer need to maintain a local Ruby installation and mess around with managing dependencies. Everything is built into the jekyll/jekyll Docker image and self-contained. When I’m done building, the container dies and nothing hangs around.
The result of this build is a new
_site folder which is the static contents of the generated site, including directories, static assets (JS, CSS, fonts, etc.) and HTML files.
Step 2 - Create a deployable artifact
Now that I have the site generated, the second step of the
build.sh script packages the code into a Docker container.
# build.sh (continued) docker build -t konrness/konrness.com .
Since the site is entirely static, I am using the
nginx:alpine Docker image to deliver the site.
The Dockerfile is as simple as:
# Dockerfile FROM nginx:alpine COPY _site /usr/share/nginx/html
This copies the static site from
_site into the default web directory for the
I can then run this Docker container locally to preview and test the site.
# run.sh docker run -p 8080:80 -it konrness/konrness.com
Step 3 - Publish to Docker Hub
Once I have validated locally that the Docker image I have created is ready for release, I tag and push to Docker Hub and GCP Container Registry.
# release.sh timestamp=$(date +%y.%-m.%-d) echo Tagging version $timestamp docker tag konrness/konrness.com konrness/konrness.com:$timestamp echo Pushing tag: $timestamp docker push konrness/konrness.com:$timestamp echo Pushing tag: latest docker push konrness/konrness.com:latest echo Pruning... docker system prune -f
The tag to be deployed is versioned based on the date. For instance, the tag I push on April 16th, 2021 would be named
konrness/konrness.com:21.4.16. I push the tag to both Docker Hub as well as my personal Google Cloud Platform Container Registry because I am hosting the site on GCP Cloud Run, and Cloud Run does not support pulling Docker images from Docker Hub.
Step 4 - Deploy to Cloud Run
The last step of the
release.sh script is to deploy to Cloud Run.
# release.sh (continued) echo Deploying to Cloud Run gcloud run deploy konrness-com --image gcr.io/personal-sites-310123/konrness.com:$timestamp --region us-central1 --platform managed
Easy as that.
This build and release process is currently entirely scripted, and only run on my local workstation. In a future iteration of this, I plan to implement a CI/CD solution that will automate the process for me. I’ll link to that here, when I get to it.