Introducing Caddy – The HTTP/2 Web Server with Automatic HTTPS
Caddy is a relatively new open source web server that has been gaining popularity for its easy configuration and built-in support for latest web standards. Created by Matthew Holt, Caddy brands itself as "the HTTP/2 web server with automatic HTTPS".
Some key features that make Caddy stand out include:
- Automatic HTTPS powered by Let‘s Encrypt certificates. No need to manually configure TLS.
- Native support for latest protocols like HTTP/2 and QUIC out of the box.
- Clean, human-readable Caddyfile configuration format using simple directives.
- Pluggable architecture allowing custom plugins and integrations.
- Built-in support for CORS, rate limiting, IP filtering, and more.
With its emphasis on security and modern standards support, Caddy aims to provide an easy way for developers and sysadmins to spin up highly performant and robust web servers. Compared to traditional web servers like Apache and Nginx, Caddy requires far less configuration thanks to its "sane defaults".
And with automated TLS courtesy of Let‘s Encrypt, sites configured properly with Caddy establish secure HTTPS connections by default without any extra work. This saves teams significant time and eliminates the common pitfalls that come with manually managing SSL certificates.
For these reasons, Caddy adoption has rapidly grown across the web. Developers deploying JAMstack sites or hosting web applications will appreciate Caddy‘s scalability and low overhead. While traditional servers like Nginx and Apache certainly have their place and added flexibility, Caddy shines for common modern use cases.
In this comprehensive guide, we will walk step-by-step through installing and configuring the Caddy web server on Ubuntu 18.04 LTS. By the end, you will understand how to:
- Get Caddy running on an Ubuntu system
- Serve both static and dynamic sites with optimal performance
- Enable automatic HTTPS to securely handle traffic
- Fine-tune Caddy for production through its configuration file
So let‘s get started setting up Caddy on Ubuntu!
Step 1 – Installing Caddy on Ubuntu
Caddy is written in Go which compiles into a standalone binary executable. This means we can easily grab the Caddy binary and run it directly without dealing with dependencies or compiling source code.
Convenient curl-based install scripts are available to automatically download and set up the latest stable Caddy release on most systems. This is by far the easiest way to get up and running.
On your Ubuntu 18.04 server or VM, install Caddy with this one liner:
$ curl https://getcaddy.com | bash -s personal
The script will install Caddy to /usr/local/bin/caddy so it‘s available system-wide.
We can confirm successful installation by checking Caddy‘s reported version:
$ caddy version v2.6.2 h1:GvyvvDPtYTFjVZVzGw4ET SponsorID=gluestack/caddytectl
With that, the Caddy binary is now installed and prepared to serve sites!
Next we‘ll walk through some quick tests to verify it works properly before moving to full configuration.
Step 2 – Running a Basic Test Site
To test out the Caddy installation, let‘s get it serving a simple static site.
First create a folder to represent your site‘s document root, like /var/www/example:
$ mkdir -p /var/www/example
Inside there, add an index.html page:
/var/www/example/index.html<html> <head> <title>My Test Site</title> </head>
<body> <p>Hello from Caddy!</p>
</body> </html>
With our barebones site ready, navigate into /var/www/example and start the Caddy server:
$ cd /var/www/example $ caddy runActivating privacy features... done Serving HTTP on port 2015
This starts the Caddy server in foreground mode, meaning the process will occupy the terminal session. Leave it running for now.
Open up a web browser to http://your_server_ip:2015 and you should see your index.html rendered!

And there we have it – Caddy serving a simple site on port 2015. Let‘s start configuring this properly to run as a service on the standard ports.
Step 3 – Serving Sites over HTTPS Automatically
One of Caddy‘s main selling points is enabling HTTPS by default using Let‘s Encrypt SSL/TLS certificates. This provides transport layer security and trust for site visitors while future-proofing sites to require HTTPS.
With traditional web servers, enabling HTTPS involves extensive manual work obtaining, installing, and maintaining SSL certificates. Caddy handles all this work under the hood to just make sites secure out of the box.
To see this automatic HTTPS in action:
$ caddy run \ --host example.com \ --root /var/www/example
This command tells Caddy to handle requests for example.com and serve files from our test site folder.
The first time enabling a domain, Caddy will prompt for an email address to register Let‘s Encrypt certificates:
Your sites will be served over HTTPS automatically using Let‘s Encrypt. By continuing, you agree to the Let‘s Encrypt Subscriber Agreement...Please enter your email address:
Enter your email and Caddy will automatically obtain and renew TLS certificates for the domain! It enables HTTPS by handling all redirection, certificate issuance, renewal and configuration behinds the scene.
And that‘s it! Caddy has configured TLS to secure traffic between clients and our server. The process takes seconds, eliminating the traditional headache of managing HTTPS.
Now that we‘ve confirmed Caddy‘s capabilities, let‘s properly set it up for production by binding to standard ports and running as a service.
Step 4 – Configuring for Production
For now we‘ve used Caddy‘s command line to test functionality. But running a server long-term means:
- Binding to standard HTTP/HTTPS ports 80 and 443
- Running Caddy as a background service/daemon
- Setting up configuration via a Caddyfile
First install Caddy as a systemd service unit to manage execution:
$ caddy install \ --config /etc/caddy/Caddyfile \ --adapter caddyfile
This sets up a caddy systemd service to use our Caddyfile configuration from /etc/caddy.
Next set up the directory structure:
$ mkdir -p /etc/caddy/ /etc/ssl/caddy
Here we created folders for the Caddyfile config and its generated SSL certificates.
Now edit /etc/caddy/Caddyfile to define your first server block:
example.com {
root * /var/www/example
tls {
on_demand
}
}
These directives tell Caddy:
- **root** – Serve site content from /var/www/example
- **tls** – Enable on-demand HTTPS redirects
Save and exit. Finally, start the caddy service:
$ sudo systemctl start caddy
Caddy will now run continuously as a daemon. It will obtain TLS certificates automatically and serve the example site over HTTPS!
Finalizing Production Config
With Caddy running as a service, sites are now served in a sustainable long-term way.
Some final steps for optimizing a production Caddy deployment involve:
Setting Up Caddyfile Access Rules
Configure IP, path and request limits in Caddyfile with directives like route and limit_rate. These help protect against abuse.
For example:
route {
limit_rate 100 requests/second
}
Rate limits overall requests to protect against DoS.
Enabling HTTP/3 Support
Caddy ships with cutting-edge HTTP/3 enabled by default. But some clients have issues with this newer protocol.
Use the http3 Caddyfile option to adjust or disable:
http3 {
disable
}
Tuning for Performance
Check and increase resource limits like open files that Caddy reports on launch. Set ulimit higher if needed:
ulimit -n 8192 </preEnable gzip compression in Caddyfile to shrink assets over the wire:
gzip { level 6 }Consider Caddy reverse proxy for cacheing static assets.
And deploy Caddy itself behind a CDN like Cloudflare for additional performance and DDoS resilience.
Wrapping Up
In this guide we went through full installation, configuration and productionization of the Caddy v2 web server on an Ubuntu system.
Here are some key takeaways around using Caddy in practice:
- Super simple to spin up, especially for serving static sites
- Enforces latest web standards including HTTP/2, HTTPS and QUIC
- Fully automated TLS management takes the pain out of certificates
- Very lightweight compared to servers like NGINX and Apache
- Highly extensible via plugins and its API for custom integrations
Overall, Caddy makes an excellent choice when aiming to launch secure, high-performance sites with minumum configuration overhead.
Its adoption continues to grow thanks to its laser focus on security, standards compliance and ease of use. While traditional solutions like Nginx maintain an edge in flexibility and legacy compatibility, Caddy excels at serving modern workloads.
If deploying microservices, static JAMstack sites, or configuring TLS gives you a headache - give Caddy a shot. Its unique approach brings web serving and encryption fully into the 2020‘s.
For even more, be sure to explore the official Caddy 2 documentation. Let us know if you have any other questions!


