🚀 Ultimate Guide to Enabling Gzip & Brotli Compression on VPS with EA-Nginx (CloudLinux + cPanel)
A practical, copy‑paste friendly guide for VPS admins running CloudLinux + cPanel/WHM with EA‑Nginx reverse proxy. Covers global gzip/Brotli, cache purge, verification, CDN interplay, and a full troubleshooting checklist.
📝 TL;DR (Admin Quick Start)
# 1) Enable proxy‑layer gzip (safe types only)
cat >/etc/nginx/conf.d/zz-gzip.conf <<'NGX'
# Global gzip for text assets (safe, server-wide)
gzip on;
gzip_disable "msie6";
gzip_comp_level 5;
gzip_min_length 512;
gzip_vary on;
gzip_proxied any;
# Only text-based types (do NOT include images or woff2)
gzip_types text/plain text/css text/xml text/javascript \
application/javascript application/x-javascript application/json \
application/xml application/rss+xml application/ld+json image/svg+xml \
application/vnd.ms-fontobject application/x-font-ttf application/x-font-opentype \
application/font-woff font/ttf font/otf;
NGX
# 2) (Optional) Enable Brotli (if modules present)
ls -1 /usr/lib64/nginx/modules/ | egrep 'brotli_(filter|static)_module\.so' || true
if ! nginx -T 2>/dev/null | grep -q 'ngx_http_brotli_filter_module'; then
cp -a /etc/nginx/nginx.conf{,.bak-$(date +%F-%H%M%S)}
sed -i '1iload_module modules/ngx_http_brotli_static_module.so;' /etc/nginx/nginx.conf
sed -i '1iload_module modules/ngx_http_brotli_filter_module.so;' /etc/nginx/nginx.conf
fi
cat >/etc/nginx/conf.d/zz-brotli.conf <<'NGX'
brotli on;
brotli_comp_level 4;
brotli_static on; # if .br files exist; harmless otherwise
brotli_types text/plain text/css application/json application/javascript \
text/xml application/xml application/rss+xml image/svg+xml;
NGX
# 3) Test & reload Nginx
nginx -t && (/scripts/restartsrv_nginx || systemctl reload nginx)
# 4) Purge proxy cache once (paths may vary)
CACHE_DIR=$(nginx -T 2>/dev/null | awk '/proxy_cache_path/ {print $2}' | sed 's/;.*//')
[ -n "$CACHE_DIR" ] && rm -rf "$CACHE_DIR"/* 2>/dev/null || rm -rf /var/cache/nginx/* 2>/dev/null
/scripts/restartsrv_nginx || systemctl reload nginx
# 5) Verify (HTML + real CSS/JS)
for url in \
https://example.com/ \
https://example.com/wp-includes/css/dist/block-library/style.min.css
do
echo -e "\n==> $url"; curl -sI -H 'Accept-Encoding: gzip,br' "$url" | egrep -i 'HTTP/|server:|content-type:|content-encoding:|vary:'; done
Expect: Content-Encoding: br
or gzip
+ Vary: Accept-Encoding
.
🔍 Why .htaccess Isn’t Enough in EA-Nginx
Apache's DEFLATE via .htaccess
only applies if Apache handles the response. EA-Nginx often caches and serves content without Apache, making .htaccess
ineffective.
✅ Solution: Enable Nginx-level compression and purge the proxy cache.
🤖 Stack Detection & Brotli Availability
Check:
/scripts/restartsrv_nginx --status || systemctl status nginx
nginx -V 2>&1 | egrep -i 'nginx version|brotli|modules'
Look for:
-
EA-Nginx present:
/scripts/restartsrv_nginx
works -
Brotli: modules exist under
/usr/lib64/nginx/modules/
🛠️ Enable Gzip & Brotli Compression (Safe Types)
-
Create
/etc/nginx/conf.d/zz-gzip.conf
and/zz-brotli.conf
-
Load Brotli modules if available
-
Reload Nginx safely
-
Purge proxy cache
Compression Levels:
-
gzip_comp_level 4-5
-
brotli_comp_level 3-5
Never compress binary types (images, WOFF2, archives).
🔎 Verification Methods
cURL
curl -I -H 'Accept-Encoding: gzip,br' https://example.com/
Check for:
-
Content-Encoding: br/gzip
-
Vary: Accept-Encoding
Browser
-
DevTools → Network Tab
-
Look for headers in HTML/CSS/JS
🤔 Common Pitfalls
-
gzip off;
in later includes:nginx -T | grep -n 'gzip\s\+(on|off);'
-
CDN like Cloudflare overriding with its compression: enable Speed → Brotli
-
Testing 404s or binary files: always verify real, existing assets
📊 Performance Notes
-
Compression is cached = minimal CPU impact
-
Only for text-based assets
-
Vary: Accept-Encoding
ensures CDN/client compatibility
🚀 Rollout & Rollback Procedures
Rollout
# Add .conf files
# Load brotli modules (if needed)
# Reload nginx
# Purge cache
Monitoring
top -o %CPU
journalctl -u nginx -n 200 --no-pager
Rollback (Instant)
mv /etc/nginx/conf.d/zz-brotli.conf{,.disabled}
mv /etc/nginx/conf.d/zz-gzip.conf{,.disabled}
sed -i '/load_module modules\/ngx_http_brotli_.*_module.so;/d' /etc/nginx/nginx.conf
nginx -t && (/scripts/restartsrv_nginx || systemctl reload nginx)
🔧 Troubleshooting Checklist
-
Confirm Nginx serving (check
Server:
header) -
Test real assets (avoid 404s/images)
-
Ensure
Content-Encoding
andVary
present -
Purge proxy cache
-
Check for
gzip off;
in config includes -
Validate CDN settings (Cloudflare Brotli, etc.)
-
Check app/plugin compression overrides
-
Confirm correct subdomain docroots
-
Set
gzip_comp_level 1
temporarily if needed -
Inspect Nginx logs
🖊️ One-Liner: Verify Any Domain
domain=example.com
for u in "https://$domain/" \
"https://$domain/wp-includes/css/dist/block-library/style.min.css"; do
echo "$u";
curl -sI -H 'Accept-Encoding: gzip,br' "$u" | egrep -i 'HTTP/|server:|content-type:|content-encoding:|vary:';
echo;
done
🌐 Appendix: "Optimize Website" in cPanel
It’s safe to keep Apache DEFLATE enabled in cPanel, but EA-Nginx compression is what actually matters for client performance.