Skip to content

fix(backups): leave the .git history of cloned checkouts out of web-server backups - #5734

Closed
Gourav224 wants to merge 3 commits into
Dokploy:canaryfrom
Gourav224:fix/web-server-backup-skip-git-checkouts
Closed

Gourav224 wants to merge 3 commits into
Dokploy:canaryfrom
Gourav224:fix/web-server-backup-skip-git-checkouts

Conversation

@Gourav224

@Gourav224 Gourav224 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

What is this PR about?

The web-server backup rsyncs all of BASE_PATH, including the git checkouts Dokploy clones at deploy time under applications/*/code/ and compose/*/code/ (#5731). Their .git history can be huge: in the report it was 1.5 GB of the 3 GB a single service added.

This PR excludes applications/*/code/.git/ and compose/*/code/.git/ from the backup. That history is never needed after a restore. Every deploy runs rm -rf <code> and clones again (the git providers and raw compose all do this).

Why not exclude all of */code/, as the issue suggests? An earlier version of this PR did, and review showed it isn't safe:

  • A compose bind mount such as ./data:/var/lib/postgresql/data resolves inside compose/<app>/code/, so code/ can hold a running service's live data.
  • restoreWebServerBackup runs rm -rf "$BASE_PATH/"* before copying the archive back. A same-server restore would delete that data and never bring it back.
  • Drop (zip upload) apps keep their only copy of the code in applications/<app>/code/.

The working tree therefore stays in the backup, and only .git is skipped. That still removes the largest reproducible part. The tracked files themselves (1.7 GB in the report) can't be told apart from bind-mounted data without parsing every compose file's volumes, so they're out of scope here.

Checklist

Before submitting this PR, please make sure that:

  • You created a dedicated branch based on the canary branch.
  • You have read the suggestions in the CONTRIBUTING.md file https://github.com/Dokploy/dokploy/blob/canary/CONTRIBUTING.md#pull-request
  • You have tested this PR in your local instance. If you have not tested it yet, please do so before submitting. This helps avoid wasting maintainers' time reviewing code that has not been verified by you.

Testing: the new __test__/backups/web-server-filters.test.ts runs the real rsync with the excludes on a sample BASE_PATH. Both .git directories are skipped. The application working tree, a drop app's code, a compose code/data bind mount, files/ and traefik/ are all kept. It is skipped if rsync isn't installed. All __test__/backups tests and tsc --noEmit for packages/server pass.

Issues related (if applicable)

Partially addresses #5731 (the .git part; see above for why the working tree is kept).

🤖 Generated with Claude Code

The web-server backup copied every service's */code/ directory, the git
working tree cloned at deploy time, which can add gigabytes per service
and is re-created on the next deploy. Exclude applications/*/code/ and
compose/*/code/, but keep the code of drop (zip upload) applications,
since their code/ directory is the only copy.

Closes Dokploy#5731

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(appName) => `--include=${quote([`applications/${appName}/code/***`])}`,
),
"--exclude='applications/*/code/'",
"--exclude='compose/*/code/'",

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 Compose backups omit live data

The blanket Compose exclusion removes live files, not just cloned source. A raw Compose service with ./data:/var/lib/postgresql/data stores its database under compose/<appName>/code/data. Those files cannot be rebuilt from the saved Compose text. Restore deletes the existing data path before copying the archive, so this change loses that database on restore.

Preserve bind-mounted paths under code/ instead of excluding the whole directory.

Knowledge Base Used: Backups and restore

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right. Restore runs rm -rf "$BASE_PATH/"* before copying, so excluding compose/*/code/ would delete a running service's ./data on a same-server restore. Fixed in fd7533f: the backup now keeps every working tree and only excludes applications/*/code/.git/ and compose/*/code/.git/, which every deploy re-clones. The rsync test now asserts that a compose/stack/code/data file is kept. I updated the PR description to explain the narrower scope.

Comment on lines +88 to +91
const dropApps = await db.query.applications.findMany({
columns: { appName: true },
where: eq(applications.sourceType, "drop"),
});

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 Drop backups can omit uploads

The drop-app list is read after pg_dump, so it can disagree with the saved database. If a user switches a drop app to Git while the dump runs, the dump can still contain sourceType: "drop" while this query omits the app. The new exclusion then skips its uploaded code even if those files remain untouched. Restoring that backup brings back a drop app with no source to redeploy.

Use the dump's snapshot for the include list, or conservatively keep code for apps whose source changes during the backup.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Resolved by fd7533f: with only .git excluded there's no drop-app lookup anymore, so nothing depends on database state and there's no race with pg_dump. Drop apps' code is kept like everything else.

Excluding whole */code/ directories dropped live data: compose bind
mounts like ./data resolve inside code/, and restore replaces BASE_PATH,
so a same-server restore would delete that data. Keep the working trees
and exclude only */code/.git/, which every deploy re-clones. This also
removes the drop-app lookup, so there is no race with the database dump.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Gourav224 Gourav224 changed the title fix(backups): leave cloned git checkouts out of web-server backups fix(backups): leave the .git history of cloned checkouts out of web-server backups Oct 22, 2026
# Conflicts:
#	packages/server/src/utils/backups/web-server.ts
@EmrysMyrddin

Copy link
Copy Markdown

Could we allow users to provide their own backup exclusion patterns ?

This way, if one actually want to optimise backup size, it is its responsability to verify what is excluded is not required for a restore (like in my case when you never use Drop nor compose local volumes).

Thank you anyway for the quick answer on this subject and for the hard and awesome work on Dokploy!

@narcisonunez

Copy link
Copy Markdown
Collaborator

This was already fixed. Thank you for your time.

@EmrysMyrddin that can be done in another time. For now just doing two specific paths. If more people are in need of this feature we can come back to this. Thank you

@Gourav224
Gourav224 deleted the fix/web-server-backup-skip-git-checkouts branch October 30, 2026 03:01
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.

3 participants