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 https://repo.varnish-cache.org/GPG-key.txt | apt-key add -
echo "deb https://repo.varnish-cache.org/ubuntu/ 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 = "127.0.0.1";
.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 = "web1.domain.com";
.port = "8080";
}
backend web2 {
.host = "web2.domain.com";
.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"
to
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?
protected
def is_prod?
Rails.env.production?
end
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}"
end
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.