Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDN for caching static assets / deprecation of fresh/runtime #2758

Open
predaytor opened this issue Nov 12, 2024 · 1 comment
Open

CDN for caching static assets / deprecation of fresh/runtime #2758

predaytor opened this issue Nov 12, 2024 · 1 comment

Comments

@predaytor
Copy link

predaytor commented Nov 12, 2024

I want to cache static assets using Varnish Cache as a proxy layer (deployed to fly.io), but currently it seems that due to the nature of Fresh (2.0.0-alpha.25), assets to be marked at runtime using asset/assetSrcSet from fresh/runtime. Varnish doesn't seem to be able to cache such assets. What could be wrong?

Also, is there a plan to get rid of the fresh/runtime entirely to reduce the js bundle, as we already have a prebuild step for files in outdir at /_fresh, but no file hashes for now?

Dockerfile:

FROM denoland/deno:debian

WORKDIR /app

RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y supervisor varnish varnish-modules && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

COPY ./web .

RUN deno task build

COPY ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf

ENV VARNISH_SIZE=128M
ENV VARNISH_HTTP_PORT=80
COPY ./varnish/default.vcl /etc/varnish/
COPY ./varnish/entrypoint.sh /usr/local/bin/varnish/entrypoint.sh
RUN chmod +x /usr/local/bin/varnish/entrypoint.sh

EXPOSE 80
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

supervisord.conf:

[supervisord]
logfile=/dev/stdout
logfile_maxbytes=0
loglevel=info
pidfile=/tmp/supervisord.pid
nodaemon=true
user=root

[unix_http_server]
file=/tmp/supervisor.sock

[program:varnish]
command=/usr/local/bin/varnish/entrypoint.sh
stdout_logfile=/dev/stdout
stderr_logfile=/dev/stderr
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0

[program:app]
command=/bin/bash -c "deno run -A main.ts"
stdout_logfile=/dev/stdout
stderr_logfile=/dev/stderr
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0

default.vcl:

vcl 4.1;

sub vcl_recv {
    // ...

    // Mark static files with the X-Static-File header, and remove any cookies
    if (req.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|ogg|ogm|opus|otf|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
        set req.http.X-Static-File = "true";
        unset req.http.Cookie;
        return (hash);
    }

    return (hash);
}

// ...

sub vcl_backend_response {
    // ...

    // If the file is marked as static and no custom Cache-Control max-age specified, cache it for 1 year
    if (bereq.http.X-Static-File == "true" && !beresp.http.Cache-Control) {
        unset beresp.http.Set-Cookie;
        set beresp.http.Cache-Control = "public, max-age=31536000, immutable";
        set beresp.ttl = 1y;
    }

    return (deliver);
}

sub vcl_deliver {
    // Check if the object has been served from cache (HIT) or fetched from the backend (MISS)
    if (obj.hits > 0) {
        // For cached objects with a TTL of 0 seconds but still in grace mode, mark as STALE
        if (obj.ttl <= 0s && obj.grace > 0s) {
            set resp.http.X-Cache = "STALE";
        } else {
            // For regular cached objects, mark as HIT
            set resp.http.X-Cache = "HIT";
        }
    } else {
        // For uncached objects, mark as MISS
        set resp.http.X-Cache = "MISS";
    }

    // Set the X-Cache-Hits header to show the number of times the object has been served from cache
    set resp.http.X-Cache-Hits = obj.hits;
}
@predaytor
Copy link
Author

And for some unknown reason, some HTML pages got caching working properly, while others have identical headers (also cache control) but always have Age: 0. Using the same Varnish configuration for all projects on Node.js - never seen such an error. 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant