Caddy Reverse Proxy Tutorial

Jim Kang
Fullstack Memory Dump
3 min readMar 23, 2018


We’re going to use caddy’s reverse proxy function to protect all your api, website, and whatever you put on it. This tutorial will use docker container as one of the base setup. If you don’t know anything about docker, you’re still ok. I’ve also wrote a tutorial “From Go code to Docker container” if you’re a go programmer. Let’s get started!

note1: You’ll need to setup docker as a pre-requisite. If you don’t, here’s the site
note2: You’ll have to have a domain name and IP address, if not, you probably won’t be able to have a “hands-on” experience.

1. Let’s start some API service.

docker container run -p 5000:5000 proclaim/crp-app1

use your browser and points to localhost port 5000

Member API

Let’s start another API

docker container run -p 8800:8800 proclaim/crp-app2

open another browser’s tab and points to localhost port 8800

Food API

Now we got 2 API service up and running, it’s time to put on Caddy
(I’m using 2 API to illustrate different API, developed by different team, using different DB, docker network…etc, to illustrate the idea that they can all put together with reverse proxy)

2. Setup Caddyfile for reverse proxy info

This part will have to do with your server, you can ssh into your server (linux?). Start at the default path cd ~ Make a file call Caddyfile and let’s put in some content {
proxy /api/member
proxy /api/food

please replace with your domain name, and with your server’s IP. We can see that we proxy memberto port 5000, and food to port 8800. Hope you’re following along ok.

3. Start Caddy

  • If you got time to read, read this article and make sure you don’t do anything until you finished reading until the end. Otherwise you’ll end up like me, used up all the SSL requests and have to wait for a week (bummer)
  • If you’re too lazy, oh, I mean your time is very precious, here’s the rest of the tutorial:

from home directory ( cd ~ ), make a folder called .caddy

mkdir .caddy

Here’s the Caddy startup script

docker run -d --name caddy \
-p 80:80 \
-p 443:443 \
-v $HOME/Caddyfile:/etc/Caddyfile \
-v $HOME/.caddy:/root/.caddy \

-d means running as daemon (background)
--name is the name of this container running instance name
-p ports are 80 and 443
-v (first) is the volume (mount) for Caddyfile setup instruction
-v (second) is the SSL certificate storage location, so we won’t request a new SSL every time we start caddy.

If you’re having trouble, I encourage to read / learn more about docker. And finally, here are the results:

Quite easy eh? Hope I leveled you up a bit ;-)



Jim Kang
Fullstack Memory Dump

love writing bit sized programming memo, acoustic guitarist, proud daddy of 5 and great listener (to my kids)