Introduction
Varnish help to decreases directly request to the web server by cache response after first-time response, help your website perform better. You can make the configuration for caching-path, what you want to ignore, how to purge/ban cache.
I like Docker, I run my website on Docker, multiple services by Docker-Compose, I’m just a developer, no more knowledge about the system like a DevOps, I want to make it run by the simple way.
I would like to mention online NGINX and varnish. It’s mean NGINX will cover backend and connect to varnish to handle the response.
Requisites
- Nginx has covered web and it’s still running before installing varnish
- Nginx and varnish must be on the same internal network
Notes
- Nginx will run out with port 8080
- Varnish will run out with port 80
- Varnish can’t handle SSL. If you need to handle this protocol, this post can’t help you more
- Property build:
../nginx-server
includes NGINX configuration, you could use the image directly. It should be controlled on your side Property build:../varnish
includes varnish configuration. I will explain only this part
Docker images
Varnish docker image: https://github.com/newsdev/docker-varnish (It has included the way to setting and run docker image, I just write more for docker-compose config)
Nginx: https://hub.docker.com/_/nginx/
Settings
- Create
../varnish
folder - Access to created folder and make
Dockerfile
FROM newsdev/varnish:4.1.0
ENV VARNISH_MEMORY 100m
- Create
default.vcl
in the same folder, it’s varnish configuration
vcl 4.0;
backend default {
.host = "nginx-server";
.port = "80";
}
# If you don't include below, header Age in response to client always be 0
sub vcl_deliver {
# Display hit/miss info
if (obj.hits > 0) {
set resp.http.V-Cache = "HIT";
}
else {
set resp.http.V-Cache = "MISS";
}
set resp.http.Access-Control-Allow-Origin = "*";
set resp.http.Access-Control-Allow-Headers = "Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With";
set resp.http.Allow = "GET, POST";
set resp.http.Access-Control-Allow-Credentials = "true";
set resp.http.Access-Control-Allow-Methods = "GET, POST, PUT, DELETE, OPTIONS, PATCH";
set resp.http.Access-Control-Expose-Headers = "X-Pagination-Total, X-Pagination-Page, X-Pagination-Limit";
}
sub vcl_backend_response {
if (beresp.status == 200) {
unset beresp.http.Cache-Control;
set beresp.http.Cache-Control = "public; max-age=200";
set beresp.ttl = 200s;
}
set beresp.http.Served-By = beresp.backend.name;
set beresp.http.V-Cache-TTL = beresp.ttl;
set beresp.http.V-Cache-Grace = beresp.grace;
}
- Modify service’s configuration for
docker-compose.yml
version: '2'
networks:
localnetwork:
driver: bridge
ipam:
driver: default
config:
- subnet: 162.11.1.0/24
gateway: 162.11.1.1
services:
nginx-server:
container_name: nginx-server
build: ../nginx-server
networks:
- localnetwork
ports:
- "8080:80"
varnish:
build: ../varnish
container_name: varnish
networks:
- localnetwork
ports:
- "80:80"
depends_on:
- nginx-server
- Build & run Docker
docker-compose build
docker-compose up -d
- Access URLs and check the headers
http://docker-host-ip:8080/users/{user_id} #Routing to your method, always no cache
http://docker-host-ip/users/{user_id} #Through Varnish first
- Hit varnish caching URL, and see the
Age
value in the response headers:
Age = 0, Cache wasn’t HIT (known as MISS)
Age != 0, Cache was HIT (you’re successful)
Helpful commands
# View varnish cache his/miss
docker exec -it varnish bash
varnishncsa -F "%m %U%q ---- %{Varnish:handling}x"
Top comments (3)
Great post! Unfortunately following it for us leads to the following Vagrant error log:
Found out the typos; it should be:
set resp
instead ofsetresp
unset beresp
instead ofunsetberesp
set beresp
instead ofsetberesp
Thanks for catching 😂. I have updated the post 🤗.