Fix url
Deploy stack su Proxmox / deploy (push) Successful in 6m26s

This commit is contained in:
Lorenzo Sanesi
2026-08-06 21:03:56 +02:00
parent fb5423f625
commit 66bb936dce
8 changed files with 138 additions and 60 deletions
+18 -3
View File
@@ -30,13 +30,28 @@ ATTIVITA_BACKEND_PORT=8001
MAGAZZINO_BACKEND_PORT=8002
EVENTI_BACKEND_PORT=8003
# Deve coincidere con il secret del client "scouthub-home-be" in keycloak/realm-export.json
# URL pubbliche dei servizi, cosi' come raggiungibili dal browser (e da Keycloak per i redirect
# OIDC). Di default puntano a localhost sulle porte sopra, per lo sviluppo locale. Quando lo
# stack va in produzione dietro un reverse proxy (es. Caddy) con dominio pubblico, sovrascrivere
# ognuna con l'URL reale, senza porta (es. https://home.tuodominio.it) - vedi Caddyfile.example
# in root per un setup di riferimento con un sottodominio per servizio.
KEYCLOAK_PUBLIC_URL=http://localhost:6999
HOME_FE_PUBLIC_URL=http://localhost:7000
ATTIVITA_FE_PUBLIC_URL=http://localhost:7001
MAGAZZINO_FE_PUBLIC_URL=http://localhost:7002
EVENTI_FE_PUBLIC_URL=http://localhost:7003
HOME_BE_PUBLIC_URL=http://localhost:8000
ATTIVITA_BE_PUBLIC_URL=http://localhost:8001
MAGAZZINO_BE_PUBLIC_URL=http://localhost:8002
EVENTI_BE_PUBLIC_URL=http://localhost:8003
# Deve coincidere con il secret del client "scouthub-home-be" in keycloak/realm-export.template.json
KEYCLOAK_ORG_SERVICE_CLIENT_SECRET=change_me
# Deve coincidere con il secret del client "scouthub-magazzino-be" in keycloak/realm-export.json
# Deve coincidere con il secret del client "scouthub-magazzino-be" in keycloak/realm-export.template.json
KEYCLOAK_MAGAZZINO_CLIENT_SECRET=change_me
# Deve coincidere con il secret del client "scouthub-eventi-be" in keycloak/realm-export.json
# Deve coincidere con il secret del client "scouthub-eventi-be" in keycloak/realm-export.template.json
# (secret condiviso anche con scouthub-attivita-be e scouthub-magazzino-be, che lo usano per
# chiamare POST /eventi/:id/risorse su scouthub-eventi-be)
KEYCLOAK_EVENTI_CLIENT_SECRET=change_me
+43 -21
View File
@@ -25,7 +25,7 @@ services:
restart: unless-stopped
environment:
PORT: ${ATTIVITA_BACKEND_PORT}
CORS_ORIGIN: http://localhost:${ATTIVITA_FRONTEND_PORT}
CORS_ORIGIN: ${ATTIVITA_FE_PUBLIC_URL}
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/scouthub?schema=public
KEYCLOAK_BASE_URL: http://keycloak:8080
KEYCLOAK_REALM: scouthub
@@ -41,8 +41,8 @@ services:
build:
context: ./scouthub-attivita-fe
args:
API_URL: http://localhost:${ATTIVITA_BACKEND_PORT}
KEYCLOAK_BASE_URL: http://localhost:${KEYCLOAK_PORT}
API_URL: ${ATTIVITA_BE_PUBLIC_URL}
KEYCLOAK_BASE_URL: ${KEYCLOAK_PUBLIC_URL}
restart: unless-stopped
ports:
- "${ATTIVITA_FRONTEND_PORT}:80"
@@ -56,7 +56,7 @@ services:
environment:
PORT: ${HOME_BACKEND_PORT}
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public
FRONTEND_BASE_URL: http://localhost:${HOME_FRONTEND_PORT}
FRONTEND_BASE_URL: ${HOME_FE_PUBLIC_URL}
# Rete interna Docker: la validazione del JWT (JWKS) non controlla l'issuer,
# quindi non serve che coincida con l'hostname visto dal browser (localhost:8081).
KEYCLOAK_BASE_URL: http://keycloak:8080
@@ -75,11 +75,11 @@ services:
build:
context: ./scouthub-home-fe
args:
KEYCLOAK_BASE_URL: http://localhost:${KEYCLOAK_PORT}
ORG_SERVICE_API_BASE_URL: http://localhost:${HOME_BACKEND_PORT}
ATTIVITA_FE_BASE_URL: http://localhost:${ATTIVITA_FRONTEND_PORT}
MAGAZZINO_FE_BASE_URL: http://localhost:${MAGAZZINO_FRONTEND_PORT}
EVENTI_FE_BASE_URL: http://localhost:${EVENTI_FRONTEND_PORT}
KEYCLOAK_BASE_URL: ${KEYCLOAK_PUBLIC_URL}
ORG_SERVICE_API_BASE_URL: ${HOME_BE_PUBLIC_URL}
ATTIVITA_FE_BASE_URL: ${ATTIVITA_FE_PUBLIC_URL}
MAGAZZINO_FE_BASE_URL: ${MAGAZZINO_FE_PUBLIC_URL}
EVENTI_FE_BASE_URL: ${EVENTI_FE_PUBLIC_URL}
restart: unless-stopped
ports:
- "${HOME_FRONTEND_PORT}:80"
@@ -109,8 +109,8 @@ services:
build:
context: ./scouthub-magazzino-fe
args:
KEYCLOAK_BASE_URL: http://localhost:${KEYCLOAK_PORT}
MAGAZZINO_API_BASE_URL: http://localhost:${MAGAZZINO_BACKEND_PORT}
KEYCLOAK_BASE_URL: ${KEYCLOAK_PUBLIC_URL}
MAGAZZINO_API_BASE_URL: ${MAGAZZINO_BE_PUBLIC_URL}
restart: unless-stopped
ports:
- "${MAGAZZINO_FRONTEND_PORT}:80"
@@ -141,8 +141,8 @@ services:
build:
context: ./scouthub-eventi-fe
args:
KEYCLOAK_BASE_URL: http://localhost:${KEYCLOAK_PORT}
EVENTI_API_BASE_URL: http://localhost:${EVENTI_BACKEND_PORT}
KEYCLOAK_BASE_URL: ${KEYCLOAK_PUBLIC_URL}
EVENTI_API_BASE_URL: ${EVENTI_BE_PUBLIC_URL}
restart: unless-stopped
ports:
- "${EVENTI_FRONTEND_PORT}:80"
@@ -159,13 +159,27 @@ services:
volumes:
- scouthub_keycloak_db_data:/var/lib/postgresql/data
keycloak-realm-render:
image: alpine:3.20
restart: "no"
entrypoint: ["sh", "/render-realm-template.sh"]
environment:
HOME_FE_URL: ${HOME_FE_PUBLIC_URL}
ATTIVITA_FE_URL: ${ATTIVITA_FE_PUBLIC_URL}
MAGAZZINO_FE_URL: ${MAGAZZINO_FE_PUBLIC_URL}
EVENTI_FE_URL: ${EVENTI_FE_PUBLIC_URL}
volumes:
- ./keycloak/realm-export.template.json:/template/realm-export.template.json:ro
- ./keycloak/render-realm-template.sh:/render-realm-template.sh:ro
- scouthub_keycloak_realm:/rendered
keycloak:
image: quay.io/keycloak/keycloak:26.7
restart: unless-stopped
# --import-realm importa keycloak/realm-export.json solo se il realm non esiste già.
# Le correzioni post-import (ruoli service account, protocol mapper "organization") non
# coperte dal file JSON sono automatizzate dal servizio one-shot "keycloak-init" sotto,
# non più manuali (vedi CLAUDE.md).
# --import-realm importa il realm-export.json generato da keycloak-realm-render (a partire
# dal template) solo se il realm non esiste già. Le correzioni post-import (ruoli service
# account, protocol mapper "organization") non coperte dal file JSON sono automatizzate dal
# servizio one-shot "keycloak-init" sotto, non più manuali (vedi CLAUDE.md).
command: start-dev --import-realm --health-enabled=true
environment:
KC_DB: postgres
@@ -178,16 +192,23 @@ services:
# Verificare con `kc.sh show-config` che i flag richiesti siano invariati nella versione
# effettivamente usata: i nomi dei feature flag cambiano tra minor version di Keycloak.
KC_FEATURES: organization,admin-fine-grained-authz:v1
KC_HOSTNAME: localhost
KC_HOSTNAME_PORT: "${KEYCLOAK_PORT}"
# KC_HOSTNAME come URL completo (schema+host, es. https://auth.tuodominio.it dietro Caddy
# in produzione, http://localhost:6999 in locale): Keycloak lo usa per generare tutti i link
# (redirect, well-known, ecc.) visti dal browser. KC_PROXY_HEADERS è necessario perché
# Keycloak sta dietro un reverse proxy (Caddy) che termina il TLS e inoltra in http.
KC_HOSTNAME: ${KEYCLOAK_PUBLIC_URL}
KC_HTTP_ENABLED: "true"
KC_PROXY_HEADERS: xforwarded
ports:
- "${KEYCLOAK_PORT}:8080"
volumes:
- ./keycloak/realm-export.json:/opt/keycloak/data/import/realm-export.json:ro
- scouthub_keycloak_realm:/opt/keycloak/data/import:ro
- ./keycloak/themes/scouthub:/opt/keycloak/themes/scouthub:ro
depends_on:
- keycloak-db
keycloak-db:
condition: service_started
keycloak-realm-render:
condition: service_completed_successfully
healthcheck:
test: ["CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/9000 && echo -e 'GET /health/ready HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n' >&3 && grep -q '\"status\": \"UP\"' <&3"]
interval: 5s
@@ -211,3 +232,4 @@ services:
volumes:
scouthub_db_data:
scouthub_keycloak_db_data:
scouthub_keycloak_realm:
+11 -2
View File
@@ -1,8 +1,16 @@
# keycloak/realm-export.json
# keycloak/realm-export.template.json
Realm `scouthub` con feature Organizations abilitata, importato automaticamente
all'avvio di Keycloak (`--import-realm` nel `docker-compose.yml` alla radice).
Il file è un **template**: i placeholder `__HOME_FE_URL__`/`__ATTIVITA_FE_URL__`/
`__MAGAZZINO_FE_URL__`/`__EVENTI_FE_URL__` (redirect URI, web origins, post-logout
redirect del client `scouthub-frontend`) vengono sostituiti a runtime dal servizio
one-shot `keycloak-realm-render` con i valori delle variabili `*_FE_PUBLIC_URL` in
`.env` (localhost in locale, dominio dietro Caddy in produzione), e il risultato
(`realm-export.json`) viene scritto in un volume Docker montato da `keycloak` come
cartella di import — non esiste più un `realm-export.json` statico committato.
Basato su `keycloak/realm.json` (bozza di riferimento), con l'aggiunta del
ruolo `admin` richiesto da `POST /gruppi` e `GET /gruppi` in
`scouthub-home-be`: creazione/elenco diretti restano riservati ad `admin`,
@@ -23,7 +31,8 @@ Contiene già:
il suo `clientId`/`secret` devono corrispondere a
`KEYCLOAK_ORG_SERVICE_CLIENT_ID`/`_SECRET` in `scouthub-home-be/.env.example`)
- il client pubblico `scouthub-frontend` (login utente, condiviso da tutti i
frontend Angular del progetto, redirect su `http://localhost:7000-7003/*`)
frontend Angular del progetto, redirect sugli URL pubblici configurati in
`.env`/`*_FE_PUBLIC_URL`, `http://localhost:7000-7003/*` di default in locale)
Passi manuali ancora da fare dopo l'import (non automatizzabili in un realm
export senza conoscere gli id generati a runtime):
@@ -76,21 +76,21 @@
"standardFlowEnabled": true,
"directAccessGrantsEnabled": false,
"redirectUris": [
"http://localhost:7000/*",
"http://localhost:7001/*",
"http://localhost:7002/*",
"http://localhost:7002/silent-check-sso.html",
"http://localhost:7003/*",
"http://localhost:7003/silent-check-sso.html"
"__HOME_FE_URL__/*",
"__ATTIVITA_FE_URL__/*",
"__MAGAZZINO_FE_URL__/*",
"__MAGAZZINO_FE_URL__/silent-check-sso.html",
"__EVENTI_FE_URL__/*",
"__EVENTI_FE_URL__/silent-check-sso.html"
],
"webOrigins": [
"http://localhost:7000",
"http://localhost:7001",
"http://localhost:7002",
"http://localhost:7003"
"__HOME_FE_URL__",
"__ATTIVITA_FE_URL__",
"__MAGAZZINO_FE_URL__",
"__EVENTI_FE_URL__"
],
"attributes": {
"post.logout.redirect.uris": "http://localhost:7000/*##http://localhost:7001/*##http://localhost:7002/*##http://localhost:7003/*"
"post.logout.redirect.uris": "__HOME_FE_URL__/*##__ATTIVITA_FE_URL__/*##__MAGAZZINO_FE_URL__/*##__EVENTI_FE_URL__/*"
},
"defaultClientScopes": [
"openid",
+26
View File
@@ -0,0 +1,26 @@
#!/bin/sh
# Sostituisce nel template i placeholder __XXX_FE_URL__ con gli URL pubblici reali dei
# frontend (localhost in locale, dominio dietro Caddy in produzione — vedi CLAUDE.md/.env.example),
# scrivendo il risultato nella cartella di import di Keycloak. Necessario perche' realm-export.json
# è statico e --import-realm non supporta variabili d'ambiente nei suoi campi.
set -eu
: "${HOME_FE_URL:?variabile HOME_FE_URL mancante}"
: "${ATTIVITA_FE_URL:?variabile ATTIVITA_FE_URL mancante}"
: "${MAGAZZINO_FE_URL:?variabile MAGAZZINO_FE_URL mancante}"
: "${EVENTI_FE_URL:?variabile EVENTI_FE_URL mancante}"
mkdir -p /rendered
sed \
-e "s#__HOME_FE_URL__#$HOME_FE_URL#g" \
-e "s#__ATTIVITA_FE_URL__#$ATTIVITA_FE_URL#g" \
-e "s#__MAGAZZINO_FE_URL__#$MAGAZZINO_FE_URL#g" \
-e "s#__EVENTI_FE_URL__#$EVENTI_FE_URL#g" \
/template/realm-export.template.json > /rendered/realm-export.json
echo "[keycloak-realm-render] realm-export.json generato con:"
echo " HOME_FE_URL=$HOME_FE_URL"
echo " ATTIVITA_FE_URL=$ATTIVITA_FE_URL"
echo " MAGAZZINO_FE_URL=$MAGAZZINO_FE_URL"
echo " EVENTI_FE_URL=$EVENTI_FE_URL"
+9 -7
View File
@@ -106,7 +106,7 @@ automaticamente da `ng serve`/`ng build --configuration development`) espongono:
- `keycloakBaseUrl` — URL base dell'istanza Keycloak (default `http://localhost:8081`, coerente
con `KEYCLOAK_PORT` in `.env` alla root del repo)
- `keycloakRealm` — realm Keycloak (`scouthub`)
- `keycloakClientId` — client pubblico condiviso già definito in `keycloak/realm-export.json`
- `keycloakClientId` — client pubblico condiviso già definito in `keycloak/realm-export.template.json`
(`scouthub-frontend`)
- `eventiApiBaseUrl` — URL base di `scouthub-eventi-be` (default `http://localhost:8084`)
@@ -116,12 +116,14 @@ automaticamente da `ng serve`/`ng build --configuration development`) espongono:
```bash
docker compose up -d keycloak-db keycloak
```
Il realm `scouthub` viene importato automaticamente da `keycloak/realm-export.json` al primo
avvio (`--import-realm`).
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` che includono anche
`http://localhost:4204` (porta di default di questo progetto, vedi sotto) — se si cambia porta,
aggiornare `keycloak/realm-export.json` di conseguenza e reimportare il realm (o aggiornarlo
da console admin Keycloak).
Il realm `scouthub` viene importato automaticamente al primo avvio (`--import-realm`) a
partire dal template `keycloak/realm-export.template.json`, renderizzato con gli URL
pubblici correnti (`*_FE_PUBLIC_URL` in `.env`) dal servizio one-shot
`keycloak-realm-render` (vedi `keycloak/README.md`).
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` generati dagli URL
pubblici configurati in `.env` — se si cambia porta/dominio, basta aggiornare `.env` e
rifare `docker compose up`; per un realm già importato in precedenza va comunque
aggiornato anche da console admin Keycloak (l'import non sovrascrive un realm esistente).
3. `provideKeycloakAngular()` (`src/app/core/auth/keycloak.provider.ts`) inizializza il client con
`onLoad: 'check-sso'`: all'avvio l'app verifica in un iframe nascosto se esiste già una sessione
Keycloak, senza forzare subito un redirect di login.
+11 -9
View File
@@ -87,7 +87,7 @@ espongono:
- `keycloakBaseUrl` — URL base dell'istanza Keycloak (default `http://localhost:8081`,
coerente con `KEYCLOAK_PORT` in `.env` alla root del repo)
- `keycloakRealm` — realm Keycloak (`scouthub`)
- `keycloakClientId` — client pubblico già definito in `keycloak/realm-export.json`
- `keycloakClientId` — client pubblico già definito in `keycloak/realm-export.template.json`
(`scouthub-frontend`)
- `orgServiceApiBaseUrl` — URL base di `scouthub-home-be` (default `http://localhost:8082`)
@@ -97,14 +97,16 @@ espongono:
```bash
docker compose up -d keycloak-db keycloak
```
Il realm `scouthub` viene importato automaticamente da `keycloak/realm-export.json`
al primo avvio (`--import-realm`).
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` che includono
`http://localhost:4200` (usato da `scouthub-attivita-fe`), `http://localhost:4201`
(porta di default di questo progetto, vedi sotto) e le porte di
`scouthub-magazzino-fe`/`scouthub-eventi-fe` — il client è ora condiviso da tutti
e quattro i frontend. Se si cambia porta, aggiornare `keycloak/realm-export.json`
di conseguenza e reimportare il realm (o aggiornarlo da console admin Keycloak).
Il realm `scouthub` viene importato automaticamente al primo avvio (`--import-realm`)
a partire dal template `keycloak/realm-export.template.json`, renderizzato con gli URL
pubblici correnti (`*_FE_PUBLIC_URL` in `.env`) dal servizio one-shot
`keycloak-realm-render` (vedi `keycloak/README.md`).
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` generati dagli
URL pubblici configurati in `.env` per tutti e quattro i frontend — il client è
condiviso. Se si cambia porta/dominio, basta aggiornare `.env` e rifare
`docker compose up`; per un cambiamento su un realm già importato in precedenza va
comunque aggiornato anche da console admin Keycloak (l'import non sovrascrive un
realm esistente).
3. `provideKeycloakAngular()` (`src/app/core/auth/keycloak.provider.ts`) inizializza
il client con `onLoad: 'check-sso'`: all'avvio l'app verifica in un iframe nascosto
se esiste già una sessione Keycloak, senza forzare un redirect immediato per le
+9 -7
View File
@@ -104,7 +104,7 @@ automaticamente da `ng serve`/`ng build --configuration development`) espongono:
- `keycloakBaseUrl` — URL base dell'istanza Keycloak (default `http://localhost:8081`, coerente
con `KEYCLOAK_PORT` in `.env` alla root del repo)
- `keycloakRealm` — realm Keycloak (`scouthub`)
- `keycloakClientId` — client pubblico condiviso già definito in `keycloak/realm-export.json`
- `keycloakClientId` — client pubblico condiviso già definito in `keycloak/realm-export.template.json`
(`scouthub-frontend`)
- `magazzinoApiBaseUrl` — URL base di `scouthub-magazzino-be` (default `http://localhost:8083`)
@@ -114,12 +114,14 @@ automaticamente da `ng serve`/`ng build --configuration development`) espongono:
```bash
docker compose up -d keycloak-db keycloak
```
Il realm `scouthub` viene importato automaticamente da `keycloak/realm-export.json` al primo
avvio (`--import-realm`).
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` che includono anche
`http://localhost:4203` (porta di default di questo progetto, vedi sotto) — se si cambia porta,
aggiornare `keycloak/realm-export.json` di conseguenza e reimportare il realm (o aggiornarlo
da console admin Keycloak).
Il realm `scouthub` viene importato automaticamente al primo avvio (`--import-realm`) a
partire dal template `keycloak/realm-export.template.json`, renderizzato con gli URL
pubblici correnti (`*_FE_PUBLIC_URL` in `.env`) dal servizio one-shot
`keycloak-realm-render` (vedi `keycloak/README.md`).
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` generati dagli URL
pubblici configurati in `.env` — se si cambia porta/dominio, basta aggiornare `.env` e
rifare `docker compose up`; per un realm già importato in precedenza va comunque
aggiornato anche da console admin Keycloak (l'import non sovrascrive un realm esistente).
3. `provideKeycloakAngular()` (`src/app/core/auth/keycloak.provider.ts`) inizializza il client con
`onLoad: 'check-sso'`: all'avvio l'app verifica in un iframe nascosto se esiste già una sessione
Keycloak, senza forzare un redirect immediato per le pagine pubbliche.