Deploying a Hugo Site to AWS Lightsail Containers
Last Update: Jun 7, 2024
I wrote a book! Check out A Quick Guide to Coding with AI.
Become a super programmer!
Learn how to use Generative AI coding tools as a force multiplier for your career.
Hugo is a blogging platform based on simplicity. Its main appeal is generating fast, static sites without much orchestration. If you’ve ever wanted to run containerized apps in the cloud without much work, Amazon has a new solution, Amazon Lightsail for containers. In this tutorial we’re going to bring these two simple technologies together, to show you a simple, effective option for your blog.
What’s the point?
Hugo is a simple, fast blogging platform. AWS Lightsail is a cloud platform for the “small players.” You can spin up virtual machines, software environments, and now containers in the cloud, with a very simple to use, easy interface at a low price. You can build a simple blog, create a container for it, and push it to the cloud in a few steps. The Lightsail model ensures you can keep costs low, then scale it up if your blog gets super popular (which I hope it will).
What We’ll Do:
We will build a blog and push it to the cloud from start to finish.
- Create a new Hugo Site
- Create a container for it
- Push it to Docker Hub (optional)
- Deploy it to AWS Lightsail for Containers
To do this you will need:
- Go installed (Instructions)
- Hugo (Instructions)
- Docker (Instructions)
- AWS CLI v2 (Instructions) (optional)
Step 1: Create a Hugo Site
For this tutorial, we’ll create a Hugo site. If you already have one, you can skip this step.
We’ll create a new site:
hugo new site MySuperBlog
And initialize a git repository (optional)
cd MySuperBlog
git init
git remote add origin https://github.com/JeremyMorgan/MySuperBlog.git
Now we’ll add a theme. I’m choosing “Ghostwriter” here. Once you add it in, you need to write it to your config.toml.
git submodule add https://github.com/jbub/ghostwriter.git themes/ghostwriter
echo 'theme = "ghostwriter"' >> config.toml
Now, let’s create a new blog post:
hugo new content/blog/hello-world.md
Here’s a sample post:
---
title: "Hello World"
date: 2020-12-04T23:22:48-08:00
draft: false
---
This is my first blog post!
It's exciting!
Save the file, and we’ll test it out:
hugo serve
And it’s up!
Exciting! But now we want to publish it somewhere.
Let’s commit to GitHub first.
git add .
git commit -m "Whatever"
git push --set-upstream origin main
git push
Now we have it stored there to pull from later on (or in your container if you choose).
Now we want to host it. There are plenty of well-known places like Netflify (where I host this blog), Vercel, or AWS Amplify. But by putting it into a container, we can still get low-cost static hosting but are open to so many other opportunities. Anything you can stuff in a container you can use with your site.
So let’s containerize it.
Create a Container for the Hugo Site
We’re going to stuff our blog build into a container image. We don’t know what our URL will be, so let’s modify our config.toml:
baseURL = "/"
Generally I wouldn’t advise this, but AWS Lightsail containers create a URL with a GUID. If you point your domain at the container, you can put your domain in here.
Now, let’s create a Dockerfile (a simple text file named Dockerfile)
FROM klakegg/hugo as hugo
COPY ./ /hugodir
WORKDIR /hugodir
RUN hugo --config ./config.toml
#Copy static files to Nginx
FROM nginx:alpine
COPY --from=hugo /hugodir/public /usr/share/nginx/html
WORKDIR /usr/share/nginx/html
What this file is doing is taking Klagegg’s minimal Docker image to build Hugo sites. It installs Hugo and builds the website for you.
In the file, we copy over all our files into /hugodir and make it our working directory.
We run Hugo and specify where to find config.toml.
Then, we pull from another image to build NGINX and copy the public folder from Hugo and serve them up.
Simple and easy.
So let’s build an image and spin up a container!
docker build . -t hugosite
docker run -p 8080:80 hugosite
Since I asked it to serve on port 8080, let’s try it out.
Awesome! Now that we have a nice image let’s put it up on Docker Hub.
Adding Your Image to Docker Hub
Adding an image to Docker Hub is easy. You just tag the image, log in, and push it to the hub.
docker tag hugosite jeremymorgan/lightsail-hugosite
docker login
docker push jeremymorgan/lightsail-hugosite
Now we can see it’s up on Docker Hub!
Deploying to Lightsail Containers
Log into your AWS Console, and select Lightsail. Then select the “containers” tab.
Click “Create container service”
Nobody is going to this blog, it’s brand new. So I’m choosing a Nano instance.
If my blog grows, or I need more power for something, I can scale it up quickly here.
Click Set up Deployment, and specify a custom Deployment.
Here I’m naming it “mysuperblog”. Then I’ll specify the image from Docker Hub and open up port 80. (Don’t worry, the connection will be SSL)
Next, name your service:
I named mine “jeremys-super-blog”. It shows a summary of your costs, then click “Create container service.”
You’ll then see the deployment begin:
And we’re done. It shows a successful deployment.
Don’t worry if it doesn’t work the first time, I had to try a couple of times.
Now it has deployed, and I can click my new URL to find it:
And you’re done!! There’s my container image deployed onto AWS. High fives all around.
But wait, there’s more!!
Deploying Without Docker Hub
What if you don’t want to use Docker Hub? That step is optional. You can deploy right from your local machine if you like.
Make sure you install AWS CLI (v2) with the Lightsail container services plugin.
We’ll go back to the folder with our Hugo installation and the Dockerfile, and run the following command:
aws lightsail create-container-service --service-name jeremyblog --power nano --scale 1
This will create a service on AWS Lightsail you can push your containers to.
Then, push your container image:
aws lightsail push-container-image --region us-west-2 --service-name jeremyblog --label lightsailblog2 --image jeremymorgan/lightsail-hugosite:v2
You should see a new service:
Tada! And here it is, ready to deploy. If you need to modify your image, build the new image with a new label and run push-container-image again.
Now you can deploy it just like before, without Docker Hub involved.
Congrats! That’s all there is to it!
Summary
I’ve been enjoying the AWS Lightsail service for a while. The idea behind Lightsail is creating small affordable spaces for your projects. I host many of my small low traffic web servers on a Lightsail VM, and I love the interface. So when I heard they are offering a container service, I had to try it out.
If you want yet another excellent option for hosting your Hugo blog, try this out. If you have a bigger website, you’ll likely want some of the features of AWS Amplify or Netlify, but for small one-off projects or simple blogs, it’s hard to beat seven dollars a month. By hosting it in a container, you can expand your blog. You could add Node to it, or some Web API, even a database service to your Hugo blog. If your traffic steps up, you can scale it quickly.
Overall, I’m impressed with it and had to share. Have questions or comments? Yell at me!
Want to become an expert Go programmer?
You can boost your skills in a few weekends by taking these high quality Go courses taught by top experts!
We have over 30 hours of Go courses you can take now! You can try it for 10 days free of charge.