Docker: Routing HTTPS
Come gestire il routing HTTP e la crittografia TLS (HTTPS) nei tuoi container Docker
👋 Benvenuti nella documentazione di Stackhero!
Stackhero offre una soluzione Docker cloud CaaS (Containers as a Service) pronta all'uso che fornisce numerosi vantaggi, tra cui:
- Distribuisci facilmente i tuoi container in produzione con un semplice
docker-compose up.- Nome di dominio personalizzabile protetto con HTTPS (ad esempio, https://api.tua-azienda.com, https://www.tua-azienda.com, https://backoffice.tua-azienda.com).
- Prestazioni ottimali e sicurezza robusta grazie a una VM privata e dedicata.
- Aggiornamenti senza sforzo con un solo clic.
Risparmia tempo e semplifica la tua vita: bastano 5 minuti per provare la soluzione di hosting cloud Docker CaaS di Stackhero e distribuire i tuoi container in produzione!
Ogni istanza di Stackhero per Docker include un server Traefik dedicato e preconfigurato che gestisce il traffico HTTP e lo cripta automaticamente utilizzando certificati TLS. Questa configurazione semplificata rende il routing semplice ed efficiente. Ad esempio:
- Invia il traffico da
https://www.my-company.com(con o senza il prefisso www) al tuo containerfrontend. - Instrada
https://www.my-company.com/documentationsal tuo containerdocumentations. - Dirigi
https://api.my-project.ioal tuo containerapi.
Puoi gestire un numero illimitato di domini con creazione e rinnovo automatici dei certificati TLS. La cosa migliore è che puoi configurare tutto questo con solo tre righe!
Configurazione di base di Traefik
In tutti gli esempi di configurazione seguenti, dovrai sostituire
<XXXXXX>.stackhero-network.comcon il nome di dominio della tua istanza Stackhero per Docker.
Di seguito è riportato un esempio base di un file docker-compose.yml:
services:
test:
image: nginx
labels:
- "traefik.enable=true" # Abilita Traefik per instradare il traffico a questo container
- "traefik.http.routers.test.rule=Host(`<XXXXXX>.stackhero-network.com`)" # Definisci l'host
- "traefik.http.routers.test.tls.certresolver=letsencrypt" # Usa 'letsencrypt' come risolutore di certificati TLS
In questo esempio, un container chiamato test funziona utilizzando l'immagine Nginx. La configurazione chiave è fornita nella sezione etichette. Devi semplicemente copiare queste righe nel tuo file docker-compose.yml e sostituire <XXXXXX>.stackhero-network.com con il tuo dominio di servizio.
Puoi distribuire il container utilizzando:
docker context use <XXXXXX>.stackhero-network.com
docker-compose up
Dopo l'avvio del container, visita https://<XXXXXX>.stackhero-network.com/ per vedere la pagina "Welcome to nginx!".
Pagina di benvenuto Nginx
Se non vedi la pagina di benvenuto Nginx, controlla la dashboard di Traefik per eventuali errori!
Con questa configurazione, le richieste HTTP inviate a <XXXXXX>.stackhero-network.com sono instradate al tuo container test e Traefik crea e gestisce automaticamente i certificati TLS per HTTPS.
Gestire domini personalizzati con Traefik
Nell'esempio precedente, abbiamo utilizzato il dominio predefinito <XXXXXX>.stackhero-network.com. In pratica, probabilmente utilizzerai i tuoi domini aziendali o di progetto, come www.my-company.com o api.my-project.io. La sezione seguente spiega come configurare domini personalizzati.
Configurare il tuo primo dominio con Traefik
In questo esempio, configurerai il dominio api.my-project.io. Sostituisci my-project.io con un dominio che possiedi e api con il tuo sottodominio desiderato.
Per prima cosa, aggiorna le impostazioni DNS del tuo dominio in modo che api.my-project.io punti al tuo dominio <XXXXXX>.stackhero-network.com.
- Accedi al tuo provider di dominio e accedi alla tua configurazione DNS.
- Crea una nuova voce chiamata
api(o un altro sottodominio a tua scelta), imposta il suo tipo suCNAMEe imposta la sua destinazione su<XXXXXX>.stackhero-network.com.
Esempio di configurazione DNS sull'interfaccia DNS di Cloudflare
Una volta configurato il DNS, puoi convalidarlo eseguendo:
host api.my-project.io
Dovresti vedere una risposta simile a:
api.my-project.io is an alias for <XXXXXX>.stackhero-network.com
La propagazione DNS può richiedere fino a 24 ore a seconda del tuo provider. Se il comando
hostnon restituisce la risposta prevista, attendi e riprova più tardi.
Successivamente, aggiorna il tuo file docker-compose.yml con la seguente configurazione:
services:
api:
image: traefik/whoami
hostname: api
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.my-project.io`)" # Aggiungi qui il tuo dominio
- "traefik.http.services.api.loadbalancer.server.port=<PORT>" # Sostituisci "<PORT>" con la porta su cui la tua API sta ascoltando
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
Non dimenticare di sostituire
api.my-project.iocon il tuo dominio reale nell'etichetta TraefikHost.
Distribuisci il tuo container con:
docker-compose up -d
Poi visita https://api.my-project.io. Dovresti vedere una pagina di testo che mostra il nome host del tuo container api.
Prova che Traefik gestisce il nostro traffico HTTP con crittografia TLS per il nostro nuovo dominio
Alla prima creazione del container, i certificati TLS potrebbero richiedere alcuni secondi per essere generati. Se incontri un errore TLS, attendi qualche secondo e aggiorna la pagina per consentire il tempo necessario alla generazione dei certificati.
Congratulazioni, hai ora configurato il tuo primo dominio personalizzato!
Come reindirizzare un sottodominio "www" al tuo dominio principale usando Traefik
Quando si definisce un URL del sito web come my-company.com, è una buona idea configurare anche un sottodominio "www". Questo garantisce che gli utenti che si connettono tramite www.my-company.com siano reindirizzati al tuo sito principale e aiuta a evitare problemi di contenuto duplicato.
Nell'esempio seguente, sia my-company.com che www.my-company.com sono gestiti. Gli utenti che accedono a www.my-company.com sono reindirizzati a 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`)" # Aggiungi entrambi i domini qui
- "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Sostituisci "<PORT>" con la porta su cui il tuo frontend sta ascoltando
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
# Reindirizza 'www.my-company.com' a '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"
Instradare un percorso a un container specifico con Traefik
Supponiamo che tu abbia un container dedicato al tuo sito di documentazione. Potresti voler instradare https://my-company.com/docs a questo container mentre invii altre richieste, come https://my-company.com/, al tuo container frontend. L'esempio seguente mostra come questo viene realizzato:
services:
documentations:
image: traefik/whoami
hostname: documentations
labels:
- "traefik.enable=true"
- "traefik.http.routers.documentations.rule=Host(`my-company.com`) && PathPrefix(`/docs`)" # Definisci qui il prefisso del percorso
- "traefik.http.services.documentations.loadbalancer.server.port=<PORT>" # Sostituisci "<PORT>" con la porta su cui il tuo container di documentazione sta ascoltando
- "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>" # Sostituisci "<PORT>" con la porta su cui il tuo frontend sta ascoltando
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
# Reindirizza 'www.my-company.com' a '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"
Ora, visitando https://my-company.com/docs (o qualsiasi sottopercorso come https://my-company.com/docs/something) verrà visualizzato il contenuto del container documentations. Altri percorsi, ad esempio https://my-company.com/help, saranno serviti dal container frontend.
Definire una porta container personalizzata in Traefik
Per impostazione predefinita, Traefik si connette alla prima porta esposta del container. In alcuni casi, potresti dover specificare una porta particolare. L'esempio seguente dimostra come definire una porta personalizzata:
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"
# Instrada il traffico da 'https://my-company.com' al container 'frontend' sulla porta 80
- "traefik.http.services.frontend.loadbalancer.server.port=80"
Buone pratiche di denominazione Traefik e Docker Compose
Quando definisci un container nel tuo file docker-compose.yml, alcuni campi sono importanti per una migliore coerenza e facilità di gestione. Considera l'uso della seguente configurazione consigliata:
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"
Sostituisci semplicemente <CONTAINER_NAME> con il nome desiderato per il tuo container, ad esempio frontend.
Errore Let's Encrypt "Domain name contains an invalid character"
Quando si crea un sottodominio, Let's Encrypt segue le RFC 952 e 1123, che consentono solo caratteri nel set [a-zA-Z0-9-].
Sebbene gli underscore ('_') siano consentiti nei nomi dei record DNS, non sono accettabili nei nomi host. Di conseguenza, Let's Encrypt rifiuta sottodomini come "my_subdomain.example.com" e visualizza l'errore "Domain name contains an invalid character".
Per risolvere questo problema, rimuovi semplicemente tutti gli underscore dai tuoi sottodomini.