Can't obtain certificate - Reverse Proxy with Cloudflare

1. Caddy version (caddy version):

v2.4.3

2. How I run Caddy:

a. System environment:

Ubuntu 20.04 using docker/docker-compose
the docker image I’m using is

slothcroissant/caddy-cloudflaredns

b. Command:

docker-compose up



but when testing I use

docker-compose up --scale caddy=0 -d

and then

docker-compose run caddy  

separately. so that I can watch the caddy services actions independently

c. Service/unit/compose file:

---
version: "3.7"
services:
  organizr:
    image: organizr/organizr
    container_name: organizr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    volumes:
      - /opt/appdata/organizr:/config
    ports:
      - 9983:80
    restart: unless-stopped
  nzbget:
    image: ghcr.io/linuxserver/nzbget
    container_name: nzbget
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    volumes:
      - /opt/appdata/nzbget:/config
      - /home/rob/Downloads/nzbget:/downloads
    ports:
      - 6789:6789
    restart: unless-stopped
  sonarr:
    image: ghcr.io/linuxserver/sonarr
    container_name: sonarr
    volumes:
      - /opt/appdata/sonarr:/config
      - /mnt/Media 2TB/media/tv:/tv
      - /home/rob/Downloads/nzbget:/downloads
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    ports:
      - 8989:8989
    restart: unless-stopped
  radarr:
    image: ghcr.io/linuxserver/radarr
    container_name: radarr
    volumes:
      - /opt/appdata/radarr:/config
      - /mnt/Media 2TB/media/movies/:/movies
      - /home/rob/Downloads/nzbget:/downloads
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    ports:
      - 7878:7878
    restart: unless-stopped
  jellyfin:
    image: ghcr.io/linuxserver/jellyfin
    container_name: jellyfin
    volumes:
      - /opt/appdata/jellyfin:/config
      - /mnt/Media 2TB/media/tv:/data/tvshows
      - /mnt/Media 2TB/media/movies:/data/movies
      - /mnt/Media 2TB/media/anime:/data/anime #optional
      - /mnt/Media 2TB/media/other:/data/other #optional
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
      - JELLYFIN_PublishedServerUrl=192.168.0.5 #optional
    ports:
      - 8096:8096
      - 8920:8920 #optional
      - 7359:7359/udp #optional
      - 1900:1900/udp #optional
    restart: unless-stopped
  ombi:
    image: ghcr.io/linuxserver/ombi
    container_name: ombi
    volumes:
      - /opt/appdata/ombi:/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
      - BASE_URL=/ombi #optional
    ports:
      - 3579:3579
    restart: unless-stopped
  caddy:
    image: slothcroissant/caddy-cloudflaredns
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - $PWD/Caddyfile:/etc/caddy/Caddyfile
      - $PWD/site:/srv
      - caddy_data:/data
      - caddy_config:/config
    environment:
      - CLOUDFLARE_API_TOKEN={my api token here}
      - CLOUDFLARE_EMAIL=mymail@mail.com

volumes:
  caddy_data:
  caddy_config:


d. My complete Caddyfile or JSON config:

{
        # Email
        email rob@mymail.com

        # Debug
        acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
        debug
}
(cloudflare) {
        tls {
                dns cloudflare $CLOUDFLARE_API_TOKEN
                alpn disable_tlsalpn_challenge
        }
}

uns-media.xyz {
        import cloudflare
        reverse_proxy 127.0.0.1:9983
}

jellyfin.uns-media.xyz {
        import cloudflare
        reverse_proxy 127.0.0.1:8096
}

ombi.uns-media.xyz {
        import cloudflare
        reverse_proxy 127.0.0.1:3579
}

3. The problem I’m having:

Cannot obtain a certificate.

4. Error messages and/or full log output:

2021/08/08 11:45:20.496 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "GET", "url": "https://acme-staging-v02.api.letsencrypt.org/directory", "headers": {"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 200, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["724"],"Content-Type":["application/json"],"Date":["Sun, 08 Aug 2021 11:45:20 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:20.641 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "HEAD", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/new-nonce", "headers": {"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 200, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Date":["Sun, 08 Aug 2021 11:45:20 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0001LTBajV97O5fqTjILdORkP3P90FDnQUfQEHMIIXjkKvA"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:21.071 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "HEAD", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/new-nonce", "headers": {"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 200, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Date":["Sun, 08 Aug 2021 11:45:21 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0001z-34sR8eSn_cMIH43OZWjPvL9F5yOP5WkBGaz4nGWl4"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:21.085 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "HEAD", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/new-nonce", "headers": {"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 200, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Date":["Sun, 08 Aug 2021 11:45:21 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0002-CJCSmYkbHQgy9hQankJjnDnlmHDJeRvo1IdaJX9_uo"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:21.238 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "POST", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/new-order", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 201, "response_headers": {"Boulder-Requester":["22604178"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["352"],"Content-Type":["application/json"],"Date":["Sun, 08 Aug 2021 11:45:21 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-staging-v02.api.letsencrypt.org/acme/order/22604178/247782458"],"Replay-Nonce":["00010WfUvt0O2Wwu9iml8BV5edM_QHapNwMNCwzytT1vscg"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:21.252 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "POST", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/new-order", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 201, "response_headers": {"Boulder-Requester":["22604178"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["347"],"Content-Type":["application/json"],"Date":["Sun, 08 Aug 2021 11:45:21 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-staging-v02.api.letsencrypt.org/acme/order/22604178/247782468"],"Replay-Nonce":["0001rosPjuIqHe2eUetfwRo_pOQXDz_v3viIeliZW5SDWOs"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:21.383 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "POST", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/222418238", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 200, "response_headers": {"Boulder-Requester":["22604178"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["817"],"Content-Type":["application/json"],"Date":["Sun, 08 Aug 2021 11:45:21 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0001wHucOfYt16eSUpUELm9zzh3wGLzk6oHUp3Rk8nZ9-4w"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:21.384 INFO    tls.issuance.acme.acme_client   trying to solve challenge       {"identifier": "ombi.uns-media.xyz", "challenge_type": "dns-01", "ca": "https://acme-staging-v02.api.letsencrypt.org/directory"}
2021/08/08 11:45:21.432 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "POST", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/222418248", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 200, "response_headers": {"Boulder-Requester":["22604178"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["812"],"Content-Type":["application/json"],"Date":["Sun, 08 Aug 2021 11:45:21 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0002CRI7v50myrCoxxx07jK7IhdeIIf2L6CxWyqqL8lxZ2k"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:21.433 INFO    tls.issuance.acme.acme_client   trying to solve challenge       {"identifier": "uns-media.xyz", "challenge_type": "dns-01", "ca": "https://acme-staging-v02.api.letsencrypt.org/directory"}
2021/08/08 11:45:22.340 ERROR   tls.issuance.acme.acme_client   cleaning up solver      {"identifier": "ombi.uns-media.xyz", "challenge_type": "dns-01", "error": "no memory of presenting a DNS record for ombi.uns-media.xyz (probably OK if presenting failed)"}
2021/08/08 11:45:22.491 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "POST", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/222418238", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 200, "response_headers": {"Boulder-Requester":["22604178"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["821"],"Content-Type":["application/json"],"Date":["Sun, 08 Aug 2021 11:45:22 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0002JEOYVqFEnHkL_o-2Jf0SWKIftIsuDdVILE_vuIMbSJA"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:22.492 ERROR   tls.obtain      will retry      {"error": "[ombi.uns-media.xyz] Obtain: [ombi.uns-media.xyz] solving challenges: presenting for challenge: adding temporary record for zone uns-media.xyz.: got error status: HTTP 400: [{Code:6003 Message:Invalid request headers}] (order=https://acme-staging-v02.api.letsencrypt.org/acme/order/22604178/247782458) (ca=https://acme-staging-v02.api.letsencrypt.org/directory)", "attempt": 1, "retrying_in": 60, "elapsed": 2.63417577, "max_duration": 2592000}
2021/08/08 11:45:22.722 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "POST", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/new-order", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 201, "response_headers": {"Boulder-Requester":["22604178"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["356"],"Content-Type":["application/json"],"Date":["Sun, 08 Aug 2021 11:45:22 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-staging-v02.api.letsencrypt.org/acme/order/22604178/247782588"],"Replay-Nonce":["00026s6ehyr2QsPADHOJNxeexVjbC_TrT_oA1gLC-mAjPmw"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:22.869 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "POST", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/222418358", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 200, "response_headers": {"Boulder-Requester":["22604178"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["821"],"Content-Type":["application/json"],"Date":["Sun, 08 Aug 2021 11:45:22 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0001PG8HMvDO6PhbkbdX4VONKkwOubJW6Gj8q6favQ-ycag"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:22.869 INFO    tls.issuance.acme.acme_client   trying to solve challenge       {"identifier": "jellyfin.uns-media.xyz", "challenge_type": "dns-01", "ca": "https://acme-staging-v02.api.letsencrypt.org/directory"}
2021/08/08 11:45:23.168 ERROR   tls.issuance.acme.acme_client   cleaning up solver      {"identifier": "uns-media.xyz", "challenge_type": "dns-01", "error": "no memory of presenting a DNS record for uns-media.xyz (probably OK if presenting failed)"}
2021/08/08 11:45:23.320 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "POST", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/222418248", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 200, "response_headers": {"Boulder-Requester":["22604178"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["816"],"Content-Type":["application/json"],"Date":["Sun, 08 Aug 2021 11:45:23 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0002FkXQ_g9_gWD6ynA4q41NMSBOwd3fvip7FoaJxeEOp3I"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:23.320 ERROR   tls.obtain      will retry      {"error": "[uns-media.xyz] Obtain: [uns-media.xyz] solving challenges: presenting for challenge: adding temporary record for zone uns-media.xyz.: got error status: HTTP 400: [{Code:6003 Message:Invalid request headers}] (order=https://acme-staging-v02.api.letsencrypt.org/acme/order/22604178/247782468) (ca=https://acme-staging-v02.api.letsencrypt.org/directory)", "attempt": 1, "retrying_in": 60, "elapsed": 3.462599818, "max_duration": 2592000}
2021/08/08 11:45:24.002 ERROR   tls.issuance.acme.acme_client   cleaning up solver      {"identifier": "jellyfin.uns-media.xyz", "challenge_type": "dns-01", "error": "no memory of presenting a DNS record for jellyfin.uns-media.xyz (probably OK if presenting failed)"}
2021/08/08 11:45:24.158 DEBUG   tls.issuance.acme.acme_client   http request    {"method": "POST", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/222418358", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.3.0 CertMagic acmez (linux; amd64)"]}, "status_code": 200, "response_headers": {"Boulder-Requester":["22604178"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["825"],"Content-Type":["application/json"],"Date":["Sun, 08 Aug 2021 11:45:24 GMT"],"Link":["<https://acme-staging-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["0001a5ryHbNVSymRfFQuYJlWx8YSbHInb-4iHFHZ2wANxmg"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}}
2021/08/08 11:45:24.158 ERROR   tls.obtain      will retry      {"error": "[jellyfin.uns-media.xyz] Obtain: [jellyfin.uns-media.xyz] solving challenges: presenting for challenge: adding temporary record for zone uns-media.xyz.: got error status: HTTP 400: [{Code:6003 Message:Invalid request headers}] (order=https://acme-staging-v02.api.letsencrypt.org/acme/order/22604178/247782588) (ca=https://acme-staging-v02.api.letsencrypt.org/directory)", "attempt": 1, "retrying_in": 60, "elapsed": 4.30078412, "max_duration": 2592000}

When accessing the sites I get an error from cloudflare. Error 525: SSL handshake failed
Interestingly, when having the rest of the docker containers up and removing the

https

from

https://jellyfin.uns-media.xyz

I can then access the unencrypted version of the site, using my servers public IP? Though for the other sites I cannot do this.

5. What I already tried:

Mainly modifying the Caddyfile, making changes to cloudflare settings or docker images

Previously I was using godaddy as my DNS provider. Due to the lack of an active plugin being developed for caddy and their subpar API I switched it to cloudflare instead but I still am facing the same issues as you can see here.

Below I’ll link just a few of the places I scoured for any semblance of advice, mostly found on this forum.

6. Links to relevant resources:

Caddy Cloudflare SSL Cert Challenge doesn’t work on 1 Domain - Help - Caddy Community

Error 525 ssl handshake failed - Help - Caddy Community

How to setup Caddy + Cloudflare end-to-end HTTPS encryption tutorial | ruX’s mind

Recent Issues with Cloudflare DNS Challenges - Help - Caddy Community

This is not the right syntax for environment variables. It should read like this:

dns cloudflare {$CLOUDFLARE_API_TOKEN}

You don’t need this – enabling the DNS challenge implicitly disables the HTTP and TLS-ALPN challenges.

From your logs, it looks like you’re using Caddy v2.3.0, not v2.4.3. Make sure to pull the latest version of the image you’re using – or build Caddy yourself using the builder Docker image. See the docs on Docker, specifically the section “Adding custom Caddy modules”.

You’re right. Thank you, this cleared up most of the terminal errors.

I removed this part of the Caddyfile as it was unnecessary, like you pointed out.

I was under the impression I was on v2.4.3 but I think I was just confused from all the versions of Caddy I was trying.

Now I have made these changes and the sites are being routed through https with the right certificates. However, when I try to access them I receive a blank white page and the following in the terminal:

caddy_1     | {"level":"error","ts":1628592550.7643154,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:8096: connect: connection refused","request":{"remote_addr":"104.28.22.108:12592","proto":"HTTP/2.0","method":"GET","host":"jellyfin.uns-media.xyz","uri":"/cdn-cgi/images/cf-icon-error.png","headers":{"Accept-Language":["en-GB,en;q=0.9"],"Referer":["https://jellyfin.uns-media.xyz/"],"Accept":["image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"Accept-Encoding":["gzip, deflate, br"],"If-None-Match":["\"610bdacc-356\""],"If-Modified-Since":["Thu, 05 Aug 2021 12:34:20 GMT"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"jellyfin.uns-media.xyz"}},"duration":0.000722237,"status":502,"err_id":"4tmp73v8v","err_trace":"reverseproxy.statusError (reverseproxy.go:857)"}
caddy_1     | {"level":"debug","ts":1628592550.7644286,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"127.0.0.1:8096","request":{"remote_addr":"104.28.22.108:12592","proto":"HTTP/2.0","method":"GET","host":"jellyfin.uns-media.xyz","uri":"/cdn-cgi/images/cf-icon-server.png","headers":{"X-Forwarded-Proto":["https"],"Accept":["image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"If-None-Match":["\"610bdacc-568\""],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15"],"X-Forwarded-For":["104.28.22.108"],"Accept-Encoding":["gzip, deflate, br"],"If-Modified-Since":["Thu, 05 Aug 2021 12:34:20 GMT"],"Accept-Language":["en-GB,en;q=0.9"],"Referer":["https://jellyfin.uns-media.xyz/"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"jellyfin.uns-media.xyz"}},"duration":0.000690956,"error":"dial tcp 127.0.0.1:8096: connect: connection refused"}
caddy_1     | {"level":"debug","ts":1628592550.7645926,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"127.0.0.1:8096","request":{"remote_addr":"104.28.22.108:12592","proto":"HTTP/2.0","method":"GET","host":"jellyfin.uns-media.xyz","uri":"/cdn-cgi/images/cf-icon-browser.png","headers":{"Accept-Encoding":["gzip, deflate, br"],"If-Modified-Since":["Thu, 05 Aug 2021 12:34:20 GMT"],"Referer":["https://jellyfin.uns-media.xyz/"],"X-Forwarded-For":["104.28.22.108"],"X-Forwarded-Proto":["https"],"Accept":["image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"If-None-Match":["\"610bdacc-1e4\""],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15"],"Accept-Language":["en-GB,en;q=0.9"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"jellyfin.uns-media.xyz"}},"duration":0.00047079,"error":"dial tcp 127.0.0.1:8096: connect: connection refused"}
caddy_1     | {"level":"debug","ts":1628592550.7646325,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"127.0.0.1:8096","request":{"remote_addr":"104.28.22.108:12592","proto":"HTTP/2.0","method":"GET","host":"jellyfin.uns-media.xyz","uri":"/cdn-cgi/images/cf-icon-cloud.png","headers":{"Accept-Encoding":["gzip, deflate, br"],"Referer":["https://jellyfin.uns-media.xyz/"],"X-Forwarded-For":["104.28.22.108"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15"],"Accept-Language":["en-GB,en;q=0.9"],"X-Forwarded-Proto":["https"],"Accept":["image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"If-None-Match":["\"610bdacc-5cc\""],"If-Modified-Since":["Thu, 05 Aug 2021 12:34:20 GMT"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"jellyfin.uns-media.xyz"}},"duration":0.000473478,"error":"dial tcp 127.0.0.1:8096: connect: connection refused"}
caddy_1     | {"level":"error","ts":1628592550.7647178,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:8096: connect: connection refused","request":{"remote_addr":"104.28.22.108:12592","proto":"HTTP/2.0","method":"GET","host":"jellyfin.uns-media.xyz","uri":"/cdn-cgi/images/cf-icon-server.png","headers":{"Accept":["image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"Accept-Encoding":["gzip, deflate, br"],"If-None-Match":["\"610bdacc-568\""],"If-Modified-Since":["Thu, 05 Aug 2021 12:34:20 GMT"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15"],"Accept-Language":["en-GB,en;q=0.9"],"Referer":["https://jellyfin.uns-media.xyz/"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"jellyfin.uns-media.xyz"}},"duration":0.001157109,"status":502,"err_id":"7pbzr78px","err_trace":"reverseproxy.statusError (reverseproxy.go:857)"}
caddy_1     | {"level":"error","ts":1628592550.7647722,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:8096: connect: connection refused","request":{"remote_addr":"104.28.22.108:12592","proto":"HTTP/2.0","method":"GET","host":"jellyfin.uns-media.xyz","uri":"/cdn-cgi/images/cf-icon-browser.png","headers":{"Accept":["image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"Accept-Encoding":["gzip, deflate, br"],"If-None-Match":["\"610bdacc-1e4\""],"If-Modified-Since":["Thu, 05 Aug 2021 12:34:20 GMT"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15"],"Accept-Language":["en-GB,en;q=0.9"],"Referer":["https://jellyfin.uns-media.xyz/"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"jellyfin.uns-media.xyz"}},"duration":0.000915643,"status":502,"err_id":"axwme7uvx","err_trace":"reverseproxy.statusError (reverseproxy.go:857)"}
caddy_1     | {"level":"error","ts":1628592550.7648218,"logger":"http.log.error","msg":"dial tcp 127.0.0.1:8096: connect: connection refused","request":{"remote_addr":"104.28.22.108:12592","proto":"HTTP/2.0","method":"GET","host":"jellyfin.uns-media.xyz","uri":"/cdn-cgi/images/cf-icon-cloud.png","headers":{"Accept-Language":["en-GB,en;q=0.9"],"Referer":["https://jellyfin.uns-media.xyz/"],"Accept":["image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5"],"Accept-Encoding":["gzip, deflate, br"],"If-None-Match":["\"610bdacc-5cc\""],"If-Modified-Since":["Thu, 05 Aug 2021 12:34:20 GMT"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"jellyfin.uns-media.xyz"}},"duration":0.000904237,"status":502,"err_id":"gaqinmaju","err_trace":"reverseproxy.statusError (reverseproxy.go:857)"}

The result is the same whether accessed from the host machine or another computer.

This is my updated Caddyfile now

{
	# Email
	email myname@gmail.com

	# Debug
	acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
	debug
}
(cloudflare) {
	tls {
		dns cloudflare {$CLOUDFLARE_API_TOKEN}
	}
}

uns-media.xyz {
	import cloudflare
	reverse_proxy 127.0.0.1:9983
}

jellyfin.uns-media.xyz {
	import cloudflare
	reverse_proxy 127.0.0.1:8096
}

ombi.uns-media.xyz {
	import cloudflare
	reverse_proxy 127.0.0.1:3579
}

Right – so this issue is because when running in Docker, 127.0.0.1/localhost mean “the container you’re currently in”. This means Caddy is trying to connect to something inside the caddy container. This won’t work.

The way to address other services when using docker-compose is to use their service name as the address (and you need to use the container port, not the port you used to bind to the host).

reverse_proxy jellyfin:8096
reverse_proxy organizr:80

and so on.

You also won’t need these lines in your docker-compose config anymore:

Because Caddy will proxy requests to those containers, you don’t need to bind the ports to the host.

1 Like

I couldn’t help but laugh when I implemented your suggested changes and all my caddy problems simply went away, thank you so much for this help.

up to date Caddyfile

{
	# Email
	email mymail@mail.com

	# Debug
	#acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
	debug
}
(cloudflare) {
	tls {
		dns cloudflare {$CLOUDFLARE_API_TOKEN}
	}
}

uns-media.xyz {
	import cloudflare
	reverse_proxy organizr:80
}

jellyfin.uns-media.xyz {
	import cloudflare
	reverse_proxy jellyfin:8096
}

ombi.uns-media.xyz {
	import cloudflare
	reverse_proxy ombi:3579
}

and docker-compose.yaml

---
version: "3.7"
services:
  organizr:
    image: organizr/organizr
    container_name: organizr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    volumes:
      - /opt/appdata/organizr:/config
    restart: unless-stopped
  nzbget:
    image: ghcr.io/linuxserver/nzbget
    container_name: nzbget
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    volumes:
      - /opt/appdata/nzbget:/config
      - /mnt/Media 2TB/Data/Downloads/Usenet:/Downloads/Usenet
    ports:
      - 6789:6789
    restart: unless-stopped
  sonarr:
    image: ghcr.io/linuxserver/sonarr
    container_name: sonarr
    volumes:
      - /opt/appdata/sonarr:/config
      - /mnt/Media 2TB/Data/Media/TV Shows:/Media/TV Shows
      - /mnt/Media 2TB/Data/Media/Anime:/Media/Anime
      - /mnt/Media 2TB/Data/Downloads:/Downloads
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    ports:
      - 8989:8989
    restart: unless-stopped
  radarr:
    image: ghcr.io/linuxserver/radarr
    container_name: radarr
    volumes:
      - /opt/appdata/radarr:/config
      - /mnt/Media 2TB/Data/Media/Movies:/Media/Movies
      - /mnt/Media 2TB/Data/Downloads:/Downloads
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    ports:
      - 7878:7878
    restart: unless-stopped
  jellyfin:
    image: ghcr.io/linuxserver/jellyfin
    container_name: jellyfin
    volumes:
      - /opt/appdata/jellyfin:/config # Config files
      - /mnt/Media 2TB/Data/Media/TV Shows:/Media/TV Shows # TV Shows
      - /mnt/Media 2TB/Data/Media/Movies:/Media/Movies # Movies
      - /mnt/Media 2TB/Data/Media/Anime:/Media/Anime # Anime
      - /mnt/Media 2TB/Data/Media/Music:/Media/Music # Music
      - /mnt/Media 2TB/Data/Media/Other:/Media/Other # Other
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
      - JELLYFIN_PublishedServerUrl=192.168.0.5 #optional
    ports:
      - 8096:8096
      - 8920:8920 #optional
      - 7359:7359/udp #optional
      - 1900:1900/udp #optional
    restart: unless-stopped
  ombi:
    image: ghcr.io/linuxserver/ombi
    container_name: ombi
    volumes:
      - /opt/appdata/ombi:/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
      - BASE_URL=/ombi #optional
    ports:
      - 3579:3579
    restart: unless-stopped
  caddy:
    image: honeyglazedtreats/caddy-cloudflare
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - $PWD/Caddyfile:/etc/caddy/Caddyfile
      - $PWD/site:/srv
      - caddy_data:/data
      - caddy_config:/config
    environment:
      - CLOUDFLARE_API_TOKEN=MY_API_TOKEN
      - CLOUDFLARE_EMAIL=mymail@mail.com
volumes:
  caddy_data:
  caddy_config:

For anyone that may find it useful :^)

Please note that the specific caddy image I’m using is my own built from the latest caddy version with the cloudflare dns plugin.

2 Likes

And how do you do that? Because that is exactly what I need to do. :slight_smile:

The instructions are on Docker. See the section “Adding custom Caddy modules”

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