3.25 Releases
Convox 3.25 upgrades Kubernetes to 1.35 across all providers. The 3.25.3 release adds additional node pools to GCP Racks with GPU and single-host Cloud TPU support, adds GPU observability on GCP, produces multi-arch App images on Karpenter Racks whose architectures span both amd64 and arm64, makes the BuildArch App parameter effective, adds the cloudwatch_disable and karpenter_build_disruption_budget_nodes rack parameters for AWS, and replaces AWS additional node groups create-first so a replacing configuration change creates the new group before removing the old one. The 3.25.2 release changes the environment drop guard to warn and continue by default, with CONVOX_ENV_DROP_GUARD=strict to restore the blocking behavior. The 3.25.1 release extends per-app instance cost tracking to Azure racks with refreshed price tables for both AWS and Azure, adds Karpenter NodeOverlay support for fractional-GPU instance families and custom price modeling, expands convox run with six new pod customization flags, adds a CLI check that flags builds which would drop environment variables set in the running release, and propagates renewed certificates to app namespaces automatically.
3.25.0
Released: 2026-07-08
Updates
- Upgraded Kubernetes to v1.35 across all providers (EKS, GKE, AKS, DOKS)
- Updated kube-proxy to v1.35.3
- Updated VPC CNI to v1.22.3
- Updated CoreDNS to v1.14.3
- Updated EBS CSI Driver to v1.62.0
- Updated EFS CSI Driver to v3.3.0
- Updated Cluster Autoscaler to v1.35.0
3.25.1
Released: 2026-07-17
Feature Additions
- Added per-app instance cost tracking for Azure racks via the new
cost_tracking_enablerack parameter, enablingconvox costper-service breakdowns, Console cost dashboards, and per-app monthly budget caps withconvox budget set, with automatic spot node pool detection and discounting - Added the
karpenter_node_overlays_configrack parameter for creating Karpenter NodeOverlays, which can advertise extended resources such asnvidia.com/gpuon fractional-GPU instance families (g6f,gr6f) or adjust the prices Karpenter uses in its provisioning cost model - Added six optional
convox runflags for per-invocation pod customization:--termination-grace,--annotations,--labels,--use-service-lifecycle,--node-affinity, and--tolerations - Added a CLI preflight check on
convox build,convox deploy, andconvox testthat stops a build from dropping environment variables set in the running release, with a--forceflag to bypass when the drop is intentional
Updates
- Updated the Karpenter chart from 1.10.0 to 1.13.1, adding Kubernetes 1.35 and 1.36 support. Racks with Karpenter enabled may see a one-time gradual node replacement after this update, depending on whether the chart change alters the NodePool drift hash. Any replacement is graceful and bounded by
karpenter_disruption_budget_nodes(default10%); lower that value before updating for a slower roll - Expanded the AWS and Azure instance price tables to 489 instance types each, covering arm64 Graviton, AMD, network-optimized, storage-optimized, high-memory, and GPU families, with AWS prices refreshed to current us-east-1 Linux on-demand list prices
- Run and timer pods now honor the service's
termination.gracesetting fromconvox.yml, matching the behavior of service deployments
Fixes
- Renewed Let's Encrypt certificates now propagate automatically from the rack namespace to app namespaces, so services referencing a certificate through the
certificate:option always serve the current certificate without requiring a new deploy
3.25.2
Released: 2026-07-21
Updates
- The environment drop guard added in 3.25.1 now warns and continues instead of blocking. When the newest Release drops environment variables that are still set in the running Release,
convox build,convox deploy, andconvox testprint aWARNING:block to stderr naming the dropped variables and the Build proceeds. SetCONVOX_ENV_DROP_GUARD=strictto restore the blocking behavior, which fails with the same error text and the same exit code as 3.25.1.--forcereduces the message to a one-line notice
Notes
- 3.25.2 is a CLI-only release with no Rack-side or Terraform change, so the new behavior arrives by updating the
convoxCLI rather than by runningconvox rack update
3.25.3
Released: 2026-07-26
Feature Additions
- Added the
additional_node_groups_configrack parameter to GCP Racks, using the same JSON format as Azure. Each pool acceptstype,disk,disk_type,capacity_type,min_size,max_size,label,dedicated,tags, andzones. GCP uses regional GKE clusters, somin_sizeandmax_sizeapply per zone rather than as cluster totals - Added GPU node pools on GCP through the
gpu_typeandgpu_countfields ofadditional_node_groups_config, with the GKE-managed NVIDIA driver installed automatically - Added single-host Cloud TPU node pools on GCP through the
tpu_topologyfield ofadditional_node_groups_config, which requires a TPU machine type and creates the pool with a COMPACT placement policy. Services request TPUs withscale.gpu.vendor: google, which maps to thegoogle.com/tpuresource - Added the
gpu_observability_enable,gpu_observability_chart_version, anddcgm_scrape_intervalrack parameters to GCP Racks. Enabling GPU observability installs the NVIDIA DCGM exporter inkube-systemon port 9400 and creates six Grafana dashboard ConfigMaps labeledgrafana_dashboard=1for sidecar discovery. GKE manages the device plugin, sonvidia_device_plugin_enableis not required on GCP. A GCP Rack does not run its own Prometheus; the exporter advertises itself withprometheus.io/*pod annotations for a Prometheus you install. Google Managed Prometheus does not read those annotations; it collects through aPodMonitoringresource you create yourself, and Convox does not create one - GCP nodes in the
g2,a2,a3,a4,a4x, andg4machine families now receive theconvox.io/gpu-vendorlabel. N1 machines can attach GPUs individually and are not detectable by machine type, so they are not labeled - Added the
cloudwatch_disablerack parameter for AWS. When enabled, the Rack stops creating, writing, and reading its own CloudWatch log groups, one per App (/convox/<rack>/<app>) plus the Rack group (/convox/<rack>/system), so the whole-App viewconvox logsandconvox rack logsreturn empty.convox logs --service <name>reads Pod logs directly and is unchanged. Application logs continue to reach CloudWatch through Fluentd unlessfluentd_disableis also set; the two together are the configuration for routing logs entirely elsewhere - Added the
karpenter_build_disruption_budget_nodesrack parameter for AWS, default100%, which sets the disruption budget for theEmptyreason on the Karpenter build NodePool so idle build nodes are reclaimed promptly. Drift and underutilization disruption on that pool remains capped at10% - Added multi-arch App image builds. On an AWS Rack with Karpenter enabled whose workload architectures span both
amd64andarm64(acrosskarpenter_archand thearchfield ofadditional_karpenter_nodepools_config), a Build now produces a multi-arch image index instead of a single-architecture image. Single-architecture Racks are unchanged - The
BuildArchApp parameter is now accepted by the Rack. Setting it pins an App's builds toamd64orarm64, both for the architecture of the produced image and, on Racks with dedicated build nodes enabled, for build pod placement
Updates
- AWS additional node groups and additional build node groups are now created before the old group is destroyed, so the replacement group is ready before the old one is removed. That ordering is not a guarantee that total capacity holds steady throughout a replacing edit, so leave headroom for pods to reschedule. Editing only the
tagsof an additional node group no longer forces a replacement; the tags are updated in place and the launch template change rolls the nodes gracefully - Raising
min_sizeon an AWS additional node group now raises the live EKS desired size, and the maximum size when needed, beforeterraform applyruns, and waits for that scaling update to finish, so the apply no longer fails when the requested minimum exceeds the group's current desired size. The reconcile runs on Rack install, parameter updates, and version updates, and prints aNOTICE:line when it acts - Convox-owned Helm releases left in a
pending-install,pending-upgrade, orpending-rollbackstate by an interrupted apply are now cleared before the nextterraform applyon AWS Racks, so a Rack does not stay stuck behind a stranded release lock. Only Convox releases are considered (aws-lbc,karpenter,karpenter-crd,keda,vpa,dcgm-exporter,nvidia-device-plugin,contour,contour-internal), and only when they have been pending for more than 15 minutes - The
zonesanddisk_typefields ofadditional_node_groups_configare now preserved by the CLI. Previously the CLI re-encoded the parameter through a structure that did not carry them, so those keys were dropped before reaching Terraform even on providers whose modules read them karpenter_disruption_budget_nodes,karpenter_build_disruption_budget_nodes, and thedisruption_budget_nodesfield ofadditional_karpenter_nodepools_confignow reject percentages above 100, so an out-of-range value fails in the CLI instead of atterraform applycapacity_typeinsideadditional_node_groups_configis now validated per provider. AWS acceptsON_DEMANDandSPOT; Azure and the other providers additionally acceptRegularandSpot. Previously all four values were accepted on every provider, and the Azure spellings reached AWS, where they are invalid- Duplicate
idvalues inadditional_node_groups_configandadditional_build_groups_configare now rejected instead of colliding on the Terraformfor_eachkey convox rack params setnow rejects Karpenter instance family lists that cannot satisfy the Rack's architecture, both forkarpenter_instance_familiesagainstkarpenter_archand forkarpenter_build_instance_familiesagainstbuild_node_type. The check runs only when Karpenter is enabled and one of the relevant parameters is being setconvox rack params setnow warns whencloudwatch_disableandfluentd_disableare set inconsistently on AWS: enablingcloudwatch_disablealone still leaves Fluentd shipping application logs to CloudWatch, and enablingfluentd_disablealone still leaves an empty log group per App- Upgraded the build toolchain to Go 1.25.12 and refreshed
golang.org/x/textto 0.39.0,golang.org/x/cryptoto 0.53.0, andgo-jose/go-joseto 4.1.4 - Build source packaging and
.dockerignorematching now usemoby/go-archiveandmoby/patternmatcher, which removes thedocker/docker,moby/buildkit,containerd, andruncdependencies from theconvoxbinary. Build context exclusion now matchesdocker buildfor nested patterns: a.dockerignorethat combines a wildcard directory exclude with a re-include underneath it previously leaked files under the excluded directory into the build context. Patterns containing regex characters such as+,(,), and|are now treated literally. This ships in the CLI, so it applies once you update theconvoxCLI, independent of your Rack version
Fixes
- Fixed
convox rack install metalfailing atterraform validate. The metal router module used thekey_algorithmargument removed in version 4 of the TLS provider and did not declare the provider convox builds exportandconvox builds importnow copy every platform in an image manifest instead of only the default one, so exporting and re-importing a multi-arch Build preserves all architectures- A failed image push during
convox builds importnow fails the import instead of being reported as success
Notes
- Terraform module changes and Rack control-plane images arrive with
convox rack update 3.25.3, but the changes that live in theconvoxbinary do not. The stranded Helm release cleanup and the node group desired-size reconcile, and the new parameter names and validators, arrive only with an updatedconvoxCLI, which for a Console-managed Rack means a Console deploy carrying that CLI version. A pre-3.25.3 CLI rejects the new parameter names outright - A single non-default
karpenter_archstill builds native to the build node, so pairkarpenter_arch=arm64with a Gravitonbuild_node_type - Containerized resource images are not architecture-aware
- The
BuildArchApp parameter was announced in 3.24.1 but was not registered by the Rack until 3.25.3, so on earlier Racks the value was accepted and discarded - GCP additional node pools are new in 3.25.3. Downgrading a GCP Rack below 3.25.3 destroys every additional node pool, because the older cluster module does not declare the resource. Parameter reconciliation also drops the stored value, so a Console-managed Rack has it re-supplied on the way back up while a self-managed Rack has to set it again. See additional_node_groups_config
- Set
gpu_observability_enable=falseand let that apply finish before downgrading a GCP Rack below 3.25.3. Downgrading with the exporter still enabled fails the apply withError: Provider configuration not present, because thehelmprovider is new to the GCP cluster module in this release. See gpu_observability_enable
Thanks to @beastawakens for the three user-submitted GCP pull requests in this release.
See Also
- Releases for the full release history
- cost_tracking_enable for Azure per-app cost tracking
- Cost Tracking and Budget Caps for the cost and budget surface
- karpenter_node_overlays_config for Karpenter NodeOverlays
- Karpenter for Karpenter configuration including NodeOverlays and architecture selection
- run for the new pod customization flags
- build for the environment drop guard
- SSL for certificate renewal propagation
- additional_node_groups_config for GCP node pools, including GPU and Cloud TPU pools
- gpu_observability_enable, gpu_observability_chart_version, and dcgm_scrape_interval for GPU observability on GCP
- Monitoring for the DCGM exporter and Grafana dashboard surface
- cloudwatch_disable and fluentd_disable for routing Rack and App logs away from CloudWatch
- karpenter_build_disruption_budget_nodes and karpenter_disruption_budget_nodes for Karpenter disruption budgets
- additional_node_groups_config and additional_build_groups_config for AWS node groups
- additional_node_groups_config for Azure node pools
- BuildArch for pinning an App's build architecture
- Workload Placement for architecture and node placement strategies