Skip to content

Document how to serve theme files and catalogue images from a CDN - #83

Merged
anoziere merged 6 commits into
mainfrom
docs/cdn-setup
Oct 20, 2026
Merged

anoziere merged 6 commits into
mainfrom
docs/cdn-setup

Conversation

@julescournut

@julescournut julescournut commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

New page getting-started/cdn.md (Next and 3.2): how to serve theme files and catalogue images from a CDN.

Content

  • Recommended setup: a pull CDN in front of the shop's own domain. URLs do not change and the back office keeps working. Three steps: cache headers on the origin (nginx block given), url_site then SYMFONY_TRUSTED_HOSTS, and the trusted proxies.
  • Separate domain: ASSETS_CDN_URL through framework.assets.base_urls, MEDIA_CDN_URL through LiipImagine's ProxyResolver. Both files can be committed and stay inert while the variable is empty. The CORS header is then required.
  • Pitfalls: deploys (no purge, asset-map:compile), the WebP setting that makes every image uncacheable, protected files that must stay out of CDN caching, HTML.
  • Checks: a few curl commands and what to look at in the browser.

The nginx page gets a separate fix: its static files location had no try_files, so /media/cache/resolve/... never reached PHP and an image derivative not generated yet stayed broken (also in 3.0 and 3.2).

How it was checked

On a shop running 3.2 and the core development version, with Flexy and the default back office theme, behind a caching nginx proxy that behaves as a pull CDN. It is not a commercial CDN, and the page says so.

Measured with curl and Chromium in both setups: URLs, cache misses then hits, private HTML and protected files never cached, scripts blocked without the CORS header, no purge after a deploy, a forged Host refused with 400 once trusted hosts are set, console commands failing with Untrusted Host "localhost" while url_site is empty. The nginx fix was checked in a throwaway nginx: /media/cache/resolve/... answered 404 before and reaches PHP after.

Known limitation in the back office theme

thelia/backoffice-default-twig-template loads backoffice/app.js through asset(), which follows base_urls, but bo_importmap() writes publicPath values on the shop's domain. With ASSETS_CDN_URL set, the browser requests undigested files on the CDN domain (/assets/frontOffice/flexy/backoffice/bootstrap.js, 404) and the back office loses its scripts. Same code in 1.2.2 and in the development version. The page warns against ASSETS_CDN_URL with this theme until it is fixed.

Published versions

Labelled released: the nginx fix corrects a configuration already published for 3.0 and 3.2, and the 3.2 copy of the page describes released code (3.2, default-twig 1.2.2). It leaves out the link to the reverse proxy cache guide, a 3.3 feature that only exists in Next.

Build: npm run build passes with no broken link.

@julescournut julescournut added the released Every change to versioned_docs describes a tagged release label Oct 19, 2026
@julescournut
julescournut marked this pull request as ready for review October 19, 2026 09:51
@anoziere

Copy link
Copy Markdown
Member

Thanks, the page reads well and most of it matches the code. One thing to fix before merge, and two smaller points.

The image path is wrong. With TheliaLibrary, which Flexy needs, the LiipImagine resolver writes derivatives under cache_prefix: "cache/images" (Config/liip_imagine_thelia.yaml.example:10, copied to config/packages/liip_imagine_thelia.yaml on activation). The files are served from /cache/images/<filter>/..., and only the resolve redirect lives under /media/cache/resolve/. So:

  • line 11: the "Served from" cell should say public/cache/images/;
  • the location ^~ /media/cache/ block (line 36) never matches an image file. Those fall into the static-files regex location (expires 30d, no public), so the header block belongs on /cache/images/.

With ASSETS_CDN_URL empty, framework.assets.base_urls still swaps PathPackage for UrlPackage, and a shop installed in a subdirectory loses its base path. A sentence on that would do, or a note that the setup assumes the shop runs at the domain root.

Line 140 says protected files are sent private. BinaryFileResponse is public by default and only turns private when the session was used. The guest route /order/track/{token}/download/{id} reads no session, so either check what it actually sends or drop the claim for that route.

…ory shops and explain why downloads are private
@julescournut
julescournut requested a review from anoziere October 20, 2026 07:51
@anoziere
anoziere merged commit b07509c into main Oct 20, 2026
2 checks passed
@anoziere
anoziere deleted the docs/cdn-setup branch October 20, 2026 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released Every change to versioned_docs describes a tagged release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants