Magento, Docker & Traefik

Magento, Docker & Traefik

Besides being big fans of Mark Shust's Docker Configuration for Magento project as I already blogged about, we also love Traefik, the Cloud Native Edge Router. I discovered Traefik years ago and try to use it wherever we can. Depending on the project's goals we either use the open-source version or the enterprise edition. Disclaimer: I am Traefik Ambassador, so I might be a bit biased :)

Since it was clear that we'd use a containerization approach to ship and run the latest Magento project, it meant using Traefik in production as well. In turn that meant to use also use Traefik locally on the development machines to have a consistent set-up in place.

Adding Traefik to Mark Shust's Docker configuration is not so hard. Add the following lines to your docker-compose.yaml file to add Traefik to your local stack:

traefik:
image: traefik:1.7
ports:
  - "80:80"
  - "443:443"
  - "8080:8080"
volumes:
  - /var/run/docker.sock:/var/run/docker.sock
  - ./docker/traefik/traefik.toml:/traefik.toml
  - ./docker/traefik/domains.pem:/domains.pem
  - ./docker/traefik/domains.key.pem:/domains.key.pem


We expose the ports 80 and 443 to serve the Magento sites locally as well as the Trafik Web UI on port 8080 to see the current configuration which helps when debugging things. Besides that, we mount the docker socket from the local machine into the container to that Traefik can listen to the different events when containers go up or down. Additionally, we mount the Traefik configuration file into the container as well as the SSL certificates which more or less looks like this:

defaultEntryPoints = ["https","http"]
logLevel = "ERROR"
debug = true

[web]

[entryPoints]
  [entryPoints.http]
  address = ":80"
      [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
  address = ":443"
  [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      certFile = "/domains.pem"
      keyFile = "/domains.key.pem"
      
[docker]
exposedbydefault = false
watch = true


To generate the SSL certificates, I can highly recommend mkcert which allows you to create locally-trusted development certificates. To generate the SSL certificates is a matter of running mkcert like this:

mkcert domain1.loc domain2.loc


If this is the first time you are running mkcert, you should install the local CA in the system trust store to make sure your browser won't complain about insecure SSL certificates. You can do that by running the following command:

mkcert -install


Since the Magento project is using multiple domains that map to different websites in Magento, it was needed to customize the default nginx configuration that is shipped with Mark Shust's setup. The default.conf file looks like this:

# map domains to Magento website identifiers
map $http_host $MAGE_RUN_CODE {
    default '';
    # local development
    domain1.loc website1;
    domain2.loc website2;
}

upstream fastcgi_backend {
  server unix:/sock/docker.sock;
}

server {
  listen 8443;
  server_name _; # catch all
  set $MAGE_ROOT /var/www/html;
  set $MAGE_RUN_TYPE website;

  include /var/www/html/nginx[.]conf;
}


First, we need to map the domain names to the website identifiers defined in Magento. This is what happens in the map section above. Second, it was needed to set $MAGE_RUN_TYPE to website to make it clear to Magento that the $MAGE_RUN_CODE represents a website identifier.

Those variables also need be passed to the phpfm process in Magento's default nginx configuration. Besides that it was also needed to pass the HTTPS parameter to phpfpm:

# PHP entry point for main application
location ~ ^/(index|get|static|errors/report|errors/404|errors/503)\.php$ {
  try_files $uri =404;
  fastcgi_pass   fastcgi_backend;
  fastcgi_buffers 1024 4k;

  fastcgi_read_timeout 600s;
  fastcgi_connect_timeout 600s;

  fastcgi_index  index.php;
  fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  fastcgi_param  MAGE_RUN_CODE $MAGE_RUN_CODE;
  fastcgi_param  MAGE_RUN_TYPE $MAGE_RUN_TYPE;
  fastcgi_param  HTTPS $https if_not_empty;
  include        fastcgi_params;
}


To make Traefik aware of the domains it should handle, all you need is to set a few Traefik labels in the docker-compose.yml configuration file:

app:
image: markoshust/magento-nginx:1.13-8
links:
  - db
  - phpfpm
volumes: &appvolumes
  - ./.git:/var/www/.git
  - ~/.composer:/var/www/.composer:delegated
  - ./src:/var/www/html
  - ./docker/nginx/conf/default.conf:/etc/nginx/conf.d/default.conf
  - sockdata:/sock
labels:
  - "traefik.enable=true"
  - "traefik.backend=app"
  - "traefik.protocol=http"
  - "traefik.port=8443"
  - "traefik.frontend.passHostHeader=true"
  - "traefik.frontend.rule=Host:domain1.loc,domain2.loc"


The domains are configured in the traefik.frontend.rule. Since we are still using Traefik 1.7 the syntax is Host:domain1.loc,domain2.loc. Besides that, it is important to set the traefik.frontend.passHostHeader flag to true so that nginx gets the information forwarded which domain is requested and then can do the domain name to website identifier mapping properly.


Eintrag von Stephan Hochdörfer am 18.05.2020

Tags: Magento2, Magento, Docker, Traefik

Diese Webseite verwendet Cookies, um die Bedienfreundlichkeit zu erhöhen. Mit der Nutzung unserer Webseite wird das Einverständnis erklärt, dass wir Cookies verwenden. Weitere Informationen.