Hugo App Runner

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

Prerequisits

  • Install AWS CLI
  • Install Hugo (or see the quick start guide linked below)
  • Install Docker

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

 1server {
 2    listen       80;
 3    server_name  localhost  # add your custom domain(s) here
 4    root         /usr/share/nginx/html;
 5    index        index.html;
 6
 7    # Enable gzip compression
 8    gzip on;
 9    gzip_vary on;
10    gzip_min_length 1024;
11    gzip_proxied expired no-cache no-store private auth;
12    gzip_types
13        text/plain
14        text/css
15        text/xml
16        text/javascript
17        application/javascript
18        application/xml+rss
19        application/json
20
21    # Cache static assets
22    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
23        expires 1y;
24        add_header Cache-Control "public, immutable";
25    }
26
27    # Handle Hugo's pretty URLs
28    location / {
29        try_files $uri $uri/ $uri/index.html =404;
30    }
31
32    # Security headers
33    add_header X-Frame-Options "SAMEORIGIN" always;
34    add_header X-Content-Type-Options "nosniff" always;
35    add_header X-XSS-Protection "1; mode=block" always;
36    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
37
38    # Handle 404 errors
39    error_page 404 /404.html;
40}

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

  1. Search ECR from the AWS console
  2. Click ‘Create repository’
  3. 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

 1FROM nginx:alpine
 2
 3# Copy the Hugo-generated static files to nginx web root.
 4COPY public/ /usr/share/nginx/html/
 5
 6# Copy custom nginx configuration
 7COPY nginx.conf /etc/nginx/conf.d/default.conf
 8
 9# Expose port 80
10EXPOSE 80
11
12# Start nginx
13CMD ["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.

  1. Retrieve an authentication token and authenticate your Docker client to your registry.
  2. Build your Docker image
  3. Tag your image
  4. 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:

  1. Navigate to Route 53 in the AWS Management Console. Click on ‘Registered domains’ then ‘Register Domains’
  2. Enter your desired domain name in the search box iwth your preferred top-level domain eg .com, .io, etc
  3. Select the domain, if available, and ‘Proceed to checkout’
  4. Select duration and whether to auto-renew
  5. Fill in registrant contact details and choose whether to enable privacy protection (recommended to hide personal info from WHOIS)
  6. Finally ‘Complete purchase’
  7. Domain registration typically takes 10-15 minutes to complete
  8. 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:

  1. Navigate to AWS Certificate Manager in the AWS Management Console
  2. Ensure you’re in the us-east-1 (N. Virginia) region (required for App Runner)
  3. Click “Request a certificate” and “Request a public certificate”
  4. Enter your domain name (e.g., example.com) and add a wildcard subdomain (e.g., *.example.com) to cover subdomains like www.example.com
  5. Choose DNS validation (recommended, especially if you registered the domain in Route 53)
  6. Review all details and click “Request”
  7. 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
  8. 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.