DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
World desk11 min

How to Set Up Varnish With Nginx and SSL (Nginx TLS Termination Guide)

A practical Debian/Ubuntu guide to running Nginx as the HTTPS edge, Varnish as a private cache, and your origin on a separate port—with working configuration patterns and troubleshooting steps.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The most practical arrangement for an Nginx site is client HTTPS on Nginx port 443 → private HTTP on Varnish → origin Nginx or application on port 8080. Nginx owns the certificate and redirects HTTP to HTTPS; Varnish listens only on a protected internal port such as 6081; its VCL points to the origin listener. This separation prevents port conflicts, keeps TLS management in one deliberate place, and lets you test each layer independently.

Choose the request path before changing any service

Varnish and Nginx cannot both bind the same address and port. Decide which process is public and which ports are private before editing configuration. The common Nginx-fronted topology is:

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Client
  │ HTTPS :443
  ▼
Nginx (TLS termination, redirect, headers)
  │ HTTP 127.0.0.1:6081
  ▼
Varnish (VCL and cache policy)
  │ HTTP 127.0.0.1:8080
  ▼
Origin application or origin Nginx

Port 80 can remain on Nginx solely to issue an HTTPS redirect. The cache does not need to be reachable from the public network. Bind Varnish to loopback (or a firewall-restricted private address) and expose only Nginx’s public listeners.

Layer Suggested address Purpose Public?
Nginx HTTP 80 301 redirect to HTTPS Yes
Nginx HTTPS 443 Certificate handling and reverse proxy Yes
Varnish 127.0.0.1:6081 VCL, cache lookup, cache storage No
Origin Nginx/application 127.0.0.1:8080 Generates the response No

Varnish’s conservative listener default is commonly 6081. A Varnish-fronted design may instead move Varnish to port 80, but that is a different topology: Nginx would then need to be behind it or used only for another role. Do not copy a port-80 Varnish example into an Nginx-fronted deployment without changing the listeners.

#1 Best Overall
HP ProLiant DL360 G7 1U RackMount 64-bit Server - Dual 6-Core X5675 Xeon 3.06GHz CPUs - 72GB PC3-10600R RAM - 4x900GB 10K SAS SFF HDD - P410i RAID, 4xGigaBit NIC - 2 PSU (Renewed)
  • HP ProLiant DL360 G7 Business Server, the perfect enterprise server or small business server!
  • Processors: Dual (2) Xeon X5675 6-Core 3.06 GHz 12MB CPUs Max Turbo 3.46 GHz
  • Memory: 72GB (4 x 16GB) DDR3 PC3-10600R Memory; Storage: 3.6TB (4 x 900GB) 10K 12Gb/s SAS 2.5" HDDs
  • Power: Redundant Power Supplies; RAID: HP Smart Array P410i-a 12Gb/s with 4×GigaBit NIC
  • Hard drives and memory upgrades included separately NOT installed, installation required.

Prepare the server and install Varnish

Check existing listeners and configuration

Before installation, record what is already listening and where Nginx serves the application. On Debian or Ubuntu, inspect listening sockets and the active Nginx configuration:

sudo ss -ltnp
sudo nginx -T

Look for an existing listen 80; or listen 443 ssl; block and for the server block that currently serves the application. You need a separate origin listener after the public Nginx block begins proxying to Varnish.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install from the official Varnish repository

Install a package version supported by your operating system and the official Varnish repository. After installation, inspect the systemd unit rather than assuming a distribution-specific command line:

systemctl cat varnish
systemctl status varnish

The installation guide places the vendor unit at /lib/systemd/system/varnish.service and shows changing its ExecStart listener and cache-size arguments. A systemd drop-in is safer than editing a vendor file directly because package upgrades can replace the vendor unit. Whichever method you use, make the listener explicit and keep the cache size appropriate for the machine’s available memory.

Set the Varnish listener

For this layout, configure Varnish to listen on loopback port 6081. If your package starts on another port, change the service’s address argument so it matches Nginx’s proxy_pass. Do not leave Varnish on a publicly reachable address unless you have a specific reason, firewall rules, and an operational plan for direct cache access.

After changing a unit file or drop-in, reload systemd’s unit definitions:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo systemctl daemon-reload
sudo systemctl restart varnish
sudo systemctl status varnish

Move the origin Nginx listener away from the public port

Varnish must have an origin to contact. The documented quick-start approach changes Nginx listen 80; directives to listen 8080;, then uses 8080 as the VCL backend. Do not perform a blind recursive replacement on a complex production configuration: it can alter an HTTPS block, an included file, or a site that should remain public.

Instead, edit the specific origin server block. A private origin block commonly starts like this:

Rank #2
Quiet Rackmount Computer (3.8-4.6GHz AMD Ryzen 7 5700G CPU, 32GB RAM, 2TB SSD, W11 Pro) - 2U Rack Mount Server or Workstation Desktop PC for Home or Business
  • [CPU] AMD Ryzen 7 5700G Processor (8 Cores, 16 Threads, 3.8 GHz Base Clock Speed up to 4.6 GHz Max Boost Clock Speed) for Gaming and Content Creation with 7nm Leading Edge Technology | [STORAGE] 2TB PCIe NVMe M.2 SSD - Experience Hyper-Fast Bootup and Data Transfer thats up to 30x Faster Performance than a Traditional Hard Drive.
  • Graphics: Integrated AMD Radeon Graphics | [RAM] 32GB DDR4 RAM 3200 Gaming Memory for Seamless Multitasking from Multiple Web Pages to Playing Games Online Simultaneously | [OS] Windows 11 Pro x64
  • 2x 3.5" Drive Bays | 4x Expansion Slots | mATX Motherboard | ATX PSU
  • [BUY WITH CONFIDENCE] Empowered PCs are Assembled in the USA, Rigorously Stress-Tested Before Shipping, and Supported with Lifetime Technical and Diagnostic Support and 3-Year Limited Hardware Warranty.
server {
    listen 127.0.0.1:8080;
    server_name example.com www.example.com;

    root /var/www/example;
    # application-specific location and fastcgi/proxy settings go here
}

If your application server already listens on another local port, keep that port and use it in VCL. The important rule is that the address and port in default.vcl must exactly match the service that can answer an ordinary HTTP request. Bind to loopback when the origin and Varnish share a host; use a private network address when they are separate hosts.

Keep the public redirect and TLS server blocks separate from the origin block. The public blocks should proxy to Varnish, while the origin block should serve the application directly and should not redirect every request back to HTTPS, or the cache will encounter a redirect loop.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Point Varnish at the origin with VCL

Set the backend address

Edit /etc/varnish/default.vcl and define the backend that Varnish will fetch:

vcl 4.1;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

The standard VCL supplied with Varnish uses 127.0.0.1:8080. Change both values if your origin differs. VCL hostnames are resolved when the VCL is compiled, not dynamically for every request. If a DNS name in a backend changes address, compile or reload the VCL again so Varnish uses the new resolution.

Add policy only for responses you know are safe to cache

Start with the generated VCL and the default HTTP cache semantics. Add explicit bypass rules for authenticated or personalized traffic, and for operations that change state. A conservative starting pattern is:

sub vcl_recv {
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }
    if (req.http.Authorization) {
        return (pass);
    }
    if (req.url ~ "^/(login|account|checkout|cart|admin)(/|$)") {
        return (pass);
    }
}

sub vcl_backend_response {
    if (beresp.http.Set-Cookie || beresp.http.Cache-Control ~ "private|no-store") {
        set beresp.uncacheable = true;
        set beresp.ttl = 0s;
    }
}

Treat that as a policy starting point, not a universal recipe. Preserve Host, cookies, authorization, and origin Cache-Control behavior unless the application owner has explicitly decided otherwise. A page containing a user name, account balance, shopping cart, or administrative controls must not be served from a shared cache merely because it returned HTTP 200.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Configure Nginx to terminate HTTPS and proxy to Varnish

Nginx’s HTTPS server requires an SSL-enabled listener, a certificate, and a private key. The following example uses the conventional certificate paths for example.com; substitute the paths installed on your server:

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:6081;
        proxy_set_header Host $host;
        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_pass sends the request to Varnish. The Host header lets the origin select the correct virtual host; X-Real-IP and X-Forwarded-For preserve client address information for logs and application controls; X-Forwarded-Proto https tells the application that the original client connection was secure even though the internal hop is HTTP.

Rank #3
Dell PowerEdge R730xd Server 24B SFF 2U, 2X Intel Xeon E5-2690 v4 2.6Ghz (28-cores Total), 128GB DDR4 RAM, 4X 1.2TB 10K SAS 2.5” 12Gb/s HDD, H730P 2GB RAID, NIC 10Gb + I350 1Gb (Renewed)
  • Dell PowerEdge R730xd 24B SFF 2U Server
  • 2x Intel Xeon E5-2690 v4 2.6Ghz 14-Core (28-cores Total)
  • 128GB DDR4 RAM – 4x 1.2TB 10K SAS 2.5” 12Gb/s
  • Dell H730P mini 2GB 12Gb/s RAID
  • 2x 750W PSU - 2x 10Gb SFP+ 2x 1Gb (RJ45) NIC

If your application builds absolute URLs, enforces secure cookies, or performs HTTPS redirects, make sure it trusts the forwarded scheme only from this controlled proxy. Do not let an arbitrary client supply a trusted forwarding header by reaching the origin directly.

Validate Nginx before reloading

Always test syntax before replacing a running configuration:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo nginx -t
sudo systemctl reload nginx

If the test fails, keep the previous configuration active and fix the reported file and line. A certificate path, key permission, duplicate listener, or malformed proxy directive can prevent Nginx from starting or reloading.

Apply the changes in a safe order

  1. Prepare the origin: make the application answer on the chosen local port, normally 8080, and verify it directly with a local HTTP request.
  2. Compile and load VCL: check that /etc/varnish/default.vcl parses, then reload or restart Varnish. Inspect the service journal if the VCL is rejected.
  3. Set Nginx proxying: change the public HTTPS location to proxy_pass http://127.0.0.1:6081;, retain the forwarding headers, run nginx -t, and reload only after a successful test.
  4. Verify listeners: run ss -ltnp and confirm that Nginx owns 80 and 443, Varnish owns the private cache port, and the origin owns 8080 (or your selected port).
  5. Test from outside: request the public HTTPS name and inspect the certificate, redirect, status code, and response headers.

Verify each layer instead of guessing from one browser request

Check the public endpoint

curl -I http://example.com/
curl -I https://example.com/

The HTTP request should return the configured redirect. The HTTPS request should complete the certificate handshake and return the application response through Nginx and Varnish. A 502 or 503 usually means the next hop is not listening, is blocked, or is returning an invalid response.

Check cache behavior with two requests

Choose a URL that the application has declared cacheable and request it twice:

curl -I https://example.com/cacheable-page
curl -I https://example.com/cacheable-page

Use headers such as Age, Via, or an application-specific cache header if your configuration emits them. Timing differences alone do not prove a cache hit. The expected result depends on cookies, authorization, response directives, VCL rules, and whether the first request populated the cache.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check bypass and state-changing paths

Test an authenticated URL, a cart or checkout path, and a non-GET request with application-appropriate credentials and methods. Confirm that these requests pass to the origin or invalidate objects according to your policy. Never infer that every 200 response is safe to cache.

Read service logs and statistics

When behavior is unexpected, inspect Nginx error logs, the Varnish service journal and Varnish request statistics together. A browser hides which hop failed; correlated timestamps reveal whether Nginx could connect to Varnish, whether Varnish could connect to the backend, and whether the backend returned a cacheable response.

Rank #4
Sale
Rosewill 4U Server Chassis Rackmount Case | 15 3.5" HDD Bays | E-ATX Compatible | 6 Front 120mm Fans, 2 Rear 80mm Fans | 2X USB 3.0 | Front Panel Lock and Key | Silver/Black - RSV-L4500U
  • Spacious Chassis: This huge 4U server case comes with 15 internal 3.5" HDD bays.
  • Expandable & E-ATX Compatible: 7 PCI expansion slots and E-ATX compatibility gives you growth options for all of your needs.
  • Exceptional Cooling: 8 pre-installed cooling fans provide excellent airflow and heat protection. 3 front 120mm PWM fans, 3 middle 120mm fans and 2 rear 80mm fans ensure your drives and chassis avoid overheating.
  • Desired Features: Front panel LED indicators for power, HDD, and LAN status monitoring allow quick, easy visual assessment. Additional utility with 2 USB 3.0 port and built-in front panel lock.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Decide where TLS should terminate

Design Client connection Internal connection Advantages Costs and cautions
Nginx terminates TLS Nginx :443 HTTP to private Varnish Simple certificate management; straightforward redirects and headers; Nginx can provide the public TLS edge Protect the internal network; pass the original scheme explicitly; Varnish does not see client TLS directly
Varnish terminates TLS Varnish HTTPS listener HTTP or HTTPS to backend Varnish can be the front proxy and apply VCL immediately at the edge Certificate loading and renewal move to Varnish; Nginx must be behind it or serve another role
Encrypted Varnish-to-backend hop Nginx or Varnish terminates client TLS HTTPS to backend Protects traffic between separate hosts or trust zones More certificates, validation, and troubleshooting; configure the backend with .ssl = 1

When Nginx termination is the better default

Use Nginx termination when one host handles certificates, redirects, HTTP edge behavior, and proxy headers, while Varnish remains a private cache. This is usually the least complicated arrangement for a conventional Nginx deployment. It also gives you a clear place to add HTTP/2 or HTTP/3 edge support when your Nginx build and clients require it; the internal Varnish hop can remain ordinary HTTP on loopback.

When Varnish termination is appropriate

Varnish documents native HTTPS listeners, including separate address arguments for HTTP and HTTPS and a certificate-loading workflow. Choose this only when you intentionally want Varnish to own the public TLS socket and have a renewal process that updates its loaded certificates. Nginx cannot continue listening on the same public address and port.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When to encrypt the backend hop

If Varnish and the origin are on different machines or cross a network you do not fully trust, define the backend on its HTTPS port and set .ssl = 1. Validate certificate names and trust requirements for that connection; do not assume that enabling the flag alone provides hostname verification suitable for every deployment.

Troubleshoot by symptom

Nginx reports “address already in use”

Two services are competing for the same socket. Run ss -ltnp, identify the process, and assign distinct listeners. In the recommended layout, Nginx owns 80 and 443, Varnish owns 127.0.0.1:6081, and the origin owns 127.0.0.1:8080.

Nginx returns 502 Bad Gateway

Confirm that Varnish is running and listening on the exact address in proxy_pass. Then request Varnish’s listener locally and inspect its logs. If Varnish is healthy, test the backend port directly; a stopped origin, wrong VCL port, local firewall rule, or origin application crash is the likely next fault.

Varnish returns 503 Backend fetch failed

Check the backend host and port in default.vcl, whether the origin binds only to an address Varnish cannot reach, and whether the origin expects a different Host value. A DNS name in VCL may also point to an old address until the VCL is recompiled and reloaded.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Every request is a cache miss

Inspect response Cache-Control, Set-Cookie, authorization headers, request methods, and VCL bypass rules. Personalized responses should miss by design. If a public response is intended to cache, remove accidental cookies or private directives at the application layer rather than stripping them blindly in VCL.

Users see the wrong scheme or redirect loops

Ensure Nginx sets X-Forwarded-Proto https and that the application trusts that header only from Nginx. A redirect loop often occurs when the origin sees the internal HTTP hop and believes the original request was insecure.

The certificate is valid but renewal breaks traffic

Check certificate and key permissions, reload Nginx after renewal, and verify the new certificate with an external curl -I https://... request. If Varnish terminates TLS, its certificate-loading and commit step must also run after renewal; reloading only Nginx will not update a Varnish-owned listener.

Operational safeguards after the first deployment

  • Restrict exposure: firewall the Varnish and origin ports so only the intended local or private-network peers can reach them.
  • Keep forwarding headers consistent: document which proxy sets X-Forwarded-For and X-Forwarded-Proto, and configure the application to trust only that proxy chain.
  • Plan invalidation: define how publishing, profile changes, cart updates, and emergency content removal purge or bypass cached objects.
  • Monitor certificate expiry: alert before the certificate expires and test the renewal reload path, not just the renewal command.
  • Review cache keys: ensure host, path, query-string handling, cookies, authorization, and language or device variants match the application’s content model.
  • Retain observability: keep Nginx access/error logs and Varnish logs or statistics long enough to diagnose stale content, backend failures, and unusual hit rates.
  • Reload deliberately: run an Nginx syntax test before every reload, and compile or validate VCL before replacing the active configuration.

Recommended final configuration checklist

  • Nginx listens publicly on 80 and 443; no other service competes for those ports.
  • The HTTPS server has listen 443 ssl, valid certificate and key paths, and the intended TLS protocol versions.
  • Nginx proxies to the private Varnish listener and sends Host, client-IP, forwarded-for, and original-scheme headers.
  • Varnish’s listener address matches Nginx’s proxy_pass and is not unnecessarily exposed.
  • /etc/varnish/default.vcl points to the real origin address and port, with a reload after any DNS change.
  • The origin serves directly on its private port and does not redirect the internal hop back to HTTPS.
  • VCL bypasses authenticated, personalized, administrative, checkout, cart, and state-changing traffic unless the application has a tested alternative policy.
  • nginx -t, service status checks, listener checks, public curl -I requests, and two-request cache tests all succeed.

For most Nginx deployments, terminate client TLS at Nginx, keep Varnish on a private HTTP listener, and point VCL at a private origin port. Move TLS to Varnish or encrypt the backend hop only when a specific network or ownership requirement justifies the added certificate and operational complexity.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick Recap

Bestseller No. 1
HP ProLiant DL360 G7 1U RackMount 64-bit Server - Dual 6-Core X5675 Xeon 3.06GHz CPUs - 72GB PC3-10600R RAM - 4x900GB 10K SAS SFF HDD - P410i RAID, 4xGigaBit NIC - 2 PSU (Renewed)
HP ProLiant DL360 G7 1U RackMount 64-bit Server - Dual 6-Core X5675 Xeon 3.06GHz CPUs - 72GB PC3-10600R RAM - 4x900GB 10K SAS SFF HDD - P410i RAID, 4xGigaBit NIC - 2 PSU (Renewed)
Processors: Dual (2) Xeon X5675 6-Core 3.06 GHz 12MB CPUs Max Turbo 3.46 GHz; Power: Redundant Power Supplies; RAID: HP Smart Array P410i-a 12Gb/s with 4×GigaBit NIC
$349.00
Bestseller No. 3

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.