diff --git a/CHANGELOG.md b/CHANGELOG.md index b4ca603..a37ba0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Added configurable deployment strategy support, allowing users to switch between `RollingUpdate` and `Recreate` strategies. [#82](https://github.com/sourcebot-dev/sourcebot-helm-chart/pull/82) + ## [0.1.71] - 2026-04-09 ### Added diff --git a/README.md b/README.md index 7addfc1..bc1dde3 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,37 @@ sourcebot: existingSecretKey: license-key ``` +## Deployment Strategy + +By default, the chart uses a `RollingUpdate` strategy, which creates the new pod before terminating the old one during upgrades. You can customize the rolling update behavior: +```yaml +sourcebot: + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 1 +``` + +On multi-node clusters with `ReadWriteOnce` persistent volumes, the new pod may fail to start if it gets scheduled on a different node than the old pod. To avoid this, you can pin pods to the same node using pod affinity: +```yaml +sourcebot: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: sourcebot + topologyKey: kubernetes.io/hostname +``` + +Alternatively, you can use the `Recreate` strategy, which terminates the old pod before creating the new one. This avoids PVC conflicts but causes brief downtime during upgrades: +```yaml +sourcebot: + strategy: + type: Recreate +``` + ## Persistence Each component has its own persistent volume for storing data across pod restarts. @@ -325,6 +356,31 @@ sourcebot: secretName: sourcebot-tls ``` +### Zero-downtime upgrades on multi-node clusters + +Use a `ReadWriteMany` access mode so the old and new pods can mount the PVC simultaneously during rolling updates. This requires a storage class that supports `ReadWriteMany` (e.g., EFS on AWS, Filestore on GCP, Azure Files): + +```yaml +sourcebot: + persistence: + accessModes: + - ReadWriteMany + storageClass: "efs-sc" # example: AWS EFS storage class +``` + +Alternatively, you can keep `ReadWriteOnce` and use pod affinity to pin pods to the same node: + +```yaml +sourcebot: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: sourcebot + topologyKey: kubernetes.io/hostname +``` + ### Using an existing PVC ```yaml diff --git a/charts/sourcebot/README.md b/charts/sourcebot/README.md index bac9c55..41c3842 100644 --- a/charts/sourcebot/README.md +++ b/charts/sourcebot/README.md @@ -130,6 +130,7 @@ Sourcebot is a self-hosted tool that helps you understand your codebase. | sourcebot.startupProbe.httpGet.path | string | `"/api/health"` | Path to check | | sourcebot.startupProbe.httpGet.port | string | `"http"` | Port to check | | sourcebot.startupProbe.periodSeconds | int | `30` | Initial delay before the first probe | +| sourcebot.strategy | object | `{"type":"RollingUpdate"}` | Deployment strategy configuration | | sourcebot.tolerations | list | `[]` | Set tolerations for pod scheduling See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ | ---------------------------------------------- diff --git a/charts/sourcebot/templates/deployment.yaml b/charts/sourcebot/templates/deployment.yaml index d64da76..7dc6d2b 100644 --- a/charts/sourcebot/templates/deployment.yaml +++ b/charts/sourcebot/templates/deployment.yaml @@ -8,6 +8,10 @@ metadata: {{- include "sourcebot.labels" $ | nindent 4 }} spec: replicas: {{ $.Values.sourcebot.replicaCount }} + {{- with $.Values.sourcebot.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} selector: matchLabels: {{- include "sourcebot.selectorLabels" $ | nindent 6 }} diff --git a/charts/sourcebot/values.schema.json b/charts/sourcebot/values.schema.json index 1fea3fd..d6a5135 100644 --- a/charts/sourcebot/values.schema.json +++ b/charts/sourcebot/values.schema.json @@ -36,6 +36,26 @@ "type": "integer", "minimum": 1 }, + "strategy": { + "type": "object", + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "type": { "type": "string", "const": "RollingUpdate" }, + "rollingUpdate": { "type": "object" } + }, + "required": ["type"] + }, + { + "additionalProperties": false, + "properties": { + "type": { "type": "string", "const": "Recreate" } + }, + "required": ["type"] + } + ] + }, "image": { "type": "object", "properties": { diff --git a/charts/sourcebot/values.yaml b/charts/sourcebot/values.yaml index aa35132..80229cd 100644 --- a/charts/sourcebot/values.yaml +++ b/charts/sourcebot/values.yaml @@ -4,7 +4,7 @@ global: security: # -- Allow insecure images to use bitnami legacy repository. Can be set to false if secure images are being used (Paid). allowInsecureImages: true - + # -- Global Docker registry secret names as an array imagePullSecrets: [] @@ -19,6 +19,10 @@ sourcebot: # -- Set the number of replicas for the deployment replicaCount: 1 + # -- Deployment strategy configuration + strategy: + type: RollingUpdate + # Image configuration image: # -- Container image repository