Docker install guide

This install guide explains how to deploy Varnish Cache using the official Docker container.

Pull the Varnish docker image

First pull the Docker image from the Docker hub to ensure you have the latest version:

docker pull varnish

This command will implicitly use the latest tag to get the right version of the container. You can pin a specific version by adding one of the available tags.

Here’s an example where we explicitly pull version 8.0 of Varnish Cache:

docker pull varnish:8.0

Create a VCL file

Unlike traditional Varnish setups where the software needs to be installed first, the Docker images allow you to spin up containers that have a full Varnish setup in a matter of seconds.

This means you can focus on your VCL, rather than the stack running your VCL code. Here’s the absolute minimum amount of VCL you need to connect to your origin server:

vcl 4.1;

backend default {
    .host = "backend.example.com";
    .port = "80";
}

The backend definition in the VCL file refers to the origin server for which we are caching HTTP resources. The .host property contains the hostname of the origin and the .port property contains the port number on which your origin is listening for incoming HTTP connections.

For real-world applications, there’s probably some more VCL required that depends on the type of application you’re trying to accelerate. Store your VCL code in a file on your host system, we will mount it into the container in the next step.

Run the Varnish Docker container

The docker run command can be used to run a Docker container. While this command has many options, here’s a typical example where the varnish image is used to spin up a Docker container:

docker run -v /path/to/default.vcl:/etc/varnish/default.vcl:ro \
	--tmpfs /var/lib/varnish:exec \
	--name varnish \
	-p 80:80 \
	-e VARNISH_SIZE=2G \
	varnish

Let’s break this command down and explain the various parameters into the subsections below.

Mounting the VCL file

The -v option is used to mount volumes into your Docker container. These are shared filesystems that are used to share files from the host system.

The -v /path/to/default.vcl:/etc/varnish/default.vcl:ro definition will mount /path/to/default.vcl from your host system into /etc/varnish/default.vcl in your container.

The :ro option will only allow read-only access to the VCL file inside the Docker container.

Loading /var/lib/varnish into memory

The /var/lib/varnish folder is frequently accessed by the varnishd program. Loading this folder into memory and accessing it through tmpfs would accelerate access to this folder.

--tmpfs /var/lib/varnish:exec takes care of this. The :exec option gives container execution permissions on that folder.

Naming the container

The --name varnish option will assign varnish as the name of the container. If no --name option is added, Docker will generate a random name.

Exposing the listening port

The -p 80:80 option will expose port 80 from the container as port 80 on the host system. This allows users to access Varnish by calling the http://localhost endpoint on the host system.

If the host seems also exposes port 80 to the outside world, the IP address or hostname of the system can also be used to access Varnish.

Setting the cache size

The standard size of the cache is 100 MB. The VARNISH_SIZE environment variable is used to override this value. Environment variables are set using the -e option in Docker.

This means that the -e VARNISH_SIZE=2G option from the example above will set the cache size to 2 GB.

Additional parameters

The Varnish Docker image is designed in such a way that extra varnishd runtime parameters can be added.

Any option that is added after the image, will be attached as a varnishd runtime parameter.

For example docker run varnish -p default_ttl=3600 will assign a -p option to the varnishd program. This allows you to extend Varnish’s runtime parameters.

-p default_ttl=3600 wil set the standard Time-To-Live of Varnish to an hour, whereas the standard value is 2 minutes.

Running commands

We can use docker exec to execute commands on our running Varnish container.

The following access gives you access to the Bash shell of the varnish container:

docker exec -ti varnish bash

This allows you to execute commands like varnishreload, varnishadm, varnishlog, varnishncsa and various other commands on the system.

It is also possible to access these commands directly without going through the Bash shell.

Here’s an example where we reload the VCL configuration using a single command:

docker exec varnish varnishreload

The following command will interactively run the varnishlog -g request -q "ReqURl eq '/'" command:

docker exec -ti varnish varnishlog -g request -q "ReqURl eq '/'"

This command will display Varnish Shared Memory Logs in real-time, group the output by request and filter requests for the homepage.

Docker Compose

If you’re planning to orchestrate a multi-container setup using Docker Compose, here’s an example of a compose.yml file that contains a Varnish configuration:

services:
  varnish:
    image: varnish
    container_name: varnish
    volumes:
      - "./default.vcl:/etc/varnish/default.vcl"
    ports:
      - "80:80"
    tmpfs:
      - /var/lib/varnish:exec
    environment:
      - VARNISH_SIZE=2G
    command: "-p default_keep=300"
    depends_on:
      - "httpd"
  httpd:
    image: httpd:latest
    container_name: httpd
    ports:
      - "8080:80"

This docker-compose.yml file will spin up 2 containers:

  • A Varnish container named varnish
  • An Apache container named httpd

The Varnish container

The Varnish container uses the varnish image and exposes HTTP port 80 to the host system. The /var/lib/varnish folder from the container will be mounted through tmpfs. This means the directory will be a separate RAM disk volume with execute permissions.

Through the VARNISH_SIZE environment variable, we’re extending the size of the cache to 2 GB.

The command: "-p default_keep=300" statement allows us to attach extra parameters to the varnish program and override some runtime parameters. In this case we’re setting the value of the default_keep runtime parameter to 300 seconds.

The VCL file

The default.vcl file from the host system will be mounted into the Varnish container and will be available through /etc/varnish/default.vcl.

Here’s what the VCL file could look like:

vcl 4.1;

backend default {
    .host = "httpd";
    .port = "80";
}

The httpd hostname in the VCL backend refers to the Apache container where Varnish will proxy requests to.

The Varnish container depends on the Apache container. The depends_on syntax will ensure the Varnish container is created after the Apache container. Otherwise the httpd hostname would not be resolvable in VCL.

The Apache container

The Apache container itself is pretty basic: it uses the httpd:latest images.

Its HTTP port is exposed to the host system as port 8080. Internally, port 80 is still used, as you can see in the VCL example above.

The Apache webserver acts as the origin and its contents will be cached by Varnish.

Starting the containers

To set up our Varnish and Apache stack using Docker Compose, run the following command:

docker compose up

This command will read the compose.yml file in the current directory and start the containers based on the configuration.

Access the containers

After the environment has been started, you can access Varnish through the http://localhost endpoint on your host system. If you want access the Apache webserver directly you can use the http://localhost:8080 endpoint.

To access the bash shell of the Varnish container, simply run the following command:

docker exec -ti varnish bash

This will allow you to use tools like varnishadm, varnishstat and varnishlog.

Cleaning up

When you’re done running this Docker Compose environment, you can tear it down using a single command:

docker compose down