This simple tutorial guides you in the setup of Varnish Cache in order to make it work properly with systemd, on Debian Jessie for example.
The Varnish documentation is pretty clear and easy to understand, even if you did not study the entire Debian Administrator Handbook. So you should easily come to the chapter of the official tutorial about putting Varnish on port 80. And this is really easy too. Neverthless, you’re on Debian Jessie, which uses systemd as init system. Cool, but hey, after following the official tutorial, Varnish still doesn’t listen on port 80!
Let’s dive in…
By default (if you installed it with APT) Varnish listens on port 6081, which is good for development purposes, but totally unuseful in production. It acts as a caching reverse proxy for any web server, so it should act as the front door for, let’s say, Apache or nginx. In a production environment you’ll most likely want Varnish to listen on port 80 and put the web server behind the scenes, listening on port 8080.
As said before, the official tutorial explains how to achieve this, let me make a brief summary. First of all, make Apache (let’s take it as an example) listen on port 8080. In order to do this, edit
/etc/apache2/ports.conf and replace the line
Listen 80 with
Listen 8080. The result will be something like this:
Listen 8080 <IfModule ssl_module> Listen 443 </IfModule> <IfModule mod_gnutils.c> Listen 443 </IfModule>
Now, you have to update your VirtualHost accordingly. Edit
/etc/apache2/sites-available/000-default.conf (or any other VirtualHost config file you use), replace the line
<VirtualHost :80> with
<VirtualHost :8080> (this may be slightly different in your configuration).
Now it’s time to configure Varnish. Edit the file /etc/default/varnish and search for the configuration with VCL, which looks something like this:
DAEMON_OPTS="-a :6081 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m"
The value associated with the
-a flag is what we actually have to change, in fact it is the port Varnish is listening on. The first line of the snippet above should become:
According to the official tutorial, we’re done. Since we changed the default file, we should reload systemd, then restart Varnish:
# systemctl daemon-reload # systemctl restart varnish.service
Now, check that the new configuration has been correctly applied. Just point your browser to the right URL, for example
http://www.example.com. At this stage you should receive a connection error.
Make Varnish listen port 80 with systemd
Want to know the problem? Just have a look at the active processes related to varnish:
$ ps aux | grep varnish
You should see two processes run by the user root with the command
/usr/sbin/varnishd -a :6081 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secred -s malloc,256m. Note something familiar? That’s the
DAEMON_OPTS we changed before in
/etc/default/varnish. So, what happened? Obviously, Varnish didn’t take our new configuration. But why? We followed the official tutorial…
The real problem
The official tutorial is a little bit outdated. Or, better, doesn’t take into account the testing version of Debian, which uses systemd instead of init.d as init system. And this makes a huge difference, explained in a bug report. Basically,
/etc/default/varnish is only read by the
/etc/init.d/varnish script, not by the systemd init script (
Now that we know this little detail not reported in the documentation, it’s easy for us to solve the problem.
The easy solution
All we have to do is override the systemd init script of varnish and change something.
# cp /lib/systemd/system/varnish.service /etc/systemd/system/ # nano /etc/systemd/system/varnish.service
We come up with something like this:
[Unit] Description=Varnish HTTP accelerator [Service] Type=forking LimitNOFILE=131072 LimitMEMLOCK=82000 ExecStartPre=/usr/sbin/varnishd -C -f /etc/varnish/default.vcl ExecStart=/usr/sbin/varnishd -a :6081 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m ExecReload=/usr/share/varnish/reload-vcl [Install] WantedBy=multi-user.target
Which is similar to what we saw before. We already now that we have to change the port passed as a value to the -a flag:
ExecStart=/usr/sbin/varnishd -a :80 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m
Why don’t just let this script read the
/etc/default/varnish file? Because we don’t know, for now, what systemd or other init systems are going to do with default files. They could ignore them in the future, for example. Therefore, the safest solution for us is writing the full command in the script itself.
Problems: reloading Varnish
After discovering what explained above, we could consider the varnish default file completely unuseful. That’s not right. In any moment we could want to reload the Varnish configuration, this way:
# systemctl reload varnish.service
And here come other problems. That command runs the
/usr/share/varnish/reload-vcl script, which reads the
/etc/default/varnish file. This implies that we have to update both
/etc/default/varnish in order to make Varnish work properly.
I hope this would be helpful for other people that otherwise could waste a lot of time trying to figure out why Varnish doesn’t listen on port 80.
I’ll go on with a series of tutorial related to Varnish, so please consider buying me a coffee to support those free contributions. In particular, we’ll see how to properly configure Varnish 4 to make it work with WordPress. Stay tuned!