explain caddy config

This commit is contained in:
Kulvir Singh
2025-11-02 14:50:57 +05:30
parent d22f33469e
commit af6e365459
2 changed files with 153 additions and 39 deletions

View File

@@ -1,4 +1,4 @@
pokemon.domain-name.com {
pokemon.domain.com {
reverse_proxy :8080 # Assuming the application is running at PORT 8080
handle_errors {
@@ -10,6 +10,6 @@ pokemon.domain-name.com {
}
# just domain name looks much cleaner
www.pokemon.domain-name.com {
redir pokemon.domain-name.com{uri}
www.pokemon.domain.com {
redir pokemon.domain.com{uri}
}

View File

@@ -1,77 +1,191 @@
# Caddy web server and reverse proxy
# Caddy Web Server and Reverse Proxy
Usually we will have multiple services and websites running on our VPS. So we need a web server which will listen on `HTTP` and `HTTPS` ports and redirect the traffic to correct service.
**Caddy** is a web server that:
* Serves websites and web applications
* Can act as a [reverse proxy](https://en.wikipedia.org/wiki/Reverse_proxy)
* Automatically gets and renews TLS certificates so you get HTTPS for free!!
## Installation
I'll install caddy as a `systemd` service on my ubuntu machine. Hence I'll following [debian docs](https://caddyserver.com/docs/install#debian-ubuntu-raspbian) to install caddy.
To verify if caddy is installed and running run the following command.
Follow the official [Caddy Installation guide](https://caddyserver.com/docs/install#debian-ubuntu-raspbian) to install it.
To check if Caddy is installed and running
```bash
sudo service caddy status
# You should see something like
# active (running)
```
Caddy web server is now started on your VPS and you can visit `domain-name.com` and see the caddy homepage. Caddy homepage will tell you where to edit caddy config and where you can put your static files for your webserver.
## TLS Certificates
Caddy is now running! By default, it listens on port 80 (HTTP). Visit your domain name in a browser - you should see Caddy's default welcome page.
Right now Caddy is running on HTTP only `80` port. To use automatic HTTPS replace the `:80` port in caddy config to your domain name.
Before that ensure DNS record of domain name points to IP address of VPS.
```diff
- :80 {
+ domain-name.com {
Caddy's main config file is usually at `/etc/caddy/Caddyfile`.
This is where we will configure caddy web server.
## Setting up HTTPS for secure connection
**Pre Requisite**: Make sure domain's DNS A record points to your VPS IP address.
If you haven't done this yet, go back to the [VPS setup guide](../setup-vps.md) and complete the domain name section.
Open Caddy's config file
```bash
sudo vim /etc/caddy/Caddyfile
```
You'll see something like
```Caddyfile
:80 {
root * /var/www/html
file_server
}
```
After making any change to caddy config we also need to restart the caddy service.
Replace it with your domain name
```Caddyfile
domain.com {
root * /var/www/html # website files to server
file_server # enable static file server
}
```
Caddy will automatically get TLS certificate for `domain.com`.
We need not to worry about provisioning certificates or renewning them.
After making changes, reload Caddy configuration:
```bash
sudo systemctl reload caddy
```
Now visit `domain-name.com` again and it will be serving site over HTTPS.
Caddy will automatically provision and renew TLS certificates from [LetsEncrypt](https://letsencrypt.org)
Now visit `https://domain.com` (notice the `https`). HTTP traffic is secure and encrypted.
## Redirects
You might want to setup few redirects to your root domain for like IP Address and `www` sub domain.
You probably want to redirect a few things:
* Visitors using `www.domain.com` -> redirect to `domain.com`
* Visitors using your server's IP address (`192.168.1.`) -> redirect to `domain.com`
```Caddyfile
192.168.1.1,
www.domain-name.com {
redir https://domain-name.com{uri}
www.domain.com {
redir https://domain.com{uri}
}
```
You can setup this rule for multiple domains by either writing them space seperated or comma seperated as above.
`{uri}` specified at the end of domain name preserves the path from the URL user entered.
Now if anyone visits your website via server's IP address or using `www` subdomain they will be redirected to your root domain.
**It just looks cleaner.**
## Multiple file caddy config
This config sets up the redirects as mentioned. You can list multiple domains/addresses separated by commas or spaces.
All visitors will end up at `https://yourdomain.com`, which looks clean imo!!!
Caddy supports writing config in multiple files so that we don't polluting our main config. Just import all other caddy configs to the main caddy config.
Usually we can structure our config files in any way it doesn't matter. But there are some common ways to structure it.
Reload Caddy after making changes
```bash
sudo systemctl reload caddy
```
## Organizing Configuration
As we add more services, Caddyfile can get long and bloated. Caddy lets you split your configuration across multiple files!
### 1. Create the Config Directory
```bash
sudo mkdir -p /etc/caddy/conf.d
```
This directory will hold service specific config files, one file per service (e.g. `pokemon-api.Caddyfile`).
### 2. Update Main Caddyfile
Add this line in the main Caddyfile
Place all other config files inside `/etc/caddy/conf.d/` directory and import Caddyfile from this directory to main config file.
```Caddyfile
import conf.d/*.Caddyfile
```
## Handling errors
It will load all `.Caddyfile` files from the `conf.d` directory.
We can put each service's config in its own file!
We can setup seperate error pages for different kind of error. But I'll be using single `error.html` page which is a [caddy template](https://caddyserver.com/docs/caddyfile/directives/templates) page and I can fill in error msg and error code using [placeholders](https://caddyserver.com/docs/modules/http.handlers.templates#placeholder).
For reference look at [error.html](./error.html) file.
Right now we don't have any specific service, but soon we will have.
To learn more about it check the Caddy docs **RTFM** about [handling errors](https://caddyserver.com/docs/caddyfile/directives/handle_errors).
## Custom Error Page
When something goes wrong, we can show a nice custom error page instead of Caddy's default.
There's a custom error page you can use [error.html](./error.html). It uses Caddy placeholders to show the error code and message.
Save it inside `/var/www` directory.
In your Caddyfile, add error_handler inside your domain block
```Caddyfile
domain.com {
root * /var/www/html
file_server
handle_errors {
root * /var/www
rewrite * /error.html
templates
file_server
}
}
```
* `handle_errors` - Catches all error responses
* `root * /var/www` - Specifies here to find the error.html file
* `rewrite * /error.html` - shows error.html for all errors
* `templates` - Enables Caddy's templating
**To learn more** Check out [error handling](https://caddyserver.com/docs/caddyfile/directives/handle_errors) and [templates](https://caddyserver.com/docs/caddyfile/directives/templates) documentation
Reload caddy as usual
```bash
sudo systemctl reload caddy
```
## Reverse Proxy
**Most of the devs don't know what reverse proxy is. So maybe [check this](https://en.wikipedia.org/wiki/Reverse_proxy) out.**
Reverse proxy makes it easier to run multiple services running on one server without exposing multiple ports
We can have different subdomain for each service and reverse proxy will handle the routing.
When someone visits `pokemon.domain.com`, the reverse proxy looks at the request and forwards it to the correct service running on the server.
Lets say we have `pokemon` API running on PORT `8080` and we want any traffic coming to subdomain `pokemon.domain-name.com` to be redirected to the pokemon server.
To achieve this we can setup reverse proxy for this subdomain.
To setup reverse proxy first we need to set `A Record` of sub-domain to the IP address of the VPS.
Then we can define the reverse proxy in our caddy config like mentioned below.
Let's say we have a pokemon API running on port 8080, and it should accessible at `pokemon.domain.com`.
### 1. Set Up DNS
In domain's DNS settings, create an A record
- **Name**: `pokemon` (for `pokemon.domain.com`)
- **Value**: Server's IP address
Wait for few minutes for DNS to propagate.
### 2. Create the Reverse Proxy Config
Create a new config file for the pokemon api
```bash
sudo vim /etc/caddy/conf.d/pokemon.Caddyfile
```
Add this block of configuration
```Caddyfile
pokemon.domain-name.com {
pokemon.domain.com {
reverse_proxy :8080
}
```
Checkout this sample reverse proxy [config](./pokemon.Caddyfile) and ofc read [caddy docs](https://caddyserver.com/docs/quick-starts/reverse-proxy) to check what else you can do with reverse proxy.
Reload Caddy
```bash
sudo systemctl reload caddy
```
Now visit `https://pokemon.domain.com` - Caddy will forward all traffic to your service and automatically get an HTTPS certificate for this domain.
I've included a template for reverse proxy block with error handling and redirects for `www` subdomain
Checkout the [`pokemon.Caddyfile`](./pokemon.Caddyfile) file. You can use as it as for setting up reverse proxies.
**To learn more** check out [reverse proxy](https://caddyserver.com/docs/quick-starts/reverse-proxy) documentation.