DEV Community

Vuong
Vuong

Posted on • Edited on

Dockerization: Varnish, Nginx & try to hit the first cache

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 
Enter fullscreen mode Exit fullscreen mode
  • 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; } 
Enter fullscreen mode Exit fullscreen mode
  • 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 
Enter fullscreen mode Exit fullscreen mode
  • Build & run Docker
docker-compose build docker-compose up -d 
Enter fullscreen mode Exit fullscreen mode
  • 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 
Enter fullscreen mode Exit fullscreen mode
  • 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) 
Enter fullscreen mode Exit fullscreen mode

Helpful commands

# View varnish cache his/miss docker exec -it varnish bash varnishncsa -F "%m %U%q ---- %{Varnish:handling}x" 
Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
rvanlaak profile image
Richard van Laak

Great post! Unfortunately following it for us leads to the following Vagrant error log:

Error: Message from VCC-compiler: Expected an action, 'if', '{' or '}' ('input' Line 12 Pos 5) setresp.http.V-Cache = "HIT"; ----####################---------- Running VCC-compiler failed, exited with 2 VCL compilation failed 
Collapse
 
rvanlaak profile image
Richard van Laak

Found out the typos; it should be:

  • set resp instead of setresp
  • unset beresp instead of unsetberesp
  • set beresp instead of setberesp
Collapse
 
vuong profile image
Vuong

Thanks for catching 😂. I have updated the post 🤗.