Developer Tools AWS

Caddy Web Server on AWS User Guide

| Product: Caddy Web Server on AWS

Screenshots

Caddy version and service status

Caddy serving HTTP requests

Caddy configuration

Overview

This image runs Caddy, the open source web server and reverse proxy, fully installed and configured from the official Caddy package repository. The Caddy service is enabled and starts automatically at boot, serving a default landing page over HTTP on port 80.

Caddy's defining feature is automatic HTTPS. When you add a domain name to the configuration file, Caddy obtains and renews a publicly trusted TLS certificate for it with no separate certificate client to install or schedule. The web server is configured through a single, readable file, the Caddyfile, and a loopback only administration interface.

The document root and the site files served by the web server are stored on a separate, independently resizable storage volume mounted at /var/www, so web content is kept off the operating system disk and can be grown without disturbing the rest of the instance.

On the first boot of every deployed instance, a one shot service records a short information file at /stage/scripts/caddy-info.log listing the web server's listening ports and configuration paths. This file contains no secrets, because Caddy has no admin password and no rotatable credential.

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances
  • IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access to the instance
  • A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and ports 80 and 443 from the clients that will reach your sites
  • A registered domain name and the ability to create a DNS record for it, if you want to use automatic HTTPS
  • The AWS CLI version 2 installed locally if you plan to deploy from the command line

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Caddy. Select the cloudimg listing and choose Select, then Continue on the subscription summary.

Pick an instance type of m5.large or larger as a balanced default; size the instance to the traffic you intend to serve. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network and ports 80 and 443 from the clients that will reach your sites. Leave the root volume at the default size or larger.

Select Launch instance. First boot initialisation takes only a few seconds after the instance state becomes Running and the status checks pass.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg Caddy Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens port 22 from your management network and ports 80 and 443 for your sites.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --block-device-mappings '{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":30,"VolumeType":"gp3"}}' \
  --metadata-options 'HttpTokens=required,HttpEndpoint=enabled' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=caddy-web-server}]'

The image attaches a dedicated 20 GiB web content volume automatically, mounted at /var/www. To start with more web storage, enlarge that volume on the Storage step in the console, or add a second block device mapping on the CLI.

Step 3: Connect to the Instance over SSH

Connect to the instance with SSH as the default login user for the operating system variant you launched. The login user differs by variant:

Operating system variant SSH login user
Ubuntu 24.04 ubuntu

Replace <key-file> with the path to your private key file and <instance-public-ip> with the public IP address or DNS name of the instance.

ssh -i <key-file> ubuntu@<instance-public-ip>

Step 4: Confirm the Web Server

Check the installed Caddy version. Caddy reports its version and build identifier:

caddy version

Confirm the Caddy service is enabled and running:

systemctl is-active caddy.service

Confirm the web server is answering on port 80. The request returns the default cloudimg landing page:

curl -I http://localhost/

The instance information file records the listening ports and configuration paths. It holds no secrets:

cat /stage/scripts/caddy-info.log

Step 5: The Caddyfile and the Document Root

Caddy is configured through a single file, the Caddyfile, at /etc/caddy/Caddyfile. The image ships with a default Caddyfile that serves the document root over HTTP on port 80. Review it with:

cat /etc/caddy/Caddyfile

The document root is /var/www/html, on a dedicated filesystem. List its contents and confirm the mount:

ls -l /var/www/html
findmnt /var/www

To publish your own static website, place your files under /var/www/html, replacing or adding to the default landing page. After editing site files or the Caddyfile, validate the configuration and reload the service. A reload applies the new configuration with no dropped connections:

sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl reload caddy

Step 6: Enable Automatic HTTPS for Your Domain

Automatic HTTPS is the reason most teams choose Caddy. To serve your own domain over HTTPS, first point a DNS A record for the domain at this instance's public IP address. Then edit /etc/caddy/Caddyfile and replace the :80 site block with a block named for your domain. The configuration below serves files from the document root for www.example.com:

www.example.com {
    root * /var/www/html
    file_server
    encode gzip
}

Validate the configuration and reload Caddy:

sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl reload caddy

On the first request to https://www.example.com, Caddy contacts the Let's Encrypt certificate authority, proves control of the domain, obtains a publicly trusted certificate, and serves the site over HTTPS. Caddy also redirects plain HTTP requests to HTTPS automatically and renews the certificate well before it expires. No certificate client and no renewal schedule are required.

Step 7: Use Caddy as a Reverse Proxy

Caddy is also a capable reverse proxy and is commonly placed in front of an application backend to provide automatic HTTPS termination. The site block below forwards all requests for a domain to an application listening on port 8080 on the same instance:

app.example.com {
    reverse_proxy localhost:8080
}

Caddy passes the appropriate headers to the backend, load balances across multiple upstreams if you list more than one, and obtains a TLS certificate for app.example.com exactly as it does for a static site. After editing the Caddyfile, validate it and reload the service.

Step 8: Web Content Storage

The document root and the files served by the web server are stored under /var/www, which is a separate filesystem on its own EBS volume. Confirm the dedicated mount and review free space:

findmnt /var/www
df -h /var/www

Because the web content is on its own volume, you can grow it independently of the operating system disk. Modify the EBS volume in the AWS console or with the CLI, then extend the filesystem on the instance with resize2fs against the volume's device.

Step 9: The Administration Interface

Caddy exposes a JSON administration interface bound to the loopback address on port 2019, reachable only from the instance itself. It is useful for scripting and for inspecting the live configuration. Retrieve the active configuration with:

curl -s http://127.0.0.1:2019/config/ | head -c 200; echo

For day to day operation, editing the Caddyfile and reloading the service is the recommended workflow; the administration interface is an advanced option and does not need to be exposed to the network.

Step 10: Maintenance

Keep the operating system patched with the standard package manager. To upgrade Caddy itself, the official Caddy package repository is already configured on the image, so server upgrades are delivered through the normal package update process. After a Caddy upgrade, restart the service:

sudo systemctl restart caddy

Review the web server logs through the systemd journal:

sudo journalctl -u caddy --no-pager -n 20

Whenever you change the configuration, validate it before reloading. A reload applies a new configuration gracefully, while a restart briefly stops and starts the server.

Support

This Amazon Machine Image is provided by cloudimg with 24/7 technical support by email and chat. Contact cloudimg for help with web server configuration, reverse proxy setup, automatic HTTPS, virtual hosts and upgrades.

Caddy is a registered trademark of Stack Holdings GmbH. All other product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.