When called with an empty array, `docker service ps` receives no
SERVICE argument and fails with "requires at least 1 argument".
Return early with [] when appNames is empty.
getSwarmNodes was changed to return [] on error, but the existing
SwarmMonitorCard checks `if (!nodes)` to detect failures. Since ![]
is false, the error state was silently skipped, breaking the Overview
tab for users without Docker Swarm initialized.
Reverted to return undefined on error (original behavior) so the
existing Overview tab error handling continues to work. The Containers
tab already handles nodes === undefined explicitly.
TL;DR: New "Containers" tab on the Swarm page showing which containers
run on which nodes, with live CPU/Memory/Block I/O/Network I/O metrics
refreshing every 5 seconds. Comprehensive edge case handling guides
users through prerequisites (swarm init, registry, service deployment).
---
## New Files
- `apps/dokploy/components/dashboard/swarm/containers/show-swarm-containers.tsx`
Main component: data fetching, error/empty states, summary cards,
and the node-grouped container layout.
- `apps/dokploy/components/dashboard/swarm/containers/node-section.tsx`
Collapsible per-node section with container table, role badge,
and down-node indicator.
- `apps/dokploy/components/dashboard/swarm/containers/container-row.tsx`
Table row for a single container: state badge with error tooltip,
formatted CPU/memory/IO metrics.
- `apps/dokploy/components/dashboard/swarm/containers/utils.ts`
Formatting helpers for docker stats values (CPU %, memory, I/O).
- `apps/dokploy/components/dashboard/swarm/containers/types.ts`
Shared TypeScript interfaces (ContainerStat, ContainerInfo, SwarmNode,
NodeGroup).
## Modified Files
- `apps/dokploy/pages/dashboard/swarm.tsx`
Added Tabs (Overview / Containers) wrapping existing SwarmMonitorCard
and the new ShowSwarmContainers component.
- `apps/dokploy/server/api/routers/swarm.ts`
Added `getContainerStats` tRPC endpoint calling `getAllContainerStats`,
following existing auth/validation patterns.
- `packages/server/src/services/docker.ts`
- Added `getAllContainerStats()` — runs `docker stats --no-stream` for
cluster-wide container metrics.
- Fixed `getSwarmNodes`, `getNodeApplications`, `getApplicationInfo` to
return `[]` instead of `undefined` on errors (prevents tRPC
serialization crashes) and added `console.error` logging.
- Added empty stdout guard (`if (!stdout.trim()) return []`) to prevent
`JSON.parse("")` crashes when no services exist.
## Features
- Container table per node: name, image, state, CPU %, memory usage,
block I/O, and network I/O
- Resource formatting: values rounded to 1 decimal (2.711MiB → 2.7 MiB),
CPU to 1 decimal (0.00% → 0.0%)
- Node role badges (Leader / Reachable / Worker) on each section header
- Error tooltips: hover the status badge to see Docker error details
- Down/drained node detection with red indicator dot and warning banner
- Multi-node metrics banner explaining docker stats manager-only limitation
- Unscheduled services footer for services scaled to 0 replicas
- Contextual empty/error states with actionable guidance, doc links to
Dokploy docs and Docker Swarm guide, and links to Cluster Settings
## Edge Cases Handled
1. Swarm not initialized (tRPC error or undefined data)
2. Docker command failures (stderr / non-zero exit)
3. Swarm active but no services deployed
4. Services exist but no running containers
5. Containers with Docker errors (shown in tooltip + error alert)
6. Nodes down or drained (cross-referenced from node list)
7. Multi-node setups (metrics only from manager node)
8. Services scaled to 0 replicas (separated from running containers)
9. Empty stdout from docker commands (no JSON.parse crash)
- Eliminated the getDokployImage and pullLatestRelease functions to streamline the settings service.
- Updated the code to focus on dynamic image retrieval, enhancing clarity and maintainability.
- Simplified the rendering of DriverOptsEntries in the network form by consolidating the mapping logic.
- Improved formatting of example driver options in the form description for better readability.
- Ensured consistent handling of adding and removing driver options within the form.
- Removed the deprecated getDokployImage function and replaced it with dynamic image retrieval based on available updates.
- The service update now checks for available updates and uses the latest version from the update data, enhancing deployment efficiency.
- Introduced DriverOptsEntries to the network form schema, allowing users to specify driver options for networks.
- Updated the form UI to support adding, editing, and removing driver options dynamically.
- Adjusted the backend schema to accept driver options as a record of key-value pairs.
- Updated the backupVolume function to use `docker service update --replicas` instead of `docker service scale` for stopping and starting application replicas.
- This change enhances the backup process by ensuring proper handling of service updates with registry authentication.
- Updated backup processing logic to destructure appName from backup objects, ensuring it is available for further operations.
- This change is applied consistently across multiple sections of the project router.
- Introduced a new notification type 'resend' to the database.
- Created a new table 'resend' with fields for managing resend notifications.
- Updated the 'notification' table to include a foreign key reference to 'resendId'.
- Added corresponding snapshot and journal entries to reflect these changes.
- Introduced a new notification type 'pushover' to the database.
- Created a new table 'pushover' with relevant fields for notification management.
- Updated the 'notification' table to include a foreign key reference to 'pushoverId' for enhanced notification handling.
- Added corresponding snapshot and journal entries to reflect these changes.
- Deleted the '0137_worried_shriek.sql' file as it is no longer needed.
- Updated the journal to remove references to the deleted SQL file.
- Removed the corresponding snapshot JSON file to maintain a tidy project structure.
- Deleted SQL files '0136_tidy_puff_adder.sql' and '0137_worried_shriek.sql' as they are no longer needed.
- Updated the journal and removed references to the deleted SQL files.
- Cleaned up the corresponding snapshot JSON files to maintain a tidy project structure.
- Eliminated the sponsors section and related acknowledgments from the README.md to simplify the document.
- Updated the layout to focus on the core features and purpose of Dokploy.
- Added BETTER_AUTH_SECRET constant to manage authentication secret, defaulting to a predefined value if not set in the environment.
- Updated betterAuth configuration to utilize BETTER_AUTH_SECRET for enhanced security in authentication processes.
- Updated error handling in the ShowExternal*Credentials components for MariaDB, MongoDB, MySQL, PostgreSQL, and Redis to display specific error messages when saving the external port fails.
- Moved LICENSE_KEY_URL definition to a centralized location for better maintainability.
- Updated license validation function to utilize the new LICENSE_KEY_URL import, enhancing clarity and consistency in API calls.
- Upgraded @types/node from version ^18.19.104 to ^20.16.0 in package.json files for apps/api, apps/dokploy, apps/schedules, and packages/server.
- Adjusted pnpm-lock.yaml to reflect the updated @types/node version across all relevant dependencies.
- Added a new setup file for mock database interactions in the dokploy app to enhance testing capabilities.
- Updated drizzle-orm from version ^0.39.3 to ^0.41.0 for enhanced performance and features.
- Upgraded @better-auth/utils from version 0.2.4 to 0.3.0 to incorporate the latest improvements.
- Adjusted pnpm-lock.yaml to reflect these dependency updates.
- Upgraded drizzle-orm from version ^0.39.3 to ^0.41.0 for improved functionality and performance.
- Updated drizzle-kit from version ^0.30.6 to ^0.31.4 to ensure compatibility with the latest drizzle-orm version.
- Adjusted related dependencies in pnpm-lock.yaml to reflect these changes.
- Upgraded Vitest from version 1.6.1 to 4.0.18 to leverage new features and improvements.
- Updated dependency versions in pnpm-lock.yaml to ensure compatibility with the latest Vitest version.
- Deleted the mock database setup file to streamline the test environment.
- Updated the Vitest configuration to remove the reference to the deleted setup file, enhancing clarity in test setup.
- Added mock implementations for `member.findFirst` and `member.findMany` methods in the mock database setup.
- This enhancement improves the test environment by allowing more comprehensive simulation of member-related database interactions.
- Added logic to retrieve and delete SSO providers, ensuring proper permission checks and error handling.
- Updated user trusted origins when adding or removing SSO providers, maintaining accurate origin lists.
- Refactored trusted origins retrieval to improve clarity and efficiency in the authentication process.
- Introduced utility functions for normalizing trusted origins and converting request headers.
- Created a new table `sso_provider` with relevant fields and constraints.
- Added new columns to the `user` table: `enableEnterpriseFeatures`, `licenseKey`, `isValidEnterpriseLicense`, and `trustedOrigins`.
- Established foreign key relationships for `user_id` and `organization_id` in the `sso_provider` table.