docker stack deploy reads env_file literally without stripping
quotes (unlike docker compose), so the quoting/escaping added to
fix#4694 was shipping literal quote characters into stack
containers.
Fixes#5096, #5110.
Fixes#5108. The changePassword mutations for postgres/mysql/mariadb/mongo/redis
detected the running container via a shell one-liner (docker ps -q --filter
status=running | head -n1) executed through execAsync/execAsyncRemote. When that
shell command failed for any reason the CONTAINER_ID ended up empty and the
mutation incorrectly reported the container as not running even though it was.
Replaced it with getServiceContainer(), the existing dockerode-based lookup
already used by mount.ts and schedules/utils.ts for the same purpose.
Also fixes the postgres ALTER USER command, which never selected a database
and defaulted to a database named after the user, causing a false
'database "<user>" does not exist' failure whenever the db name differs
from the username.
Fixes#5092 — typing in the database/docker terminal overwrote text
instead of continuing on new lines. The xterm.js client never told the
backend PTY its actual size (node-pty/ssh2 always defaulted to 80x24
and were never resized), so whenever the rendered terminal width
differed from that, the remote shell's cursor math diverged from what
the client displayed.
- docker-container-terminal.ts / terminal.ts: pass the client's initial
cols/rows into node-pty spawn and ssh2 exec/shell, and resize the PTY
on a {type:"resize"} control message sent over the same ws channel.
- docker-terminal.tsx / settings/web-server/terminal.tsx: send cols/rows
on connect and on every term.onResize, and watch the container with a
ResizeObserver to refit on dialog/window resize.
Also fixes two related terminal/logs bugs surfaced while testing this:
- docker-terminal.tsx no longer opens a connection with the
"select-a-container" placeholder ID before a real container is
selected, and defers terminal creation a frame so React StrictMode's
dev-only phantom mount doesn't hit a known xterm.js dispose race
(xtermjs/xterm.js#5011, "Cannot read properties of undefined
(reading 'dimensions')").
- docker-logs-id.tsx (shared by application/compose/compose-stack logs)
had the same placeholder-ID issue, surfacing Docker's raw
"No such container: select-a-container" daemon error instead of a
proper empty state.
Replaces the static quote in the onboarding layout's left panel with
an auto-rotating carousel of product highlights (Deploy / Manage /
Scale, 3 slides x 4 items), shown on the cloud signup page only.
- OnboardingLayout gets an optional leftPanel override, default
quote untouched everywhere else (login, invitation, password reset).
- Auto-advances every 6s, pauses on hover/focus, respects
prefers-reduced-motion, manual dot + arrow navigation.
- Copy pulled from the website's existing first-features.tsx section
to stay consistent with approved marketing copy.
Fires the sign_up dataLayer event already read by GTM for the three
signup paths on the cloud version: email/password (register.tsx),
GitHub/Google OAuth (via better-auth's newUserCallbackURL, distinct
from callbackURL so returning-user logins aren't counted), and
invitation acceptance. All gated behind isCloud, same as the rest of
the analytics wiring.
Mounts the existing cloud-gated Analytics component (GTM + HubSpot
script loader) in _app.tsx. It was already implemented behind
api.settings.isCloud but never wired into the app, so it never loaded
on cloud or self-hosted instances.
Resolve conflicts in docker.ts and domain.ts: canary already contains
a superset of main's hotfix cherry-picks (isDockerDesktop, isolated
network label pinning), just refactored/reformatted, so both sides
kept canary's version.
Also fix hotfix-cherry-pick.yml to sync each cherry-pick back into
canary immediately, so canary and main share history for that change
and the next canary->main release PR doesn't re-conflict on it.
Some self-hosted GitLab instances (e.g. older versions without
expires_in configured in doorkeeper) omit expires_in from the
OAuth token response. Computing Date.now()/1000 + undefined
produced NaN, which Postgres rejected on the expires_at integer
column, crashing both the initial OAuth callback and the token
refresh flow with a 500.
Falls back to null when expires_in is absent, matching the
existing Gitea callback behavior.
Closes#4362
SCIM provisioning created users with emailVerified: false, so better-auth
refused to link the matching SSO account (account_not_linked), and the
resulting redirect landed on better-auth's bare /error page with no
actionable feedback.
- Mark SCIM-provisioned users as email-verified at creation time, same
trust rationale already applied to admin-invited credential users.
- Sync a SCIM user's membership role to the organization's configured
default role instead of the hardcoded "member" the SCIM plugin creates.
- Set errorCallbackURL/onAPIError.errorURL to the sign-in page so failed
SSO/OAuth callbacks land back on Dokploy's UI instead of better-auth's
generic error page.
- Read the error query param on the sign-in page and show it through the
existing AlertBlock instead of failing silently.
Fixes#4973
Radix locks scroll on <body>, but the dashboard's actual scroll
container is the sidebar's <main data-slot="sidebar-inset">, so the
background stayed scrollable behind dialogs/sheets. Extend the lock
to that container using the same data-scroll-locked attribute Radix
already sets.
Fixes#5064
- Images tab: list, inspect and delete docker images, with a
force-delete fallback when an image is in use.
- Disk Usage tab: docker system df summary as stat cards plus a
Build Cache table (docker system df -v) with a prune action.
@aws-sdk/client-secrets-manager (pre-existing, unrelated to any recent
PR) transitively pulled @smithy/fetch-http-handler + @smithy/core
versions published the same day, with no older compatible version to
fall back to. AWS SDK v3 is dozens of interdependent packages often
published together same-day, so a global minimumReleaseAge with no
per-scope threshold (pnpm only supports all-or-nothing exclude) was
going to keep breaking builds on any lockfile touch. Commented out
rather than deleted -- left for whoever wants to revisit it, see
discussion on #4679.
Also lets @aws-sdk/client-route-53 and @aws-sdk/client-secrets-manager
resolve to their actual latest versions now that nothing blocks it.
Adds a new Events tab to /dashboard/docker showing Docker daemon
events (equivalent to `docker events`), polled via docker.getEvents
with a time-range selector and refresh button.
Also fixes a stale isCloud redirect that forced the Networks tab
back to Containers even though it is now shown in cloud.
The endpoint field let anyone with dnsProvider create permission point
the AWS SDK at an arbitrary URL (loopback, link-local, internal
network, cloud metadata), turning testConnection and every other
Route53 operation into an SSRF oracle. There's no way to keep
LocalStack-style testing working while blocking that, since the
target address is identical either way, so the field is removed
entirely rather than validated. Route53 always talks to real AWS now.
Also pin @aws-sdk/client-route-53 to ^3.1097.0 (matching the existing
client-secrets-manager pin) instead of whatever caret-latest resolved
to at install time. The version that landed in the merged PR was
published less than a day before this, which violates the
minimumReleaseAge policy that merged into canary around the same time
and broke the Docker build.
Route53 rejects the literal "@" (RRSet with DNS name @. is not
permitted); Cloudflare happens to accept it, but relying on
provider-specific handling of that shorthand isn't safe. Resolve it
client-side to the zone's actual domain name before building the
create/update payload.
Lets you connect a DNS provider and manage its records (create,
update, delete) from Settings -> DNS Providers, instead of doing it
by hand in Cloudflare/AWS.
- dns_provider table, org-scoped, jsonb config as a discriminated
union per provider type
- Cloudflare adapter (REST, bearer token)
- Route53 adapter (AWS SDK, SigV4); records are identified by
type:name since Route53 has no native record id, so update
handles renames as delete-old + upsert-new
- listZones/listRecords/createRecord/updateRecord/deleteRecord/
testConnection wired through a shared DnsClient interface
- Settings UI: provider management, zone browser, record CRUD,
IP-fill dropdown for A records (panel IP + remote servers)
- Access control: dnsProvider resource wired into custom roles
- Unit tests for both adapters and the config mask/merge logic
- Add Nodes sub-tab under Docker > Swarm (visible with organization.update permission)
- Remove Cluster item from settings sidebar and delete /dashboard/settings/cluster page
- Point internal cluster links to /dashboard/docker?tab=swarm&subtab=nodes
- Make ShowNodes card full-width to match the other docker tabs
- Included the @aws-sdk/client-secrets-manager package version 3.1097.0 to facilitate AWS Secrets Manager integration for managing environment secrets.
- Updated the environment autocomplete component to include projectId and environmentId in vault secret fetching logic.
- Added authorization checks in the vault provider router to ensure users have access to the specified project and environment.
- Modified the vault provider schema to include projectId and optional environmentId for better validation.
- Improved error handling for unauthorized access and invalid vault provider assignments.
- Introduced support for project and environment assignments for vault providers, allowing for more granular access control.
- Updated the vault provider schema to include assignments and modified related components to handle these changes.
- Enhanced UI to display assignment status and allow users to manage project and environment associations effectively.
- Added validation to ensure assignments reference valid projects and environments within the organization.
- Updated tests to cover new functionality related to vault provider assignments and environment variable resolution.
- Added support for managing various vault providers (HashiCorp, AWS, Azure, Doppler, Infisical) in the dashboard.
- Implemented environment variable resolution using vault references, allowing seamless integration of secrets into application environments.
- Enhanced UI components to display and manage vault providers effectively.
- Introduced tests for vault reference resolution and environment variable preparation.
- Updated related components to utilize new vault management features.
- Refactored SwarmMonitorCard to use optional chaining for node data handling.
- Consolidated loading and error states into a single conditional rendering block.
- Updated dashboard layout to include tabs for containers and swarm, enhancing navigation.
- Removed deprecated network-related code from the dashboard.
The cli/sdk steps copied the repo-root openapi.json, which was last committed in March, and the mcp step fetched docs.dokploy.com, which canary pushes can overwrite. Generate the spec from the release commit instead so each package release matches its dokploy tag.
npm install -g pnpm resolved to pnpm 11, which turns the esbuild ignored-build-scripts warning into a fatal error, so sync-version has failed on every release since v0.29.5 and mcp/cli/sdk were never bumped or published. Pin pnpm to 10.22.0 (same as packageManager) and write the version without the v prefix so npm packages get valid semver.
- Updated ShowIconSettings component to handle both application and compose service types.
- Added new icon column to the compose table in the database.
- Implemented fetching and updating of icons for services in the environment and application pages.
- Introduced fetchTemplateLogo function to retrieve logos for templates, improving icon handling for compose services.
Dokploy stopped using Redis in v0.29.9 when the deployment queue moved
to an in-memory implementation, and install.sh no longer creates the
dokploy-redis service. Remove the remaining references so fresh installs
don't report Redis as unhealthy:
- checkRedisHealth from infrastructure health check
- cleanRedis/reloadRedis endpoints and their UI actions
- initializeRedis dev setup and redis-connection config
- unused bullmq dependency
- Added new endpoints for application creation, retrieval, and reloading with detailed request and response schemas.
- Updated existing network validation schemas to enforce minimum length requirements for network IDs.
- Improved OpenAPI documentation to ensure better clarity and validation for application-related operations.
- Added auditing functionality for network creation, recreation, and deletion actions in the network API.
- Updated the audit log schema to include "network" as a resource type.
- Enhanced the network router to log actions with relevant metadata, improving traceability and accountability for network management operations.
- Added functionality for assigning Docker networks to services, allowing users to manage network associations directly from the UI.
- Introduced new components for assigning networks to both individual services and compose files, improving user experience and flexibility.
- Updated existing components to integrate network assignment features, ensuring seamless interaction within the dashboard.
- Enhanced the database schema to support new network-related fields, including `networkIds` and `detachDokployNetwork`, for better service configuration.
- Improved the layout and responsiveness of various UI elements to accommodate new features and enhance usability.
- Added a new API endpoint for recreating Docker networks that have been removed, allowing users to restore networks directly from the Dokploy interface.
- Updated the ShowNetworks and SyncNetworks components to include options for recreating networks, improving user management capabilities.
- Enhanced the network synchronization process to better handle stale records, providing users with clear actions for network maintenance.
- Refactored network creation logic to streamline the process and ensure consistency across network management operations.
- Added server filtering capability to the dashboard, allowing users to manage networks specific to selected servers.
- Introduced SyncNetworks component for synchronizing Docker networks with Dokploy, enabling import of new networks and cleanup of stale records.
- Updated HandleNetwork and ShowNetworks components to support server-specific operations, improving user experience and functionality.
- Enhanced API to support network synchronization and importing, ensuring accurate data handling for network management.
- Introduced a new ShowNetworkConfig component for displaying detailed Docker network configuration.
- Integrated ShowNetworkConfig into the ShowNetworks component, allowing users to view network details directly.
- Updated the layout of network actions for improved user experience and accessibility.
- Enhanced the API to support network inspection functionality, providing necessary data for the new component.
- Simplified the network form schema by removing unnecessary fields and enforcing validation rules for IP settings.
- Updated the HandleNetwork component to eliminate the edit functionality, focusing on network creation only.
- Improved the ShowNetworks component by adding a delete action for network management, enhancing user experience.
- Introduced a new SQL migration for the network schema, establishing necessary constraints and types.
- Cleaned up the API by removing the update network functionality, reflecting the immutable nature of Docker networks.
- Replaced zodResolver with standardSchemaResolver for improved schema validation.
- Added new toggle options for network settings, enhancing user interface clarity.
- Refactored network creation and update logic to streamline payload handling.
- Updated network form schema to remove default values, ensuring explicit user input.
- Introduced SERVER_LOCAL sentinel for local Dokploy server identification.
- Updated the ShowNetworks component to improve the layout and user experience.
- Introduced a new Pencil icon for editing networks and added a Badge component for displaying network drivers.
- Refactored loading and empty state handling for better visual feedback.
- Modified the API query to include server details for each network, enhancing the data returned for better context.
- Introduced a new SQL file defining the "network" type and its associated table structure.
- Added "networkIds" column to multiple application tables for network association.
- Established foreign key constraints for the "network" table linking to "organization" and "server" tables.
- Updated migration journal and added a new snapshot for versioning.
- Deleted the SQL file and snapshot related to the "network" management schema, cleaning up the database structure.
- Updated the migration journal to reflect these deletions.
- Added .playwright-* to .gitignore to exclude Playwright test files from version control.
Organization admins can define their own AI providers (name + API URL)
from the AI settings section. When at least one custom provider is
defined, it replaces the built-in provider list in the Add AI form,
the API URL is auto-filled and locked, and the backend rejects any
configuration whose URL is not in the allowed list.
Updated the SSO configuration to trust verified emails and modified user creation to set emailVerified to true by default. This enhances security and ensures that user email verification is properly handled.
The verify-totp handler checked for the error code
INVALID_TWO_FACTOR_AUTHENTICATION, which no longer exists in
better-auth 1.6.23 (the two-factor plugin now returns INVALID_CODE).
As a result, entering a wrong TOTP code fell through to the generic
catch and showed "Error verifying 2FA code / Unknown error" instead of
a clear "Invalid verification code" message.
Match the current better-auth error code so the specific, actionable
message is shown.
The organization switcher's DropdownMenuContent inherited its width from
the collapsed trigger (~40px) via the base primitive's
w-(--radix-dropdown-menu-trigger-width), clamping the menu to the
min-w-32 (128px) floor. This cut off the org name and action buttons in
icon mode.
Set an explicit w-64 so the menu fits its content regardless of the
trigger width, matching the pattern already used by the notification
dropdown in the same file.
Fixes#4840
The remote (execAsyncRemote) path built `echo ${password} | docker ${args.join(" ")}`
with the password, registryUrl and username interpolated unescaped, so a password
like `pw; whoami` ran arbitrary commands as root on the target server. Reuse
safeDockerLoginCommand (already used by create/update), which shell-escapes each
field and feeds the password via --password-stdin. The local argv+stdin path was
already safe.
server.remove deleted a server (and its deployment rows) by caller-supplied
serverId without checking it belongs to the active organization, unlike server.one
and server.update. An owner/admin of org A could delete org B's server registration.
Resolve and compare the server's organizationId before the active-services guard,
so cross-org callers are rejected without leaking existence.
writeTraefikConfigRemote piped the stringified YAML through echo '...' where a
single quote in any label/host/serviceName broke out (GHSA-478p). Encode it as
base64 like the other writers, and quote() every configPath used in remote
rm/cat/redirect commands (including the input.path-derived ones).
quote() the user-derived paths that reach the shell in file mounts
(mount.ts, docker getCreateFileCommand), patch repo read (repoPath/filePath),
certificate create/remove (certificatePath), and the remote scheduled command
(containerId/shellType/command/logPath), so $(), backticks and traversal in
these fields can no longer inject commands.