Skip to content

fix(docker): prevent scheduled Docker cleanup from pruning stopped Traefik container and image (#5698) - #5699

Open
smartcalsystems-sketch wants to merge 4 commits into
Dokploy:canaryfrom
smartcalsystems-sketch:fix/prevent-traefik-cleanup-prune-5698
Open

smartcalsystems-sketch wants to merge 4 commits into
Dokploy:canaryfrom
smartcalsystems-sketch:fix/prevent-traefik-cleanup-prune-5698

Conversation

@smartcalsystems-sketch

@smartcalsystems-sketch smartcalsystems-sketch commented Oct 17, 2026 •

Copy link
Copy Markdown

Fixes #5698

Summary

Prevents scheduled Docker cleanup from unintentionally pruning the stopped Traefik container and image. Adds validation guards to abort cleanup if Traefik restart fails and prevents fallback to local Docker when remote Docker initialization fails.

Changes

  • Update packages/server/src/utils/docker/utils.ts to inspect and verify Traefik status before cleanup
  • Abort cleanup immediately if Traefik restart fails to protect infrastructure
  • Ensure getRemoteDocker throws an explicit error instead of falling back to local Docker when remote server initialization fails
  • Add unit tests for cleanup abort logic and remote docker verification

Testing

  • Ran test suite: pnpm test — all tests pass.

console.log("dokploy-traefik was stopped prior to cleanup; restarting it...");
await container.start();
}
} catch {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Cleanup still deletes Traefik

If container.start() fails because a required mount is missing or a port is occupied, the empty catch lets cleanup continue. Existing containers lack the new label, and createTraefikInstance still creates remote containers without it. Container pruning can therefore delete the stopped dokploy-traefik, followed by its now-unused image.

Protect existing and remotely created containers too, and do not continue destructive cleanup when restarting an unprotected Traefik fails.

Knowledge Base Used: Docker networking and Traefik

Comment on lines +371 to +376
const dockerInstance = await getRemoteDocker(serverId);
const container = dockerInstance.getContainer("dokploy-traefik");
const data = await container.inspect();
if (!data.State.Running) {
console.log("dokploy-traefik was stopped prior to cleanup; restarting it...");
await container.start();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Cleanup starts the wrong proxy

When a remote server loses its SSH key, getRemoteDocker(serverId) returns the local Docker client. The new guard can then restart local dokploy-traefik, while execAsyncRemote rejects the remote cleanup. Deleting an SSH key reaches this state because it sets the server's sshKeyId to null.

Reject a remote cleanup without a usable key before inspecting or starting any container.

Knowledge Base Used: Infrastructure runtime

@smartcalsystems-sketch

Copy link
Copy Markdown
Author

Addressed both P1 architectural review items:

  1. Cleanup Abort Guard: In cleanupAll, if dokploy-traefik inspection or container.start() fails to restart Traefik, cleanup now aborts immediately to guarantee we never prune stopped Traefik infrastructure.
  2. Strict Remote Docker Validation: Updated getRemoteDocker with strict: true when a serverId is specified, throwing an explicit error when SSH keys are missing instead of silently falling back to the host Docker daemon.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduled Docker cleanup prunes a stopped dokploy-traefik container and its image, so a Traefik that failed at boot can't be restarted

1 participant