# services/jenkins/helmrelease.yaml apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease metadata: name: jenkins namespace: jenkins spec: interval: 30m chart: spec: chart: jenkins version: 5.8.114 sourceRef: kind: HelmRepository name: jenkins namespace: flux-system install: timeout: 15m remediation: retries: 3 upgrade: timeout: 15m remediation: retries: 3 remediateLastFailure: true cleanupOnFail: true rollback: timeout: 15m values: controller: nodeSelector: kubernetes.io/arch: arm64 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: ["arm64"] preferredDuringSchedulingIgnoredDuringExecution: - weight: 90 preference: matchExpressions: - key: hardware operator: In values: ["rpi5"] - weight: 50 preference: matchExpressions: - key: hardware operator: In values: ["rpi4"] resources: requests: cpu: 750m memory: 1.5Gi limits: cpu: 1500m memory: 3Gi javaOpts: "-Xms512m -Xmx2048m" startupProbe: httpGet: path: /login port: http initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 20 jenkinsUrl: https://ci.bstein.dev ingress: enabled: true hostName: ci.bstein.dev ingressClassName: traefik annotations: cert-manager.io/cluster-issuer: letsencrypt traefik.ingress.kubernetes.io/router.entrypoints: websecure tls: - secretName: jenkins-tls hosts: - ci.bstein.dev hostAliases: - ip: 38.28.125.112 hostnames: - sso.bstein.dev installPlugins: - kubernetes - workflow-aggregator - git - pipeline-utility-steps - configuration-as-code - oic-auth - job-dsl - configuration-as-code-support - simple-theme-plugin containerEnv: - name: ENABLE_OIDC value: "true" - name: OIDC_ISSUER value: "https://sso.bstein.dev/realms/atlas" - name: OIDC_CLIENT_ID valueFrom: secretKeyRef: name: jenkins-oidc key: clientId - name: OIDC_CLIENT_SECRET valueFrom: secretKeyRef: name: jenkins-oidc key: clientSecret - name: OIDC_AUTH_URL valueFrom: secretKeyRef: name: jenkins-oidc key: authorizationUrl - name: OIDC_TOKEN_URL valueFrom: secretKeyRef: name: jenkins-oidc key: tokenUrl - name: OIDC_USERINFO_URL valueFrom: secretKeyRef: name: jenkins-oidc key: userInfoUrl - name: OIDC_LOGOUT_URL valueFrom: secretKeyRef: name: jenkins-oidc key: logoutUrl - name: GITEA_PAT_USERNAME valueFrom: secretKeyRef: name: gitea-pat key: username - name: GITEA_PAT_TOKEN valueFrom: secretKeyRef: name: gitea-pat key: token customInitContainers: - name: clean-jcasc-stale image: alpine:3.20 imagePullPolicy: IfNotPresent command: - sh - -c - | set -euo pipefail rm -f /var/jenkins_home/casc_configs/* || true securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 volumeMounts: - name: jenkins-home mountPath: /var/jenkins_home initScripts: theme.groovy: | import jenkins.model.Jenkins import org.codefirst.SimpleThemeDecorator def instance = Jenkins.get() def decorators = instance.getExtensionList(SimpleThemeDecorator.class) if (decorators?.size() > 0) { def theme = decorators[0] theme.setCssUrl("https://jenkins-contrib-themes.github.io/jenkins-material-theme/dist/material-ocean.css") theme.setJsUrl("") theme.setTheme("") instance.save() println("Applied simple-theme-plugin dark theme") } else { println("simple-theme-plugin not installed; skipping theme configuration") } JCasC: defaultConfig: false securityRealm: | oic: clientId: "${OIDC_CLIENT_ID}" clientSecret: "${OIDC_CLIENT_SECRET}" tokenServerUrl: "${OIDC_TOKEN_URL}" authorizationServerUrl: "${OIDC_AUTH_URL}" userInfoUrl: "${OIDC_USERINFO_URL}" logoutFromOpenIdProvider: true postLogoutRedirectUrl: "https://ci.bstein.dev" scopes: "openid profile email" rootURLFromRequest: true userNameField: "preferred_username" fullNameFieldName: "name" emailFieldName: "email" groupsFieldName: "groups" escapeHatchEnabled: false maxClockSkew: 120 authorizationStrategy: | loggedInUsersCanDoAnything: allowAnonymousRead: false configScripts: base.yaml: | jenkins: disableRememberMe: false mode: NORMAL numExecutors: 0 labelString: "" projectNamingStrategy: "standard" markupFormatter: plainText clouds: - kubernetes: containerCapStr: "10" defaultsProviderTemplate: "" connectTimeout: "5" readTimeout: "15" jenkinsUrl: "http://jenkins.jenkins.svc.cluster.local:8080" jenkinsTunnel: "jenkins-agent.jenkins.svc.cluster.local:50000" skipTlsVerify: false usageRestricted: false maxRequestsPerHostStr: "32" retentionTimeout: "5" waitForPodSec: "600" name: "kubernetes" namespace: "jenkins" restrictedPssSecurityContext: false serverUrl: "https://kubernetes.default" credentialsId: "" podLabels: - key: "jenkins/jenkins-jenkins-agent" value: "true" templates: - name: "default" namespace: "jenkins" id: a23c9bbcd21e360a77d51b426f05bd7b8032d8fdedd6ffb97c436883ce6c5ffa containers: - name: "jnlp" alwaysPullImage: false args: "^${computer.jnlpmac} ^${computer.name}" envVars: - envVar: key: "JENKINS_URL" value: "http://jenkins.jenkins.svc.cluster.local:8080/" image: "jenkins/inbound-agent:3355.v388858a_47b_33-3" privileged: "false" resourceLimitCpu: 512m resourceLimitMemory: 512Mi resourceRequestCpu: 512m resourceRequestMemory: 512Mi ttyEnabled: false workingDir: /home/jenkins/agent idleMinutes: 0 instanceCap: 2147483647 label: "jenkins-jenkins-agent " nodeUsageMode: "NORMAL" podRetention: Never showRawYaml: true serviceAccount: "default" slaveConnectTimeoutStr: "100" yamlMergeStrategy: override inheritYamlMergeStrategy: false slaveAgentPort: 50000 crumbIssuer: standard: excludeClientIPFromCrumb: true security: apiToken: creationOfLegacyTokenEnabled: false tokenGenerationOnCreationEnabled: false usageStatisticsEnabled: true creds.yaml: | credentials: system: domainCredentials: - credentials: - usernamePassword: scope: GLOBAL id: gitea-pat username: "${GITEA_PAT_USERNAME}" password: "${GITEA_PAT_TOKEN}" description: "Gitea PAT for pipelines" jobs.yaml: | jobs: - script: | pipelineJob('harbor-arm-build') { triggers { scm('H/5 * * * *') } definition { cpsScm { scm { git { remote { url('https://scm.bstein.dev/bstein/harbor-arm-build.git') credentials('gitea-pat') } branches('*/master') } } } } } pipelineJob('ci-demo') { triggers { scm('H/1 * * * *') } definition { cpsScm { scm { git { remote { url('https://scm.bstein.dev/bstein/ci-demo.git') credentials('gitea-pat') } branches('*/master') } } scriptPath('Jenkinsfile') } } } pipelineJob('bstein-dev-home') { triggers { scm('H/2 * * * *') } definition { cpsScm { scm { git { remote { url('https://scm.bstein.dev/bstein/bstein-dev-home.git') credentials('gitea-pat') } branches('*/master') } } scriptPath('Jenkinsfile') } } } persistence: enabled: true storageClass: astreae size: 50Gi serviceAccount: create: true