Add a Varnish container and enable cache invalidation#238
Add a Varnish container and enable cache invalidation#238dunglas merged 1 commit intoapi-platform:masterfrom
Conversation
2540fe5 to
568ef1e
Compare
composer.json
Outdated
| "php": ">=7.0", | ||
| "symfony/symfony": "3.2.*", | ||
| "api-platform/core": "^2.0", | ||
| "api-platform/core": "dev-cache_tags", |
There was a problem hiding this comment.
Don't forget to change it when merging both
| import std; | ||
|
|
||
| backend default { | ||
| .host = "nginx"; |
There was a problem hiding this comment.
beware, varnish resolves the IP of the domain at boot time and keep it till the end of process.
If the IP of nginx changes (for instance when the container restarts) varnish won't be able to route traffic to the new container
There was a problem hiding this comment.
Do you know a workaround for this?
There was a problem hiding this comment.
Several people use a local nginx configured in proxy pass.
Varnish point to nginx 127.0.0.1, and nginx performs the DNS resolution on the fly.
Some other use a script in charge of reloading varnish when the I'm change.
None is ideal to me.
In dev environment, I just restart my container, in production we use a local nginx
There was a problem hiding this comment.
I suggest to let it as is for now. WDYT?
There was a problem hiding this comment.
| return(synth(400, "X-Ban-Regex HTTP header must be set.")); | ||
| } | ||
|
|
||
| # Don't cache in dev mode |
There was a problem hiding this comment.
Why? Shouldn't be an issue if the invalidator works well.
If it don't, you'll not going on prod.
There was a problem hiding this comment.
It hurts the DX. When you change the code in dev, you want the new code to be executed even if the underlying resource has not been modified.
docker/varnish/conf/default.vcl
Outdated
| # To allow API Platform to ban by cache tags | ||
| if (req.method == "BAN") { | ||
| if (client.ip !~ ban) { | ||
| return(synth(403, "Not allowed")); |
| # Don't send cache tags related headers to the client | ||
| unset resp.http.url; | ||
| # Uncomment the following line to NOT send the "Cache-Tags" header to the client (prevent using CloudFlare cache tags) | ||
| #unset resp.http.Cache-Tags; |
There was a problem hiding this comment.
I wonder if we shouldn't remove the s-max-age header too.
With this new tag feature, the app sets an arbitrary value because we known we'll be able to invalidate the varnish. Which is fine.
BUT what if an other unknown proxy is on the path? (see "proxy cache" in this old version of the documentation http://symfony.com/doc/2.2/book/http_cache.html#types-of-caches)
There was a problem hiding this comment.
We should use a custom header like X-Reverse-Proxy-TTL instead of abusing s-max-age.
There was a problem hiding this comment.
For instance, when using CloudFlare, the s-max-age header should be set too. I propose to keep it as is for now too. We'll see when we'll get some feedback.
There was a problem hiding this comment.
We must not set an incorrect s-max-age. It's 100% dangerous. If the user needs to do that for CloudFlare, they should set it themselves (or we should provide some easy way of setting it).
There was a problem hiding this comment.
I don't get your point, we don't set this value automatically, it's up to the user. We just provide a good default when using the Varnish image.
There was a problem hiding this comment.
Alright. I see that the default configuration doesn't set maxage and s-maxage, so we're safe. 😄
There was a problem hiding this comment.
But we provide an unsafe default in api-platform/api-platform. A good default is a safe default. 😞
api-platform/app/config/config.yml
Line 89 in ddb4e77
There was a problem hiding this comment.
So my suggestion is that we should use a custom header, e.g. Reverse-Proxy-TTL
Simply because the HTTP cache mechanism is not designed with reverse caching proxies in mind, so it's not the right tool for the job.
There was a problem hiding this comment.
My concern is that this custom header will not be taken into account by Cloudflare. Maybe can we set the smaxage as we currently do but remove it with Varnish before the request go outside our network?
There was a problem hiding this comment.
If CloudFlare uses s-maxage, let the user change the shared_max_age option that we already provide in the bundle config. It's not a safe default, and the default setup in api-platform/api-platform uses Varnish anyway, not CloudFlare.
app/config/config.yml
Outdated
| api_platform: | ||
| http_cache: | ||
| enable_tags: true | ||
| varnish_urls: %varnish_urls% |
ff6404e to
0c81720
Compare
|
Requires api-platform/core#1156 |
See api-platform/core#952 for the rationale.
TODO:
app_dev.php