Files
self-host-101/caddy/readme.md

189 lines
5.4 KiB
Markdown
Raw Normal View History

2025-11-02 14:50:57 +05:30
# Caddy Web Server and Reverse Proxy
2025-10-15 01:47:36 +05:30
2025-11-02 14:50:57 +05:30
**Caddy** is a web server that:
* Serves websites and web applications
* Can act as a [reverse proxy](https://en.wikipedia.org/wiki/Reverse_proxy)
2025-10-15 01:47:36 +05:30
## Installation
2025-11-02 14:50:57 +05:30
Follow the official [Caddy Installation guide](https://caddyserver.com/docs/install#debian-ubuntu-raspbian) to install it.
2025-11-03 02:05:22 +05:30
To check if Caddy is installed and running
2025-11-02 14:50:57 +05:30
2025-10-15 01:47:36 +05:30
```bash
sudo service caddy status
2025-11-02 14:50:57 +05:30
# You should see something like
2025-11-03 02:05:22 +05:30
# active (running)
2025-11-02 14:50:57 +05:30
```
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.
2025-11-03 02:05:22 +05:30
Caddy's main config file is usually at `/etc/caddy/Caddyfile`. This is where we will configure the Caddy web server.
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
## Setting up HTTPS for Secure Connection
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
Before starting, make sure your 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.
2025-11-02 14:50:57 +05:30
```bash
sudo vim /etc/caddy/Caddyfile
```
You'll see something like
```Caddyfile
:80 {
root * /var/www/html
file_server
}
2025-10-15 01:47:36 +05:30
```
2025-11-03 02:05:22 +05:30
Replace `:80` with your domain name:
2025-10-15 01:47:36 +05:30
2025-11-02 14:50:57 +05:30
```Caddyfile
domain.com {
2025-11-03 02:05:22 +05:30
root * /var/www/html # website files to serve
2025-11-02 14:50:57 +05:30
file_server # enable static file server
2025-10-15 01:47:36 +05:30
}
```
2025-11-03 02:05:22 +05:30
Caddy will automatically get a TLS certificate for `domain.com`. You don't need to worry about provisioning certificates or renewing them - Caddy handles all of that automatically!
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
After making changes, reload Caddy
2025-11-02 14:50:57 +05:30
2025-10-15 01:47:36 +05:30
```bash
sudo systemctl reload caddy
```
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
Now visit `https://domain.com` (notice the `https`). Your HTTP traffic is now secure and encrypted!
2025-10-15 01:56:24 +05:30
## Redirects
2025-11-02 14:50:57 +05:30
You probably want to redirect a few things:
2025-11-03 02:05:22 +05:30
* Visitors using `www.domain.com` → redirect to `domain.com`
* Visitors using your server's IP address (`192.168.1.1`) → redirect to `domain.com`
Add this block to your Caddyfile:
2025-10-15 01:56:24 +05:30
```Caddyfile
192.168.1.1,
2025-11-02 14:50:57 +05:30
www.domain.com {
redir https://domain.com{uri}
2025-10-15 01:56:24 +05:30
}
```
2025-10-15 02:17:55 +05:30
2025-11-03 02:05:22 +05:30
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://domain.com`, which keeps things clean and consistent!
After making changes, reload Caddy
2025-11-02 14:50:57 +05:30
```bash
sudo systemctl reload caddy
```
## Organizing Configuration
2025-10-15 02:17:55 +05:30
2025-11-03 02:05:22 +05:30
As we add more services, the Caddyfile can get long and bloated. Caddy lets you split your configuration across multiple files!
2025-11-02 14:50:57 +05:30
### 1. Create the Config Directory
```bash
sudo mkdir -p /etc/caddy/conf.d
```
2025-11-03 02:05:22 +05:30
This directory will hold service-specific config files, one file per service (e.g., `pokemon-api.Caddyfile`).
2025-11-02 14:50:57 +05:30
### 2. Update Main Caddyfile
2025-11-03 02:05:22 +05:30
Add this line to the main Caddyfile
2025-10-15 02:17:55 +05:30
```Caddyfile
import conf.d/*.Caddyfile
```
2025-10-15 02:35:39 +05:30
2025-11-03 02:05:22 +05:30
It will load all `.Caddyfile` files from the `conf.d` directory. We can put each service's config in its own file!
2025-11-02 14:50:57 +05:30
Right now we don't have any specific service, but soon we will have.
2025-10-15 02:35:39 +05:30
2025-11-02 14:50:57 +05:30
## Custom Error Page
2025-10-15 02:35:39 +05:30
2025-11-02 14:50:57 +05:30
When something goes wrong, we can show a nice custom error page instead of Caddy's default.
2025-11-03 02:05:22 +05:30
### 1. The Error Page
There's a custom error page you can use: [error.html](./error.html). It uses Caddy placeholders to show the error code and message.
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
Save it inside the `/var/www` directory.
### 2. Configure Error Handling
In your Caddyfile, add `handle_errors` inside your domain block:
2025-11-02 14:50:57 +05:30
```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
2025-11-03 02:05:22 +05:30
* `root * /var/www` - Specifies where to find the error.html file
* `rewrite * /error.html` - Shows error.html for all errors
* `templates` - Enables Caddy's templating
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
**Reference:** Check out [error handling](https://caddyserver.com/docs/caddyfile/directives/handle_errors) and [templates](https://caddyserver.com/docs/caddyfile/directives/templates) documentation.
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
After making changes, reload Caddy
2025-11-02 14:50:57 +05:30
```bash
sudo systemctl reload caddy
```
2025-10-15 13:45:16 +05:30
## Reverse Proxy
2025-11-03 02:05:22 +05:30
Reverse proxy makes it easier to run multiple services on one server without exposing multiple ports. We can have different subdomains for each service, and the 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.
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
Let's say we have a pokemon API running on port 8080, and it should be accessible at `pokemon.domain.com`.
2025-11-02 14:50:57 +05:30
### 1. Set Up DNS
2025-11-03 02:05:22 +05:30
In your domain's DNS settings, create an A record
* **Name**: `pokemon` (for `pokemon.domain.com`)
* **Value**: Server's IP address
2025-10-15 13:45:16 +05:30
2025-11-03 02:05:22 +05:30
Wait for a few minutes for DNS to propagate.
2025-11-02 14:50:57 +05:30
### 2. Create the Reverse Proxy Config
2025-11-03 02:05:22 +05:30
Create a new config file for the pokemon API
2025-11-02 14:50:57 +05:30
```bash
sudo vim /etc/caddy/conf.d/pokemon.Caddyfile
```
Add this block of configuration
2025-10-15 13:45:16 +05:30
```Caddyfile
2025-11-02 14:50:57 +05:30
pokemon.domain.com {
2025-10-15 13:45:16 +05:30
reverse_proxy :8080
}
```
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
After creating the config file, reload Caddy:
2025-11-02 14:50:57 +05:30
```bash
sudo systemctl reload caddy
```
2025-11-03 02:05:22 +05:30
Now visit `https://pokemon.domain.com` - Caddy will forward all traffic to your service and automatically get an HTTPS certificate for this domain!
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
I've included a template for reverse proxy block with error handling and redirects for `www` subdomain. Check out the [`pokemon.Caddyfile`](./pokemon.Caddyfile) file. You can use it as a template for setting up reverse proxies.
2025-11-02 14:50:57 +05:30
2025-11-03 02:05:22 +05:30
**Reference:** Check out [reverse proxy](https://caddyserver.com/docs/quick-starts/reverse-proxy) documentation.