Install Caddy reverse proxy via Docker

| | |

Why caddy?

  • Easy to configure: Caddy’s configuration language is simple and easy to use.
  • Automatic HTTPS: Caddy is designed to make HTTPS as easy as possible. Caddy will automatically obtain and renew SSL certificates for your sites using Let’s Encrypt no config or work is needed.
  • Lightweight: Caddy is extremely lightweight and fast. Caddy can handle a lot of traffic while using minimal resources. yes even less than Nginx in some instances, and I say that as a lifelong Nginx fan.
  • Security: Caddy is designed with security in mind. It uses secure defaults like HTTPS and hsts etc by default.
  • Extensibility: Caddy has a plugin system that allows you to extend its functionality. There are many plugins available on their site.
  • Reverse proxy: Caddy’s built-in reverse proxy functionality is powerful and easy to use. It supports load balancing, URL rewriting, and other advanced features.

These are just some of Caddy’s amazing features!

Install Docker and Docker Compose if you haven’t already. View our docker guide here & our docker rootless guide here.

Scenario: you have a new app you wrote or installed via docker called mycoolapp you want to allow the outside world to connect to this but have a reverse proxy in the middle so you can apply e.g. rate limiting, ssl cert, basic auth etc.

Create a new directory for your Caddy configuration and change to it:

mkdir caddy
cd caddy

I prefer to make these in /opt/docker so for me its:

mkdir -p /opt/docker/caddy
cd /opt/docker/caddy

This is purely personal preference and you are the one to decide on this location.

Create a file called Caddyfile in this directory with the following contents: {
    reverse_proxy mycoolapp:80

If you don’t want to get an SSL cert for this domain automatically for free then use this {
    reverse_proxy mycoolapp:80

The above configuration tells Caddy to proxy all requests to to a web server running on port 80 at the hostname mycoolapp. Change these values to match your own configuration.

Create a docker-compose.yml file in the same directory with the following contents:

version: '3'
    image: caddy
    container_name: caddy
      - "80:80"
      - "443:443"
      - ACME_AGREE=true
    restart: unless-stopped
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy_data:/data
      - ./caddy_config:/config
      - public

    external: true

This configuration sets up a Docker container running Caddy with the Caddyfile we created earlier mounted as a volume along with two other folders needed by caddy. the env variable of acme_agree lets you accept the letsencrypt EULA.

You need to create a new network for caddy and for any other containers you want accessible via this reverse proxy.

docker network create public
docker connect public caddy
docker connect mycoolapp

The first command will create a new network named public, the second command will connect your caddy to the public network you just created and the third command will connect your app named mycoolapp to this network also so caddy can access it.

Start the Caddy container via the following command which will start the Caddy container in detached mode, meaning it will run in the background. and it will show you the logs from caddy so you can make sure there were no errors. hit CTRL + C to close the logs.

docker compose up -d && docker compose logs -f

Open a web browser and navigate to You should see the content served by the web server running on port 80 at the mycoolapp hostname.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *