Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Varnish Bundle Laravel Package

varnish/varnish-bundle

A PHP bundle for integrating the Varnish HTTP accelerator with your application, with configuration for reverse-proxy setup, cache purging, and ban requests so dynamic pages can be served quickly from Varnish while staying fresh.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install (dev/deploy tooling only — this is a Symfony 2-era bundle):
    composer require varnish/varnish-bundle
    
  • Register the bundle in app/AppKernel.php:
    new Varnish\VarnishBundle(),
    
    (Confirm the exact namespace from the bundle's VarnishBundle.php — the repo name suggests Timewasted\VarnishBundle or similar.)
  • Configure in app/config/config.yml. Because documentation is thin, the authoritative source is DependencyInjection/Configuration.php:
    varnish:
        servers:
            - host: 127.0.0.1
              port: 6081
    
  • Look here first, in this order:
    1. DependencyInjection/Configuration.php — the real, supported config keys.
    2. Resources/config/services*.xml — the actual client service ID (varnish, varnish.client, etc.).
    3. Command/ — any shipped console commands (purge/ban/cache-clear style).
    4. Tests/ — the fastest way to see intended API usage.
  • First use case — purge a single page after an edit:
    $varnish = $this->get('varnish'); // verify service id
    $varnish->purge('http://example.com/foo');
    
    Wrap this in a kernel.request-independent service so you don't scatter get() calls throughout controllers.

Implementation Patterns

Centralize invalidation behind your own service. Don't call the bundle client from controllers. Define a CacheInvalidator that wraps the client, adds URL normalization, and fans out to every configured server. This makes the bundle swappable (you will likely need to swap it) and unit-testable.

Doctrine listener for entity-driven purge. The classic pattern: postPersist/postUpdate/postRemove on content entities, then purge the affected URL(s). Use postUpdate + a value object, not raw entity state, so you don't accidentally trigger purges inside transactions or in preUpdate.

Ban regex for bulk/related invalidation. When one edit touches many URLs (e.g. a tag page, an RSS feed, a homepage), purge per URL doesn't scale. Issue a single ban expression instead:

$varnish->ban('obj.http.X-Cache-Tags ~ "blog-42"'); // or equivalent API

Then emit a matching X-Cache-Tags header from Symfony so Varnish can match on it.

Console command for deployments. Wrap purge/ban in a Symfony command and call it from your deploy pipeline immediately after cache:warmup and before traffic is shifted. Idempotent, exit-code driven, safe to re-run.

Coordinate with Symfony's own cache layers. If you use HttpCache/ESI, Varnish sits in front of it. Decide explicitly which layer owns which URL, otherwise you'll purge Varnish and still serve stale ESI fragments from behind it (or vice versa). The common setup: Symfony app cache for internal fragments, Varnish for full-page.

Multi-node fan-out. Configure every Varnish node; loop in the invalidator and log per-node failures so a single dead node doesn't abort the whole purge set.

Environment separation. Keep Varnish servers out of config.yml defaults and into config_dev.yml/config_prod.yml — local dev commonly has no Varnish, and you don't want failing purges in development.

Gotchas and Tips

  • Health warning: this package is effectively abandoned. 3 stars, 0 dependents, Symfony 2 only. Budget for the day it won't install (Symfony 3+ removed the APIs it relies on). Treat it as a thin reference implementation, not a dependency you'll rely on long-term.
  • Varnish admin port must be reachable and opened. Default is 6081, and it is not the cache port (80). Check ACLs, firewalls, and Varnish's -T flag. This is the single most common "it does nothing" cause.
  • Purge ≠ Ban. purge matches one URL exactly; ban matches a pattern against all cached objects and stays in the ban list until its objects age out. Bans are cheap to issue but expensive on huge caches — enable the ban lurker and keep ban lists short.
  • URL normalization bites. Trailing slashes, Accept-Encoding variants, query-string order, and http vs https all create distinct cache entries. Purge exactly what was cached; if you're not sure, capture the real request URL from varnishlog and match that.
  • Your VCL must permit it. By default PURGE/BAN are rejected. You need acl purge { ... } plus if (req.method == "PURGE") blocks restricted to your app servers — otherwise you've built a remote cache-flush endpoint for anyone.
  • Escape ban regexes. Characters like ?, ., +, and : are regex-active. A naive ban("req.url == " . $url) will silently match the wrong (or no) objects.
  • Silent failures are the norm. Varnish often returns 200 from the admin socket even when nothing matched. Verify with varnishadm "ban.list" and varnishlog -g request -q 'ReqMethod eq "PURGE"' rather than trusting the client's return value.
  • Don't purge on every write. Under bulk imports this floods the admin socket and evicts the cache you just warmed. Batch purges, or bypass Varnish during imports and warm afterwards.
  • Extension points are limited, so exploit DI. The real flexibility is replacing the bundle's client service with your own implementation of the same interface, or decorating it with logging/retry. Keep your own interface in front of it from day one.
  • Debugging checklist: telnet localhost 6081 → ping; then varnishadm "ban.list"; then confirm the VCL branch; then confirm the app emits the headers your ban matches on.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin