Files
portainer/app/react/docker/containers/update/applyContainerUpdate.ts
T
vvzvlad e63d2ffe9b fix(automation): update a single container instead of redeploying its stack
Clicking "Update" on a stack member (and the native auto-update daemon
updating one) redeployed the whole compose stack instead of updating just
that container. Match Watchtower behaviour: always recreate the single
container with a re-pull. The recreate endpoint preserves config + compose
labels, so the container stays part of its project.

Collapse all update surfaces to a single-container recreate and drop the
now-dead stack-aware routing:
- frontend: "Update now" button, list badge and bulk "Update selected" now
  recreate each container individually; remove standalone/stack/external
  routing, the external refusal, the PortainerStackUpdate gate and the
  stack-update confirm dialog.
- daemon: route every outdated candidate through updateStandalone; remove
  updateStack, the stack/external grouping and the stackDeployer dependency.
- add a regression test asserting a Portainer-managed compose-stack member is
  recreated individually, not stack-redeployed.

Behavioural notes: git/external compose containers are now auto-updated too
(were detect-only), and updating a stack member no longer requires
PortainerStackUpdate (same auth as the normal Recreate action).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 15:21:29 +03:00

24 lines
1019 B
TypeScript

import { recreateContainer } from '../containers.service';
import { ContainerUpdateContext } from './types';
/**
* Shared "apply an image update" primitive. Recreates the single container with
* a fresh image pull via the Portainer `containers/{id}/recreate` endpoint. This
* is the single frontend code path behind the "Update now" button and the bulk
* "Update selected" action, guaranteeing both manual flows behave identically.
*
* The recreate endpoint preserves the container's configuration and its compose
* labels, so a recreated stack member stays part of its project — Watchtower-style:
* only this one container is updated, the owning stack is never redeployed and an
* externally-managed compose container is never refused.
*/
export async function applyContainerUpdate(
context: ContainerUpdateContext,
{ pullImage = true }: { pullImage?: boolean } = {}
): Promise<void> {
await recreateContainer(context.environmentId, context.id, pullImage, {
nodeName: context.nodeName,
});
}