Varnish, Nginx with SSL install under Ubuntu 16.04

Install Varnish 5.1 on Ubuntu 16.04 sound´s like easy. WTF? Not realy

Look at here when you in trouble with systemd and Varnish

Here is my configuration of Varnish with Nginx ssl on Ubuntu 16.04

First install Varnish  4.1 or 5.1

You can use Ubuntu repository

apt-get install varnish

Now you have Varnish 4.1 on the System

Or use these instructions

So you will get Varnish 5.1

start and enable Varnish as service

sudo systemctl start varnish.service

sudo systemctl enable varnish.service

With my configuration you don´t need adjust varnish port config. Feel free to adjust your Varnish config

!!!Attention!! THX to Mattia for this great blog post

This Snippet is from Mattia´s blog post
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 (/lib/systemd/system/varnish.service).

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:

Description=Varnish HTTP accelerator

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


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/systemd/system/varnish.service and /etc/default/varnish in order to make Varnish work properly.

See below post for editing your Varnish config


# Configuration file for Varnish Cache.
# /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK
# to be set from this shell script fragment.
# Note: If systemd is installed, this file is obsolete and ignored. You will
# need to copy /lib/systemd/system/varnish.service to /etc/systemd/system/ and
# edit that file.

# Should we start varnishd at boot? Set to "no" to disable.

# Set WARMUP_TIME to force a delay in reload-vcl between vcl.load and vcl.use
# This is useful when backend probe definitions need some time before declaring
# configured backends healthy, to avoid routing traffic to a non-healthy backend.

# Maximum number of open files (for ulimit -n)

# Maximum locked memory size (for ulimit -l)
# Used for locking the shared memory log in memory. If you increase log size,
# you need to increase this number as well

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


adjust the port on the default.vcl or more when you need it.

Change it to 8080

# This is an example VCL file for Varnish.
# It does not do anything by default, delegating control to the
# builtin VCL. The builtin VCL is called when there is no explicit
# return statement.
# See the VCL chapters in the Users Guide at
# and for more examples.

# Marker to tell the VCL compiler that this VCL has been adapted to the
# new 4.0 format.
vcl 4.0;

# Default backend definition. Set this to point to your content server.
backend default {
.host = "";
.port = "8080";

sub vcl_recv {
# Happens before we check if we have this in cache already.
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.

sub vcl_backend_response {
# Happens after we have read the response headers from the backend.
# Here you clean the response headers, removing silly Set-Cookie headers
# and other mistakes your backend does.

sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
# You can do accounting or modifying the final object here.

look with properties Varnish is running

ps aux | grep varn
varnish 18342 0.0 5.3 118936 84584 ? SLs 08:53 0:00 /usr/sbin/varnishd -a :6081 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m
vcache 18350 0.0 5.5 339568 87252 ? Sl 08:53 0:01 /usr/sbin/varnishd -a :6081 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m
root 31137 0.0 0.0 11228 876 pts/6 S+ 09:47 0:00 grep –color=auto varn
root 31600 0.1 0.2 181600 3560 pts/4 Sl+ 09:09 0:04 varnishhist

Varnish is running you can test it with

your ip:6081

You will see a screen with a backend error, lets fix us this.

Now we need the Nginx web server

apt-get install nginx

We need 3 config files

The first config file are redirect from port 80 to 443 and add www to your domain.

vim /etc/nginx/sites-available/redirect

server {
listen 80;
return 301$request_uri;

We need our main config file that will be run our website. I will serve a static html page for the moment.

vim /etc/nginx/sites-available/roundtrip

server {
listen 8080 default_server;
root /var/www/html;

server_name _;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;


The last config file our ssl termination with nginx. I´m using let´s encrypt certs. You can use self signed cert´s or buy something.

vim /etc/nginx/sites-available/ssl

server {
listen 443 ssl;

ssl_certificate /etc/letsencrypt/live/;
ssl_certificate_key /etc/letsencrypt/live/;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;


lets activate our new nginx config

cd /etc/nginx/sites-available/

ln -s /etc/nginx/sites-available/redirect redirect
ln -s /etc/nginx/sites-available/roundtrip roundtrip
ln -s /etc/nginx/sites-available/ssl ssl

check the config

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

service nginx restart

That´s it!