Skip to content

feat: add HPA & PodDisruptionBudget support - #202

Merged
juanpicado merged 5 commits into
verdaccio:masterfrom
corticph:fix-replicacount-rebased
Aug 26, 2026
Merged

juanpicado merged 5 commits into
verdaccio:masterfrom
corticph:fix-replicacount-rebased

Conversation

@pyhp2017

@pyhp2017 pyhp2017 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Closes #192

Summary

When autoscaling/HPA is used together with a GitOps controller (e.g. ArgoCD), the chart and the HPA fight over the replica count because the StatefulSet/Deployment template hardcodes replicas: 1. This PR fixes that and adds HPA + PDB support.

Problem

  • The StatefulSet template hardcodes replicas: 1 when replicaCountEnabled is false.
  • An HPA scales the workload up, but the GitOps controller (ArgoCD) resets it back to 1 from the rendered manifest, causing an endless reconcile loop.
  • No built-in support for a HorizontalPodAutoscaler or PodDisruptionBudget.

Changes

  1. feat(verdaccio): add HPA and stop hardcoding replicas when autoscaling

    • New autoscaling block in values.yaml and an hpa.yaml template (autoscaling/v2) targeting either the Deployment or StatefulSet.
    • When autoscaling.enabled: true, the replicas field is omitted from the Deployment/StatefulSet so the HPA owns the replica count (fixes the ArgoCD <-> HPA loop).
  2. feat(verdaccio): add optional PodDisruptionBudget

    • New pdb.yaml template (policy/v1) gated on podDisruptionBudget.enabled, with mutually-exclusive minAvailable / maxUnavailable. Defaults to maxUnavailable: 1.
  3. refactor(verdaccio): extract workload kind into helper template

    • New reusable verdaccio.workloadKind helper (Deployment vs StatefulSet) used by the HPA scaleTargetRef.

New values

autoscaling:
  enabled: false
  minReplicas: 2
  maxReplicas: 5
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80
  behavior: {}

podDisruptionBudget:
  enabled: false
  # minAvailable: 1
  maxUnavailable: 1

Testing

  • helm lint passes
  • Verified template rendering across 8 scenarios:
    • Default (no autoscaling, no PDB) -- replicas: 1 present, no HPA/PDB
    • autoscaling.enabled=true (Deployment) -- no replicas field, HPA targets Deployment
    • autoscaling.enabled=true + type=statefulset -- no replicas field, HPA targets StatefulSet
    • podDisruptionBudget.enabled=true -- PDB with maxUnavailable: 1
    • Both enabled -- PDB + HPA + no replicas field
    • PDB with minAvailable=2 -- PDB renders minAvailable: 2, no maxUnavailable
    • HPA with memory metric + behavior -- both CPU + memory metrics, behavior block present
    • StatefulSet + autoscaling + PDB -- all render correctly

Chart version

Bumped 4.33.1 -> 4.34.0 (new features warrant a minor bump).

Rebased on latest master (appVersion 6.9.2).

When autoscaling is enabled, omit the replicas field from the Deployment
and StatefulSet so the HorizontalPodAutoscaler owns the replica count.
Previously the StatefulSet hardcoded replicas: 1 (when replicaCountEnabled
was false), which clashed with an HPA: a GitOps controller (ArgoCD) would
reset the StatefulSet to 1 while the HPA scaled it back up, causing an
endless reconcile loop.

Adds a new autoscaling block in values.yaml and an hpa.yaml template
(autoscaling/v2) targeting either the Deployment or StatefulSet.

Fixes PLA-5974
Adds a policy/v1 PodDisruptionBudget template gated on
podDisruptionBudget.enabled, with mutually-exclusive minAvailable/
maxUnavailable. Useful alongside multi-replica/HPA setups to keep pods
available during voluntary disruptions (node drains, upgrades).

Refs PLA-5974
Replace the inline if/else for the HPA scaleTargetRef kind with a
reusable verdaccio.workloadKind helper.
Address PR review: default the PDB to maxUnavailable: 1 instead of
minAvailable: 1.
@pyhp2017 pyhp2017 changed the title feat: add HPA & PodDisruptionBudget support; fix hardcoded replicas conflicting with HPA/GitOps feat: add HPA & PodDisruptionBudget support Aug 7, 2026
@pyhp2017

Copy link
Copy Markdown
Contributor Author

@juanpicado can i please have a review on this?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class autoscaling and disruption-budget support to the Verdaccio Helm chart, and prevents GitOps controllers from continuously resetting replica counts when an HPA is enabled.

Changes:

  • Add autoscaling values plus an autoscaling/v2 (or equivalent) HorizontalPodAutoscaler template targeting Deployment/StatefulSet.
  • Add podDisruptionBudget values plus a PodDisruptionBudget template.
  • Refactor workload kind selection into a helper and omit replicas in workload templates when autoscaling is enabled.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Documents new autoscaling.* and podDisruptionBudget.* values.
charts/verdaccio/values.yaml Adds default config blocks for HPA and PDB.
charts/verdaccio/templates/deployment.yaml Omits spec.replicas when autoscaling is enabled so HPA owns scaling.
charts/verdaccio/templates/statefulset.yaml Same as deployment: omit spec.replicas when autoscaling is enabled.
charts/verdaccio/templates/hpa.yaml Introduces HPA resource targeting the selected workload kind.
charts/verdaccio/templates/pdb.yaml Introduces optional PDB resource for voluntary disruption protection.
charts/verdaccio/templates/_helpers.tpl Adds verdaccio.workloadKind helper for HPA target kind.
charts/verdaccio/Chart.yaml Bumps chart version to 4.34.0.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread charts/verdaccio/templates/hpa.yaml
Comment thread charts/verdaccio/templates/pdb.yaml
Comment thread charts/verdaccio/templates/pdb.yaml
Comment thread charts/verdaccio/templates/hpa.yaml
- hpa: fail on Kubernetes < 1.23 (autoscaling/v2) and when no CPU/memory target is configured
- pdb: select policy/v1 vs policy/v1beta1 by cluster version, fail when both or neither of minAvailable/maxUnavailable are set
@pyhp2017

Copy link
Copy Markdown
Contributor Author

@juanpicado i addressed copilot comments

@juanpicado
juanpicado self-requested a review August 18, 2026 11:14
@juanpicado
juanpicado merged commit 83a2e39 into verdaccio:master Aug 26, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add HPA & PodDisruptionBudget support; fix hardcoded replicas conflicting with HPA/GitOps (unable to open PR)

3 participants