Caddy used as reverse proxy to serve Plane self-hosted

1. The problem I’m having:

I started Caddy with a docker compose and I would like to use it as reverse proxy to serve a Plane self-hosted instance started with another docker compose. Without any success…

Somebody has a guide to configure Caddy and Plane in this configuration?

In advance, thank you!

2. Error messages and/or full log output:

A obtain always the ERR_TOO_MANY_REDIRECTS error.

3. Caddy version:

2.9.1

4. How I installed and ran Caddy:

a. System environment:

OS: Raspbian server

b. Command:

I follow the user guide of Plane to install and start the Plane self-hosted

So, start first the docker compose of Plane through the Plane setup script

docker ps
c9888b9ad534   makeplane/plane-proxy:v0.25.3       "/docker-entrypoint.…"   11 days ago   Up 11 days   0.0.0.0:8080->80/tcp, [::]:8080->80/tcp                                plane-app-proxy-1
d898771be774   makeplane/plane-backend:v0.25.3     "./bin/docker-entryp…"   11 days ago   Up 11 days   8000/tcp                                                               plane-app-worker-1
dc0775b33908   makeplane/plane-backend:v0.25.3     "./bin/docker-entryp…"   11 days ago   Up 11 days   8000/tcp                                                               plane-app-beat-worker-1
6eb06a5b6d2a   makeplane/plane-backend:v0.25.3     "./bin/docker-entryp…"   11 days ago   Up 11 days   8000/tcp                                                               plane-app-api-1
567e85e76276   makeplane/plane-space:v0.25.3       "docker-entrypoint.s…"   11 days ago   Up 11 days   3000/tcp                                                               plane-app-space-1
b59fb53e1aed   makeplane/plane-admin:v0.25.3       "docker-entrypoint.s…"   11 days ago   Up 11 days   3000/tcp                                                               plane-app-admin-1
45cac07bd4b8   makeplane/plane-live:v0.25.3        "docker-entrypoint.s…"   11 days ago   Up 11 days   3000/tcp                                                               plane-app-live-1
42b1e46ac5a0   makeplane/plane-frontend:v0.25.3    "docker-entrypoint.s…"   11 days ago   Up 11 days   3000/tcp                                                               plane-app-web-1
98cc7e63ab8c   postgres:15.7-alpine                "docker-entrypoint.s…"   11 days ago   Up 11 days   5432/tcp                                                               plane-app-plane-db-1
d8db1463781b   rabbitmq:3.13.6-management-alpine   "docker-entrypoint.s…"   11 days ago   Up 11 days   4369/tcp, 5671-5672/tcp, 15671-15672/tcp, 15691-15692/tcp, 25672/tcp   plane-app-plane-mq-1
3dd2ed302ddf   minio/minio:latest                  "/usr/bin/docker-ent…"   11 days ago   Up 11 days   9000/tcp                                                               plane-app-plane-minio-1
c046d0ff6e77   valkey/valkey:7.2.5-alpine          "docker-entrypoint.s…"   11 days ago   Up 11 days   6379/tcp                                                               plane-app-plane-redis-1

Then start the docker compose of Caddy.

docker ps
d04b4de331b8   caddy:alpine                        "caddy run --config …"   5 minutes ago   Up 5 minutes             0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp, 0.0.0.0:443->443/udp, [::]:443->443/udp, 2019/tcp   caddy
c9888b9ad534   makeplane/plane-proxy:v0.25.3       "/docker-entrypoint.…"   11 days ago     Up 11 days               0.0.0.0:8080->80/tcp, [::]:8080->80/tcp                                                                                           plane-app-proxy-1
d898771be774   makeplane/plane-backend:v0.25.3     "./bin/docker-entryp…"   11 days ago     Up 11 days               8000/tcp                                                                                                                          plane-app-worker-1
dc0775b33908   makeplane/plane-backend:v0.25.3     "./bin/docker-entryp…"   11 days ago     Up 11 days               8000/tcp                                                                                                                          plane-app-beat-worker-1
6eb06a5b6d2a   makeplane/plane-backend:v0.25.3     "./bin/docker-entryp…"   11 days ago     Up 11 days               8000/tcp                                                                                                                          plane-app-api-1
567e85e76276   makeplane/plane-space:v0.25.3       "docker-entrypoint.s…"   11 days ago     Up 11 days               3000/tcp                                                                                                                          plane-app-space-1
b59fb53e1aed   makeplane/plane-admin:v0.25.3       "docker-entrypoint.s…"   11 days ago     Up 11 days               3000/tcp                                                                                                                          plane-app-admin-1
45cac07bd4b8   makeplane/plane-live:v0.25.3        "docker-entrypoint.s…"   11 days ago     Up 11 days               3000/tcp                                                                                                                          plane-app-live-1
42b1e46ac5a0   makeplane/plane-frontend:v0.25.3    "docker-entrypoint.s…"   11 days ago     Up 11 days               3000/tcp                                                                                                                          plane-app-web-1
98cc7e63ab8c   postgres:15.7-alpine                "docker-entrypoint.s…"   11 days ago     Up 11 days               5432/tcp                                                                                                                          plane-app-plane-db-1
d8db1463781b   rabbitmq:3.13.6-management-alpine   "docker-entrypoint.s…"   11 days ago     Up 11 days               4369/tcp, 5671-5672/tcp, 15671-15672/tcp, 15691-15692/tcp, 25672/tcp                                                              plane-app-plane-mq-1
3dd2ed302ddf   minio/minio:latest                  "/usr/bin/docker-ent…"   11 days ago     Up 11 days               9000/tcp                                                                                                                          plane-app-plane-minio-1
c046d0ff6e77   valkey/valkey:7.2.5-alpine          "docker-entrypoint.s…"   11 days ago     Up 11 days               6379/tcp                                                                                                                          plane-app-plane-redis-1

We can see that Plane has created a Docker network:

julien@raspserve:~ $ docker network ls
NETWORK ID     NAME                DRIVER    SCOPE
db30b6caa305   bridge              bridge    local
375d089bc496   host                host      local
2189b2a6eb1f   julien_default      bridge    local
c3c04db02610   none                null      local
292c3552f1ab   plane-app_default   bridge    local

c. Service/unit/compose file:

My Caddy docker compose file:

services:
  caddy:
    container_name: caddy
    image: caddy:alpine
    restart: unless-stopped
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy/data:/data
      - ./caddy/config:/config
      - ./static:/srv
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"

    networks:
     - plane-app_default
	 
networks:
  plane-app_default:
    external: true

d. My complete Caddy config:

My Caddy file like suggested by the Plane documentation:

<domain> {
    redir / https://{host}{uri} permanent

    reverse_proxy plane-app-proxy-1:8080 {
        header_up X-Forwarded-Proto {scheme}
        header_up X-Forwarded-Host {host}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up Host {http.request.host}
        
        header_up Upgrade {http.request.header.Upgrade}
        header_up Connection {http.request.header.Connection}

        transport http {
            tls_insecure_skip_verify
            read_buffer 4096
            write_buffer 4096
        }
    }

    request_body {
        max_size 10MB
    }
}

d. My complete plane.env config:

This file is created during the Plane installation through the setup script:

APP_DOMAIN=localhost
APP_RELEASE=v0.25.3

WEB_REPLICAS=1
SPACE_REPLICAS=1
ADMIN_REPLICAS=1
API_REPLICAS=1
WORKER_REPLICAS=1
BEAT_WORKER_REPLICAS=1
LIVE_REPLICAS=1

NGINX_PORT=8080
WEB_URL=http://${APP_DOMAIN}
DEBUG=0
SENTRY_DSN=
SENTRY_ENVIRONMENT=production
CORS_ALLOWED_ORIGINS=http://${APP_DOMAIN}
API_BASE_URL=http://api:8000

#DB SETTINGS
PGHOST=plane-db
PGDATABASE=plane
POSTGRES_USER=plane
POSTGRES_PASSWORD=plane
POSTGRES_DB=plane
POSTGRES_PORT=5432
PGDATA=/var/lib/postgresql/data
DATABASE_URL=

# REDIS SETTINGS
REDIS_HOST=plane-redis
REDIS_PORT=6379
REDIS_URL=

# RabbitMQ Settings
RABBITMQ_HOST=plane-mq
RABBITMQ_PORT=5672
RABBITMQ_USER=plane
RABBITMQ_PASSWORD=plane
RABBITMQ_VHOST=plane
AMQP_URL=

# Secret Key
SECRET_KEY=60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5

# DATA STORE SETTINGS
USE_MINIO=1
AWS_REGION=
AWS_ACCESS_KEY_ID=access-key
AWS_SECRET_ACCESS_KEY=secret-key
AWS_S3_ENDPOINT_URL=http://plane-minio:9000
AWS_S3_BUCKET_NAME=uploads
FILE_SIZE_LIMIT=5242880

# Gunicorn Workers
GUNICORN_WORKERS=1

# UNCOMMENT `DOCKER_PLATFORM` IF YOU ARE ON `ARM64` AND DOCKER IMAGE IS NOT AVAILABLE FOR RESPECTIVE `APP_RELEASE`
# DOCKER_PLATFORM=linux/amd64

# Force HTTPS for handling SSL Termination
MINIO_ENDPOINT_SSL=0

# API key rate limit
API_KEY_RATE_LIMIT="60/minute"
DOCKERHUB_USER=makeplane
PULL_POLICY=if_not_present
CUSTOM_BUILD=false

Remove all of this

This is also wrong and should be removed

This is the biggest issue and what’s causing you trouble. Remove it.

Here’s everything you need:

<domain> {
    reverse_proxy plane-app-proxy-1:8080

    request_body {
        max_size 10MB
    }
}

The documentation on Plane website should be fixed

The container plane-app-proxy-1 should also be on the same Docker network. Is it?

Yes… The both containers are on plane-app_default :cry:

docker inspect -f '{{json .NetworkSettings.Networks}}' caddy
{"plane-app_default":{"IPAMConfig":null,"Links":null,"Aliases":["caddy","caddy"],"MacAddress":"62:7c:89:62:c8:ec","DriverOpts":null,"GwPriority":0,"NetworkID":"fccd7227df3472f7eb5576135274e940390d8dc472fda584e6f84d5479a313d0","EndpointID":"c83237f9c0f01bad440822958b24c7624a577faa66c2ca089caf889ee045b0be","Gateway":"172.18.0.1","IPAddress":"172.18.0.6","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"DNSNames":["caddy","f0f0df9df991"]}}
docker inspect -f '{{json .NetworkSettings.Networks}}' plane-app-proxy-1
{"plane-app_default":{"IPAMConfig":null,"Links":null,"Aliases":["plane-app-proxy-1","proxy"],"MacAddress":"5a:44:8f:83:4e:0a","DriverOpts":null,"GwPriority":0,"NetworkID":"fccd7227df3472f7eb5576135274e940390d8dc472fda584e6f84d5479a313d0","EndpointID":"20c5941105649b1d771da7516763017017d48cedbe6bd49390c6e8646ec286b0","Gateway":"172.18.0.1","IPAddress":"172.18.0.14","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"DNSNames":["plane-app-proxy-1","proxy","82406b6be105"]}}

In this case, I recommend asking the Docker community why isn’t Docker DNS able to resolve the container name despite the two containers being on the same network. This ultimately isn’t a Caddy issue but a Docker network issue.

Thank you Mohammed. (And sorry for the response delay)

Unfortunately, I don’t reach the goal and I don’t understand why :frowning:

But I think is due to a bad configuration about networks within Docker because when I run Caddy as a service all work fine.

Case 1: Caddy as container with Docker compose

I don’t reach the Plane web site. Error HTTP ERROR 502

My docker-compose.yml

services:
  caddy:
    container_name: caddy
    image: caddy:alpine
    restart: unless-stopped
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy/data:/data
      - ./caddy/config:/config
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"

    networks:
     - plane-app_default

networks:
  plane-app_default:
    external: true

My Caddyfile

<subdomain>.<domain> {
    respond "Hello world (served by Caddy from docker compose)"
}

plane.<domain> {
    reverse_proxy plane-app-proxy-1:8080

    request_body {
        max_size 10MB
    }
}

docker ps response command

CONTAINER ID   IMAGE                               COMMAND                  CREATED         STATUS         PORTS                                                                                                                             NAMES
f28b5e074c39   caddy:alpine                        "caddy run --config …"   3 minutes ago   Up 3 minutes   0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp, 0.0.0.0:443->443/udp, [::]:443->443/udp, 2019/tcp   caddy
82406b6be105   makeplane/plane-proxy:v0.25.3       "/docker-entrypoint.…"   17 hours ago    Up 17 hours    0.0.0.0:8080->80/tcp, [::]:8080->80/tcp                                                                                           plane-app-proxy-1
74a2d3e4e2a8   makeplane/plane-admin:v0.25.3       "docker-entrypoint.s…"   17 hours ago    Up 17 hours    3000/tcp                                                                                                                          plane-app-admin-1
cbab97155615   makeplane/plane-space:v0.25.3       "docker-entrypoint.s…"   17 hours ago    Up 17 hours    3000/tcp                                                                                                                          plane-app-space-1
739327a7b8cf   makeplane/plane-live:v0.25.3        "docker-entrypoint.s…"   17 hours ago    Up 17 hours    3000/tcp                                                                                                                          plane-app-live-1
22191b732491   makeplane/plane-frontend:v0.25.3    "docker-entrypoint.s…"   17 hours ago    Up 17 hours    3000/tcp                                                                                                                          plane-app-web-1
12ab0a259a94   makeplane/plane-backend:v0.25.3     "./bin/docker-entryp…"   17 hours ago    Up 17 hours    8000/tcp                                                                                                                          plane-app-worker-1
d3cb775567d2   makeplane/plane-backend:v0.25.3     "./bin/docker-entryp…"   17 hours ago    Up 17 hours    8000/tcp                                                                                                                          plane-app-beat-worker-1
d956e61b6eed   makeplane/plane-backend:v0.25.3     "./bin/docker-entryp…"   17 hours ago    Up 17 hours    8000/tcp                                                                                                                          plane-app-api-1
517d15d74130   rabbitmq:3.13.6-management-alpine   "docker-entrypoint.s…"   17 hours ago    Up 17 hours    4369/tcp, 5671-5672/tcp, 15671-15672/tcp, 15691-15692/tcp, 25672/tcp                                                              plane-app-plane-mq-1
11f3cb985ee3   postgres:15.7-alpine                "docker-entrypoint.s…"   17 hours ago    Up 17 hours    5432/tcp                                                                                                                          plane-app-plane-db-1
209695fbcdc3   minio/minio:latest                  "/usr/bin/docker-ent…"   17 hours ago    Up 17 hours    9000/tcp                                                                                                                          plane-app-plane-minio-1
6b64fe1b0fd0   valkey/valkey:7.2.5-alpine          "docker-entrypoint.s…"   17 hours ago    Up 17 hours    6379/tcp                                                                                                                          plane-app-plane-redis-1

docker network ls response command

NETWORK ID     NAME                DRIVER    SCOPE
665fd2044519   bridge              bridge    local
375d089bc496   host                host      local
c3c04db02610   none                null      local
fccd7227df34   plane-app_default   bridge    local

Case 2: Caddy as a service

I reach the Plane web site.

My Caddyfile

plane.<domain> {
    reverse_proxy localhost:8080

    request_body {
        max_size 10MB
    }
}

<subdomain>.<domain> {
    respond "Hello I'm fontenettes (served by Caddy from service system)"
}

In advance thank you for your support.
(post deleted by author)

I found! :raising_hands:

It just necessary to use the internal Plane proxy container port 80 instead of the NGINX_PORT configured through the plane.env configuration file (for my case 8080).

<subdomain>.<domain> {
    respond "Hello world (served by Caddy from docker compose)"
}

plane.<domain> {
    reverse_proxy plane-app-proxy-1:80

    request_body {
        max_size 10MB
    }
}
1 Like

Great! Thank you for sharing the solution :smiley: It’s been a long month and a half :grinning_face: