Skip to main content
Katapult

Hosting a website on Katapult with Caddy

9 Jan 2025 · 4 min read · Devops & Infrastructure, Tutorials

Caddy is a powerful tool that simplifies serving sites and services on Katapult. It also provides automatic TLS certification and management using Let's Encrypt, ensuring your sites are secure.

To improve the integration between Katapult and Caddy, we've published a Katapult libdns provider and Caddy module. These tools allow customers to use DNS validation for issuing TLS certificates, which is particularly helpful for firewalled sites or services that require TLS but prevent Let's Encrypt from using HTTP validation.

In this tutorial, we'll guide you through hosting a website on a Katapult virtual machine (VM) with Caddy, while using DNS validation to issue a TLS certificate for a domain managed in Katapult.

Getting started

Before moving forward, you’ll need to setup your environment in Katapult to host a website with Caddy. Log into the Katapult console and follow these steps:

Launch a virtual machine

Use the "Launch" button in the top right corner to create a new VM. Select the Ubuntu 24.04 distribution and choose a package. The ROCK-1 package will be sufficient for this tutorial.

Once your VM is running, make a note of its IP address as you'll need it later.

Set up your domain

In the Katapult main menu find "Domains" → "DNS". Add your domain and verification steps. This will involve updating nameserver information with your domain registrar.

After verification, add a DNS record:

  • Leave the name field blank (or add "site" for a subdomain like site.your-domain.com).
  • Set the type to "A".
  • Enter your VMs IP address in the IPv4 address field.

Create the record. Once propagated, your domain will point to your VM (but it isn't serving anything yet).

Create a Katapult API token

You’ll need a Katapult API token to allow Caddy to create DNS records for domain validation when issuing a TLS certificate.

Go to "Access" → "API Tokens" in the console and create a new token with the Core: Manage ACME challenge DNS records scope. This token allows Caddy to create and delete DNS records that are used by Let’s Encrypt's ACME validation process. For extra security you can add your VM's IP address in the authorized IP addresses field.

Create the token and make a note of the token secret—you will need it later and it's only displayed briefly.

Setting up your virtual machine

You should now use SSH to connect to your virtual machine.

You'll need some directories to contain the files you create later:

mkdir -p /var/www/conf
mkdir -p /var/www/html

Make sure you are working from the /var/www directory:

cd /var/www

Setting up Docker

Instead of installing dependencies manually, you'll run Caddy in Docker. The Docker documentation provides the latest installation instructions for how you can install Docker on your Ubuntu VM.

After installing Docker, create a Dockerfile. Use Caddy's builder image as the base to enable plugin support by compiling a custom binary.

Create the Dockerfile:

nano Dockerfile

Add the following content:

FROM caddy:builder AS builder

RUN xcaddy build \
    --with github.com/caddy-dns/katapult

FROM caddy:latest

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

Save and close the file by pressing ctrl+x, y then enter.

The Dockerfile instructs Docker to create an image using the Caddy builder image as the base and will then use xcaddy to compile a custom Caddy binary which includes the Katapult DNS module.

Next, you need a Docker compose file:

nano compose.yaml

Add the following content:

services:
  caddy:
    build: .
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - $PWD/conf:/etc/caddy
      - $PWD/html:/var/www/html
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:

Save and close the file.

This file instructs Docker to build an image using the Dockerfile you just created and run a container from it. It maps the necessary ports for traffic routing and links your config and HTML directories to the container. Named volumes are also created to store Caddy's internal data and configuration, ensuring state is preserved across reboots. Additionally, the restart: unless-stopped setting ensures the container automatically restarts of it exits or the virtual machine reboots.

Configuring and running Caddy

You're now ready to configure Caddy. In this tutorial you will host a single website, but if you wanted to host multiple websites you could add separate directories in /var/www/html for each one.

Create a webpage for your website with an index.html file:

nano html/index.html

Add some basic HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Hello from Caddy</title>
  </head>
  <body>
    <h1>Welcome to my website</h1>
    <p>This website is served by Caddy on Katapult!</p>
  </body>
</html>

Save and close the file.

Next, you'll need a Caddyfile, which will store configuration for your sites.

Create the Caddyfile:

nano conf/Caddyfile

Add the following content, replacing YOUR_DOMAIN with your domain and YOUR_KATAPULT_API_TOKEN_SECRET with the API token secret you created earlier:

YOUR_DOMAIN {
    root * /var/www/html
    encode gzip
    file_server

    tls {
        dns katapult YOUR_KATAPULT_API_TOKEN_SECRET
    }
}

Save and close the file.

The Caddyfile sets up Caddy to serve a static website from the /var/www/html directory. It compresses assets and automatically issues a TLS certificate using the Katapult DNS module for domain validation.

You're now ready to run Caddy:

docker compose up -d

The first run may take a few minutes as the image is built (subsequent runs will be much quicker!). Once complete, your website will be live at your domain with a valid TLS certificate!

Updating your Caddyfile

If you make changes to the Caddyfile, you'll need to reload Caddy. Use the following command so that the config is reloaded without interrupting the service:

docker compose exec -w /etc/caddy caddy caddy reload

Conclusion

Caddy is a powerful tool, and this tutorial only scratches the surface of what it can do. We'd love to hear about your experience with hosting on Katapult—join the conversation on Discord and share what you've been working on!

Feeling inspired? Sign up for Katapult today with our £100 free credit coupon to kickstart your journey.

About the author

Andrew T

Andrew is a software engineer for Krystal, he works on Krystal's cloud hosting platform Katapult. Outside of work he enjoys travel, music and gaming.

Start building today with £100 free credit

Sign up and you’ll be up and running on Katapult in less than a minute.