Using Varnish with Rails

Varnish is an open source cache (more accurately a reverse HTTP proxy or web accelerator) that can be used to speed up HTTP delivery to clients. It has many great features built specifically for HTTP caching and is very stable.

You can use Varnish with Rails to speed up your site delivery. Here is a quick guide about that.

Installing Varnish (on Ubuntu)

Installing Varnish is easy. Here is an example:

apt-get install apt-transport-https  
curl | apt-key add -  
echo "deb precise varnish-4.0" >> /etc/apt/sources.list.d/varnish-cache.list  
apt-get update  
apt-get install varnish  

Configuring Varnish

A minimum Varnish needs to be configured with two settings: the front end (where it serves the clients) and the backend where it connects to your application.

Configuration exists in /etc/varnish/default.vcl. Open in your favourite editor and start editing:

$ vi /etc/varnish/default.vcl
backend default {  
    .host = "";
    .port = "8080";

This is the default value for the backend part where Varnish connects to your application. If you Varnish is going to share a server with your application then you can leave this as it is as long as your application server (Passenger or Unicorn for example) serve on port 8080.

This is usually not the case as you really want to have your Varnish servers to sit in front of your web servers. In this case, you usually have multiple backends defined in default.vcl file:

backend web1 {  
    .host = "";
    .port = "8080";
backend web2 {  
    .host = "";
    .port = "8080";

Now that you have the backend configured, you can configure the frontend part. Move over to your favourite editor and edit /etc/default/varnish:

$ vi /etc/default/varnish

change this line:

DAEMON_OPTS="-a :6081 \  
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"


DAEMON_OPTS="-a :80 \  
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"

Now you can start Varnish:

$ service varnish start

Configuring Rails

To make sure Rails sends the right HTTP headers over to Varnish, open application_controller.rb and add the following method:

before_filter :set_cache_control_headers, if: :is_prod?


def is_prod?  

def set_cache_control_headers(max_age = 5.minutes.to_s)  
     response.headers['Cache-Control'] = 'public, no-cache'
     response.headers['Surrogate-Control'] = "max-age=#{max_age}"

The is_prod? method is optional if you see the cache settings getting in your way during development.

High Availability

Now you have 1 Varnish server backed by multiple application servers. You can increase this number to multiple Varnish servers and use a load balancer (AWS Elastic Load Balancer if you're running on AWS for example) in front of them to increase your availability.

Khash Sajadi

Khash is the founder and CEO of Cloud 66, a full stack container management as a service. Follow him on @khash

London, San Francisco
Subscribe and get updates

Have feedback? Please get in touch @cloud66 on Twitter.

Everything you need to build, manage and maintain containers in production on your own servers and any cloud

Try Cloud 66 — 14 Days Free Trial, No credit card required