28.07.2025
Lightning-Fast Cache for Your Kubernetes ApplicationVarnish - The Secret Hero of Website Performance with Kubernetes
In modern web applications, performance isn't just a feature - it's essential. Users expect fast, responsive experiences, and slow load times can lead to high bounce rates and lost engagement. This is where Varnish Cache comes in. By placing it in front of your web application, you can serve cached content at lightning speed, dramatically reducing the load on your backend. This article guides you through setting up Varnish in a Kubernetes environment to make your website significantly faster.
Why Varnish Transforms Your Website
Performance is everything on the web. When your users have to wait, they bounce. Varnish elegantly solves this problem: As an HTTP cache, it sits in front of your application and delivers content lightning-fast from storage. The result? Up to 90% less load on your backend and significantly faster loading times.
Let's Get Started: What You'll Need
Before we begin, here are the four files you'll need for a simple setup:
default.vcl
: Your Varnish configurationDockerfile
: To build your Varnish image including VCLvarnish.yaml
: Deployment and Service for KubernetesIngress.yaml
: Optional, to make your website accessible via a domain name
Understanding and Adapting the VCL File
Let's first look at the individual parts of the default.vcl
in detail:
backend default {
.host = "website-svc";
.port = "3001";
.first_byte_timeout = 300s;
}
The first block defines your backend. website-svc
is the name of the Kubernetes service that Varnish will access. The port 3001
is the port of your application (e.g., Django) which is accessible within the cluster. With first_byte_timeout
you set how long Varnish waits for the first response from the backend.
sub vcl_recv {
if (req.method == "GET" && req.http.Cookie !~ "sessionid") {
unset req.http.Cookie;
}
}
vcl_recv
is called for every incoming request. Here you decide whether cookies are removed. In this case, Varnish removes all cookies from GET requests that do not contain a sessionid
. This makes caching more effective because different cookie values would otherwise create different cache objects.
sub vcl_backend_response {
if (bereq.url ~ "^/de-de/aktuelles/.*") {
set beresp.ttl = 2h;
} else {
set beresp.ttl = 12h;
}
}
vcl_backend_response
is called when Varnish has queried the backend and received a response. Here you define how long content should be cached. News pages get 2 hours, everything else remains in the cache for 12 hours.
Dockerfile: Embedding VCL into the Image
FROM varnish:stable
COPY default.vcl /etc/varnish/
This ensures that your VCL is directly included in the container.
Next. You can attach your image with:
docker build -t varnish:latest .
Deployment and Service Definition
The Deployment ensures that your Varnish Pod runs permanently and Kubernetes automatically restarts it when it crashes. In our example, only one instance runs (replicas: 1), but for production environments you can also enter multiple replicas.
apiVersion: apps/v1
kind: Deployment
metadata:
name: varnish
spec:
replicas: 1
template:
metadata:
labels:
app: varnish
spec:
containers:
- name: varnish
image: varnish:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: varnish
spec:
selector:
app: varnish
ports:
- port: 80
targetPort: 80
The associated Service makes your Pod accessible in the cluster. It connects the Ingress or other Pods with your Varnish container. It's important that targetPort and containerPort match.
Super!
Now your Pod is reachable in the cluster.
Ingress Configuration for Domain Routing
The Ingress is the last link in the chain. It ensures that requests from the internet reach your cluster and are forwarded to the correct service, in this case your Varnish. This allows you to centrally manage domains and TLS certificates.
A simple example looks like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: varnish-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
rules:
- host: "example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: varnish
port:
number: 80
Pay attention that the service name and port exactly match your previously defined service. This way, all web traffic is processed through Varnish and your application benefits from caching.
Monitoring and Debugging
Here are a few practical commands to monitor your cache and Varnish server:
varnishstat
Shows live cache statistics, for example hits and misses.
varnishlog
Shows exactly why requests were cached or not.
varnishadm ban "req.url ~ .*"
This clears the cache and forces new content.
varnishadm ping
Checks if your Varnish admin is reachable.
varnishadm status
Shows the current status of your Varnish process.
Best Practices for Optimal Caching
1. Define Cache Strategies
- Cache static content longer (CSS, JS, images)
- Cache dynamic content shorter
- Handle session-based content individually
2. Set Up Performance Monitoring
- Regularly check cache hit rates
- Monitor storage utilization
- Monitor backend health
3. Plan Cache Invalidation
- Automated processes for content updates
- Targeted invalidation instead of complete clearing
- Health checks for backend servers
Conclusion
Now you're completely done. Your setup from default.vcl
to Ingress is complete, and Varnish now ensures your site loads significantly faster. With the right configuration, Varnish becomes the secret hero of your website performance.
Do you have questions or an opinion? With your GitHub account you can let us know...