Get Rewarded! We will reward you with up to €50 credit on your account for every tutorial that you write and we publish!

Caddy as simple Reverse Proxy and File Server

profile picture
Author
Maximilian Jannack
Published
2022-01-21
Time to read
7 minutes reading time

Introduction

Following this tutorial, you will be able to set up Caddy on a fresh system (using Ubuntu here; but instructions are very universal) and also learn about the basic usage of Caddy as file server and as reverse proxy. While this is only to get started quickly with some tips here and there, you can always dive deeper with the official documentation of Caddy:

Caddy can also be used via the Caddy CLI to quickly deploy a development setup or test things - this would lengthen the tutorial unnecessarily though. If you set up Caddy and got familiar with it, the CLI won't be a problem anyway. See the official documentation for more information.

There are many other, more advanced, directives for Caddy such as redir, rewrite, response, etc. to allow or block specific files or folders for example. To keep it short and simple, this will not be covered in this tutorial. See the official documentation for more information.


Prerequisites

  • Your server is running one of the officially supported operating system:
    • Ubuntu, Debian, Raspbian (used in this tutorial)
    • Fedora, RedHat, CentOS, Arch Linux, Manjaro, Parabola
    • Any other Docker compatible operating system
    • See the official documentation for more information and other systems
  • You have a FQDN (Fully Qualified Domain Name) which means: you need a domain which points towards the IP address of the server which runs Caddy
  • DNS (have your subdomain point to your server's IP; simply try to ping it to check if it's working)
  • SSH access with root privileges
  • PHP (if you want to use php-fpm later)
  • Port 80 and 443 are not in use (see Step #0)

Step 0 - Stop any other web servers

Since Caddy will naturally use port 80 and 443 to serve HTTP and HTTPS content - as a web server does - it is best to stop any other running web servers (e.g. Nginx, Apache, ...).

Please note, that depending on the OS, it is possible that a web server is already preinstalled and running without you knowing it. To check, you can use something like

netstat -tulpn | grep ":80\|:443"

to see whether a service is currently using port 80 and/or 443.

If for example Apache is already running, you can stop and disable it (otherwise it will try to autostart upon reboot) with

systemctl stop apache
systemctl disable apache

Step 1 - Install Caddy

If you just set up a completely fresh server, run these two commands first:

sudo apt update
sudo apt upgrade -y # optional but recommended

This will fetch available packages and update your system.

The following five commands are needed to install Caddy on your server.

Ubuntu, Debian, Raspbian:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/caddy-stable.asc
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

If you use a different OS or want to use static binaries, please refer to the official documentation.


Step 2 - Set up a subdomain to serve static files or use a reverse proxy

In the following two steps you can either (or both) create a new subdomain for any static files (Step 2.1) or for a reverse proxy (Step 2.2) to access ports instead of a folder. Step 2.3 contains a mixture of both.

You can of course have many of both possibilities, so feel free to try both examples.

To edit the global Caddyfile with your preferred editor:

nano /etc/caddy/Caddyfile

Save your changes with Ctrl+X -> Y -> Enter in the case of 'nano'.


Step 2.1 - Option 1: Set up a subdomain to serve a local website

If you have a local website or even just files/folders of any kind, which you want to make publicly available through your domain, you can use the so-called directive file_server.

Insert (or rather append) your new configuration into the global Caddyfile (see Step 2):

<sub.example.com> {
    root * /path/to/your/website # sets the root of all other directives
    file_server # tells Caddy to serve the static files found at the root (see above)
}

Replace the following placeholders with your desired values:

  • <sub.example.com> - Your subdomain (e.g. wiki) with your Top-Level-Domain (TLD) (e.g. hetznerserver.com) -> wiki.hetznerserver.com
  • /path/to/your/website - Absolute path to the root of your website (e.g. /var/www/html/mywiki)

A possible configuration would therefore be:

wiki.hetznerserver.com {
    root * /var/www/html/mywiki
    file_server
}

Now save your changes and exit the editor.

Note: If your local site needs PHP-FPM to work, just add the following directive between the root and file_server statement from above:

php_fastcgi unix//run/php/php7.4-fpm.sock # replace the php version if you use a different one

More information:

Jump to Step 3 to deploy your new subdomain!


Step 2.2 - Option 2: Set up a subdomain to reverse proxy to a local port

If you have any services running on your server, which serve their content via a dedicated port, you can use a reverse proxy to access those via a subdomain.

This is especially useful for Docker containers!

Open your global Caddyfile again (see Step 2) and append the following lines:

<sub.example.com> {
    reverse_proxy 127.0.0.1:PORT # tell Caddy to reverse proxy that port to your subdomain
}

Replace the following placeholders with your desired values:

  • <sub.example.com> - Your subdomain (e.g. cloud) with your Top-Level-Domain (TLD) (e.g. hetznerserver.com) -> cloud.hetznerserver.com
  • PORT - The port to your application or docker container

A possible configuration would therefore be:

cloud.hetznerserver.com {
    reverse_proxy 127.0.0.1:8080
}

Now save your changes and exit the editor.

Jump to Step 3 to deploy your new subdomain!


Step 2.3 - Option 3: Use a mixture of static file serving and reverse proxies

You can have a mixture of both presented use cases of Caddy deployed on your server by simply having multiple configurations in your global Caddyfile.

Using the examples from Step 2.1 and Step 2.2 this would look like this:

wiki.hetznerserver.com {
    root * /var/www/html/mywiki
    file_server
}

cloud.hetznerserver.com {
    reverse_proxy 127.0.0.1:8080
}

Now save your changes and exit the editor.

Jump to Step 3 to deploy your new subdomain!


Step 3 - Deploy changes

To apply any changes to your Caddyfile, simply reload the Caddy service:

systemctl reload caddy

That's it!

Caddy will also generate a SSL certificate for your new subdomain, so you can use HTTPS!

Now navigate to your new subdomain (e.g. https://wiki.hetznerserver.com/) and check the result!


Conclusion

Congratulations! You can now easily serve any local websites or your many docker containers - just to name a few examples.

If you need additional headers, access rules or any other custom settings, you can do so quite easily! Check the official documentation for that.

This tutorial was tested on a Hetzner CPX11 cloud server to verify the provided commands.

License: MIT
Want to contribute?

Get Rewarded: Get up to €50 in credit! Be a part of the community and contribute. Do it for the money. Do it for the bragging rights. And do it to teach others!

Report Issue
Try Hetzner Cloud

Get 20€ free credit!

Valid until: 31 December 2024 Valid for: 3 months and only for new customers
Get started
Want to contribute?

Get Rewarded: Get up to €50 credit on your account for every tutorial you write and we publish!

Find out more