Salta ai contenuti
Sirio è in beta privata: sorgenti e installer vengono inviati via email a chi la prova. Chiedi di partecipare.

Domini e siti

Sirio amministra una sola macchina, ma su quella macchina possono convivere più progetti con domini diversi. Questa pagina spiega il modello e come pubblicare il primo sito.

sito ──┬── domini ── rotte ──→ container oppure host:porta
├── container (assegnati al sito, o condivisi)
├── pipeline
└── repository

Due assi distinti, ed è la distinzione che conta:

  • proprietà: un container appartiene a un sito solo, o a nessuno. Serve a raggruppare, a filtrare la lista e a decidere cosa sparisce insieme;
  • esposizione: una rotta lega dominio + path a una destinazione. È molti-a-molti.

Ne segue che non esiste un interruttore “container cross-domain”: non serve. Se lo stesso container deve rispondere su api.negozio.it e su api.blog.it, si creano due rotte, anche da siti diversi. Un container senza sito (condiviso) è semplicemente un servizio che non appartiene a un progetto in particolare — un Postgres, un Redis — e resta fuori dalla dashboard dei singoli siti.

Una pipeline collegata a un sito vi assegna da sola i suoi container: dopo ogni step compose con up riuscito, Sirio chiede a Compose quali container ha il progetto e lega al sito della pipeline quelli condivisi. Un container già assegnato a un altro sito resta dov’è — una scelta esplicita fatta in Container non viene mai sovrascritta da un deploy. Collegare il sito a una pipeline esistente ha effetto dalla sua prossima esecuzione, anche se quella non ricrea nulla.

Un sito non è un confine di sicurezza: Sirio ha un solo account amministratore, e chi entra vede e amministra tutto. Il multisito è organizzazione, non multi-tenancy.

Con SIRIO_PROXY_ENABLED=true Sirio governa un Caddy che gira come container, non un servizio dell’host. La ragione è concreta: l’unit systemd di Sirio ha ProtectSystem=strict e concede la scrittura solo su SIRIO_DATA_DIR, quindi l’utente sirio non potrebbe scrivere in /etc/caddy né ricaricare un servizio dell’host. Passando dal socket Docker, che Sirio già usa, non serve alcun privilegio in più.

Il ciclo, a ogni modifica di siti, domini o rotte:

  1. Sirio rigenera il Caddyfile in SIRIO_DATA_DIR/proxy/Caddyfile.new;
  2. lo valida con caddy validate dentro il container;
  3. se è valido lo attiva e ricarica Caddy; se non lo è, la configurazione precedente resta in vigore e l’errore torna alla UI. Un dominio scritto male non butta giù i siti già online;
  4. se il reload fallisce, ripristina la versione precedente.

I container bersaglio di una rotta vengono collegati alla rete sirio-edge, dove Caddy li risolve per nome. Da lì in avanti non serve più pubblicare porte sull’host: la porta indicata nella rotta è quella interna del container.

Una riconciliazione gira anche dopo ogni pipeline riuscita e ogni 60 secondi. Serve: un deploy ricrea i container, che senza questo giro perderebbero l’aggancio alla rete.

1. Attiva la gestione dei domini. Apri sulla macchina il file dell’unit systemd, /etc/systemd/system/sirio-sysadmin.service:

Finestra del terminale
sudo nano /etc/systemd/system/sirio-sysadmin.service

Trova la riga Environment=SIRIO_PROXY_ENABLED=false (l’unit installata da install.sh la contiene già, disattivata) e cambia false in true:

Environment=SIRIO_PROXY_ENABLED=true

Salva, poi applica la modifica:

Finestra del terminale
sudo systemctl daemon-reload
sudo systemctl restart sirio-sysadmin

Verifica che sia partito senza errori con systemctl status sirio-sysadmin.

2. Libera le porte 80 e 443. Se hai già un Caddy o un nginx sull’host, fermalo: il container del proxy non potrebbe metterle in ascolto. Vedi la sezione sulla migrazione più sotto.

Se invece le pubblica un container — tipicamente un’app che fa da sé il TLS, come FrankenPHP o un container Caddy/nginx — togligli le porte invece di fermarlo: un container fermo non ripartirebbe più, o dopo un riavvio se le contenderebbe con il proxy. Per un servizio Compose, in un compose.override.yaml accanto al compose file:

services:
web:
ports: !reset []

poi docker compose up -d, e fai servire all’app HTTP in chiaro: il TLS lo termina il proxy, che passa X-Forwarded-For/X-Forwarded-Proto, a cui l’app deve dare fiducia (TRUSTED_PROXIES di Symfony, trusted_proxies di Caddy e così via) per vedere l’indirizzo del visitatore e l’HTTPS. Installa indica i container che pubblicano ancora le porte del proxy.

3. Installa il proxy dalla pagina Proxy del pannello. Sirio crea la rete sirio-edge, un volume per i certificati e il container sirio-caddy.

Il volume dei certificati non è un dettaglio: senza, ogni ricreazione del container rifarebbe le richieste ad ACME e i limiti di emissione di Let’s Encrypt si esauriscono in fretta.

4. Imposta l’indirizzo per Let’s Encrypt nella stessa pagina. È facoltativo ma consigliato: riceve gli avvisi di scadenza.

5. Crea il sito, il dominio e la rotta. In Siti → nuovo sito, poi nuovo dominio, poi una rotta. Il DNS del dominio deve già puntare a questa macchina: il pulsante Verifica DNS mostra cosa risolve, da confrontare con l’IP pubblico della VM.

Il certificato arriva da solo al primo accesso in HTTPS.

Il proxy gestito da Sirio può fare anche da HTTPS davanti a Sirio stesso, non solo ai siti che ospita. Il caso tipico: non hai (o non vuoi tenere) un Caddy o un nginx separato sull’host solo per il pannello. Ci sono due modi; il primo è quello consigliato.

Imposti un dominio che punta a questa macchina e sirio-caddy serve il pannello su https://DOMINIO:22722, con un certificato Let’s Encrypt che ottiene e rinnova da solo:

  • 80 e 443 restano ai siti. Il pannello ha una porta sua (SIRIO_PANEL_PORT, default 22722) che sirio-caddy pubblica accanto a quelle. Per la verifica del certificato Caddy usa comunque 80/443, che sono già sue, quindi non serve altra configurazione. Se preferisci il pannello anche su 443, con un nome suo, imposta SIRIO_PANEL_PORT=443: Caddy distingue pannello e siti per dominio.
  • Nessuna porta in chiaro. sirio-caddy parla con Sirio tramite un socket Unix, SIRIO_DATA_DIR/proxy/sirio.sock, non via TCP. SIRIO_LISTEN può quindi restare su 127.0.0.1, e solo il proxy può connettersi, perché è l’unico a montare quella cartella.
  • IP reali dei client. Sul socket, e solo lì, Sirio si fida dell’header X-Forwarded-For che imposta Caddy. Il rate limit dei login e il registro attività vedono quindi l’indirizzo del visitatore, non quello del proxy.

Passi, con il dominio assegnato dal provider (per esempio vps-005451d4.vps.ovh.net) o uno tuo:

  1. Installa il proxy (Proxy → Installa) se non l’hai ancora fatto. Le porte 80 e 443 devono essere raggiungibili da internet per il certificato, compreso l’eventuale firewall nel pannello del provider.

  2. Modifica il servizio con sudo systemctl edit sirio-sysadmin (l’override sopravvive agli aggiornamenti):

    [Service]
    Environment=SIRIO_PROXY_ENABLED=true
    Environment=SIRIO_PANEL_DOMAIN=vps-005451d4.vps.ovh.net
    Environment=SIRIO_LISTEN=127.0.0.1:22723

    SIRIO_LISTEN deve spostarsi dalla porta del pannello. Docker pubblica la porta di sirio-caddy su tutti gli indirizzi, e Linux rifiuta quel bind se Sirio occupa la stessa porta su uno qualunque di essi, loopback compreso. Sirio si rifiuta di partire con un errore esplicito invece di lasciar fallire il proxy. SIRIO_SECURE_COOKIES viene forzato a true.

  3. sudo systemctl restart sirio-sysadmin. All’avvio Sirio ricrea sirio-caddy una volta per pubblicare la nuova porta. I certificati stanno nel volume sirio-caddy-data e si conservano, e i siti restano giù per qualche secondo. Se la porta è già occupata sull’host, il vecchio container resta com’era, Proxy mostra un avviso e Sirio riprova ogni 15 minuti.

  4. Apri https://vps-005451d4.vps.ovh.net:22722/: il certificato arriva al primo accesso. Proxy mostra l’indirizzo in un badge.

Da sapere:

  • Il firewall non vede questa porta. Docker pubblica le porte con regole iptables sue, prima di ufw e firewalld: non serve ufw allow 22722, e un ufw deny non la blocca. Per limitare il pannello al tuo IP filtralo nella catena DOCKER-USER di Docker, per esempio sudo iptables -I DOCKER-USER -p tcp -m conntrack --ctorigdstport 22722 --ctdir ORIGINAL ! -s TUO.IP -j DROP (non sopravvive al riavvio: salvala con il meccanismo della tua distribuzione).
  • Accesso di riserva. Se il proxy si ferma, il pannello resta su SIRIO_LISTEN, solo in loopback. Ci arrivi con un tunnel SSH: ssh -L 22723:127.0.0.1:22723 utente@server, poi http://localhost:22723. Chrome e Firefox accettano il cookie Secure su localhost; Safari potrebbe no.
  • Disattivarlo. Togli SIRIO_PANEL_DOMAIN e riavvia: Sirio ricrea sirio-caddy senza la porta in più.

L’alternativa è una rotta normale verso la porta TCP di Sirio. Non richiede nulla oltre al pannello, ma Sirio deve continuare ad ascoltare su un indirizzo raggiungibile dal container, e vede ogni richiesta come proveniente dal proxy: il rate limit dei login è allora condiviso da tutti i visitatori.

Il punto delicato è l’indirizzo di destinazione. Sirio ascolta sull’host, non in un container, e sirio-caddy gira in una rete Docker isolata (sirio-edge): il suo 127.0.0.1 è il container stesso, non la macchina. Non scrivere 127.0.0.1 nella rotta — non risolve mai al pannello e il sintomo è un dominio senza certificato, perché la richiesta non arriva mai a un Caddyfile che lo contenga per davvero (vedi la sezione Risoluzione dei problemi più sotto per come si riconosce da fuori).

L’indirizzo giusto è host.docker.internal: Sirio configura sirio-caddy con quell’alias già puntato all’host (--add-host host.docker.internal:host-gateway), quindi funziona a prescindere dalla subnet che Docker assegna alla rete — che varia da macchina a macchina e può cambiare se la rete viene ricreata.

Se il container sirio-caddy esisteva già prima di questo alias (versioni di Sirio precedenti a questa modifica), va ricreato una volta: sudo docker rm -f sirio-caddy, poi Proxy → Installa dal pannello. Certificati e configurazione sono su volume/disco e non si perdono.

Passi concreti, con un dominio di esempio pannello.esempio.it che punta già a questa macchina:

  1. Siti → nuovo sito. Non serve un repository: basta un nome, ad esempio sirio — è solo un contenitore per il dominio.

  2. Nel sito, nuovo dominio: pannello.esempio.it, TLS auto.

  3. Nel dominio, nuova rotta:

    Campo Valore
    Path /
    Tipo host
    Destinazione host.docker.internal
    Porta 22722 (o il valore di SIRIO_LISTEN, se l’hai cambiato)
  4. Apri https://pannello.esempio.it/: il certificato arriva al primo accesso.

Con questa configurazione non spostare SIRIO_LISTEN su 127.0.0.1. host.docker.internal è l’indirizzo del bridge Docker sull’host, non il loopback, quindi un Sirio in ascolto su 127.0.0.1 rifiuta le connessioni del proxy e il dominio smette di funzionare. Per chiudere la porta in chiaro passa invece a SIRIO_PANEL_DOMAIN: SIRIO_PANEL_PORT=443 mantiene lo stesso indirizzo https://pannello.esempio.it/. Elimina prima la rotta, perché lo stesso nome su 443 non può essere sia un sito sia il pannello.

Sirio genera sempre reverse_proxy destinazione:porta in HTTP semplice: non esiste, oggi, un modo di dichiarare che l’upstream vuole TLS. Se il container di destinazione è configurato per gestire da solo l’HTTPS — capita spesso con immagini che includono un web server basato su Caddy, come FrankenPHP, quando hanno una variabile con il nome di dominio pubblico (es. SERVER_NAME) — succede questo:

  • sulla porta HTTP il container reindirizza a https:// (risponde 308), e quel redirect torna al browser puntando di nuovo al dominio pubblico: il giro si chiude sul Caddy di Sirio, che rifà la stessa richiesta, in loop;
  • sulla porta HTTPS il container si aspetta un vero handshake TLS, che Sirio non fa: la connessione cade con un errore di protocollo (dal container di Sirio si vede come 400 Bad Request o un alert TLS, non come lentezza o timeout).

In entrambi i casi il sito resta irraggiungibile anche se DNS, certificato del dominio pubblico e rotta sono tutti corretti — perché il problema è nel secondo salto, tra Caddy e il container, non nel primo.

La correzione sta nel container di destinazione, non in Sirio: disattivane l’HTTPS automatico e fallo parlare HTTP semplice, poi punta la rotta a quella porta. Per un’immagine FrankenPHP (dunglas/frankenphp o derivate) tipicamente significa cambiare, nel suo docker-compose.yml:

environment:
SERVER_NAME: docker.dev.esempio.it
SERVER_NAME: ":80"

e nella rotta di Sirio, la porta da 443 a 80. Il principio vale per qualunque immagine che faccia automatic HTTPS al suo interno (Traefik-ready, Caddy-based, ecc.): la variabile si chiama in modo diverso caso per caso, ma l’idea — “server solo HTTP su una porta nota” — è la stessa.

Da riga di comando sulla macchina, nell’ordine in cui vale la pena controllarli:

1. Il dominio è davvero nel Caddyfile generato?

Finestra del terminale
sudo docker exec sirio-caddy cat /etc/caddy/Caddyfile

Se il dominio non compare, non è mai stato salvato (o la rotta è disabilitata) — non è un problema di DNS o di certificato: quelli non vengono nemmeno tentati. Si vede anche dal pannello, in Proxy → Configurazione generata.

2. Il certificato è stato emesso?

Finestra del terminale
sudo docker logs sirio-caddy --tail 200 | grep -i -E "acme|certificate|obtain"

Un dominio che non risolve pubblicamente verso questa macchina, o una porta 80/443 già occupata da un altro processo, finiscono qui con l’errore ACME esplicito.

3. Caddy raggiunge il container/host di destinazione? Da dentro sirio-caddy, verso un container:

Finestra del terminale
sudo docker exec sirio-caddy wget -S -O - --timeout=5 http://NOME_CONTAINER:PORTA

verso l’host (es. il pannello stesso):

Finestra del terminale
sudo docker exec sirio-caddy wget -S -O - --timeout=5 http://host.docker.internal:22722/api/status

Un connection refused sull’host di solito è 127.0.0.1 scritto per errore al posto di host.docker.internal, oppure SIRIO_LISTEN spostato su 127.0.0.1 mentre una rotta host punta ancora lì (vedi sopra).

Con SIRIO_PANEL_DOMAIN il proxy raggiunge invece il pannello tramite il socket, che puoi interrogare dall’host:

Finestra del terminale
sudo curl -s --unix-socket /var/lib/sirio/proxy/sirio.sock http://panel/api/status

Nessuna risposta vuol dire che Sirio non è in esecuzione o non ha SIRIO_PANEL_DOMAIN impostato. Il log di avvio (journalctl -u sirio-sysadmin) contiene una riga panel served by the proxy con l’indirizzo e il socket. Se il socket risponde ma il dominio rifiuta la connessione, cerca the proxy isn't installed nello stesso log: Sirio non installa mai sirio-caddy da solo, quindi raggiungi il pannello su SIRIO_LISTEN (con un tunnel SSH se è sul loopback) e installalo da Proxy. Un 400/errore TLS con la destinazione container è quasi sempre il caso della sezione precedente: il backend si aspetta HTTPS e Caddy gli parla in chiaro.

4. Il certificato pubblico è quello giusto? Dall’esterno (o dalla macchina stessa, forzando la risoluzione):

Finestra del terminale
curl -vk --resolve TUO.DOMINIO:443:127.0.0.1 https://TUO.DOMINIO/ 2>&1 | grep -E "subject:|issuer:|HTTP/"

Se il certificato è di Let’s Encrypt e il subject è quello giusto, il problema non è più TLS: è il salto successivo, verso il backend (punto 3).

Aggiungere un container esterno al progetto: esempio phpMyAdmin

Sezione intitolata “Aggiungere un container esterno al progetto: esempio phpMyAdmin”

Non tutto deve passare dal docker-compose.yml di un progetto. Un caso tipico: vuoi un’interfaccia web per il database di un sito senza toccarne il compose, magari perché è condivisa fra più progetti o perché non vuoi che sparisca a ogni docker compose down. Da Container → Nuovo container puoi creare il container e collegarlo alla stessa rete del database, senza editare alcun file.

Il punto chiave è la rete: un container raggiunge un altro per nome solo se condividono una rete Docker. Se il database gira in un progetto compose chiamato ad esempio negozio, la rete di default si chiama negozio_default (verificala con docker network ls sulla macchina, o guarda il container del database in Container: la colonna espone il sito, ma la rete effettiva si vede con docker inspect NOME_DB --format '{{json .NetworkSettings.Networks}}').

1. Container → Nuovo container, con:

Campo Valore
Nome phpmyadmin
Immagine phpmyadmin:latest
Porte 8081:80 (porta a piacere sull’host)
Variabili d’ambiente PMA_HOST=negozio_db (il nome del container del database)
PMA_PORT=3306
Reti negozio_default
Riavvio automatico unless-stopped

Non serve assegnarlo a un sito: resta condiviso, il che ha senso se lo riusi per più database sullo stesso host — basta aggiungere lì le reti di ognuno.

2. Apri http://IP-DELLA-MACCHINA:8081. phpMyAdmin risolve negozio_db per nome perché ora è sulla stessa rete.

Volendo esporlo con un dominio invece che con una porta, vale lo stesso schema descritto in Esporre il pannello stesso: crea un sito, un dominio e una rotta di tipo container verso phpmyadmin, porta 80. La rotta lo aggancia anche alla rete sirio-edge — non serve indicarla a mano fra le reti del container in fase di creazione — ma resta comunque necessario aggiungere a mano la rete del database (negozio_default), perché quella non ha nulla a che fare col proxy.

Occhio all’ordine: se cambi le reti di un container già creato, oggi va fatto da riga di comando (docker network connect negozio_default phpmyadmin) — il campo Reti del form vale solo in fase di creazione, Sirio non offre ancora un modo per modificarle da un container esistente.

Un container può stare su più reti insieme: non serve un phpMyAdmin per progetto, basta collegare lo stesso container a tutte le reti dei database che deve raggiungere, uno per riga nel campo Reti. Con due progetti negozio e blog, ognuno con il proprio database (negozio_db sulla rete negozio_default, blog_db sulla rete blog_default):

Campo Valore
Reti negozio_default
blog_default
Variabili d’ambiente PMA_HOSTS=negozio_db,blog_db

PMA_HOSTS sostituisce PMA_HOST (singolare): è la variabile che l’immagine ufficiale di phpMyAdmin legge per popolare più voci — una lista di host separati da virgola, senza spazi. Se un database ascolta su una porta diversa da 3306, aggiungi anche PMA_PORTS con lo stesso numero di valori e nello stesso ordine di PMA_HOSTS (es. PMA_PORTS=3306,3307); se sono tutti su 3306 non serve indicarla.

Al login, phpMyAdmin mostra un menu a tendina con negozio_db e blog_db: username e password si inseriscono lì, non nelle variabili d’ambiente. È voluto — se i due database hanno credenziali diverse (il caso normale, un utente per progetto), impostare PMA_USER/PMA_PASSWORD a livello di container varrebbe per una sola voce e romperebbe l’altra. Se invece condividono davvero le stesse credenziali, quelle due variabili restano valide e phpMyAdmin pre-compila il login.

Ogni container aggiunto in futuro segue lo stesso schema: aggiungi la sua rete all’elenco (in creazione, o con docker network connect su un phpMyAdmin già esistente) e il suo nome a PMA_HOSTS. Le variabili d’ambiente si leggono solo all’avvio, quindi cambia PMA_HOSTS da Override variabili sul container di phpMyAdmin: ricrea il container con il nuovo valore, mantenendo il resto della configurazione (vedi Override delle variabili d’ambiente).

Un servizio condiviso raggiunto dalle app: esempio mailpit

Sezione intitolata “Un servizio condiviso raggiunto dalle app: esempio mailpit”

Stesso principio del caso phpMyAdmin — un container fuori dal docker-compose.yml di un progetto, collegato a mano alla sua rete — ma con il verso opposto: qui non è il container aggiunto a dover raggiungere un servizio del progetto, sono i container del progetto a dover raggiungere lui. Un caso tipico è un mailpit condiviso per catturare le mail di più progetti in sviluppo/staging senza installarne uno per compose.

1. Container → Nuovo container, con:

Campo Valore
Nome mailpit
Immagine axllent/mailpit:latest
Porte 8025:8025 (UI web, porta a piacere sull’host)
Reti negozio_default (la rete del progetto che deve mandare mail)
Riavvio automatico unless-stopped

2. Nell’app, punta l’host SMTP al nome del container: ad esempio MAILER_DSN=smtp://mailpit:1025 (il nome e la variabile cambiano da framework a framework, la porta 1025 è quella SMTP di mailpit, non la 8025 della UI).

Il nome del container conta, non solo la rete. Un container raggiunge l’altro per nome solo se il nome coincide con quello che l’app si aspetta — condividere la rete non basta. Se lo crei con un nome diverso da quello cercato dall’app (es. un prefisso applicato automaticamente dal tuo orchestratore, progetto_mailpit invece di mailpit), la risoluzione DNS fallisce anche se le reti coincidono; si verifica da dentro il container applicativo con docker exec NOME_APP getent hosts mailpit (exit diverso da 0 = non risolve). La soluzione più semplice è nominare il container esattamente come lo cerca l’app, come nella tabella sopra; in alternativa si aggiunge un alias sulla rete (va rifatta a ogni riconnessione, non è persistente da sola):

Finestra del terminale
docker network disconnect negozio_default mailpit
docker network connect --alias mailpit negozio_default mailpit

Per più progetti basta collegare lo stesso mailpit a tutte le reti coinvolte, una per riga nel campo Reti — esattamente come per il phpMyAdmin condiviso sopra — purché in ognuna risulti raggiungibile col nome che quel progetto si aspetta.

Sullo stesso hostname si possono definire più rotte:

Path Destinazione
/api container api, porta 3000
/ container web, porta 80

Vince la più specifica, indipendentemente dall’ordine di inserimento. Il path non viene rimosso prima di inoltrare la richiesta: l’applicazione dietro /api riceve /api/.... Se ti serve il contrario, per ora il posto giusto è la configurazione dell’applicazione.

Una rotta può chiedere ai visitatori utente e password prima di arrivare all’applicazione — quello che Apache fa con AuthType Basic e un file .htpasswd. Le credenziali stanno nelle liste di accesso, che appartengono a un sito: creane una nella scheda Liste di accesso del sito, aggiungi gli utenti, poi sceglila nel campo Accesso di ogni rotta da proteggere. Una lista può proteggere più rotte, anche su domini diversi dello stesso sito: aggiungere una volta il collega del cliente lo fa entrare sia in staging sia in preview.

Gli utenti delle liste sono i visitatori dei siti, non account di Sirio: non arrivano mai al pannello, e gli utenti di Sirio non entrano in una rotta protetta se non sono nella sua lista.

Cosa sapere:

  • La protezione è per rotta. Con /admin protetta e / pubblica, tutto quello che sta fuori da /admin resta pubblico. Per proteggere un dominio intero, imposta la lista sulla sua rotta / (e su ogni altra rotta del dominio).
  • Di ogni password si conserva solo l’hash bcrypt, quindi non può essere mostrata di nuovo: annotala (o usa Genera) prima di salvare, e impostane una nuova se va persa. Le password seguono le stesse regole di quelle di Sirio (almeno 10 caratteri).
  • Importare un file .htpasswd tiene le righe bcrypt ($2y$, scritte da htpasswd -B) ed elenca le altre, che il proxy non sa leggere ($apr1$ MD5, {SHA}, crypt): a quegli utenti va data una nuova password. Sono rifiutati anche gli hash con costo bcrypt sopra 12, perché il proxy verifica l’hash a ogni tentativo, anche quelli sbagliati.
  • L’applicazione non vede mai le credenziali: il proxy toglie l’header Authorization prima di inoltrare. Un’applicazione con un suo login dietro una rotta protetta continua a funzionare con i suoi cookie, ma una che si aspetta un’autenticazione HTTP propria non può stare dietro una lista.
  • Una lista senza utenti non fa entrare nessuno (la rotta risponde 403) invece di diventare pubblica, e una lista non si può eliminare finché una rotta la richiede.
  • Su un dominio con TLS off il browser invia la password in chiaro: proteggilo solo se l’HTTPS è terminato prima del proxy di Sirio.
  • Non c’è un limite ai tentativi su queste password, come per qualsiasi HTTP Basic Auth: sceglile lunghe.
  • Gestire le liste di un sito richiede il permesso Domini del sito, lo stesso che serve per modificarne le rotte.

Nel Caddyfile generato una rotta protetta diventa un blocco basic_auth davanti a reverse_proxy, che richiede Caddy 2.8 o successivo. L’immagine del proxy gestito viene scaricata una volta sola, quando il proxy viene installato: se la tua è precedente alla 2.8 (sudo docker exec sirio-caddy caddy version), esegui sudo docker pull caddy:2-alpine && sudo docker rm -f sirio-caddy, poi Proxy → Installa. I certificati stanno nel volume sirio-caddy-data e sopravvivono.

Modalità Quando
auto il caso normale: certificato Let’s Encrypt, rinnovato da Caddy
internal sviluppo e domini non pubblici (.local): CA interna di Caddy, il browser avvisa
off solo HTTP. Usala per un servizio dietro un’altra terminazione TLS, non per pigrizia
  • L’upstream è sempre HTTP semplice. La rotta genera reverse_proxy destinazione:porta senza schema: Sirio non parla mai TLS con il container o l’host di destinazione, qualunque sia la porta indicata. Un backend che gestisce da solo l’HTTPS va spento su quel fronte — vedi Backend che gestisce da solo TLS o redirect.
  • Wildcard. *.esempio.it è accettato dalla validazione, ma il certificato richiede la verifica DNS-01, che in Caddy vuole un plugin per ciascun provider DNS e quindi un’immagine costruita apposta. Con l’immagine standard un dominio wildcard non ottiene il certificato: la verifica DNS lo segnala.
  • Il path non viene strippato prima dell’inoltro (vedi sopra).
  • Redirect, alias e header personalizzati non ci sono ancora: www.esempio.it e esempio.it vanno per ora dichiarati come due domini con le stesse rotte.
  • Il controllo DNS è un avviso, non un blocco: l’IP pubblico della macchina non è determinabile in modo affidabile dall’interno (NAT, IPv6, proxy davanti), e rifiutare un dominio sulla base di un confronto inaffidabile bloccherebbe configurazioni legittime.

Se oggi hai un Caddy o un nginx sull’host che pubblica il pannello:

  1. annota i domini e le destinazioni che gestisce;
  2. in Sirio, crea i siti e i domini corrispondenti, con le loro rotte. Per il pannello stesso, invece di una rotta, imposta SIRIO_PANEL_DOMAIN sul suo dominio, con SIRIO_PANEL_PORT=443 per mantenere lo stesso indirizzo (dettagli e passi completi in Esporre il pannello stesso);
  3. controlla la configurazione generata in Proxy → Configurazione generata: è in sola lettura ed esiste apposta per essere ispezionata prima di fare il salto;
  4. ferma il proxy esistente (systemctl stop caddy, systemctl disable caddy);
  5. installa il proxy gestito dal pannello.

Il passo 4 è l’unico momento di disservizio. Se qualcosa va storto puoi sempre riavviare il vecchio proxy: la sua configurazione non è stata toccata.

Percorso Contenuto
SIRIO_DATA_DIR/proxy/Caddyfile configurazione attiva, generata
SIRIO_DATA_DIR/proxy/Caddyfile.bak versione precedente, per il ripristino
SIRIO_DATA_DIR/proxy/sirio.sock socket da cui il proxy raggiunge il pannello, con SIRIO_PANEL_DOMAIN
volume sirio-caddy-data certificati e stato ACME
rete sirio-edge dove il proxy raggiunge i container per nome
Variabile Default Descrizione
SIRIO_PROXY_ENABLED false attiva la gestione di domini e instradamento
SIRIO_PROXY_IMAGE caddy:2-alpine immagine del proxy
SIRIO_PROXY_CONTAINER sirio-caddy nome del container del proxy
SIRIO_PROXY_NETWORK sirio-edge rete condivisa fra proxy e container
SIRIO_PANEL_DOMAIN — dominio su cui il proxy serve il pannello in HTTPS; richiede SIRIO_PROXY_ENABLED=true
SIRIO_PANEL_PORT 22722 porta su cui viene pubblicato il pannello; 443 la condivide con i siti, 80 non è ammessa