This post shows how to configure Varnish to handle WebSocket traffic.
Varnish is an HTTP accelerator that's commonly used to cache dynamic content for a Web server. On this site, it is sitting in front of Nginx, which by itself is a resource-friendly Web server, a lot more resource-friendly than Apache. Using Varnish with Nginx makes a website load really fast.
When I decided to use NodeBB as the forum application for this website, I wasn't aware that Varnish and WebSocket don't play nice by default, so Varnish has to be explicitly configured to handle WebSocket traffic. But it took several frustrating days before I finally figured out that Varnish was the source of the problems and errors I was dealing with.
NodeBB is a NodeJS forum application that makes use of WebSocket to provide real-time features. If you haven't used it before, register an account here to get a first-hand view of how it works. It's definitely much better than your traditional PHP-based forum software. By default NodeBB does not run on the standard HTTP port, so I had to use Nginx to proxy connections to it.
To make Varnish handle WebSocket traffic, the code below was added to the Varnish configuration file (/etc/varnish/default.vcl) Note that this is in addition to what's already in that file:
backend nodejs {
  .host = "";  
  .port = "4567";  

sub vcl_recv {

  if (req.http.Upgrade ~ "(?i)websocket") {
    set req.backend = nodejs;
    return (pipe);

  if ( == "") {  
    if (req.url ~ "^/") {
        set req.backend = nodejs;
        return (pipe);  
    return (pass);  


sub vcl_pipe {
  if (req.http.upgrade) {
    set bereq.http.upgrade = req.http.upgrade;
That piece of code was taken from here. The backend points to where NodeBB is listening. To make this work, that backend has to be referencd in the Nginx configuration file for this subdomain. That file looks something like this:
 upstream nodejs {

server {    
    listen 81 default;

## Settings for proxying NodeBB forum installation.

        location / {

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://nodejs;
        proxy_redirect off;

        # Socket.IO Support                                                                                                   
        proxy_http_version 1.1;                                                                                               
        proxy_set_header Upgrade $http_upgrade;                                                                               
        proxy_set_header Connection "upgrade";                                                                                


Note that upstream and backend have to match, which is then referenced in the proxy_pass line. With that, Varnish should handle all WebSocket traffic destined for NodeBB. Note that this is not just for NodeBB, but for all NodeJS applications.