Skip to content

feat/container filesystem all service types - #5194

Open
VijinV wants to merge 3 commits into
Dokploy:canaryfrom
VijinV:feat/container-filesystem-all-service-types
Open

feat/container filesystem all service types#5194
VijinV wants to merge 3 commits into
Dokploy:canaryfrom
VijinV:feat/container-filesystem-all-service-types

Conversation

@VijinV

@VijinV VijinV commented Aug 26, 2026

Copy link
Copy Markdown

What is this PR about?

This PR extends the container filesystem browser (browse, download, and upload files inside a running container) from application services to every other service type: postgres, mysql, mariadb, mongo, redis, and compose (which also covers deployed templates, since a template becomes a regular compose entity once deployed).

Previously this feature (packages/server/src/services/container-filesystem.ts, the application-only filesystemContainers/filesystemList/filesystemReadFile procedures, and the ShowContainerFileSystem component) only worked from the Application service page. This PR:

  • Adds getComposeFilesystemContainers/getComposeFilesystemContainer for compose's multi-container discovery, since compose containers are labeled differently depending on deploy mode (com.docker.compose.project=<appName> for plain docker compose, vs a <appName>_<service>-prefixed swarm service name for docker stack deploy) — unlike the other service types, which are always a single swarm service.
  • Replaces the application-only application-filesystem.ts auth util with a generic service-filesystem.ts that dispatches to the right entity finder (findApplicationById, findPostgresById, etc.) based on a serviceType, while preserving the same per-service containerFilesystem permission check and accessedServices scoping.
  • Introduces a single shared filesystem tRPC router ({ serviceType, serviceId } inputs) instead of duplicating the same three procedures across seven routers, and updates the /api/filesystem/download and /api/filesystem/upload routes to take serviceType/serviceId instead of being application-specific.
  • Adds a containerFilesystem write permission (previously read-only) so uploads can be permission-gated separately, with owner/admin granted by default and an opt-in toggle for custom roles.
  • Adds a "Files System" tab to the postgres, mysql, mariadb, mongo, redis, and compose dashboard pages, matching the existing tab pattern and permission gating already used on the Application page.
  • Fixes an unrelated bug found along the way: browsing a directory whose recursive Docker archive exceeded the safety byte cap used to hang forever instead of erroring, because destroying the stream without an error never fired the finish/error listeners the code was waiting on. It now returns a partial, truncated: true listing instead.
  • Defaults the file browser to the container's WORKDIR instead of / when a container is selected.
  • The "Running" state badge in the container selector now renders green instead of the default gray/secondary style.

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.

Issues related (if applicable)

Screenshots (if applicable)

image image

Greptile Summary

The PR generalizes container filesystem browsing, downloading, and uploading across applications, Compose workloads, and managed databases, with shared authorization and new write permissions.

  • Adds shared tRPC and HTTP filesystem endpoints with bounded archive and upload handling.
  • Adds Compose container discovery and filesystem tabs across supported service dashboards.
  • Extends custom-role permissions with separate container filesystem read and write actions.
  • Adds filesystem ownership, archive-safety, upload, and permission tests.

Confidence Score: 3/5

The PR should not merge until Compose stack discovery handles worker-node tasks and oversized uploads can return their intended error response.

Multi-node Compose stacks can hide valid running containers from the filesystem browser, while exceeding the upload limit destroys the connection and prevents the browser from receiving the structured rejection.

Files Needing Attention: packages/server/src/services/container-filesystem.ts; apps/dokploy/pages/api/filesystem/upload.ts

Reviews (1): Last reviewed commit: "feat: extend container filesystem browsi..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

Context used (4)

VijinV added 2 commits August 26, 2026 12:06
Add container filesystem browse/download/upload support for postgres,
mysql, mariadb, mongo, redis, and compose services (previously
application-only). Compose gets its own container-discovery logic
since it's multi-container, matching either the docker-compose project
label or the swarm stack service-name prefix depending on deploy mode.

Introduces a shared filesystem tRPC router and service-filesystem auth
util used across every service type instead of duplicating per-router
procedures, a containerFilesystem "write" permission for uploads, and
a "Files System" tab on each service's dashboard page. Also fixes an
infinite-loading bug in the large-directory truncation path and
defaults the browser to the container's WORKDIR.
@VijinV
VijinV requested a review from Siumauricio as a code owner August 26, 2026 14:28
Comment on lines +318 to +321
const filters = { status: ["running"] };
const containers = await docker.listContainers({
filters: JSON.stringify(filters),
});

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 Swarm tasks stay hidden

If a Compose stack has tasks scheduled on worker nodes, this single-daemon listContainers call omits them, causing the filesystem selector to show missing or no containers and reject access to those tasks.

Knowledge Base Used: Infrastructure runtime

Comment on lines +63 to +65
if (total > maxBytes) {
req.destroy();
reject(

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 Upload response socket destroyed

When an upload exceeds the size limit, req.destroy() closes the shared connection before the catch handler sends its 413 JSON response, causing the browser to receive a generic network failure instead of the upload-limit message.

Knowledge Base Used: API boundary

@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Aug 26, 2026
Cross-checks compose stack task counts against the swarm control plane so
the filesystem browser can warn when replicas live on nodes this server
has no direct connection to, instead of silently showing a partial list.
Also fixes the upload route destroying the request socket before the
413 response could flush to the client.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant