Getting started with caddy web server
Tags: beginners, devops, programming, opensource
Published: 2018-05-26 09:57:45

---
title: Getting started with caddy web server
published: true
description: a super cool webserver for quickly spinning up https services
tags: #beginners #devOps #programming #opensource
cover_image: https://thepracticaldev.s3.amazonaws.com/i/31vgsq5w5qfa0afrk3h0.png
---

> The piece was originally published on my blog at [legobox](https://medium.com/legobox/another-kickass-server-called-caddy-2bc24e8d8028)

# Background

Last year I came across a server called caddy, I kinda liked it because it's name sounded similar to that of one of my favourite rap artiste cardi b, sounds weird right?, just kidding, that not why I loved the caddy web server, rather it was a much simpler server to install and configure than nginx, and what’s more it comes with its own integration of ssl certificates for your domains and these includes wildcards, in this article we are going to take a birds eye view of the server and get to understand why it's a great tool.


# Prerequisite

There are really not much to know about, before diving into this, but it would be nice if you’ve got the following.


- At least a good understanding of servers and proxying.
- A general understanding of SSL - Secure Shell Layer and HTTPs

With these, you are good to go.

# Origins.

Long story short caddy was created by Light Code Labs, and made open source, it operates in a similar manner to nginx with the use of server blocks, just that in this case all configurations can be done in one file called the Caddyfile, It implements https (yea emphasis on s) once its specified as part of the domain name.

Its light and lightening fast and has lots of really good documentation associated with it. Since I’ve been able to convince you (hopefully), let us have a look at how we can install and setup caddy.


# Setting up caddy

First things first, you can download caddy by visiting the website (https://caddyserver.com/download), installation is pretty straightforward and easy to get on with, Most of it has been specified by their documentation, If you are looking to set up for a docker container, you might be interested in checking out this docker image.

If you downloaded the zip file, The follow these instructions to get rolling.

First, put the caddy binary in the system wide binary directory and give it appropriate ownership and permissions:

```bash
    sudo cp /path/to/caddy /usr/local/bin
    sudo chown root:root /usr/local/bin/caddy
    sudo chmod 755 /usr/local/bin/caddy
```

Give the caddy binary the ability to bind to privileged ports (e.g. 80, 443) as a non-root user:

```bash

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

Set up the user, group, and directories that will be needed:


```bash
    sudo groupadd -g 33 www-data
    sudo useradd \
      -g www-data --no-user-group \
      --home-dir /var/www --no-create-home \
      --shell /usr/sbin/nologin \
      --system --uid 33 www-data
    
    sudo mkdir /etc/caddy
    sudo chown -R root:www-data /etc/caddy
    sudo mkdir /etc/ssl/caddy
    sudo chown -R root:www-data /etc/ssl/caddy
    sudo chmod 0770 /etc/ssl/caddy
```

Place your caddy configuration in the appropriate directory and give it appropriate ownership and permissions:

```bash

    sudo cp /path/to/Caddyfile /etc/caddy/
    sudo chown www-data:www-data /etc/caddy/Caddyfile
    sudo chmod 444 /etc/caddy/Caddyfile
```

Create the home directory for the server and give it appropriate ownership
and permissions:

```bash

    sudo mkdir /var/www
    sudo chown www-data:www-data /var/www
    sudo chmod 555 /var/www
```

Let's assume you have the contents of your website in a directory called 'example.com'.
Put your website into place for it to be served by caddy:

```bash
    sudo cp -R example.com /var/www/
    sudo chown -R www-data:www-data /var/www/example.com
    sudo chmod -R 555 /var/www/example.com
```

You'll need to explicitly configure caddy to serve the site from this location by adding
the following to your Caddyfile if you haven't already:

```bash
    example.com {
        root /var/www/example.com
        ...
    }
```

Install the systemd service unit configuration file, reload the systemd daemon,
and start caddy:


```bash
    wget https://raw.githubusercontent.com/mholt/caddy/master/dist/init/linux-systemd/caddy.service
    sudo cp caddy.service /etc/systemd/system/
    sudo chown root:root /etc/systemd/system/caddy.service
    sudo chmod 644 /etc/systemd/system/caddy.service
    sudo systemctl daemon-reload
    sudo systemctl start caddy.service
```

Have the caddy service start automatically on boot if you like:


```bash
    sudo systemctl enable caddy.service
```

If caddy doesn't seem to start properly you can view the log data to help figure out what the problem is:

```bash
    journalctl --boot -u caddy.service
```

Use `log stdout` and `errors stderr` in your Caddyfile to fully utilize systemd journaling.

If your GNU/Linux distribution does not use *journald* with *systemd* then check any logfiles in `/var/log`.

If you want to follow the latest logs from caddy you can do so like this:

```bash
    journalctl -f -u caddy.service
```

You can make other certificates and private key files accessible to the `www-data` user with the following command:


```bash
    setfacl -m user:www-data:r-- /etc/ssl/private/my.key
```


# The caddy file

While setting up you may have caught a glimpse of the caddyfile, now lets have a real look at it, how do we setup a server block, its as simple as this.

```
    https://mydopesite.com {
      root /path/to/site_files
    }
```

Voila, that simple. Let's break it down so we can understand it some more (since its so difficult)


## Site Address

The HTTP server uses site addresses for labels. Addresses are specified in the form `scheme``://``host``:``port``/``path`, where all but one are optional.

The host portion is usually localhost or the domain name. The default port is 2015 (unless the site qualifies for automatic HTTPS, in which case it's changed to 443 for you). The scheme portion is another way to specify a port. Valid schemes are "http" or "https" which represent, respectively, ports 80 and 443. If both a scheme and port are specified, the port takes precedence. For example (this table assumes automatic HTTPS is applied where it qualifies):

```
    :2015                    # Host: (any), Port: 2015
    localhost                # Host: localhost; Port: 2015
    localhost:8080           # Host: localhost; Port: 8080
    example.com              # Host: example.com; Ports: 80->443
    http://example.com       # Host: example.com; Port: 80
    https://example.com      # Host: example.com; Ports: 80->443
    http://example.com:1234  # Host: example.com; Port: 1234
```

Wildcard characters `*` can be used in a hostname. A wildcard must take the place of an entire domain label: `*.example.com` is valid but `foo*.example.com` is not.


## Path Matching.

Some directives accept an argument that specifies a base path to match. A base path is a prefix. If the URL starts with the base path, it will be a match. For example, a base path of `/foo` will match requests to `/foo`, `/foo.html`, `/foobar`, and `/foo/bar.html`.

## Directives

Most directives invoke a layer of middleware. Middleware is a small layer in the application that handles HTTP requests and does one thing really well. Middleware are chained together (pre-compiled, if you will) at startup. Only middleware handlers which are invoked from the Caddyfile will be chained in, so small Caddyfiles are very fast and efficient.

The syntax of arguments varies from directive to directive. Some have required arguments, others don't. Consult the documentation of each directive for their signatures.

## Placeholders

In some cases, directives will accept placeholders (replaceable values). These are words that are enclosed by curly braces `{ }` and interpreted by the HTTP server at request-time. For example, `{query}` or `{>Referer}`. Think of them like variables. These placeholders have no relationship to the environment variables you can use in Caddyfiles, except we borrowed the syntax for familiarity.

If you are looking to understand some more about this, it would be wonderful to invest some time into the docs. (click here to get there)


## Proxying and Load balancing in caddy

Pulling off proxy actions in caddy is as simple as setting up the proxy directive.
This middleware adds a placeholder that can be used in log formats: {upstream} - the name of the upstream host to which the request was proxied.

```
    https://mydomain.here{
      // usual structure is (proxy from to)
      proxy /api localhost:9005
    }
```

The above proxy makes all /api routes redirect to localhost:9005 (the machine’s localhost).
You can use the policy options in the proxy to set up proxying algorithm based on the same concept if the nginx algorithms.

```
    proxy / web1.local:80 web2.local:90 web3.local:100 {
            policy round_robin
    }
```

Here are the policies associated with load balancing

**Policies**
There are several load balancing policies available:


- random (default) - Randomly select a backend
- least_conn - Select backend with the fewest active connections
- round_robin - Select backend in round-robin fashion
- first - Select the first available backend in the order they are defined in the Caddyfile
- ip_hash - Select backend by hashing the request IP, distributing evenly over the hash space based on the total number of backends
- uri_hash - Select backend by hashing the request URI, distributing evenly over the hash space based on the total number of backends
- header - Select by hashing the value of a given header, specified by the [value] after the policy name, distributing evenly over the hash space based on the total number of backends


# Conclusion

It’s clear by now that I do love working with caddy, it's a simple tool that does the job so well, there are many options for web servers out there, but the benefits this server gives is quite exciting and worthwhile.

If you are looking to learn some more about it, feel free to check out the project on https://caddyserver.com.