Skip to content

Recipe: Interpret a drift warning

Use this recipe when a POST /external-deploy/sync result contains:

{
"status": "drift_recovered"
}

in one or more entries of the results[] array.

drift_recovered is set when Reoclo receives a sync call for an application it has no signature record for, and a live inspection of the server shows that the container is already running the declared image and already attached to the reoclo-proxy network.

In other words: the deploy already happened — Reoclo just learned about it. The container is correct. The proxy routes and a new signature record have been written. The Caddy reconciler has been triggered.

The recovered_from_drift flag on the resulting signature record is true, which lets operators distinguish these events from ordinary deploys in audit views.

Common causes:

  • A workflow ran docker run or docker compose up directly without calling the Reoclo sync action.
  • An infrastructure recovery event (e.g. a server reboot or database restore) left containers intact but cleared signature records.
  • A first sync after the external-deploy feature was enabled on a server that was already running containers.

If you surfaced this status to the user, explain:

The sync result includes status: drift_recovered for one or more applications. Reoclo inspected the live container and found it was already running the correct image on the reoclo-proxy network. Your routes are up to date. No action is needed.

You may want to check whether the workflow that deployed the container also called the Reoclo sync step — if not, that is why the sync call was the first time Reoclo saw this deployment.

  • Do not re-run the sync.
  • Do not redeploy the container or change the Compose file.
  • Do not modify the proxy route configuration manually.
  • Do not file a bug report on behalf of the user unless the site is also returning errors.
  • Do not attempt to diagnose the source of the drift unless the user specifically requests it and the site is not working.
  • Record the event in your context so you can reference it if the user asks later.
  • If the user asks why it happened, walk through the common causes listed above.
  • Suggest the user check whether the workflow integration that deployed the container included the Reoclo sync step. If it did not, that is the gap to fix.
  • If drift_recovered appears repeatedly for the same application, it may indicate the sync step is missing from a regular deploy path — worth mentioning proactively.

In addition to the drift_recovered sync result, Reoclo also emits tenant notifications when the background drift scan (runs every ~30 minutes) detects that a live container has diverged from its recorded deployment signature.

These notifications fire on state transitions only. Seeing the same drift status across multiple scan ticks does NOT produce repeated notifications.

EventNotification
Any non-ok drift first detected”External deploy drift detected” (WARNING severity)
Container returns to matching state”External deploy drift resolved” (INFO severity)
Runner unreachable (UNREACHABLE)No notification emitted (transient)

What agents should do with drift notifications

Section titled “What agents should do with drift notifications”

Do NOT automatically redeploy. The notification tells you the container has drifted — it does not tell you why. Possible causes include:

  • A deliberate manual change by an operator (docker stop, image swap for a hotfix, maintenance window).
  • A container crash or OOM kill that the workflow has not yet re-triggered.
  • A rollback performed outside of the normal deploy path.
  • A failed deploy that left the container in a partial state.

Automatically redeploying in any of these cases could overwrite intentional changes, restart a container mid-maintenance, or mask an underlying failure.

What agents should do instead:

  1. Surface the notification to the user in plain language: which container, which server, what the drift type means (see the table in Troubleshooting — Drift notifications).
  2. Ask the user whether the change was intentional.
  3. If intentional: suggest calling POST /external-deploy/sync with force: true to update the recorded signature to match the running state.
  4. If unintentional: help the user decide whether to redeploy via the normal workflow or investigate the root cause first.
  5. If the status is container_missing: direct the user to check container logs and server health before attempting a redeploy.
  • Do not call POST /external-deploy/sync automatically on behalf of the user.
  • Do not interpret DRIFT_RESOLVED as requiring any action — it is informational only.
  • Do not file a bug report unless the site is actually returning errors to end users.