global: imagePullSecrets: [] image: # When non-empty, overrides every components.*.image.tag (see _helpers.tpl). Production/staging: pin to released # semver (e.g. 3.3.13) and use pullPolicy Always or bump tag each release — do not rely on :latest + IfNotPresent alone. # tag: "latest" # pullPolicy: IfNotPresent # Optional rollout tuning (see NOTES): pin a fixed pod annotation or add a nonce for frozen/git-rendered manifests. # rollme: "" # rolloutNonce: "" nameOverride: "" fullnameOverride: "" # Server ConfigMap (appsettings.json); referenced from components.server.configMapFile when tpl: true certsServerConfig: allowedHosts: "*" logging: default: Information microsoftAspNetCore: Warning configuration: certsUIEngineConfiguration: # Add-only column sync after FluentMigrator (ALTER ADD IF NOT EXISTS; never DROP). Set false to disable. autoSyncSchema: true admin: username: "admin" jwt: issuer: "" audience: "" expiresIn: 15 refreshTokenExpiresIn: 180 twoFactor: label: "CertsUI" issuer: "MaksIT.CertsUI" algorithm: "" digits: 6 period: 30 timeTolerance: 1 agent: agentHostname: "" agentPort: 5000 serviceToReload: haproxy production: "https://acme-v02.api.letsencrypt.org/directory" staging: "https://acme-staging-v02.api.letsencrypt.org/directory" # Server Secret (appsecrets.json); referenced from components.server.secretsFile when tpl: true # Configuration:CertsUIEngineConfiguration:ConnectionString — same structural role as MaksIT.Vault VaultEngineConfiguration:ConnectionString. certsServerSecrets: authSecret: changeme-generate-a-long-random-string authPepper: "" agentKey: "" adminPassword: changeme-generate-a-strong-password certsUIEngineConfiguration: connectionString: "" # Client ConfigMap (config.js); referenced when tpl: true. Prefer a relative URL (/api) when UI and API share one ingress origin. certsClientRuntime: apiUrl: "/api" components: # Per-component replica count (minimum 1). Server is stateless for app data (PostgreSQL); scale freely. server: replicaCount: 1 image: registry: cr.maks-it.com repository: certs-ui/server tag: latest pullPolicy: IfNotPresent env: - name: ASPNETCORE_ENVIRONMENT value: Production - name: ASPNETCORE_HTTP_PORTS value: "5000" - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name service: enabled: true type: ClusterIP port: 5000 targetPort: 5000 # Stateless default (no ClientIP). Set enabled: true only if you want sticky sessions at the Service layer. sessionAffinity: enabled: false clientIPTimeoutSeconds: 10800 # Give kube-proxy / ingress time to stop sending new connections before SIGKILL (pairs with preStop). terminationGracePeriodSeconds: 90 lifecycle: preStop: exec: command: ["/bin/sh", "-c", "sleep 5"] persistence: storageClass: local-path # Optional extra mounts (e.g. emptyDir scratch). ACME sessions and HTTP-01 tokens use PostgreSQL, not /acme. volumes: [] secretsFile: key: appsecrets.json mountPath: /secrets/appsecrets.json tpl: true keep: true existingSecret: "" content: | { "Configuration": { "CertsUIEngineConfiguration": { "ConnectionString": {{ .Values.certsServerSecrets.certsUIEngineConfiguration.connectionString | toJson }}, "Admin": { "Password": {{ .Values.certsServerSecrets.adminPassword | toJson }} }, "JwtSettingsConfiguration": { "JwtSecret": {{ .Values.certsServerSecrets.authSecret | toJson }}, "PasswordPepper": {{ .Values.certsServerSecrets.authPepper | toJson }} }, "Agent": { "AgentKey": {{ .Values.certsServerSecrets.agentKey | toJson }} } } } } configMapFile: key: appsettings.json mountPath: /configMap/appsettings.json tpl: true keep: true existingConfigMap: "" content: | { "Logging": { "LogLevel": { "Default": {{ .Values.certsServerConfig.logging.default | toJson }}, "Microsoft.AspNetCore": {{ .Values.certsServerConfig.logging.microsoftAspNetCore | toJson }} } }, "AllowedHosts": {{ .Values.certsServerConfig.allowedHosts | toJson }}, "Configuration": { "CertsUIEngineConfiguration": { "AutoSyncSchema": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.autoSyncSchema }}, "Admin": { "Username": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.admin.username | toJson }}, "Password": "" }, "JwtSettingsConfiguration": { "JwtSecret": "", "Issuer": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.jwt.issuer | toJson }}, "Audience": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.jwt.audience | toJson }}, "ExpiresIn": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.jwt.expiresIn }}, "RefreshTokenExpiresIn": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.jwt.refreshTokenExpiresIn }}, "PasswordPepper": "" }, "TwoFactorSettingsConfiguration": { "Label": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.twoFactor.label | toJson }}, "Issuer": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.twoFactor.issuer | toJson }}, "Algorithm": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.twoFactor.algorithm | toJson }}, "Digits": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.twoFactor.digits }}, "Period": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.twoFactor.period }}, "TimeTolerance": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.twoFactor.timeTolerance }} }, "Agent": { "AgentHostname": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.agent.agentHostname | toJson }}, "AgentPort": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.agent.agentPort }}, "AgentKey": "", "ServiceToReload": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.agent.serviceToReload | toJson }} }, "Production": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.production | toJson }}, "Staging": {{ .Values.certsServerConfig.configuration.certsUIEngineConfiguration.staging | toJson }} } } } livenessProbe: httpGet: path: /health/live port: http initialDelaySeconds: 20 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /health/ready port: http initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 5 failureThreshold: 3 client: replicaCount: 1 image: registry: cr.maks-it.com repository: certs-ui/client tag: latest pullPolicy: IfNotPresent service: enabled: true type: ClusterIP port: 5173 targetPort: 5173 configMapFile: key: config.js mountPath: /app/dist/config.js tpl: true keep: true existingConfigMap: "" content: | window.RUNTIME_CONFIG = { API_URL: {{ .Values.certsClientRuntime.apiUrl | toJson }} }; livenessProbe: tcpSocket: port: http initialDelaySeconds: 10 periodSeconds: 10 readinessProbe: tcpSocket: port: http initialDelaySeconds: 5 periodSeconds: 5 resources: {} reverseproxy: replicaCount: 1 # kubernetesUpstreamHosts: when true (default), Helm adds YARP destination env on the reverseproxy pod (see templates/deployments.yaml). # Example: helm install acme ./chart → fullname acme-certs-ui, server port 5000 / client port 5173 (defaults below) yields: # ReverseProxy__Clusters__webapiCluster__Destinations__d1__Address=http://acme-certs-ui-server:5000/ # ReverseProxy__Clusters__webuiCluster__Destinations__d1__Address=http://acme-certs-ui-client:5173/ # Ports mirror components.server.service.port and components.client.service.port. Docker Compose: set the same two env keys in # docker-compose.override.yml to http://server:5000/ and http://client:5173/ (Compose service names), not Helm. # false: Helm does not inject those env vars — supply addresses yourself (custom Service names, mesh, external hosts). kubernetesUpstreamHosts: true image: registry: cr.maks-it.com repository: certs-ui/reverseproxy tag: latest pullPolicy: IfNotPresent env: - name: ASPNETCORE_ENVIRONMENT value: Production - name: ASPNETCORE_HTTP_PORTS value: "8080" service: enabled: true type: ClusterIP port: 8080 targetPort: 8080 livenessProbe: tcpSocket: port: http initialDelaySeconds: 15 periodSeconds: 10 readinessProbe: tcpSocket: port: http initialDelaySeconds: 5 periodSeconds: 5 resources: {}