How to set up a reverse proxy with HTTPS in less than 2 minutes with Caddy on Ubuntu

Subscribe to my newsletter and never miss my upcoming articles

Tired of nginx? Try Caddy -- a full featured web server that automatically handles HTTPS and SSL and is easily configurable.

Prerequisites

Install Caddy

echo "deb [trusted=yes] https://apt.fury.io/caddy/ /" \
    | sudo tee -a /etc/apt/sources.list.d/caddy-fury.list
sudo apt update
sudo apt install caddy

Install Caddy via the apt package manager Here's what these commands do:

  1. Add the Caddy source to your local package registry
  2. Pull in the new packages
  3. Install Caddy

Setup Caddy

This is painfully easy. When you installed Caddy it was automatically added as a service, all you need to do is edit the configuration file located at /etc/caddy/Caddyfile . Open it with your favourite text editor and paste the following:

your.domain.com

reverse_proxy 127.0.0.1:8000

Substitute your.domain.com for – well – your domain (don't forget to add a DNS record pointing to your server) and 8000 for the port you want to reverse proxy requests to.

Restart the Caddy service with sudo systemctl restart caddy and Caddy will automatically issue a SSL certificate for your domain via Let's Encrypt and activate HTTPS – no more configuration required.

Extra: If you want to add multiple domains

Just change the Caddyfile to the following and restart the service:

your.domain.com {

    reverse_proxy 127.0.0.1:8000

}

other.domain.com {

    reverse_proxy 127.0.0.1:5432

}

Extra: More configuration options

There are a lot more directives (that's what the reverse_proxy part is called). If you're curious what else Caddy can do (it's a full featured web server – e.g. a lot) check out their brilliant documentation.

Sandeep Panda's photo

Caddy is wonderful. We use it at Hashnode in production and totally love it. :)

Bruce Röttgers's photo

Amazing, switched from a Ghost blog self-hosted with Caddy to Hashnode. The branding is a bit aggressive but for what you're providing a good trade-off. Would be amazing if you guys added a Ghost importer :)

Peter Thaleikis's photo

Nice, if my servers wouldn't be managed by a service I would switch...

Show +4 replies
Bruce Röttgers's photo

Peter Thaleikis You get unlimited bandwith + serverless functions. Their DNS propagation is blazing fast and it auto-generates deployments for all your branches (tho I think that this works with netlify as well)

Peter Thaleikis's photo

Yeah, deployments for all branches works with Netlify too. Looking at this feature set, how do they earn money Bruce Röttgers ?

Damon's photo

Hi Bruce, I hope you can help me. I found your instructions very user friendly, easy to read, easy to follow, easy to get up and running. Thanks for the help.

Now for my problem. I have two servers, server-a and server-b. Server-a runs NGINX websites with PHP. I was trying to get an NGINX reverse-proxy working, but was having to much trouble. After following your guide, I was able to get all three of my sites up and running on both servers (server-a and server-b both have websites on them). My problem is I can't get my PHP enabled NGINX site to run the PHP code. When I click a link, it keeps downloading the file instead of executing and changing pages. I've searched the web and found several suggestions on how to enable PHP in Caddy, but none of them are working. Here is what my Caddy file looks like: my.domain-1 { reverse_proxy localhost:7080 encode gzip zstd php_fastcgi unix//run/php/php7.4-fpm.sock } my.domain-2 { reverse_proxy 10.10.2.24:8080 } my.domain-3 { reverse_proxy localhost:9080 }

All three sites are working, but only my.domain-1 is a PHP site.

Again, I am using NGINX as my web server on both server-a and server-b, and PHP is installed on server-a only. The NGINX site on server-a works perfectly without the Caddy reverse-proxy.

Can you help me get PHP enabled on my site with Caddy as my reverse-proxy?

Thanks, Damon

Bruce Röttgers's photo

Hi Damon,

do I understand correctly that you're installing Caddy on server-a?

The php_fastcgi directive replaces the reverse_proxy directive.

Do you have a specific reason you want to keep serving the PHP site via nginx?

If you want to proxy to nginx, you don't need the php_fastcgi, but should be able to only use reverse_proxy.

If you want to switch completely to Caddy on server-a, you could try out the example in their docs. I would also review their documentation on the php_fastcgi directive. As my knowledge of php is fairly limited, I don't know how this is usually done on either nginx or caddy.

Hope this helps.