Docker Caddyfile reverse_proxy fails

1. Caddy version (caddy version):

v2.4.6

2. How I run Caddy:

docker-compose (one compose file for the entire stack)

a. System environment:

Digital Ocean droplet running Ubuntu 20.04, Docker 20.10.7, docker-compose version 1.25.0

b. Command:

'''
docker-compose down && docker-compose up -d

c. Service/unit/compose file:

version: '3'

services:
  proxy:
    image: caddy:alpine
    container_name: proxy
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - $PWD/Caddyfile:/etc/caddy/Caddyfile
      - $PWD/caddy/data:/data
      - $PWD/caddy/config:/config
    environment:
      - DOMAIN={}
      - EMAIL={}   # Email used for ACME registration
      - LOG_FILE=$PWD/access.log

  vaultwarden:
    image: vaultwarden/server:alpine
    container_name: vaultwarden
    restart: always
    volumes:
      - ./vw-data:/data

  linkding:
    image: sissbruecker/linkding:latest
    container_name: linkding
    restart: always
    ports:
      - 9090:9090
    volumes:
      - /srv/linkding:/etc/linkding/data

networks:
  default:
    external:
      name: docker

d. My complete Caddyfile or JSON config:

vault.{$DOMAIN}:443 {
  log {
    level INFO
    output file {$LOG_FILE} {
      roll_size 10MB
      roll_keep 10
    }
  }

  # Use the ACME HTTP-01 challenge to get a cert for the configured domain.
  tls {$EMAIL}

  # This setting may have compatibility issues with some browsers
  # (e.g., attachment downloading on Firefox). Try disabling this
  # if you encounter issues.
  encode gzip

  # Notifications redirected to the WebSocket server
  reverse_proxy /notifications/hub vaultwarden:3012

  # Proxy everything else to Rocket
  reverse_proxy vaultwarden:80 {
       # Send the true remote IP to Rocket, so that vaultwarden can put this in the
       # log, so that fail2ban can ban the correct IP.
       header_up X-Real-IP {remote_host}
  }
}

links.{$DOMAIN}:80 {
    reverse_proxy linkding:9090
}

3. The problem I’m having:

I can get vaultwarden to work properly through it’s subdomain (vault.domain) and it persists as it should through restarts. curl output:

root@ubuntu-s-1vcpu-1gb-nyc3-01:/srv# curl -v vault.{}
*   Trying {}...
* TCP_NODELAY set
* Connected to vault.{} ({}) port 80 (#0)
> GET / HTTP/1.1
> Host: vault.{}
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://vault.{}/
< Server: Caddy
< Date: Thu, 21 Apr 2022 17:36:32 GMT
< Content-Length: 0
< 
* Closing connection 0

I can also get linkding (and this applies to everything except vaultwarden) to work if I host it separately (for example, if I type {DOMAIN}:9090, I will get the linkding interface), so I know the problem isn’t with the service.

But when I try to go to the new subdomain (link.{DOMAIN}, it fails 100% of the time.

root@ubuntu-s-1vcpu-1gb-nyc3-01:/srv# curl -v links.{}
*   Trying {}...
* TCP_NODELAY set
* Connected to links.{} ({}) port 80 (#0)
> GET / HTTP/1.1
> Host: links.{}
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< Content-Language: en
< Content-Length: 0
< Content-Type: text/html; charset=utf-8
< Location: /bookmarks
< Referrer-Policy: same-origin
< Server: Caddy
< Vary: Accept-Language
< X-Content-Type-Options: nosniff
< X-Frame-Options: DENY
< Date: Thu, 21 Apr 2022 17:36:11 GMT
< 
* Connection #0 to host links.{} left intact

4. Error messages and/or full log output:

5. What I already tried:

I have tried multiple iterations of reverse_proxy with different settings and multiple services (several different bookmark hosting services, calibre-web, nextcloud, bookstack, and others) and they all have the same issue. I have searched this forum and elsewhere for a solution, but none of them fix the problem.

I have checked my DNS settings and made sure that I have A records pointing to the server, and they match the other functional A records, so it’s not a DNS issue. The issue persists through multiple devices (tried mobile, my local computer, and directly from within the server) and they all have the same issue, so it’s not a cache problem.

I’ve hidden the domain because the WHOIS contains PII (I cannot use domain privacy with .us domains), and I already had my IP switched twice because malicious abuse of the shared Digital Ocean IPs, so I’ve removed those too.

6. Links to relevant resources:

Hi :wave:

I don’t fully get what’s supposedly not working :woman_shrugging:
Your Caddyfile and docker-compose looks alright to me.

Though it is a bit odd, that you specified port :443 for vault.* but port :80 for links.*.
Specifying :80 essentially disables Caddy’s Automatic HTTPS — Caddy Documentation

So vault.* will be served via https:// (with automatic redirects from http:// to https://), but links.* will be served unencrypted http:// over port :80.

Your curl command defaults to port :80 when used without specifying https:// and shows that exact behavior I just described above too:

[automatic redirects from http:// to https://. Actual service will be served under https://]

and

[no https redirect but instead the service itself, served under http://. So I would guess that service should work just fine when typing http://links.* in the browser.]

  1. You can omit :443 in your Caddyfile, because it is somewhat redundant
  2. Remove :80 for the other vhost to serve it over https.

So like that:

- vault.{$DOMAIN}:443 {
+ vault.{$DOMAIN} {
    log {
      level INFO

- links.{$DOMAIN}:80 {
+ links.{$DOMAIN} {
    reverse_proxy linkding:9090
  }

If your problem persists, it would be nice if you could explain your problem again :innocent:

2 Likes

It looks like it was a DNS issue in the end. After 24 hours, I tried using the link again and it works. It’s unusual for me because the DNS records tend to update within minutes, so I guess it was taking namecheap longer than usual to get them running.

As far as this section

Though it is a bit odd, that you specified port :443 for vault.* but port :80 for links.*.
Specifying :80 essentially disables Caddy’s Automatic HTTPS — Caddy Documentation

So vault.* will be served via https:// (with automatic redirects from http:// to https://), but links.* will be served unencrypted http:// over port :80.

I had links.* on port 80 to eliminate the possibility that it was an SSL issue, now that it works, I’m going to switch to SSL for it

2 Likes

This topic was automatically closed after 30 days. New replies are no longer allowed.