Docker: HTTPS-routing

Hoe HTTP-routing en TLS-encryptie (HTTPS) in uw Docker-containers te beheren

👋 Welkom bij de documentatie van Stackhero!

Stackhero biedt een kant-en-klare Docker cloud CaaS (Containers as a Service) oplossing die tal van voordelen biedt, waaronder:

  • Zet eenvoudig uw containers in productie met slechts een docker-compose up.
  • Aanpasbare domeinnaam beveiligd met HTTPS (bijvoorbeeld, https://api.uw-bedrijf.com, https://www.uw-bedrijf.com, https://backoffice.uw-bedrijf.com).
  • Optimale prestaties en robuuste beveiliging aangedreven door een privé en toegewijde VM.
  • Moeiteloze updates met slechts één klik.

Bespaar tijd en vereenvoudig uw leven: het kost slechts 5 minuten om de Docker CaaS cloud hosting oplossing van Stackhero te proberen en uw containers in productie te zetten!

Elke Stackhero voor Docker-instantie bevat een toegewijde, vooraf geconfigureerde Traefik-server die HTTP-verkeer beheert en automatisch versleutelt met TLS-certificaten. Deze gestroomlijnde setup maakt routing eenvoudig en efficiënt. Bijvoorbeeld:

  • Verkeer van https://www.my-company.com (met of zonder de www-prefix) naar uw frontend-container sturen.
  • https://www.my-company.com/documentations naar uw documentations-container routeren.
  • https://api.my-project.io naar uw api-container leiden.

U kunt een onbeperkt aantal domeinen beheren met automatische creatie en vernieuwing van TLS-certificaten. Het beste van alles is dat u dit allemaal kunt configureren met slechts drie regels!

In alle volgende configuratievoorbeelden moet u <XXXXXX>.stackhero-network.com vervangen door uw Stackhero voor Docker-instantie domeinnaam.

Hieronder staat een basisvoorbeeld van een docker-compose.yml-bestand:

services:
  test:
    image: nginx
    labels:
      - "traefik.enable=true" # Traefik inschakelen om verkeer naar deze container te routeren
      - "traefik.http.routers.test.rule=Host(`<XXXXXX>.stackhero-network.com`)" # Host definiëren
      - "traefik.http.routers.test.tls.certresolver=letsencrypt" # 'letsencrypt' gebruiken als TLS-certificaatresolver

In dit voorbeeld draait een container genaamd test met de Nginx-image. De sleutelconfiguratie wordt verstrekt in de labels-sectie. U hoeft alleen deze regels in uw docker-compose.yml-bestand te kopiëren en <XXXXXX>.stackhero-network.com te vervangen door uw servicedomein.

U kunt de container implementeren met:

docker context use <XXXXXX>.stackhero-network.com
docker-compose up

Na het starten van de container, bezoekt u https://<XXXXXX>.stackhero-network.com/ om de "Welcome to nginx!"-pagina te zien.

Nginx welkomstpaginaNginx welkomstpagina

Als u de Nginx welkomstpagina niet ziet, controleer dan het Traefik-dashboard op mogelijke fouten!

Met deze configuratie worden HTTP-verzoeken naar <XXXXXX>.stackhero-network.com gerouteerd naar uw test-container en Traefik maakt en beheert automatisch TLS-certificaten voor HTTPS.

In het vorige voorbeeld hebben we het standaarddomein <XXXXXX>.stackhero-network.com gebruikt. In de praktijk zult u waarschijnlijk uw eigen bedrijfs- of projectdomeinen gebruiken, zoals www.my-company.com of api.my-project.io. De onderstaande sectie legt uit hoe u aangepaste domeinen configureert.

In dit voorbeeld configureert u het domein api.my-project.io. Vervang my-project.io door een domein dat u bezit en api door uw gewenste subdomein.

Werk eerst uw domein-DNS-instellingen bij zodat api.my-project.io verwijst naar uw <XXXXXX>.stackhero-network.com-domein.

  1. Log in bij uw domeinprovider en ga naar uw DNS-configuratie.
  2. Maak een nieuwe vermelding genaamd api (of een ander subdomein naar keuze), stel het type in op CNAME en stel de bestemming in op <XXXXXX>.stackhero-network.com.

Voorbeeld van DNS-configuratie op Cloudflare DNS-interfaceVoorbeeld van DNS-configuratie op Cloudflare DNS-interface

Zodra de DNS is geconfigureerd, kunt u deze valideren door het volgende uit te voeren:

host api.my-project.io

U zou een antwoord moeten zien dat lijkt op:

api.my-project.io is an alias for <XXXXXX>.stackhero-network.com

DNS-propagatie kan tot 24 uur duren, afhankelijk van uw provider. Als de host-opdracht niet het verwachte antwoord geeft, wacht dan en probeer het later opnieuw.

Werk vervolgens uw docker-compose.yml-bestand bij met de volgende configuratie:

services:
  api:
    image: traefik/whoami
    hostname: api
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.my-project.io`)" # Voeg hier uw domein toe
      - "traefik.http.services.api.loadbalancer.server.port=<PORT>" # Vervang "<PORT>" door de poort waarop uw API luistert
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"

Vergeet niet api.my-project.io te vervangen door uw werkelijke domein in het Traefik-label Host.

Implementeer uw container met:

docker-compose up -d

Bezoek vervolgens https://api.my-project.io. U zou een tekstpagina moeten zien die de hostnaam van uw container api weergeeft.

Bewijs dat Traefik ons HTTP-verkeer met TLS-encryptie voor ons nieuwe domein beheertBewijs dat Traefik ons HTTP-verkeer met TLS-encryptie voor ons nieuwe domein beheert

Bij de eerste creatie van de container kunnen TLS-certificaten enkele seconden duren om te genereren. Als u een TLS-fout tegenkomt, wacht dan een paar seconden en vernieuw de pagina om tijd te geven voor het genereren van de certificaten.

Gefeliciteerd, u heeft nu uw eerste aangepaste domein geconfigureerd!

Bij het definiëren van een website-URL zoals my-company.com, is het een goed idee om ook een "www"-subdomein in te stellen. Dit zorgt ervoor dat gebruikers die verbinding maken via www.my-company.com worden doorgestuurd naar uw hoofdsite en helpt dubbele inhoudsproblemen te voorkomen.

In het onderstaande voorbeeld worden zowel my-company.com als www.my-company.com behandeld. Gebruikers die www.my-company.com bezoeken, worden doorgestuurd naar my-company.com:

services:
  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`) || Host(`www.my-company.com`)" # Voeg beide domeinen hier toe
      - "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Vervang "<PORT>" door de poort waarop uw frontend luistert
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Redirect 'www.my-company.com' naar 'my-company.com':
      - 'traefik.http.routers.frontend.middlewares=redirect-www'
      - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
      - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
      - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"

Stel dat u een container heeft die is gewijd aan uw documentatiesite. U wilt misschien https://my-company.com/docs naar deze container routeren terwijl u andere verzoeken, zoals https://my-company.com/, naar uw frontend-container stuurt. Het onderstaande voorbeeld laat zien hoe dit wordt bereikt:

services:
  documentations:
    image: traefik/whoami
    hostname: documentations
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.documentations.rule=Host(`my-company.com`) && PathPrefix(`/docs`)" # Definieer hier het padprefix
      - "traefik.http.services.documentations.loadbalancer.server.port=<PORT>" # Vervang "<PORT>" door de poort waarop uw documentatiecontainer luistert
      - "traefik.http.routers.documentations.tls.certresolver=letsencrypt"

  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`) || Host(`www.my-company.com`)"
      - "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Vervang "<PORT>" door de poort waarop uw frontend luistert
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Redirect 'www.my-company.com' naar 'my-company.com':
      - 'traefik.http.routers.frontend.middlewares=redirect-www'
      - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
      - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
      - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"

Nu zal het bezoeken van https://my-company.com/docs (of een subpad zoals https://my-company.com/docs/something) inhoud van de documentations-container weergeven. Andere paden, bijvoorbeeld https://my-company.com/help, worden bediend door de frontend-container.

Standaard maakt Traefik verbinding met de eerste blootgestelde poort van de container. In sommige gevallen moet u mogelijk een specifieke poort opgeven. Het onderstaande voorbeeld laat zien hoe u een aangepaste poort definieert:

services:
  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`)"
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Verkeer van 'https://my-company.com' naar de 'frontend'-container op poort 80 routeren
      - "traefik.http.services.frontend.loadbalancer.server.port=80"

Bij het definiëren van een container in uw docker-compose.yml-bestand zijn enkele velden belangrijk voor betere consistentie en eenvoudig beheer. Overweeg de volgende aanbevolen configuratie te gebruiken:

services:
  <CONTAINER_NAME>:
    image: traefik/whoami
    hostname: <CONTAINER_NAME>
    container_name: <CONTAINER_NAME>
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.<CONTAINER_NAME>.rule=Host(`my-company.com`)"
      - "traefik.http.routers.<CONTAINER_NAME>.tls.certresolver=letsencrypt"

Vervang eenvoudig <CONTAINER_NAME> door de gewenste naam voor uw container, bijvoorbeeld frontend.

Bij het maken van een subdomein volgt Let's Encrypt RFC 952 en 1123, die alleen tekens in de set [a-zA-Z0-9-] toestaan.

Hoewel underscores ('_') zijn toegestaan in DNS-recordnamen, zijn ze niet acceptabel in hostnamen. Als gevolg hiervan wijst Let's Encrypt subdomeinen zoals "my_subdomain.example.com" af en geeft de foutmelding "Domeinnaam bevat een ongeldig teken".

Om dit probleem op te lossen, verwijdert u eenvoudig alle underscores uit uw subdomeinen.