Up and Running with Caddy

Interested in a lightweight, high performing web server alternative that makes encrypting traffic stupid easy? By Andy Soell
Wed, Mar 2, 2016
Filed under: server admin, web server, caddy, howto,

I’ve been writing PHP applications for the better part of twenty years, so you probably won’t be surprised to know that I’m an old-school Apache guy. I’ve certainly worked on PHP applications built on other web servers like Nginx and even Microsoft IIS, but when I’m building out the hosting environment I’ve always defaulted to Apache. I know how it works, I know how to install and configure it, so I haven’t had much motivation to branch out into other options. When we recently announced the launch of our new web site and blog, though, I was intrigued by some feedback we got:

I had actually not heard about Caddy before, but I was intrigured. It’s relatively new and built on the Go programming language. I’ve been quite taken by several other products built in Go, so Joe’s tweet certainly caught my attention. There’s a lot of jargon here, so before we dive into implementation let’s break down the benefits Joe is pointing out:


What is HTTP/2? It’s a major update to the fundamental way that data is transmitted across the Internet. The previous standard, HTTP 1.1, was standardized in 1997 so an update has been a long time coming. HTTP/2 is (without splitting hairs too much) backwards compatible with HTTP 1.1, meaning that web applications themselves do not need to be written differently, and all that is required is that web servers and web browsers be updated to handle the updated protocol. As of 2016 every major web browser how has HTTP/2 support, so adopting it on the server side makes a lot of sense now.

What does HTTP/2 support do to benefit us, though? The details are, to be quite honest, over my head—but the short answer is that it brings reduced latency and increased page load speeds, mostly through optimized encryption and compression. So if your web application relies on lots of data communication between the server and the front-end, using an HTTP/2 capabile web server like Caddy makes a whole lot of sense.

Built-in TLS support

There is no reason in 2016 for any web site to not deliver content over a secure connection and Caddy, along with the fine people at LetsEncrypt, have made it insanely easy (not to mention free). When configured properly, Caddy serves your application over a TLS-secured connection so you and your users know that your data is encrypted.

Let’s Do This!

Seriously, this is going to be really easy. Let me outline the assumptions we’re making here first:

  • You have a moderate familiarity with Linux-based servers (in our case, we’re running an Ubuntu 14.04.4 x64 droplet on DigitalOcean)
  • You have a domain name and know enough about DNS to point it to your server’s IP address


First things first, lets install Caddy:

sudo curl -fsSL https://getcaddy.com | bash -s search

If you’re not sure what this does and are at all cautious about running a random script downloaded from the Internet on your server (as you should be) you can instead download the install script directly or download the server and do a manual installation. It’s not much harder, but does involve a few more steps.

System configuration

Second, we’re going to allow caddy to use standard Internet network ports:

sudo setcap cap_net_bind_service=+ep /usr/local/bin/caddy

Site configuration

Next, we’re going to configure Caddy. Use your favorite editor to create a new file (I keep it in the directory that contains all my web sites) called Caddyfile and define your site using the following format:

yourdomain.com {
  root /opt/sites/yourdomain.com/dist/
  tls you@yourdomain.com

This does three important things:

  • Tells Caddy the domain name it will be responding to requests for;
  • Shows it where the application lives in the file system; and,
  • Tells it to enable TLS support

This last point deserves a little more detail: In just that one line, Caddy knows that it should talk to the LetsEncrypt service and get a TLS certificate and route all traffic through it. All you need to do is supply your email address and everything else is taken care of, including automatically renewing the TLS certificate every 90 days. It really can’t get much easier than that, although you can certainly add some complexity if your application requires it.

Server configuration

Finally, we need to tell the server that it should start Caddy during the boot process. Create a new file at /etc/init/caddy.conf and add the following system configuration directives.

description "Caddy Server startup script"

start on runlevel [2345]
stop on runlevel [016]

respawn limit 10 5

        cd /opt/sites # This is the path to where you placed the Caddyfile
        exec /usr/local/bin/caddy
end script

Start it up!

From here you should be ready to run your new web server: service caddy start should give you a pretty friendly response. Then just plug your domain name into your web browser (you did set up your DNS properly, right?) and bask in the glory of your HTTP/2 served, TLS encrypted web application!

Building On This

Of course, this is the bare minimum. This installation doesn’t really even do anything like serve dynamic content or serve multiple sites, but Caddy is certainly capabile of that. If you’re intrigued I recommend looking at the Caddy Documentation for a better look at everything it can do, including PHP via fastcgi, gzip compression, url rewriting, load balancing and WebSockets.

Old Dog, New Tricks

Although I’m still relatively new to Caddy, I’m having a hard time thinking of a good reason to keep using Apache. I’m much more familiar with it, but that’s a pretty bad reason to continue using a piece of software as important as a web server. The next time you start in on a new project, take a few minutes to evaluate the assumptions you’re making about the tools you’re using and ask yourself if there might be a tool out there better suited for the task.