Varnish
Contents:
Varnish is a popular HTTP proxy server, often used for caching. It is usually not needed on Platform.sh, as each project’s router provides an HTTP cache already and most more advanced use cases will use a CDN instead, both of which render Varnish redundant.
However, it is possible to configure a Varnish instance as part of an application if Varnish-specific functionality is needed.
Supported versions
Grid | Dedicated |
---|---|
|
None available |
How it works
All incoming requests still go through the environment’s router first. When using Varnish, a Varnish service sits between the router and the application server or servers.
web -> router -> varnish -> application
-> application2
Configuration
Add a Varnish service
Add the following to your .platform/services.yaml
file:
proxy:
type: varnish:6.0
relationships:
application: 'app:http'
configuration:
vcl: !include
type: string
path: config.vcl
In the relationships
block, define a relationship (application
) to the application container (app
) using the http
endpoint. That allows Varnish to talk to the application container.
The configuration block is required, and must reference a VCL file (here config.vcl
). The file name is relative to the .platform
directory.
Create a VCL template file
The VCL file you provide has three specific requirements over and above the VCL syntax itself.
- You MUST NOT define a
vcl_init()
function. Platform.sh will auto-generate that function based on the relationships you define. In particular, it will define a “backend” for each relationship defined inservices.yaml
, named the same as the relationship. - You MUST NOT include the preamble at the beginning of the file, specifying the VCL version. That will be auto-generated as well. You CAN add imports, but not
std
anddirectors
, as they’re imported already. - You MUST specify the backend to use in
vcl_recv()
. If you have a single app container/relationship/backend, it’s just a single line. If you want to split requests to different relationships/backends based on some rule then the logic for doing so should be incorporated into thevcl_recv()
function.
The absolute bare minimum VCL file is:
sub vcl_recv {
set req.backend_hint = application.backend();
}
Where application
is the name of the relationship defined in services.yaml
. (If the relationship was named differently, use that name instead.)
If you have multiple applications fronted by the same Varnish instance then you will need to include logic to determine to which application a request is forwarded. For example:
varnish:
type: varnish:6.0
relationships:
blog: 'blog:http'
main: 'app:http'
configuration:
vcl: !include
type: string
path: config.vcl
# config.vcl
sub vcl_recv {
if (req.url ~ "^/blog/") {
set req.backend_hint = blog.backend();
} else {
set req.backend_hint = main.backend();
}
}
This configuration will direct all requests to a URL beginning with a /blog/
path to the application on the relationship blog
, and all other requests to the application on the relationship main
.
Besides that, the VCL file, including the vcl_recv()
function, can be arbitrarily complex to suit the needs of the project. That includes additional include
directives if appropriate. See the Varnish documentation for more details on the functionality offered by Varnish.
Note:
A misconfigured VCL file can result in incorrect, often mysterious and confusing behavior. Platform.sh does not provide support for VCL configuration options beyond the basic connection logic documented here.
Route incoming requests to Varnish
To enable Varnish now, edit the .platform/routes.yaml
file to point to the Varnish service you just created. You also need to disable the router cache as it is now entirely redundant with Varnish.
For example:
"https://{default}/":
type: upstream
upstream: "varnish:http"
cache:
enabled: false
That will map all incoming requests to the Varnish service rather than the application. Varnish will then, based on the VCL file, forward requests to the application as appropriate.
Modules
Platform.sh supports a number of optional modules you can include in your VCLs, namely:
- cookie
- header
- saintmode
- softpurge
- tcp
- var
- vsthrottle
- xkey
To use in your VCL, add an import such as:
import xkey;
Circular relationships
At this time Platform.sh does not support circular relationships between services or applications. That means you cannot add a relationship in your .platform.app.yaml
that points to the Varnish service. If you do so then one of the relationships will be skipped and the connection will not work. This limitation may be lifted in the future.
Stats endpoint
The Varnish service also offers an http+stats
endpoint, which provides access to some Varnish analysis and debugging tools. To access it, from a dedicated app container add the following to .platform.app.yaml
:
relationships:
varnishstats: "proxy:http+stats"
You can then access the varnishstats
relationship over HTTP at the following paths to get diagnostic information:
/
: returns the error if generating the VCL failed with an error/config
: returns the generated VCL/stats
: returns the output ofvarnishstat
/logs
: returns a streaming response ofvarnishlog
Note that because of the circular relationship issue noted above this cannot be done on the application that Varnish is forwarding to. It will need to be run on a separate application container.