From af6e3654595808f0092fe50d3eef0619edf0ff8e Mon Sep 17 00:00:00 2001 From: Kulvir Singh Date: Sun, 2 Nov 2025 14:50:57 +0530 Subject: [PATCH] explain caddy config --- caddy/pokemon.Caddyfile | 6 +- caddy/readme.md | 186 ++++++++++++++++++++++++++++++++-------- 2 files changed, 153 insertions(+), 39 deletions(-) diff --git a/caddy/pokemon.Caddyfile b/caddy/pokemon.Caddyfile index 7379838..3acf8ed 100644 --- a/caddy/pokemon.Caddyfile +++ b/caddy/pokemon.Caddyfile @@ -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} } diff --git a/caddy/readme.md b/caddy/readme.md index 3707816..ddaf14c 100644 --- a/caddy/readme.md +++ b/caddy/readme.md @@ -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.