Embedding the full YAML (base64-encoded) into a single SSH exec command
silently fails once the payload passes the SSH transport's packet size
ceiling (~90-100KB), truncating the dynamic config with no error
surfaced anywhere. Switch to SFTP, which has no such limit.
--project-directory was added unconditionally in 87b914996 to fix
relative bind mount resolution for git-based compose deploys with a
nested composePath (#5181). It also moves where build.context and the
generated .env resolve, breaking any compose file in a subdirectory
that has context: . alongside its Dockerfile (#5230), or interpolates
env vars (#5242).
Only pin --project-directory when the compose actually has mounts
configured; otherwise build.context and .env resolve against the
compose file's own directory like plain docker compose. Also pass
--env-file explicitly pointing at the generated .env next to the
compose file, so it's found even when --project-directory is pinned
(credit: tonnenpinguin, PR #5235).
Fixes#5230Fixes#5242
Attaching Basic Auth or a Redirect to an application with no domains
wrote an empty routers/services block to the app's dynamic config
file. Traefik's file provider rejects that as invalid and aborts its
watcher, blocking config updates for every other application.
Fixes#5189
Compose deployments using a git provider (GitHub/GitLab/Gitea/Bitbucket/
custom Git) clone the repo verbatim, so composePath can point into a
subdirectory (e.g. deploy/docker-compose.yml). Docker Compose resolves
relative bind mounts (../files) against the compose file's own directory,
not against the code/ dir where file mounts are actually written, so the
mount silently binds an empty directory instead of the configured content.
Pin --project-directory to code/ when building the docker compose command
so relative mounts always resolve the same way raw deployments already do.
Fixes#5181
Escaping in prepareEnvironmentVariablesForFile escaped every $,
including inside a deliberate ${VAR} reference, breaking Compose's
documented .env variable interpolation. Only escape $ that isn't
part of a ${IDENTIFIER} sequence.
Fixes#5151
Adds Porkbun as a supported DNS provider alongside Cloudflare and
AWS Route53, allowing Dokploy to automatically create DNS records
for domains managed on Porkbun.
- New DnsClient implementation for the Porkbun API v3
- porkbun enum value and config schema (apiKey/secretApiKey)
- Drizzle migration for the new DnsProviderType enum value
- UI: provider icon, form fields and provider selector entry
- Unit tests covering listZones/listRecords/upsertRecord/updateRecord/deleteRecord/testConnection
Route53 returns a record set as a list of values, but listing joined them
into one string and writing sent that string back as a single
ResourceRecord. Editing a multi-value NS, MX or TXT set therefore either
failed validation or collapsed the set into one bogus value, and creating
a record for a name that already had values replaced them silently.
Values are now newline separated end to end: listing joins with a
newline, writing splits back into one ResourceRecord per line, and
creating merges into the existing set instead of replacing it. Unquoted
TXT values get the quotes Route53 requires. The record panel shows a
textarea for Route53 and validates every line.
Cloudflare treats content as read-only for SRV and CAA and expects a
data object instead, so both types were rejected on write. The client
now parses the inline value into the fields Cloudflare wants, and
builds the payload before the lookup request so a malformed value
fails without spending an API call.
The form rejects a malformed SRV or CAA value up front and shows the
expected shape, so the error lands on the field instead of coming
back from the provider.
Providers, domains and records now each have their own page instead of
a stack of modals. A provider opens its domains as cards, with the
record count loading separately so the domains appear right away. A
domain opens its records as a table with search, type filter and
pagination. Creating or editing a record happens in a panel that
slides in next to the table.
The type list was capped at A and CNAME in the zod schema, so widening
the dropdown alone would not have worked. AAAA, MX, TXT, NS, SRV, CAA
and PTR work now. MX carries a priority that Cloudflare takes as a
separate field and Route53 takes inline in the value, so the
Cloudflare client splits it out on write and puts it back on read.
The form keeps one value field for both providers.
Cloudflare proxy status is now editable and visible. A, AAAA and CNAME
records get a Proxied / DNS only toggle in the form and a cloud icon
in the table. The proxy field only goes to the API when the caller
sets it, so an update from another path cannot silently disable the
proxy.
Tests cover the MX priority round trip and the proxy rules in the
Cloudflare client.
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.
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
- 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.
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.
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
Fixes#4986. initCancelDeployments blindly marked every 'running'
deployment as 'cancelled' on boot, including schedule runs whose
actual work (docker exec into another container, or SSH to a remote
host) is decoupled from the Dokploy process and keeps running after
a restart. Now only deployments with no schedule, or schedules of
type dokploy-server (a real child process), get cancelled.
Also resolve any stale 'running' deployment for a schedule when a
new run starts, so restarted panels don't leave ghost 'running' rows
forever.
dockerSafeExec's busy-wait matched any process with "docker <letter>"
anywhere in its argv (e.g. Grafana's --packaging=docker cfg:...),
causing the wait loop to spin forever. Anchor the match to the actual
docker binary (argv[0]) instead, and add a MAX_WAIT ceiling so a
genuinely stuck docker process can't hang cleanup indefinitely either.
Also log failures in cleanupAll's catch instead of swallowing them,
since the scheduled cleanup path only goes through this function.
Fixes#5044
Adds Scaleway Secret Manager as a first-class vault provider alongside
HashiCorp Vault/OpenBao, Infisical, AWS, Doppler and Azure Key Vault.
- New `scaleway` provider type, zod-validated config (region, project ID,
API secret key, overridable API URL) and migration adding the enum value
- Plain `fetch` client (no new dependency) against the Secret Manager
v1beta1 REST API: access-by-path for reads, paginated listing for the
env editor autocomplete, and a connection test
- Refs are `[folder/]name[:field]` — the field selector extracts a key
from JSON/key-value secrets, like the AWS provider
- Secret key masked in API responses like every other provider credential
- Settings -> Secrets form with region picker, brand icon and reference
format help
- 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.