Endless redirect when running behind Traefik

Hey,

I’m currently trying to get Ghost to run in docker behind a Traefik reverse proxy. This is all on the same machine, so I don’t want to bother with https traffic between Traefik and the Ghost containers.

My current problem is that the caddy container constantly sends out 308 responses to any request on (container internal) port 80. I’ve seen the suggestion to set the X-Forwarded-Proto: https header, but configuring that did not change anything. The header is in fact set, though. Here’s a logged request from the caddy container (6th header in the list):

http.log.access.log0 handled request
{
    "request": {
        "remote_ip": "172.18.0.3",
        "remote_port": "55770",
        "client_ip": "172.18.0.3",
        "proto": "HTTP/1.1",
        "method": "GET",
        "host": "REDACTED",
        "uri": "/",
        "headers": {
            "Accept": [
                "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
            ],
            "Cache-Control": [
                "max-age=0"
            ],
            "Priority": [
                "u=0, i"
            ],
            "Sec-Fetch-Dest": [
                "document"
            ],
            "Sec-Fetch-Site": [
                "cross-site"
            ],
            "X-Forwarded-Proto": [
                "https"
            ],
            "Accept-Encoding": [
                "gzip, deflate, br, zstd"
            ],
            "X-Real-Ip": [
                "REDACTED"
            ],
            "Dnt": [
                "1"
            ],
            "Sec-Ch-Ua-Platform": [
                "\"Windows\""
            ],
            "X-Forwarded-Host": [
                "REDACTED"
            ],
            "Upgrade-Insecure-Requests": [
                "1"
            ],
            "User-Agent": [
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36"
            ],
            "Sec-Ch-Ua": [
                "\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\""
            ],
            "Sec-Fetch-User": [
                "?1"
            ],
            "X-Forwarded-Server": [
                "b1d1b1436715"
            ],
            "Sec-Ch-Ua-Mobile": [
                "?0"
            ],
            "Accept-Language": [
                "en-US,en;q=0.9"
            ],
            "Sec-Fetch-Mode": [
                "navigate"
            ],
            "X-Forwarded-For": [
                "REDACTED"
            ],
            "X-Forwarded-Port": [
                "443"
            ]
        }
    },
    "bytes_read": 0,
    "user_id": "",
    "duration": 0.000044487,
    "size": 0,
    "status": 308,
    "resp_headers": {
        "Server": [
            "Caddy"
        ],
        "Connection": [
            "close"
        ],
        "Location": [
            "https://REDACTED"
        ],
        "Content-Type": []
    }
}

I’m running the caddy:2.10.2-alpine@sha256:953131cfea8e12bfe1c631a36308e9660e4389f0c3dfb3be957044d3ac92d446 as the image version (latest at the time of writing)

Is there anything else that I need to set to have Ghost accept http requests?

David

ok, no idea if this is intended, but here’s how I solved it.

Prevent Caddy from redirecting:

  1. Turn auto-https off and ensure that the application is listening on port 80. Your Caddyfile has to start like this (notice the additional :80 after the domain. If you don’t set this, it will only listen on 443, not 80)
  2. Ensure the X-Forwarded-* headers are forwarded to Ghost

This is now what my caddy file looks like

{
        auto_https off
}

{$DOMAIN}:80 {
        import snippets/Logging

        # Traffic Analytics service
        import snippets/TrafficAnalytics

        # ActivityPub Service
        import snippets/ActivityPub

        # Default proxy everything else to Ghost
        handle {
                reverse_proxy ghost:2368 {
                    header_up X-Forwarded-Proto https
                    header_up X-Forwarded-Port 443
                }
        }

        # Optional: Enable gzip compression
        encode gzip

        # Optional: Add security headers
        import snippets/SecurityHeaders
}

Idk if this configuration will have any side effects, but at least I have a running instance now.