Caddy Server - Basic Configuration
Tags: webdev, go, linux, caddy
Published: 2023-11-18 19:19:40

Caddy 2 is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go. And in this article, I'm going to show you how you can get started using it. This article will not give you an in-depth explanation of how to serve your applications, it's just a starting point.

First of all, you will need to install Caddy, for that, you can take a look at their awesome [documentation](https://caddyserver.com/docs/install). Once you have Caddy installed, we can get into configuring it.

In order to configure Caddy we will need to modify the Caddyfile, this file can be found in `/etc/caddy/Caddyfile`. This file has no extension and holds our Caddy configuration.

The first thing I like to do is create a `conf.d` directory inside `/etc/caddy` and now you will see why. But first, let's modify the Caddyfile.

Our final Caddyfile should look something like this:
```
{
    email example@mail.com
}

(static) {
    @static {
        file 
        path *.ico *.css *.js *.gif *.js *.jpeg *.jpg *.png *.webp *.ico *.svg *.ttf *.json
    }
    header @static Cache-Control max-age=5184000
}

(security) {
    header {
        #Enable HSTS
        Strict-Transport-Security max-age=31536000;
        #Disable Clients from Sniffing Media Type
        X-Content-Type-Options nosniff
        #Keep Referrer Data off of HTTP Connections
        Referrer-Policy no-referrer-when-downgrade
    }
}

(cors) {
  @cors_preflight method OPTIONS
  @cors header Origin {args.0}

  handle @cors_preflight {
    header Access-Control-Allow-Origin "{args.0}"
    header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE"
    header Access-Control-Allow-Headers "Content-Type"
    header Access-Control-Max-Age "3600"
    respond "" 204
  }

  handle @cors {
    header Access-Control-Allow-Origin "{args.0}"
    header Access-Control-Expose-Headers "Link"
  }
}

import conf.d/*.conf
```
Every time we define something between parenthesis, we are defining some values that we will be able to import into our specific site configuration. This configuration contains the basics that any project should have.

Once we have the Caddyfile ready, we can create a specific file for each project we want to use Caddy on, inside the `conf.d` directory. Let's say, for example, that we have a project named Example, we would create a `example.conf` file inside the `conf.d` directory we created earlier, and thanks to our Caddyfile configuration, Caddy will load and use this file.

What should this configuration file look like?
If we have a node server running that we want to expose, we can use a **reverse proxy**, and for that, our config file could look something like:
```
myexampledomain.com {
    encode zstd gzip 
    import static
    import security    

    reverse_proxy http://localhost:3000
}
```
See that we are importing `static` and `security` that we have defined in our Caddyfile, then we are using the `reverse_proxy` directive to essentially bind `http://localhost:3000` to the domain name we provided.

We can also host a static site, that could look something like:
```
myexampledomain.com {
	encode zstd gzip 
	import static
	import security
	
	root * /var/www/public_html/examplesite
	file_server  
}

```
Here we are serving the site located in `/var/www/public_html/examplesite` on the domain we specified.

And lastly, we can even handle CORS with Caddy. Imagine we have an exposed Golang API and Vue as our frontend. If we want, we can handle CORS with Caddy like this:
```
myexampledomain.com {
	encode zstd gzip 
	import static
	import security

	root * /var/www/public_html/examplesite
	try_files {path} /
	file_server
}

api.myexampledomain.com{
	import cors https://myexampledomain.com
	encode zstd gzip
        import static
        import security

	reverse_proxy http://localhost:8080
}

```
And this CORS configuration is the one we defined inside our Caddyfile! 

Caddy is my go-to server for serving my applications, and these are some of the configurations I use. I hope they can help some of you get started with Caddy. For a more in-depth explanation of what each directive does, I suggest you look at the [Caddy Documentation](https://caddyserver.com/docs/).