Reverse-Proxy für automatisierte HTTPS-Zertifikate

Das erstellen und verwalten von SSL/TLS-Zertifikaten für eine sichere HTTPS-Verbindung zu einer Ignition-Applikationkann aufwändig und kompliziert sein. Vor allem wenn wir viele verschiedene Applikationen unter verschiedenen Subdomains haben.

Wir zeigen wie Sie sich das Leben leichter machen. Durch die Verwendung von Docker und dem Reverse-Proxy Traefik können wir Let’s Encrypt Zertifikate automatisch erstellen und verwalten lassen.

Vorbereitung

Für dieses Beispiel benötigen wir einen Linux-Server welcher aus dem Internet unter einer Domain erreichbar ist. Ausser dem muss darauf Docker installiert sein. In unserem Fall verwenden wir zusätzlich die Docker-Verwaltungssoftware Portainer welche als Container ausgeführt wird. Für die Vorbereitungen finden Sie am Ende dieses Beitrags Links zu weiteren Informationen. Ebenfalls am Ende dieses Beitrags finden Sie die Docker-Compose Files im YML-Format welche wir im Webinar erstellen.

version: '3'
services:
  traefik:
    image: "traefik:v2.5"
    container_name: "traefik"
    ports:
      - "80:80"
      - "443:443"
      # (Optional) Expose Dashboard
      #- "8080:8080"  # Don't do this in production!
    environment:
      ### traefik API
      #- TRAEFIK_API=true
      #- TRAEFIK_API_DASHBOARD=true
      #- TRAEFIK_API_INSECURE=true
      ### Entrypoint web
      - TRAEFIK_ENTRYPOINTS_web=true
      - TRAEFIK_ENTRYPOINTS_web_ADDRESS=:80
      ### Entrypoint websecure
      - TRAEFIK_ENTRYPOINTS_websecure=true
      - TRAEFIK_ENTRYPOINTS_websecure_ADDRESS=:443
      ### Entrypoint ...

      ### Configure your CertificateResolver here
      ## STAGING
      - TRAEFIK_CERTIFICATESRESOLVERS_staging=true
      - TRAEFIK_CERTIFICATESRESOLVERS_staging_ACME_CASERVER=https://acme-staging-v02.api.letsencrypt.org/directory
      - TRAEFIK_CERTIFICATESRESOLVERS_staging_ACME_HTTPCHALLENGE=true
      - TRAEFIK_CERTIFICATESRESOLVERS_staging_ACME_HTTPCHALLENGE_ENTRYPOINT=web
      - TRAEFIK_CERTIFICATESRESOLVERS_staging_ACME_STORAGE=/etc/traefik/certs/acme.json
      - TRAEFIK_CERTIFICATESRESOLVERS_staging_ACME_EMAIL=m.keller@mpi.ch
      ## PRODUCTION
      - TRAEFIK_CERTIFICATESRESOLVERS_production=true
      - TRAEFIK_CERTIFICATESRESOLVERS_production_ACME_CASERVER=https://acme-v02.api.letsencrypt.org/directory
      - TRAEFIK_CERTIFICATESRESOLVERS_production_ACME_HTTPCHALLENGE=true
      - TRAEFIK_CERTIFICATESRESOLVERS_production_ACME_HTTPCHALLENGE_ENTRYPOINT=web
      - TRAEFIK_CERTIFICATESRESOLVERS_production_ACME_STORAGE=/etc/traefik/certs/acme.json
      - TRAEFIK_CERTIFICATESRESOLVERS_production_ACME_EMAIL=m.keller@mpi.ch
      
      ### Providers
      ## Enabling docker provider
      - TRAEFIK_PROVIDERS_DOCKER=true
      ## Do not expose containers unless explicitly told so
      - TRAEFIK_PROVIDERS_DOCKER_EXPOSEDBYDEFAULT=false
      #- TRAEFIK_PROVIDERS_FILE_FILENAME=/etc/traefik/traefik_dynamic.yml #edit traefik_dynamic.yml for some services

    volumes:
      - /etc/traefik:/etc/traefik
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ### needed for the correct exposure of the container to the network for Linux older than 20.10.0 (https://doc.traefik.io/traefik/providers/docker/)
    extra_hosts:
      - host.docker.internal:172.17.0.1
    restart: always
version: '3'
services:
  gateway:
    image: inductiveautomation/ignition:8.1.20
    networks:
      - frontend
      - backend
    volumes:
      - gw-data:/usr/local/bin/ignition/data
    environment:
      - ACCEPT_IGNITION_EULA=Y
      - GATEWAY_ADMIN_USERNAME=admin
      - GATEWAY_ADMIN_PASSWORD=demo_pwd4iccx
      - IGNITION_EDITION=standard
      - TZ=Europe/Zurich  # see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
    command: >
      -n iccx-demo
      --
      gateway.useProxyForwardedHeader=true
    labels:
      ## Explicitly tell Traefik to expose this container
      - "traefik.enable=true"
      ## optinal when more than one network attached (https://doc.traefik.io/traefik/v2.0/routing/providers/docker/)
      - "traefik.docker.network=traefik_default"
      - "traefik.http.routers.iccx-demo-router.entrypoints=websecure"
      - "traefik.http.routers.iccx-demo-router.rule=Host(`iccx.demo-mpi.ch`)"
      ## optional nessesairy for next line (https://forum.inductiveautomation.com/t/docker-traefik-letsencrypt-acme-automatic-ssl/52305)
      - "traefik.http.routers.iccx-demo-router.service=iccx-demo-service"
      ## optional when port has to be specific and more than one is available
      - "traefik.http.services.iccx-demo-service.loadbalancer.server.port=8088"
      - "traefik.http.routers.iccx-demo-router.tls=true"
      - "traefik.http.routers.iccx-demo-router.tls.certresolver=production"
    restart: unless-stopped
  #-------------------------------------------------------------
  db:
    image: postgres:14-alpine
    restart: always
    networks:
      - backend
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=ignition
  #-------------------------------------------------------------
volumes:
  gw-data:
  db-data:
networks:
  frontend:
    external:
      name: traefik_default
  backend:
    name: iccx-demo_backend