---

Alias: ["caddy"]
Tag: ["💻", "🖥️", "Reverse-Proxy"]
Date: 2021-09-19
DocType: "Personal"
Hierarchy: "NonRoot"
TimeStamp:
location: [51.514678599999996, -0.18378583926867909]
CollapseMetaTable: true

---

Parent:: [[Selfhosting]], [[Server Tools]]

---

 ^Top

 

```button
name Save
type command
action Save current file
id Save
```
^button-caddySave

 

# Configuring caddy

 

```ad-abstract
title: Summary
collapse: open
This note runs through [caddy](https://caddyserver.com), a free tool webserver allowing for reverse-proxy and automatic SSL certifications.
```

 

```toc
style: number
```

 

---

 

### Installation
[[#^Top|TOP]]
 

#### Program installation

1. **Pull the software signature key & image**

```ad-command
~~~bash
echo "deb [trusted=yes] https://apt.fury.io/caddy/ /" | sudo tee -a /etc/apt/sources.list.d/caddy-fury.list
~~~
```

3. **Install caddy**

```ad-command
~~~bash
sudo apt update
sudo apt install caddy
~~~
```

Installing caddy will create a default user 'caddy'.

4. **Test install**

Go to the homepage to see the caddy default page.

 

#### Installing php

PHP needs to be enabled for caddy to work.

```ad-command
~~~bash
sudo add-apt-repository ppa:ondrej/php
sudo apt install php-cli php-fpm php-mysql
~~~
```

Check if php is installed correctly:

```ad-command
~~~bash
php --version
~~~
```

 

---

 

### Configuration of caddy
[[#^Top|TOP]]
 

Caddy will fetch a **SSL certificate** for all sub-domains and addresses present in the config file automatically, once the declaration is made properly.

 

#### Basic files & directories
[[#^Top|TOP]]
1. Create a default website folder

```ad-command
~~~bash
sudo mkdir -p /var/www/html
~~~
```

2. Create a default log folder

```ad-command
~~~bash
sudo mkdir /var/log/caddy
sudo chown -R caddy:caddy /var/log/caddy
~~~
```

 

---

 

#### Caddy configuration file
[[#^Top|TOP]]
Caddy's configuration file is inder:

```ad-path
/etc/caddy/Caddyfile
```

Default configuration is:

```ad-code
~~~javascript
(localhost) {
	root * /var/www/html
	encode gzip zstd
	php_fastcgi unix//run/php/php7.4-fpm.sock
	tls (service email) {
		protocols tls1.2 tls1.3
	}
}
~~~
```

 

---

 

#### PHP configuration file
[[#^Top|TOP]]
To update php, edit the following file:

```ad-path
/etc/php/7.4/fpm/pool.d/www.conf
```

Change all 'www-data' user reference with 'caddy' including:

```ad-code
~~~yaml
listen.owner = caddy
listen.group = caddy
~~~
```

Once this is done, restart php:

```ad-command
~~~bash
sudo systemctl restart php7.4-fpm
~~~
```

 

---

 

#### Configuring CORS
[[#^Top|TOP]]
 

##### Preliminary CORS code snippet

```ad-code
~~~javascript
(cors) {
        @origin{args.0} header Origin {args.0}
        header @origin{args.0} Access-Control-Allow-Origin "{args.0}"
}
~~~
```

 

##### CORS for a sub-domain

```ad-code
~~~javascript
 import cors (http://subdomain.tld)
 header Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT"
 header Access-Control-Allow-Headers "*"
~~~
```

 

---

 

#### Configuration of a sub-domain suffix
[[#^Top|TOP]]
Configuration requires to add the following in the sub-domain definition of the [[Configuring Caddy#Caddy configuration file|Caddyfile]]:

```ad-code
~~~javascript
 handle_path /(suffix)* {
	 root * /(path to suffix)
	 file_server
 }
~~~
```

 

---

 

#### Configuring with the docker network
[[#^Top|TOP]]
Configuration of a service attached to the docker network is easy:

```ad-code
~~~javascript
(hostname) {
	encode zstd gzip
	reverse_proxy xxx.yyy.zzz.aaa:port
}
~~~
```

 

---

 

#### Configuring login with a cookie
[[#^Top|TOP]]
```ad-info
title: Tutorial
[Link](https://josheli.com/knob/2021/02/24/single-sign-on-in-caddy-server-using-only-the-caddyfile-and-basic-authentication/)
```

 

##### Preliminary login code snippets

1. **Creat hashed passwords**

```ad-command
~~~bash
caddy hash-password
~~~
```

2. **Define the array of users and hashed password**

In the [[Configuring Caddy#Caddy configuration file|Caddyfile]]:

```ad-code
~~~javascript
(basic-auth) {
	basicauth / {
		user hashed-password
	}
}
~~~
```
 
3. **Define the snippet to test whether the cookie is installed**

In the [[Configuring Caddy#Caddy configuration file|Caddyfile]]:

```ad-code
~~~javascript
(proxy-auth) {
% if cookie not = some-token-nonsense
	@no-auth {
		not header_regexp mycookie Cookie myid=(regex-to-match-id)
	}

% store current time, page and redirect to auth
	route @no-auth {
		header Set-Cookie "myreferer={scheme}://{host}{uri}; Domain=example.com; Path=/; Max-Age=30; HttpOnly; SameSite=Strict; Secure"
		redir https://auth.example.com
	}
}
~~~
```

 

##### Intermediary authentication page
[[#^Top|TOP]]
After setting up a new subdomain/page and appropriate DNS records, define it as follows in the [[Configuring Caddy#Caddy configuration file|Caddyfile]]:

```ad-code
~~~javascript
auth.example.com {
	route / {
% require authentication
		import basic-auth

% upon successful auth, set a client token
		header Set-Cookie "myid=some-long-hopefully-random-string; Domain=example.com; Path=/; Max-Age=3600; HttpOnly; SameSite=Strict; Secure"

% delete the referer cookie
		header +Set-Cookie "myreferer=null; Domain=example.com; Path=/; Expires=Thu, 25 Sep 1971 12:00:00 GMT; HttpOnly; SameSite=Strict; Secure"
     
% redirect back to the original site
		redir {http.request.cookie.myreferer}
	}

% fallback
	respond "Hi."
}
~~~
```

 

##### Adding authentication to a subdomain

Simply add the following at the top of all declarations for sub-domain definitions:

```ad-code
~~~javascript
import proxy-auth
~~~
```

 

---

 

#### Configuring logging for Caddy

1. In the [[Configuring Caddy#Caddy configuration file|Caddyfile]], add a logging module:

```ad-code
title: logging script
~~~javascript
(log) {
 
 log {

   output file /var/log/caddy/caddy.log {
    roll_local_time
	# Other parameters can be found on the Caddy website
   }
   format json # (or console)
   level INFO # (or ERROR)
 }
}
~~~
```

 

2. In the global configuration section, add the `import log` directive

```ad-code
~~~javascript
{
 import log
}
~~~
```

2. In each subdomain definition, add the following line

`import log`

 

---

 

### Utilities
[[#^Top|TOP]]
 

#### SSL Certification location

Look for a folder with the following sequence:

```ad-path
/.local/share/caddy
```

 

#### Reading the log file

Caddy does offer a `common_log` field in their JS log that can be called for consumption by other software:

```ad-command
~~~bash
sudo cat /var/log/caddy/caddy.log | jq -r ' .. | .common_log? | select(. !=null)'
~~~
```

 

#### Sending logs to user

In order to consume the logs, it is sent through a cron job to a [[Configuring Telegram bots|Telegram bot]].

The script is below:

```ad-code
~~~bash

~~~
```

 

---

 

### Basic commands
[[#^Top|TOP]]
A full repository of commands can be found [here](https://caddyserver.com/docs/)

 

#### Start/Stop/Restart

```ad-command
~~~bash
sudo systemctl start/stop/restart caddy
~~~
```

 

#### Reload config

Once config amended just run:

```ad-command
~~~bash
sudo systemctl reload caddy
~~~
```

[[#^Top|TOP]]