Deployment safety and rollback
A failed image download or build should not remove an application that is already serving customers. The updated Docker executor prepares all images before replacing containers. Portal, REST and MCP deployments use this same executor.
What happens during redeploy #
- Save the previous
compose.yamland.env. - Validate the new Compose configuration, pull service images and build services that declare a build.
- If preparation fails, restore those two files and leave the existing containers in place. The attempt remains failed, with a diagnostic explaining what was preserved or whether restoration failed.
- If preparation succeeds, run
docker compose up -d --no-build --pull never, then the existing startup checks and lifecycle steps.
Automatic recovery of a previous version #
Before changing a healthy existing runtime, the updated agent saves its resolved configuration and the exact image IDs of its containers. A mutable tag such as latest cannot silently change this recovery target. If replacement fails, the new containers crash-loop, Docker health checks miss the startup deadline, or the install hook fails, the agent attempts to restore that version.
Recovery uses local images, preserves volumes and does not repeat installation hooks. The previous containers must pass Docker startup checks before recovery is reported as successful. If an image is missing or recovery fails, the runtime is reported as unknown. First installations and already-broken runtimes have no eligible previous version and retain the existing failure policy.
Using it through portal or MCP #
Use the existing redeploy action, impreza_redeploy_deployment, or POST /v1/platform/deployments/custom/{id}/redeploy. No new arguments are required. On failure, inspect the reported error, correct the image, configuration or build, and retry. Check the application itself before interpreting a failed attempt as an outage.
Open Deployment history on an app card to see its ten most recent deployment attempts. The attempt remains failed when a rollback restores the previous version. The history records that recovery separately. These are historical results, not a live uptime monitor.
Failed attempts include a diagnosis with a likely cause, a description of the recorded evidence and a next action. Supported cases include Git authentication, missing branches, SSH host identity, source retrieval, Compose validation, image pull/build, startup and storage failures. Unknown errors remain unclassified. Evidence is summarized without raw logs or credentials; this is not a live health check or proof of a root cause. A failed attempt can coexist with a successfully restored previous version.
The same history is available as release_history in GET /v1/platform/deployments/{id}. Through MCP, find that read with impreza_api_search and call it using impreza_api_call. History excludes environment variables, snapshot contents and credentials. Older agents have no release or rollback metadata.
Manual release selection #
In Deployment history, managers can choose Restore this release for entries with rollback_supported: true and confirm the interruption. REST clients use POST /v1/platform/deployments/{id}/rollback, manage scope and {"target_version":"rel_...","confirm":true}. The target is a snapshot ID, not a semantic version.
MCP uses impreza_rollback_deployment with deployment_id and target_version. Remote MCP requires its two-call confirm_token flow; local MCP requires confirm: true after customer confirmation. Use agent 0.6.0 or newer and impreza-mcp 0.12.0 or newer for the local connector.
The support flag records a release-v1 agent report, not current availability. An agent downgrade cannot claim success without the matching release and startup receipt. Expired snapshots, unavailable immutable images, changed ports, storage or routing are rejected before replacing containers. The current runtime must pass startup checks so it can be saved as a recovery target if the chosen version fails.
Manual rollback does not rerun hooks or revert database/mutable data. A rejected attempt can set the control-plane status to failed while the containers remain available. Desired control-plane configuration is kept for the next redeploy.
Retention #
The agent keeps five local configuration snapshots per deployment, with owner-only permissions, and tags their images for retention. Uninstall removes those snapshots and releases their private image tags even when app data is retained. The control-plane history can outlive those snapshots, so a historical release ID is not a guarantee that the version can still be restored. External image pruning can remove unused images.
What this does not guarantee #
This is not blue-green deployment, database rollback or crash recovery. Replacement and recovery can interrupt traffic. Builds consume VPS resources. Mutable bind-mounted files, build contexts, databases and lifecycle side effects are not reverted. Custom lifecycle health scripts and HTTPS probes retain their advisory behavior; Docker startup checks do not prove that every business operation works. Control-plane variables remain the desired values for the next attempt.
Reproducing the integration test #
Use an isolated disposable Linux VPS with Docker and Docker Compose. In the DevKit agent module, run IMPREZA_DOCKER_TEST=1 go test -v ./internal/executor -run TestDockerPreparationPreservesRunningDeployment -count=1.
The test deploys an HTTP service, provokes invalid Compose, an unavailable image tag and a failing Dockerfile, and checks that the same container keeps serving the old version. It also verifies restored configuration and persistent data, then successfully builds and deploys the corrected version. Its own containers are removed at cleanup.
Run IMPREZA_DOCKER_TEST=1 go test -v ./internal/executor -run TestDockerAutomaticRollback -count=1 for crash-loop, unhealthy-container, install-hook and replacement failures. It verifies the old HTTP response, immutable image identity, persistent data and literal environment values, then checks missing-image recovery, retention permissions and a successful new deployment.
Exact Git revisions #
Agents 0.6.1 and later honor the full Git commit supplied by a push webhook or manifest build context. If the branch has advanced, the agent fetches and checks out the requested commit. Invalid or unavailable commits fail before container replacement; the current application remains running. When no commit is supplied, deployment follows the selected branch. This does not pin external image tags, dependencies or database state.
Unsupported commands (agent 0.6.2+) #
Agents 0.6.2 and later reject unsupported command kinds with status failed and an explicit diagnostic, instead of reporting simulated success. No operation is performed and the polling loop continues with subsequent commands. Queued agent_upgrade remains unsupported; use the customer-initiated update command. A failed command report does not itself mean the running application is unhealthy.
