Updates
Releases come in two shapes; your deployment tells them apart by itself.
| Shape | What it is | How it applies |
|---|---|---|
| Soft | Image-only: a pull and a container restart, confirmed locally against the release manifest | Automatically where an applier exists (something that can pull images and restart services), typically within ~15 minutes of a release |
| Hard | A new required env var, or a release the vendor flagged breaking | Never automatic: the console shows Update needs an operator naming exactly what to set (names only; values never leave the deployment) |
| Platform | Soft updates |
|---|---|
| Docker / Compose | Applied automatically, through the bundled updater. |
| AWS (CloudFormation quicklaunch) | Applied automatically via the stack's updater Lambda. EnableAutoUpdate=false removes the applier. |
| Kubernetes (Helm) | Off by default (images stay pinned). One value, image.tag: policy-stable, turns on a moving channel plus the chart's nightly roll. That roll is unconditional, so it applies hard releases too (they stall rather than start). Automatic image updates. |
| Railway | Change the app image references to the approved release, then redeploy. |
Auto-apply is on by default wherever an applier exists. Toggle it in the console's sidebar
Updates panel, or via the API (capability update:run):
{ "autoSoftUpdates": false }
PUT /admin/update/settings also accepts autoFallback (default true), Connect’s automatic direct fallback. Send either setting or both.
Start a soft update now
Sign in with the admin CLI, then use the gateway:
anyray-connect admin api POST settings/updates/run --json
anyray-connect admin api GET settings/updates --json
This uses the existing HTTP applier on Compose or AWS quicklaunch. It works even
when autoSoftUpdates is off. A newer release must pass the local manifest preflight.
The request accepts no target, image or URL override.
202 returns target and attemptId. It acknowledges an attempt, not an installed
release. updateAttempt on the GET survives gateway restarts; pending means no
outcome was confirmed. Shared coordination suppresses repeat attempts for six hours
when the applier may have received the request. Failure before connecting returns 502
with an unreachable attempt. GET keeps that attempt and its ID visible until a
retry claims a new ID. Only a request that never reached the applier permits
immediate retry. An HTTP failure such as 500 also reads unreachable and
keeps the six-hour hold, for manual and automatic attempts.
The request ends within ten seconds. If that deadline expires before dispatch,
it returns 503; GET reports unreachable once the store returns. A timeout or
disconnect after dispatch stays pending; read status before retrying.
A hard or unknown preflight returns 409; unavailable shared coordination returns 503.
Poll the GET's version and verify every app replica through your platform.
One responding gateway does not prove the whole deployment has converged.
Watchtower ignores the target body, so a pinned image can leave the version unchanged.
Without an HTTP applier, the POST returns 501 update_applier_unavailable with
platform guidance. On Railway, change the app image references to the approved
release and redeploy, preserving variables and volumes. On Helm, invoke a Job
from the existing updater CronJob when rendered, or upgrade the chart and image
values. On ECS without the quicklaunch Lambda, use your deployment pipeline.
Restarting an unchanged immutable image pin cannot upgrade it.
Schema and data migrations
No manual migration step: the gateway self-migrates its schema on boot, and migrations are
expand/contract-safe, so rolling updates and rollbacks keep working. Durable state (spend
history, client keys, provider keys, caps, aliases, routing config) lives in Postgres, not the
containers; nobody re-runs anyray-connect after an upgrade. To roll back, pin the previous
ANYRAY_IMAGE_TAG and re-pull (note your version before updating; latest records no prior
one).