# Upgrading

> Move from one minor version to another: validate the configuration with the new image before rolling out, then upgrade gateway and console.

Guide - Since version 1.0.0 - Flexway v1.7.1 - https://flexway.io/en/docs/operations-upgrade/

> Operations guide: configure, deploy and observe the gateway. What the feature does, product side: [product guide](https://flexway.io/en/docs/product-overview/); calling it: [developer guide](https://flexway.io/en/docs/developer-overview/).

Since `1.0.0`, a minor version (`1.x.0`) is **additive**: what is written for `1.0.0` reads in `1.x`
without an edit, a new key has a default that reproduces the previous behaviour, and a feature is
withdrawn only after a deprecation announced **two** minors ahead. Six surfaces are held by this
promise: the `flexway.yaml` schema, the `x-flexway-*` extensions, the policy catalogue, the metric
names and dimensions, the RFC 9457 error codes and the admin contract. A major version (`2.0.0`) is the
only one that may break them.

## Steps

1. Read the release notes of **every** minor between yours and the target: what is new, deprecations,
   fixes.

2. Validate the running configuration with the **new** version's image, before any rollout - the
   validator is the start's loader:

   ```bash
   docker run --rm -v "$PWD:/etc/flexway:ro" ghcr.io/flexwiz/flexway:<new-version> validate -v
   ```

3. Upgrade the gateway. In Kubernetes, the chart carries the same version as the image:

   ```bash
   helm upgrade orders oci://ghcr.io/flexwiz/charts/flexway --version <new-version> -f values.yaml
   ```

   Each replaced replica first leaves the rotation (`/readyz` turns `503`), then drains the requests in
   flight (`server.shutdown.drain`, 20 s by default). Outside Kubernetes: replace the binary or the
   image, then restart - `SIGTERM` drains the same way.

4. Upgrade the console, when deployed - its accounts are kept:

   ```bash
   helm upgrade console oci://ghcr.io/flexwiz/charts/flexway-console --version <new-version> -f console-values.yaml
   ```

5. Only then, write into the configuration the keys or extensions the new version brings.

## Verify

```bash
curl -s http://localhost:9090/config | jq '.build'       # {"version":"v<new-version>","commit":"..."}
curl -s http://localhost:9090/readyz                     # {"status":"ready","operations":...}
```

Every replica announces the new version in `build`; the foot of the console shows the console's
version and the gateway's.

## Good to know

| The loader refuses | Why it matters for an upgrade |
| --- | --- |
| An unknown `flexway.yaml` key | Decoding is strict: a key brought by a newer version is refused by an older one - which is what step 2 catches the other way round |
| A `version` other than `1` | The value is checked, never assumed |
| An `x-flexway-*` extension unknown, not served yet, or written where it is not read | An extension planned for a future version is refused with the version that brings it |

> [!WARNING]
> **Rolling back**: `helm rollback`, or the previous image. If the configuration already uses a key or
> an extension of the new version, the old one refuses it: go back to the previous configuration first.
> A configuration refused at reload never replaces the one serving; at start, it prevents the start.

> [!NOTE]
> The settings read at start only ([list](https://flexway.io/en/docs/operations-live-config/)) apply naturally: a new image is
> a restart. During the console's rolling update, a replica of the old version keeps the data it does
> not know untouched; a rollback leaves it in place, ignored.

`0.x` versions promised nothing: moving from a `0.x` to `1.0.0` takes a review of the configuration
against the [configuration reference](https://flexway.io/en/docs/operations-configuration-reference/).
