caddyserver / cache-handler

Distributed HTTP caching module for Caddy
Apache License 2.0
234 stars 17 forks source link

Cache miss on cached requests #86

Open garraflavatra opened 1 week ago

garraflavatra commented 1 week ago

I run Caddy with cache-handler, backed by Redis, in a Docker container. It successfully caches all cacheable responses, however it doesn't seem to be able to retrieve cached responses according to the Cache-Status header, which keeps reporting fwd=uri-miss, although the keys stored in Redis do exist and contain the cached response body.

The header ?Cache-Control rules I tried removing, with no effect, just as replacing Redis by NutsDB or Badger, or adding order cache after header. #64 and #48 seem related, but I haven't quite been able pinpoint the problem.

What is the culprit here?

# ./caddy/caddyfile

{
    order cache before rewrite
    order cache after header

    cache {
        redis {
            url redis:6379
        }
    }
}

(common) {
    encode gzip zstd
}

# Proxy main domain to app server
www.domain.com, v3.domain.com {
    cache {
        cache_name sanl_web
        default_cache_control "private, no-store"
        ttl 24h
    }

    # Contains some default settings
    import common

    # Route requests to app container at http://app (routed by Docker)
    reverse_proxy http://app:8000

    header ?Cache-Control "private, no-store, must-revalidate, max-age=0"
}

# Subdomain serving static assets and uploads
static.domain.com {
    cache {
        cache_name sanl_static
        default_cache_control "public, max-age=600"
        ttl 24h
    }

    import common

    # Serve user-uploaded media from S3 bucket.
    # Caching lowers egress expense and latency.
    handle /media/* {
        header ?Cache-Control "public, max-age=43200"
        rewrite * /path/to/media/{uri}

        reverse_proxy https://s3.domain.com {
            header_up Host {upstream_hostport}
        }
    }

    # Static files are served by app container.
    # Cached because Python should not be serving static files (but dynamic requests).
    handle /static/* {
        reverse_proxy http://app:8000
    }
}

http:// {
    import common
    redir https://www.domain.com
}

domain.com {
    import common
    redir https://www.{host}{uri} permanent
}
# ./caddy/dockerfile

FROM caddy:2.8-builder AS builder
RUN xcaddy build --with github.com/caddyserver/cache-handler@v0.13.0

FROM caddy:2.8-alpine
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
COPY caddyfile /etc/caddy/Caddyfile
# ./docker-compose.yml

services:
    app:
        restart: always
        build: .
        volumes:
            - media:/app/media
            - database:/app/db
        env_file: [./.env]
        depends_on: [redis]

    caddy:
        restart: always
        build: ./caddy
        ports: [80, 443]
        volumes:
            - caddydata:/data

    redis:
        restart: always
        image: redis:7.2-alpine
        volumes:
            - redis:/data

volumes:
    media:
    database:
    redis:
    caddydata:

For completeness: access logs (with remote IP redacted): accesslogs.json

darkweak commented 1 week ago

Hello @garraflavatra thank you for posting this issue. I will try to fix that. My first idea would be about a broken pipe between caddy and your redis instance and can't reconnect. I will keep you informed about that.

garraflavatra commented 1 week ago

Hi @darkweak, thanks for your reply! That might indeed be a problem, but I also tried using Badger and NutsDB, which both gave the same result, so I'm not sure if this is a Redis issue (unless the connection with Badger and Nuts was broken as well). Maybe it has something to do with the proxy and rewrite configuration?