fix(k8s): stabilize keycloak rollout and align CD deploy manifests

Update Keycloak probe/realm import behavior and authority config so auth services start reliably on the dev cluster, while keeping CD deployment steps aligned with the actual Kubernetes overlay behavior.
This commit is contained in:
WorkClub Automation
2026-03-13 06:25:07 +01:00
parent 7272358746
commit eaa163afa4
9 changed files with 394 additions and 46 deletions

View File

@@ -67,8 +67,13 @@ spec:
secretKeyRef:
name: workclub-secrets
key: database-connection-string
- name: Keycloak__Url
- name: Keycloak__Authority
valueFrom:
configMapKeyRef:
name: workclub-config
key: keycloak-url
key: keycloak-authority
- name: Keycloak__Audience
valueFrom:
configMapKeyRef:
name: workclub-config
key: keycloak-audience

View File

@@ -9,6 +9,8 @@ data:
cors-origins: "http://localhost:3000"
api-base-url: "http://workclub-api"
keycloak-url: "http://workclub-keycloak"
keycloak-authority: "http://workclub-keycloak/realms/workclub"
keycloak-audience: "workclub-api"
keycloak-realm: "workclub"
# Database configuration
@@ -39,3 +41,18 @@ data:
\c workclub
GRANT ALL PRIVILEGES ON SCHEMA public TO app;
ALTER SCHEMA public OWNER TO app;
-- App admin role for RLS bypass policies used by API startup seed
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'app_admin') THEN
CREATE ROLE app_admin;
END IF;
END
$$;
GRANT app_admin TO app WITH INHERIT FALSE, SET TRUE;
GRANT USAGE ON SCHEMA public TO app_admin;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO app_admin;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO app_admin;
ALTER DEFAULT PRIVILEGES FOR ROLE app IN SCHEMA public GRANT ALL ON TABLES TO app_admin;
ALTER DEFAULT PRIVILEGES FOR ROLE app IN SCHEMA public GRANT ALL ON SEQUENCES TO app_admin;

View File

@@ -7,6 +7,9 @@ metadata:
component: auth
spec:
replicas: 1
strategy:
type: Recreate
progressDeadlineSeconds: 1800
selector:
matchLabels:
app: workclub-keycloak
@@ -21,25 +24,37 @@ spec:
image: quay.io/keycloak/keycloak:26.1
imagePullPolicy: IfNotPresent
args:
- start
- start-dev
- --import-realm
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: management
containerPort: 9000
protocol: TCP
readinessProbe:
httpGet:
path: /health/ready
port: http
initialDelaySeconds: 150
port: management
initialDelaySeconds: 240
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 10
startupProbe:
httpGet:
path: /health/ready
port: management
initialDelaySeconds: 60
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 120
livenessProbe:
httpGet:
path: /health/live
port: http
initialDelaySeconds: 240
port: management
initialDelaySeconds: 420
periodSeconds: 20
timeoutSeconds: 5
failureThreshold: 5
@@ -84,3 +99,11 @@ spec:
value: "true"
- name: KC_HEALTH_ENABLED
value: "true"
volumeMounts:
- name: keycloak-realm-import
mountPath: /opt/keycloak/data/import
readOnly: true
volumes:
- name: keycloak-realm-import
configMap:
name: keycloak-realm-import

View File

@@ -0,0 +1,246 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: keycloak-realm-import
labels:
app: workclub-keycloak
data:
realm-export.json: |
{
"realm": "workclub",
"enabled": true,
"displayName": "Work Club Manager",
"registrationAllowed": false,
"rememberMe": true,
"verifyEmail": false,
"loginWithEmailAllowed": true,
"duplicateEmailsAllowed": false,
"resetPasswordAllowed": true,
"editUsernameAllowed": false,
"bruteForceProtected": true,
"clients": [
{
"clientId": "workclub-api",
"name": "Work Club API",
"enabled": true,
"protocol": "openid-connect",
"clientAuthenticatorType": "client-secret",
"secret": "dev-secret-workclub-api-change-in-production",
"redirectUris": [],
"webOrigins": [],
"publicClient": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"standardFlowEnabled": false,
"implicitFlowEnabled": false,
"fullScopeAllowed": true,
"protocolMappers": [
{
"name": "audience-workclub-api",
"protocol": "openid-connect",
"protocolMapper": "oidc-audience-mapper",
"consentRequired": false,
"config": {
"included.client.audience": "workclub-api",
"id.token.claim": "false",
"access.token.claim": "true"
}
},
{
"name": "clubs-claim",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"user.attribute": "clubs",
"claim.name": "clubs",
"jsonType.label": "String",
"id.token.claim": "true",
"access.token.claim": "true",
"userinfo.token.claim": "true"
}
}
]
},
{
"clientId": "workclub-app",
"name": "Work Club Frontend",
"enabled": true,
"protocol": "openid-connect",
"publicClient": true,
"redirectUris": [
"http://localhost:3000/*",
"http://localhost:3001/*",
"http://workclub-frontend/*"
],
"webOrigins": [
"http://localhost:3000",
"http://localhost:3001",
"http://workclub-frontend"
],
"directAccessGrantsEnabled": true,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"fullScopeAllowed": true,
"protocolMappers": [
{
"name": "audience-workclub-api",
"protocol": "openid-connect",
"protocolMapper": "oidc-audience-mapper",
"consentRequired": false,
"config": {
"included.client.audience": "workclub-api",
"id.token.claim": "false",
"access.token.claim": "true"
}
},
{
"name": "clubs-claim",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"user.attribute": "clubs",
"claim.name": "clubs",
"jsonType.label": "String",
"id.token.claim": "true",
"access.token.claim": "true",
"userinfo.token.claim": "true"
}
}
]
}
],
"roles": {
"realm": [
{
"name": "admin",
"description": "Club admin"
},
{
"name": "manager",
"description": "Club manager"
},
{
"name": "member",
"description": "Club member"
},
{
"name": "viewer",
"description": "Club viewer"
}
]
},
"users": [
{
"username": "admin@test.com",
"enabled": true,
"email": "admin@test.com",
"firstName": "Admin",
"lastName": "User",
"credentials": [
{
"type": "password",
"value": "testpass123",
"temporary": false
}
],
"realmRoles": [
"admin"
],
"attributes": {
"clubs": [
"64e05b5e-ef45-81d7-f2e8-3d14bd197383,Admin,3b4afcfa-1352-8fc7-b497-8ab52a0d5fda,Member"
]
}
},
{
"username": "manager@test.com",
"enabled": true,
"email": "manager@test.com",
"firstName": "Manager",
"lastName": "User",
"credentials": [
{
"type": "password",
"value": "testpass123",
"temporary": false
}
],
"realmRoles": [
"manager"
],
"attributes": {
"clubs": [
"64e05b5e-ef45-81d7-f2e8-3d14bd197383,Manager"
]
}
},
{
"username": "member1@test.com",
"enabled": true,
"email": "member1@test.com",
"firstName": "Member",
"lastName": "One",
"credentials": [
{
"type": "password",
"value": "testpass123",
"temporary": false
}
],
"realmRoles": [
"member"
],
"attributes": {
"clubs": [
"64e05b5e-ef45-81d7-f2e8-3d14bd197383,Member,3b4afcfa-1352-8fc7-b497-8ab52a0d5fda,Member"
]
}
},
{
"username": "member2@test.com",
"enabled": true,
"email": "member2@test.com",
"firstName": "Member",
"lastName": "Two",
"credentials": [
{
"type": "password",
"value": "testpass123",
"temporary": false
}
],
"realmRoles": [
"member"
],
"attributes": {
"clubs": [
"64e05b5e-ef45-81d7-f2e8-3d14bd197383,Member"
]
}
},
{
"username": "viewer@test.com",
"enabled": true,
"email": "viewer@test.com",
"firstName": "Viewer",
"lastName": "User",
"credentials": [
{
"type": "password",
"value": "testpass123",
"temporary": false
}
],
"realmRoles": [
"viewer"
],
"attributes": {
"clubs": [
"64e05b5e-ef45-81d7-f2e8-3d14bd197383,Viewer"
]
}
}
]
}

View File

@@ -9,6 +9,10 @@ resources:
- postgres-statefulset.yaml
- postgres-service.yaml
- keycloak-deployment.yaml
- keycloak-realm-import-configmap.yaml
- keycloak-service.yaml
- configmap.yaml
- ingress.yaml
generatorOptions:
disableNameSuffixHash: true

View File

@@ -11,10 +11,10 @@ commonLabels:
environment: development
images:
- name: workclub-api
- name: 192.168.241.13:8080/workclub-api
newName: 192.168.241.13:8080/workclub-api
newTag: dev
- name: workclub-frontend
- name: 192.168.241.13:8080/workclub-frontend
newName: 192.168.241.13:8080/workclub-frontend
newTag: dev