Caddy is a modern, open-source web server that stands out for its automatic HTTPS configuration using Let's Encrypt, simplifying the process of securing websites. It's designed with user-friendliness in mind making it accessible to both beginners and experienced users. Caddy's modular architecture allows easy integration of plugins for extended functionality.
Installing Caddy
Caddy is available on multiple platforms including Windows. For this guide, we are going to install the binaries, but you are also able to compile it from source.
We need to add the required repos and install Caddy :
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
installing this package automatically starts and runs Caddy as a systemd service named caddy. It also comes with an optional caddy-api service which is used if you primarily configure Caddy via its API instead of config files.
Then we will enable and start Caddy.
systemctl enable caddy && systemctl start caddy
We can check if everything with the status flag of systemctl:
systemctl status caddy
Output:
caddy.service - Caddy
Loaded: loaded (/lib/systemd/system/caddy.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-08-28 10:44:07 UTC; 1min 19s ago
Docs: https://caddyserver.com/docs/
Main PID: 154914 (caddy)
Tasks: 6 (limit: 2274)
Memory: 10.3M
CGroup: /system.slice/caddy.service
└─154914 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
Adding modules
One of the most popular features of Caddy is the ease of installing different modules to suit your needs. The process is very streamlined. The only caveat is, if you have already installed Caddy you will need to download the program anew, selecting the modules you want installed, or recompile it with the appropriate flags. We will touch only on the standard download. Go to this page https://caddyserver.com/download. Select your platform, in our case Linux amd64, click on the modules you wish to be included with your installation, and click on download.
After the installation is done you can check the modules installed by running the following command:
caddy list-modules
To add a module you will need to visit their GitHub page because their configuration varies. As an example let's say that you want to add the Cloudflare module. By visiting their GitHub repo we can see that we need to add the following to our Caddyfile with the appropriate token:
tls {
dns cloudflare {env.CF_API_TOKEN}
}
Configure Caddy
You are able to configure Caddy both with standard config files and through the API using Json files. We will go over both methods starting with the standard file configuration.
Caddyfile and .html configuration
Create the /var/www/html directory if it doesn't already exist with the following command:
mkdir -p /var/www/html
Here we will place the .html files of our site. You can use the example file provided here for testing purposes.
<!DOCTYPE html>
<html>
<head>
<title>Hello from Caddy!</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
Then we will need to edit the /etc/caddy/Caddyfile with the text editor of your choice:
nano /etc/caddy/Caddyfile
<your_Domain_here>
root * /var/www/html
file_server
There might be a lot more text when you open the Caddyfile, but these settings are all that's needed for setting up a basic website.
Now reload Caddy with the following command:
systemctl reload caddy
Now in our web browser type the domain that we put in the config file and we will get the following page:
As you can see by the lock at the top right, the site is automatically HTTPS certified, which is one of the main features of Caddy
JSON and API configuration
The endpoint by default is localhost:2019. This can be changed by setting the CADDY_ADMIN environment variable. We will be using the default endpoint.
We will need to create a .json file for our configuration.
nano config.json
{
"apps": {
"http": {
"servers": {
"my_server": {
"listen": [":443"],
"routes": [
{
"handle": [
{
"handler": "static_response",
"body": "Hello world"
}
],
"match": [
{
"host": [Your_Domain_here]
}
]
}
]
}
}
}
}
}
Now to run the .json file with the API type the following command:
curl localhost:2019/load \
-H "Content-Type: application/json" \
-d @config.json
You can either go to your domain in your browser or use curl to verify that everything works:
curl <your_domain_here>
Hello world
You are also able to use the API with Caddyfile configuration with the following synaxis:
curl "http://localhost:2019/load" \
-H "Content-Type: text/caddyfile" \
--data-binary @Caddyfile
Here are some useful API calls that might come in handy.
Caddy API Calls
API Call | Description |
---|---|
/config |
Retrieve the current Caddy configuration. |
/load |
Load a new configuration into Caddy (does not activate it). |
/validate |
Validate the configuration for errors without loading it. |
/reload |
Reload the active configuration, applying any changes. |
/stop |
Stop the Caddy server gracefully. |
/status |
Check the status of the Caddy server. |