Hosting a Hugo Blog in AWS App Runner
Hugo is great option to host a blog/static content site. Combining Hugo and AWS App Runner is a simple and straightforward approach to hosting your own blog at a reasonable cost. Few items this blog will walk through
- Create a basic hugo site
- Create an nginx Configuration File
- Create an ECR Registry
- Create a Docker Container
- Building a Docker image for Hugo + NGINX
- Deploying to AWS App Runner
- Request a domain in AWS
- Create a hosted zone tied to your new domain in Route 53
- Request a public certificate to use with your App Runner custom domain
- Update App Runner with custom domains
Prerequisits
Create a Hugo Site
Follow the Hugo Quick Start guide. A basic Hugo site is sufficient for this guide.
Be sure you can run hugo
from a terminal to generate the public
folder. This folder will be copied to the docker conainer and deployed to AWS.
Create an nginx Configuration File
We’ll create a docker container to host the nginx instance. This configuration file will be needed once we create the container.
Create a file named nginx.conf
server {
listen 80;
server_name localhost # add your custom domain(s) here
root /usr/share/nginx/html;
index index.html;
# Enable gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json
# Cache static assets
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Handle Hugo's pretty URLs
location / {
try_files $uri $uri/ $uri/index.html =404;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Handle 404 errors
error_page 404 /404.html;
}
Create an ECR Registry
ECR includes 500mb free storage (as of writing this blog post). Creating a private repository requires a name only. All other default settings are are sufficent
- Search ECR from the AWS console
- Click ‘Create repository’
- Enter repository name and ‘Create’
Create a Docker Container
This container can be run locally and can be pushed to AWS Elastic Container Registry (ECR).
Create a file named Dockerfile
FROM nginx:alpine
# Copy the Hugo-generated static files to nginx web root.
COPY public/ /usr/share/nginx/html/
# Copy custom nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Expose port 80
EXPOSE 80
# Start nginx
CMD ["nginx", "-g", "daemon off;"]
Deploying to AWS App Runner
The new ECR registry contains the commands to build the docker image and deploy it. Look for the View push commands
button in your repository. The commands will be as follows. Copy the provided commands and paste into your termianl.
- Retrieve an authentication token and authenticate your Docker client to your registry.
- Build your Docker image
- Tag your image
- Push this image
Request a domain in AWS
AWS Route 53 provides domain registration services that integrate seamlessly with other AWS services. Here’s how to register a new domain:
- Navigate to Route 53 in the AWS Management Console. Click on ‘Registered domains’ then ‘Register Domains’
- Enter your desired domain name in the search box iwth your preferred top-level domain eg .com, .io, etc
- Select the domain, if available, and ‘Proceed to checkout’
- Select duration and whether to auto-renew
- Fill in registrant contact details and choose whether to enable privacy protection (recommended to hide personal info from WHOIS)
- Finally ‘Complete purchase’
- Domain registration typically takes 10-15 minutes to complete
- Route 53 automatically creates a hosted zone for your new domain
Request a public certificate to use with your App Runner custom domain
AWS Certificate Manager (ACM) provides free SSL/TLS certificates for use with AWS services. Follow below steps to request a certificate for your domain:
- Navigate to AWS Certificate Manager in the AWS Management Console
- Ensure you’re in the us-east-1 (N. Virginia) region (required for App Runner)
- Click “Request a certificate” and “Request a public certificate”
- Enter your domain name (e.g.,
example.com
) and add a wildcard subdomain (e.g.,*.example.com
) to cover subdomains likewww.example.com
- Choose DNS validation (recommended, especially if you registered the domain in Route 53)
- Review all details and click “Request”
- Click “Create record in Route 53” for automatic validation
- If using external DNS: Manually add the provided CNAME records to your DNS provider
- Validation typically takes 5-30 minutes
- The certificate status will change from “Pending validation” to “Issued” once issued and the certificate is ready to use with App Runner
Important Notes:
- The certificate must be in the us-east-1 region for App Runner compatibility
- DNS validation is faster and more reliable than email validation
- Certificates are automatically renewed by AWS before expiration
Update App Runner with custom domains
From your AWS App Runner instance, click on the ‘Custom Domains’ tab, then ‘Link Domain’ button. Chose ‘Amazon Route 53’ as the registrar and pick the domain you created above in the drop down. The sub domain can be left blank. Finally choose ‘CNAME’ for DNS Record Type. Repeat this process but use ‘www’ for the subdomain.