Writing a Caddy JSON config from scratch

Using JSON can be tedious but has numerous advantages, including the ability to easily generate and consume the structure in almost any programming language, fine-grained control via the API, and unparalleled flexibility that you don’t get with any config adapters. Chances are, if you’re trying to accomplish something that is difficult or complex with a config adapter, there is a more elegant solution in straight JSON.

First, become familiar with Caddy’s JSON structure.

:sparkles: I highly recommend installing an auto-completion helper into your editor. Install the caddy-json-schema plugin and then install the output of caddy json-schema into your editor for a streamlined experience.

An empty config looks like this and is totally valid (but does nothing):

{}

To be useful, you’ll want to start by declaring an “app” module. For example, the http app makes it easy to set up an HTTP server:

{
	"apps": {
		"http": {
			"servers": {
				"myserver": {
					"listen": [":80"]
				}
			}
		}
	}
}

This HTTP server only writes empty responses. To do something useful, create a route:

{
	"apps": {
		"http": {
			"servers": {
				"myserver": {
					"listen": [":80"],
					"routes": [
						{
							"handle": [{
								"handler": "file_server",
								"root": "/var/www"
							}]
						}
					]
				}
			}
		}
	}
}

That serves static files out of the /var/www folder.

To enable automatic HTTPS, all we need to do is specify a hostname at which we are serving the site (notice how we change the port here to the HTTPS port):

{
	"apps": {
		"http": {
			"servers": {
				"myserver": {
					"listen": [":443"],
					"routes": [
						{
							"match": [{"host": ["localhost"]}],
							"handle": [{
								"handler": "file_server",
								"root": "/var/www"
							}]
						}
					]
				}
			}
		}
	}
}

With that, Caddy will generate and renew a certificate for localhost and static files will only be served at that hostname.

That’s about all there is to it!

Bonus tips

  • Building up a config from scratch can be a rewarding experience. But, it’s not always necessary. You can often get “close enough” using an adapter of your choice like the Caddyfile or nginx config and then edit the resulting JSON to accomplish what you need.

  • Using a code editor with IntelliSense (i.e. intelligent code completion) features can be a big help, but especially when writing JSON Caddy configuration you will find caddy-json-schema incredibly useful. See this post for more info: Getting a better experience with JSON/YAML configuration

6 Likes