Files
self-host-101/caddy
2025-11-02 14:50:57 +05:30
..
2025-10-15 01:43:32 +05:30
2025-10-15 02:35:39 +05:30
2025-11-02 14:50:57 +05:30
2025-11-02 14:50:57 +05:30

Caddy Web Server and Reverse Proxy

Caddy is a web server that:

  • Serves websites and web applications
  • Can act as a reverse proxy
  • Automatically gets and renews TLS certificates so you get HTTPS for free!!

Installation

Follow the official Caddy Installation guide to install it.

To check if Caddy is installed and running

sudo service caddy status
# You should see something like 
# active (running) 

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.

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 and complete the domain name section.

Open Caddy's config file

sudo vim /etc/caddy/Caddyfile

You'll see something like

:80 {
    root * /var/www/html
    file_server
}

Replace it with your domain name

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:

sudo systemctl reload caddy

Now visit https://domain.com (notice the https). HTTP traffic is secure and encrypted.

Redirects

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
192.168.1.1,
www.domain.com {
    redir https://domain.com{uri}
}

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!!!

Reload Caddy after making changes

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

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

import conf.d/*.Caddyfile

It will load all .Caddyfile files from the conf.d directory. We can put each service's config in its own file!

Right now we don't have any specific service, but soon we will have.

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. 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

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 and templates documentation

Reload caddy as usual

sudo systemctl reload caddy

Reverse Proxy

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.

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

sudo vim /etc/caddy/conf.d/pokemon.Caddyfile

Add this block of configuration

pokemon.domain.com {
    reverse_proxy :8080
}

Reload Caddy

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 file. You can use as it as for setting up reverse proxies.

To learn more check out reverse proxy documentation.