Unable to get compression (gzip)

Hello, I am unable to get compression (gzip), I have enabled:

  - "traefik.http.middlewares.test-compress.compress=true"

If I deploy the same container (gunicorn/flask) with nginx as reverse proxy I can set the gzip compression and the load time of my app decreases to 2-3 seconds compared to 8-10 seconds with traefik.

With traefik:
Page Size: 19.6 KB
Compressed Page Size: 4.5 KB
Potential Savings: 77%

Also I noted that if I disable the 443 entrypoint and SSL conf (With letsencrypt) the site improves the performance to load the page as 4-5 seconds.

We are used to deploy the python apps with nginx but we are in with love traefik simple configuration through labels,the great dashboard and the letsencrypt integration...but, how can I get a better performance?

docker-compose.yml file:

version: '3'

services:

  reverse-proxy:
    restart: always

    image: traefik:v2.2
    # Enables the web UI and tells Traefik to listen to docker
    command: 
      - --log.level=DEBUG
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --api
      - --providers.docker
      - --certificatesresolvers.le.acme.email=some@gmail.com
      - --certificatesresolvers.le.acme.storage=/acme.json
      - --certificatesresolvers.le.acme.tlschallenge=true
      - --certificatesresolvers.le.acme.httpchallenge=true
      - --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
    ports:
      - "80:80"
      - "443:443"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
      - ./acme.json:/acme.json

    networks:
      - backend

    labels:
      - "traefik.http.routers.traefik.rule=Host(`traefik.myapp.live`)"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.tls.certresolver=le"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.middlewares=authtraefik"
      - "traefik.http.middlewares.authtraefik.basicauth.users=admin:pass/"
      - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.entrypoints=web"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.middlewares.test-compress.compress=true"
      - "traefik.http.middlewares.testHeader.Headers.AccessControlMaxAge=31536000"


  myapp:
    restart: always
    image: myapp:latest
    build:
      context: .
      dockerfile: Dockerfile.myapp

    environment:
      MYSQL_DB: 'myapp'
      MYSQL_USER: 'root'
      MYSQL_HOST: 'myapp-mysql'
      APP_ENVIRONMENT: development

    depends_on:
      - myapp-mysql

    networks:
      - backend

    labels:
      - traefik.http.routers.myapp.rule=Host(`myapp.live`)
      - traefik.http.routers.myapp.tls.certresolver=le
      - traefik.http.routers.myapp.tls=true
      - traefik.http.routers.myapp.entrypoints=websecure

  myapp-mysql:
    restart: always
    image: mysql:8.0
    command: mysqld --default-authentication-plugin=mysql_native_password

    environment:
      MYSQL_ROOT_PASSWORD: my-secret-pw

    networks:
      - backend

networks:
  backend:
    driver: bridge



Thanks in advance
1 Like

Hello,

to use a middleware you need to apply it on a router:

- "traefik.http.routers.traefik.middlewares=authtraefik,test-compress"

# Middleware defintions
- "traefik.http.middlewares.test-compress.compress=true"
- "traefik.http.middlewares.authtraefik.basicauth.users=admin:pass/"

Hello

It worked, thanks!

Hi! I have a similar issue with version 2.2.5.

services:
  traefik:
    image: traefik:v2.2.5
    command:
      - "--providers.docker=true"
    ...
    labels:
    ...
      - "traefik.http.middlewares.gzip.compress=true"
    ...

 whoami:
    image: containous/whoami:v1.3.0
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.middlewares=gzip,redirect-to-https,securityHeader"

I've declared middleware and set routers, but the compression is not activated

Hello @kapa, here is the documentation for compress middleware: https://docs.traefik.io/middlewares/compress/ I hope it helps.

Unfortunately, docs was not helpful

@kapa okay then. How do you know that the compression is not activated?

@zespri I checked my service with this tool

Can you post the response, you observed, along with the headers?

Request header

GET / HTTP/2
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:79.0) Gecko/20100101 Firefox/79.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: it
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache

Response header

HTTP/2 200 OK
content-type: text/plain; charset=utf-8
date: Wed, 15 Jul 2020 11:56:52 GMT
strict-transport-security: max-age=31536000; includeSubDomains; preload
vary: Accept-Encoding
vary: Origin
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block
content-length: 731
X-Firefox-Spdy: h2

content-length: 731

It appears that the response is 731 bytes long. Do you have any reason to doubt this?

It's so small because it's containous/whoami image. I'll try with something more real.

Exactly my point. I would not expect it to be compressed. Would you?

No, but I would have expected to get some Content-encoding on response header

Why would you have expected that?

I thought sure this was my issue, but I still can't get compression to work. I'm looking at the headers in the Chrome dev tools, and there's no content-encoding in the response.

Here's the traefik service of my docker compose file...

services:

   traefik:

      image: "traefik:v2.2"
      container_name: "traefik"

      ports:
         - "80:80"
         - "443:443"

      # Traefik DYNAMIC configuration
      #
      labels:
         - "traefik.enable=true"

         - "traefik.http.routers.traefik_rtr.entrypoints=web"
         - "traefik.http.routers.traefik_rtr.service=api@internal"
         - "traefik.http.routers.traefik_rtr.entrypoints=websecure"
         - "traefik.http.routers.traefik_rtr.tls=true"

         - "traefik.http.services.traefik.loadbalancer.server.port=8080"

         # Enable gzip compression
         #
         - "traefik.http.routers.traefik_rtr.middlewares=traefik-compress"
         - "traefik.http.middlewares.traefik-compress.compress=true"

      volumes:
         - "/var/run/docker.sock:/var/run/docker.sock:ro"

      networks:
         app_net:

Here's what I see in the Chrome dev console...

Request headers

accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
cache-control: no-cache
cookie: _ga=GA1.2.1548035689.1594861400; _gid=GA1.2.1699448156.1594861400
dnt: 1
pragma: no-cache
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: cross-site
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36

Response headers

content-type: text/html; charset=UTF-8
date: Thu, 16 Jul 2020 01:40:04 GMT
link: <https://mysite.localhost/wp-json/>; rel="https://api.w.org/"
link: <https://mysite.localhost/>; rel=shortlink
server: nginx
status: 200
x-powered-by: PHP/7.4.8

It's a WordPress back end, if that makes any difference. What am I missing?

EDIT: I should add that none of the JS or CSS files have a content-encoding header in the response either, although they do have a content-length.

@shot two questions: 1) when you look at trafik dashboard, do you see gzip middleware associated with the router? 2) There is no content-length header in the response, how large is it?

Thanks for such a quick response, @zespri.

Ahhh, your question just prompted a revelation! Let me try something and get back shortly...

I thought I had it, but nope, still no joy. :frowning_face:

Initially, I associated the middleware with the wrong router, but then it occurred to me that it needs to be associated with the router for the WordPress website. Here's the way it's configured now (what I thought I needed)...

services:

	webserver_nginx:

	  image: nginx:1.19-alpine
	  container_name: webserver_nginx
	  restart: unless-stopped

	  volumes:

		 # Configuration files for nginx
		 #
		 - ./nginx/nginx-conf:/etc/nginx/conf.d

	  labels:
		 - "traefik.enable=true"

		 - "traefik.http.routers.mysite_rtr.tls=true"
		 - "traefik.http.routers.mysite_rtr.entrypoints=websecure"

		 # Define middleware to enable gzip compression
		 - "traefik.http.middlewares.wp_compress.compress=true"

		 # Associate that middleware with relevant routers.
		 - "traefik.http.routers.mysite_rtr.middlewares=wp_compress"

	  networks:
		 app_net:

I do see it in the Middlewares section of the dashboard, but how do I see if it's "associated with" a router? The compress middleware is not mentioned anywhere on the Routers dashboard page. :confused:

It's well over 1400 bytes, which is what the docs say is the minimum for compression to kick in. Plus, for other requests which do have content-length header in the response, there's still no content-encoding header.

I'm stumped right now. :cry:

It was a WordPress cache issue!!!! Bahhhhhh! I cleared the cache with a plugin, and now I get the content-encoding: gzip header! Hooray!

I have the PHP opcache and an optimizing plugin disabled for precisely this reason, but I guess I never cleared the cache after disabling everything. :crazy_face:

1 Like