Docker Compose setup behind Caddy results in 502 Bad Gateway

Hi everyone,

I’m trying to set up InvoiceNinja on my VPS behind a Caddy Reverse Proxy, specifically using lucaslorentz/caddy-docker-proxy.

I’ve successfully configured other applications using this setup, but when I try to access InvoiceNinja, I’m only getting a 502 Bad Gateway error (from nginx I suppose?).

The containers start without errors, and inter-container communication seems to work, so I think it’s a misconfiguration of either nginx oder the Caddy Reverse Proxy, but I cannot figure out the issue. Is anyone familiar with Caddy and could help me resolving this?

Here’s my docker-compose.yml

version: '3.7'
services:
  server:
    image: nginx
    restart: always
    env_file: env
    volumes:
      - ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro
      - ./docker/app/public:/var/www/app/public:ro
    depends_on:
      - app
    ports:
      - "8082:80"
    networks:
      - invoiceninja
      - caddy
    labels:
      caddy: invoiceninja.example.com
      caddy.reverse_proxy: "{{upstreams 8082}}"
    extra_hosts:
      - "in5.localhost:192.168.0.124 "
  app:
    image: invoiceninja/invoiceninja:5
    env_file: env
    restart: always
    volumes:
      - ./config/hosts:/etc/hosts:ro
      - ./docker/app/public:/var/www/app/public:rw,delegated
      - ./docker/app/storage:/var/www/app/storage:rw,delegated
    depends_on:
      - db
    networks:
      - invoiceninja
    extra_hosts:
      - "in5.localhost:192.168.0.124 "
  db:
    image: mysql:8
    ports:
      - "3305:3306"
    restart: always
    env_file: env
    volumes:
      - ./docker/mysql/data:/var/lib/mysql:rw,delegated
    networks:
      - invoiceninja
    extra_hosts:
      - "in5.localhost:192.168.0.124 "
networks:
  invoiceninja:
    external: false
  caddy:
    external: true

env variables:

APP_URL=https://invoiceninja.example.com
REQUIRE_HTTPS=false
TRUSTED_PROXIES=*
[…]

Hi,

@david do you have any thoughts?

Caddy has been on my list of tech learning.

The dockerfile was originally created by a community member who already implemented Caddy, you should just be able to uncomment the line in the docker-compose file

  # Vhost configuration
  #- ./config/caddy/Caddyfile:/etc/caddy/Caddyfiledocker-com
  - ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro
  - ./docker/app/public:/var/www/app/public:ro

And then comment out the nginx config and it should work.

I haven’t actually tried this, but from feedback I believe it is working.

Thanks @david !

I’m not a Caddy expert myself, so it’s a lot of trial and error for me :wink:

I’ve tried uncommenting the line, looked at the Caddyfile and the other config files, but no, something’s wrong with my setup.

I will keep trying, and I will report back if I am successful.

@mattsches

I was able to get this working on my system, but it did take some changes:

These were the changes needed to the docker-compose file:

  1. change server to caddy:alpiine
  2. comment out nginx conf and uncomment Caddy
  3. for my system port 80 was not available so i changed the mapping to 8030
version: '3.7'

services:
  server:
    image: caddy:alpine
    restart: always
    env_file: env
    volumes:
      # Vhost configuration
      - ./config/caddy/Caddyfile:/etc/caddy/Caddyfile
        #- ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro
      - ./docker/app/public:/var/www/app/public:ro
    depends_on:
      - app
    # Run webserver nginx on port 80
    # Feel free to modify depending what port is already occupied
    ports:
      - "8030:80"

In the caddy file, by default it will always attempt to force HTTPS, as i am running this locally, i needed to edit the caddyfile to turn off https using the global parameter.

I also had to explicitly define http://in.localhost for the vhost

{
        auto_https off
}

http://in.localhost {
        root * /var/www/app/public
        php_fastcgi app:9000
        encode zstd gzip
        file_server browse
}

After saving, the container came up fine and I was able to log in.

Hope this helps!

2 Likes

Thank you, this is really helpful :+1:
I have already tried the same changes to docker-compose.yml without success, but I have not yet modified the Caddyfile as you suggest. I will give that a try in the next few days. Right now I don’t have time for it, but I’ll give feedback if it worked.

Hi @mattsches ,

I’m not in front of my laptop right now and don’t have access to any servers, but the upstreams directive should take the containers port, not the docker port published on localhost for the container.

So in the above docker-compose.yml, your labels should look like this to be picked up correctly by lucaslorentz-docker-proxy:

labels:
  caddy: yourserver.tld
  caddy.reverse_proxy: "{{upstreams 80}}"

I think this is pretty much how I run IN behind caddy proxy but will check again later. Replacing nginx completely also works (should have a working config somewhere), but this way you use IN’s nginx and just give caddy-proxy the proxying and certs job. Works nicely.

Hope this helps, if not, let me know and I’ll check again on my side.

Caddy is amazing, as is licaslorentz-docker-proxy, and of course IN! Great combo.

2 Likes