dockerdocker-composemagento2traefikvarnish

Docker + traefik + varnish for magento 2 app


I would like to know if it's possible to configure for a local usage a docker compose with both traefik and varnish.

I have created my magento 2 image with nginx on the port 8080. When I use traefik only, no problem everything works correctly.

But when I want to add varnish I cannot bind the backend host to varnish.

I have set varnish like this:

       - traefik.enable=true
       - traefik.http.routers.varnish-http.rule=Host(`${VARNISH_DOMAIN:-magento.front.dev.local}`)
       - traefik.http.routers.varnish-http.entrypoints=http
       - traefik.http.routers.varnish-http.middlewares=https-redirect
       - traefik.http.routers.varnish-https.rule=Host(`${VARNISH_DOMAIN:-magento.front.dev.local}`)
       - traefik.http.routers.varnish-https.entrypoints=https
       - traefik.http.routers.varnish-https.tls=true
       - traefik.http.routers.varnish-https.tls.certresolver=le
       - traefik.http.services.varnish.loadbalancer.server.port=80

and in my vcl config I have

backend default {
    .host = "magento";
    .port = "8080";
    .first_byte_timeout = 600s;
    .probe = {
        .url = "/health_check.php";
        .timeout = 2s;
        .interval = 5s;
        .window = 10;
        .threshold = 5;
   }
}

acl purge {
    "magento";
}

I have checked with docker inspect the hostname of my container is "magento".

For magento in docker compose I have

    hostname: magento
    env_file:
      - .env
    labels:
      - "traefik.enable=true"
      # URL pour accéder à ce conteneur
      - traefik.http.routers.magento-http.rule=Host(`${MAGENTO_DOMAIN:-magento.dev.local}`)
      - traefik.http.routers.magento-http.entrypoints=http
      - traefik.http.routers.magento-http.middlewares=https-redirect
      - traefik.http.routers.magento-https.rule=Host(`${MAGENTO_DOMAIN:-magento.dev.local}`)
      - traefik.http.routers.magento-https.entrypoints=https
            # Activation de TLS
      - "traefik.http.routers.nginx.tls=true"
      # Si le port est différent de 80, utilisez le service suivant:
      # - "traefik.http.services.<service_name>.loadbalancer.server.port=<port>"
      - traefik.http.services.magento.loadbalancer.server.port=8080

When I go to magento.dev.local everything works prefectly. But varnish is not taken into account..logic he is waiting the address magento.front.dev.local. But when I go to magento.front.dev.local I have a 503 (varnish is well activated I see "X-Magento-Cache-Debug: MISS" but the backend host is not binded to this url.

Here are the things are tried: I tried to add in my nginx conf an other server with servername magento.front.dev.local and port 80 it does not works. I tried to replace magento.front.dev.local by magento.dev.local in my varnish config but it does not works. I tried to tests different ports. nothing work. I have tried to enter the ip of the container, the host id of the container in the varnish vcl config for the host value but nothing works. I think I have missed something to manage to bind the backend host with the behaviour of traefik. Without Traefik, I have no problem to bind a backend host when i use docker! it's only for this case.

So if you have ideas I am listening:)

Thanks.


Solution

  • I tried to reproduce the problem. You didn't include your compose.yaml file so I had to construct my own; this works for me when accessed as magento.front.dev.local:

    volumes:
      mariadb_data:
      magento_data:
      elasticsearch_data:
    
    services:
      traefik:
        image: docker.io/traefik:latest
        command:
          - "--api.insecure=true"
          - "--providers.docker=true"
          - "--entrypoints.web.address=:80"
        ports:
          - "80:80"
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock:ro"
      varnish:
        labels:
           - traefik.enable=true
           - traefik.http.routers.varnish-http.rule=Host(`${VARNISH_DOMAIN:-magento.front.dev.local}`)
           - traefik.http.routers.varnish-http.entrypoints=web
           - traefik.http.services.varnish.loadbalancer.server.port=80
        image: docker.io/varnish
        volumes:
          - ./varnish.vcl:/etc/varnish/default.vcl:ro
        restart: on-failure
    
      mariadb:
        image: docker.io/mariadb:10.6
        environment:
          - MARIADB_ROOT_PASSWORD=secret
          - MARIADB_USER=magento
          - MARIADB_DATABASE=magento
          - MARIADB_PASSWORD=secret
        volumes:
          - 'mariadb_data:/var/lib/mysql'
    
      magento:
        image: docker.io/bitnami/magento:2
        environment:
          - MAGENTO_HOST=localhost
          - MAGENTO_DATABASE_HOST=mariadb
          - MAGENTO_DATABASE_PORT_NUMBER=3306
          - MAGENTO_DATABASE_USER=magento
          - MAGENTO_DATABASE_NAME=magento
          - MAGENTO_DATABASE_PASSWORD=secret
          - ELASTICSEARCH_HOST=elasticsearch
          - ELASTICSEARCH_PORT_NUMBER=9200
        volumes:
          - 'magento_data:/bitnami/magento'
    
      elasticsearch:
        image: docker.io/bitnami/elasticsearch:7
        volumes:
          - 'elasticsearch_data:/bitnami/elasticsearch/data'
    

    What I noticed is that the Magento container takes a while to come up; during this time you'll get a 503 error.

    I've intentionally omitted the TLS configuration here because I'm not deploying this anywhere on which a letsencrypt HTTPS-01 challenge would succeed.

    I have also intentionally omitted both the traefik configuration and the ports configuration from the magento container: the only way to access magento with this configuration is via traefik -> varnish -> magento.