Files
athletic-map-deploy/tenants/plataforma/20-keycloak.yaml
T
deploy 16e805cc35 feat(plataforma): o Keycloak monta o tema de e-mail Athletic Map
Sao quatro arquivos em tres diretorios, e ConfigMap nao tem diretorio: as
chaves sao achatadas e o items[].path do volume remonta a hierarquia.
2026-09-25 00:33:40 +00:00

137 lines
5.0 KiB
YAML

# Keycloak dedicado do tenant `plataforma` (IdP proprio da Athletic Map), persistindo no Postgres
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
namespace: plataforma-prod
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:26.0
args: ["start-dev", "--import-realm"]
env:
- name: KC_DB
value: postgres
- name: KC_DB_URL
value: "jdbc:postgresql://postgres:5432/keycloak?sslmode=require"
- name: KC_DB_USERNAME
value: atm
- name: KC_DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
- name: KC_BOOTSTRAP_ADMIN_USERNAME
value: admin
- name: KC_BOOTSTRAP_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: keycloak-admin
key: password
- name: KC_HEALTH_ENABLED
value: "true"
- name: KC_HTTP_ENABLED
value: "true"
- name: KC_PROXY_HEADERS
value: xforwarded
# URL COMPLETA, e nao so o hostname. A diferenca nao e estetica.
#
# Com so o hostname, o Keycloak resolve esquema e porta A PARTIR DA
# REQUISICAO. Isso funciona para quem chega pelo ingress (que manda
# X-Forwarded-Proto), e quebra para quem chega por DENTRO: o
# provisionamento chama a Admin API em http://keycloak:8080, e o link
# do e-mail de boas-vindas saiu
# `http://auth-plataforma.athleticmap.com:8080/...` — hostname certo,
# esquema e porta da conexao interna. O cliente clicava e dava
# ERR_CONNECTION_TIMED_OUT.
#
# Medido em 2026-09-24, no primeiro convite que chegou a uma caixa de
# verdade. Com a URL completa, o Keycloak para de deduzir e passa a
# montar todo link externo com este endereco — inclusive os que nascem
# de chamadas internas.
- name: KC_HOSTNAME
value: "https://auth-plataforma.athleticmap.com"
- name: KC_HOSTNAME_STRICT
value: "true"
ports:
- containerPort: 8080
- containerPort: 9000
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
readinessProbe:
httpGet:
path: /health/ready
port: 9000
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 40
volumeMounts:
- name: realm-import
mountPath: /opt/keycloak/data/import
readOnly: true
# O tema de login Athletic Map, o mesmo que o `escolinha` usa.
#
# Vem por ConfigMap e nao por imagem: o `login.ftl` traz as imagens
# embutidas em data URI, porque o ConfigMap e montado READ-ONLY sobre
# o diretorio do tema e nao sobra `resources/` para o Keycloak
# servir. Gerado por scripts/tema_login_escolinha.py --destino
# plataforma.
#
# Aqui ele vale para TODO tenant provisionado: eles nao tem Keycloak
# proprio, usam este, um realm cada.
- name: theme-athleticmapv2
mountPath: /opt/keycloak/themes/athleticmap-v2/login
readOnly: true
# O tema de E-MAIL, no mesmo `athleticmap-v2`.
#
# Sao quatro arquivos em tres diretorios, e ConfigMap nao tem
# diretorio: as chaves sao achatadas e o `items[].path` do volume
# remonta a hierarquia. Gerado por
# scripts/tema_email_athleticmap.py.
- name: email-athleticmapv2
mountPath: /opt/keycloak/themes/athleticmap-v2/email
readOnly: true
volumes:
- name: realm-import
configMap:
name: kc-realm-import
- name: theme-athleticmapv2
configMap:
name: kc-theme-athleticmapv2
- name: email-athleticmapv2
configMap:
name: kc-email-athleticmapv2
# Os caminhos TEM de bater com o mapa ARQUIVOS do gerador.
items:
- { key: theme.properties, path: theme.properties }
- { key: template.ftl, path: html/template.ftl }
- { key: executeActions.ftl, path: html/executeActions.ftl }
- { key: messages_pt_BR.properties, path: messages/messages_pt_BR.properties }
- { key: messages_en.properties, path: messages/messages_en.properties }
---
apiVersion: v1
kind: Service
metadata:
name: keycloak
namespace: plataforma-prod
spec:
selector:
app: keycloak
ports:
- port: 8080
targetPort: 8080