Commit Graph

4079 Commits

Author SHA1 Message Date
Narciso E. Núñez Arias fc6f4d9af8 Merge pull request #5079 from NoiceHax/fix/issue-4074
fix(github-webhook): apply preview limit only to new previews
2026-08-18 17:21:08 -04:00
Mauricio Siu cf6f5e39d2 Merge pull request #5118 from andwati/fix/tag-assignment-on-project-create
fix: assign tags created from the project dialog
2026-08-18 14:22:12 -06:00
Mauricio Siu 76c2416613 fix: correct switch thumb translate-x for checked state
Fixes #5120
2026-08-18 14:20:26 -06:00
andwati 0ea7de7d31 fix: assign tags created from the project dialog
The tag dialog's form is nested inside the project dialog's form in the
React tree, and React propagates events along the React tree rather than
the DOM tree, so submitting the tag form also submitted the project form.
The project was created immediately with no tags and the dialog closed
before more than one tag could be picked.

Stop propagation in the tag form's onSubmit, and select the new tag in
the selector so it is included when the project is saved.

Fixes #5117
2026-08-18 14:18:39 +03:00
Mauricio Siu 41d355c7dc fix: use dockerode API instead of shell docker ps for changePassword container lookup
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.
2026-08-18 02:19:41 -06:00
Mauricio Siu ff275fe94e fix: sync terminal size with backend PTY, avoid connecting with placeholder container ID
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.
2026-08-17 02:03:47 -06:00
Shuvo 2cb499fb64 fix: prevent Postgres 100-argument limit crash and restore data parity for restricted-member project access
The application table has 101 columns. The restricted-member branch of
project.one (apps/dokploy/server/api/routers/project.ts) queried the
applications relation with no columns narrowing, so Drizzle's relational
query builder generated a json_build_array call with one argument per
column, exceeding Postgres's FUNC_MAX_ARGS (100). Any non-owner/admin
member with limited access to a project containing at least one
application hit an opaque INTERNAL_SERVER_ERROR and got redirected away
from the project/environment page instead of seeing their project.

The same branch was also missing the "server" relation that the
owner/admin path (findProjectById) already includes, so restricted
members saw different (incomplete) data than owners/admins for the same
project.

Fixes this by extracting the existing serviceColumns column-selection
constant to a module-level export in packages/server/src/services/project.ts
and applying it (plus the server relation) to all 8 service relations in
the restricted-member query path, matching the owner/admin path.
2026-08-17 13:37:11 +06:00
Mauricio Siu b976c7b4f7 Merge pull request #5085 from Dokploy/feat/signup-showcase-panel
feat: interactive feature showcase on the signup panel
2026-08-14 10:02:17 -06:00
Mauricio Siu ac9ad72875 feat: interactive feature showcase on the signup panel
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.
2026-08-14 09:24:54 -06:00
Mauricio Siu d8b7c1ea5e feat: track cloud sign_up event in dataLayer
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.
2026-08-14 09:09:27 -06:00
Mauricio Siu aedb35b8df feat: enable Google Tag Manager on cloud version only
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.
2026-08-14 08:44:50 -06:00
Mauricio Siu 7b3c5355fa chore: update version to v0.30.0 in package.json 2026-08-14 00:40:40 -06:00
Mauricio Siu 1828e7c276 Merge pull request #5076 from Dokploy/feat/overview-dashboard
feat: add Overview dashboard (Services, Backups & Domains tabs)
2026-08-14 00:40:13 -06:00
autofix-ci[bot] d583ba8bd3 [autofix.ci] apply automated fixes 2026-08-14 06:26:26 +00:00
Mauricio Siu b8e8704493 refactor: adjust icon sizes and styles in overview components 2026-08-14 00:25:59 -06:00
Narciso 518ee44ea6 feat: move deployments into an overview page tab 2026-08-13 18:30:45 -04:00
Narciso 046a608f8c feat: add Overview dashboard (Services, Backups & Domains tabs) 2026-08-13 17:03:42 -04:00
Mauricio Siu 171c70492d refactor: remove deployment failure classifier and related tests 2026-08-13 15:03:35 -06:00
Mauricio Siu a4425cfb1d Merge branch 'canary' into feat/docker-health-dashboard 2026-08-13 14:45:23 -06:00
Mauricio Siu fc5b8d03e5 fix(gitlab): handle missing expires_in in OAuth token response
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
2026-08-13 14:41:10 -06:00
Narciso E. Núñez Arias 1183c7c4a9 Merge pull request #4317 from difagume/fix(ui)--prevent-layout-shift
fix(ui): prevent layout shift in log counter using tabular-nums
2026-08-13 15:14:38 -04:00
NoiceHax 98dbc59a02 fix(github-webhook): apply preview limit only to new previews
The preview deployment limit was checked before looking up whether the
pull request already had a preview, so once an application reached the
limit every `synchronize` event was dropped and existing previews went
stale while GitHub still saw a 200. The check now runs inside the branch
that creates a preview, uses the schema default of 3 when no limit is
configured (instead of 0, which blocked every app without an explicit
value) and compares with `>=` so the configured limit is inclusive.

Closes #4074
2026-08-13 22:46:40 +05:30
Narciso 95b1afc2c2 fix: correct log-tail server resolution, drop unrelated Networks gating
- Log tail for failed-deployment classification now checks the app's
  current buildServer before falling back to its server, matching the
  buildServerId-then-serverId precedence used everywhere else in the
  codebase (application.ts, drop.ts, directory.ts, patch-repo.ts).
- Removes a stale !isCloud gate on the Networks tab that this branch
  had reintroduced from before Mauricio removed it in daba2d7fb
  (Networks is intentionally shown in cloud now) — unrelated to this
  PR's scope, docker.tsx's Networks tab/content now matches canary.
2026-08-13 12:03:38 -04:00
Narciso E. Núñez Arias 52aca4636d Merge pull request #4583 from TpmyCT/fix/deployments-open-tab
fix: open deployments tab when opening a service from the deployments list
2026-08-13 11:19:58 -04:00
Narciso c741ff36c0 fix: don't auto-run Health diagnostics on mount
Reverts the mount-only auto-refetch — it still ran host shell, Docker,
DB, and SSH log-tail work before the user asked for it, just once
instead of on every filter change. Back to fully manual: nothing runs
until Check/Re-check is clicked, matching the panel's own copy
("Nothing runs automatically — click to check").
2026-08-13 11:15:12 -04:00
Narciso 4bf6dfff13 feat: add Docker Health diagnostics tab
Server diagnostics tab (Docker dashboard) with:
- Per-network IP usage: subnet capacity vs. containers in use, including
  reserved networks like dokploy-network which are excluded from the
  managed Networks tab. Surfaces read errors instead of silently showing
  zeroes when the Docker API call fails.
- Broadened daemon-error detection and failure classification for Swarm
  network failures: IP pool exhaustion on an existing network
  ("could not find an available IP", "task allocation failure") and
  network attach timeouts ("attaching to network failed", "context
  deadline exceeded") — both previously fell through as Unclassified.
  Verified end-to-end against a real systemd-managed dockerd.
- Failed-deployment rows now carry the raw log tail used for
  classification, shown on hover and linked to their service/project,
  so a guess (or lack of one) can be verified against the actual error
  and followed straight to the app.
- Daemon-error panel is a read-only code editor, always visible (not
  hidden when empty), prefixed with the actual "Logs from X to Y"
  window passed to journalctl so the --since window can be verified.
- "Download report" exports everything on screen (metrics + raw logs)
  as Markdown, so a customer can send one file instead of a screen-share.
- Health check now IS_CLOUD-gated the same way network sync already is:
  a cloud org can no longer omit serverId and have the check silently
  run against the shared platform host instead of their own server.

Includes an inotify diagnostics card (current vs. max_user_instances/
watches/queued_events) and a failed-deployments log with automatic
cause classification based on daemon/log error patterns.
2026-08-13 10:00:54 -04:00
Mauricio Siu a1a672b672 fix(auth): link SCIM-provisioned users through SSO and surface sign-in errors
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
2026-08-13 02:11:15 -06:00
Mauricio Siu c61163d721 feat: update icons for Sessions and S3 Destinations in the sidebar menu 2026-08-13 01:31:19 -06:00
Mauricio Siu a2329aed26 feat: add user filtering to session management and update search functionality 2026-08-13 01:25:15 -06:00
Mauricio Siu f6c1e77279 feat: implement session management with filtering and sorting capabilities 2026-08-13 01:22:49 -06:00
Mauricio Siu dbe2b38ea9 Merge branch 'canary' into feat/session-management 2026-08-13 00:40:34 -06:00
Mauricio Siu dc9c67129e fix: lock sidebar-inset scroll while a modal is open
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
2026-08-12 15:38:39 -06:00
Narciso 795f6f094e test: fix stale composeFile mock in domain enabled-filter test 2026-08-12 16:28:06 -04:00
autofix-ci[bot] 26c871946a [autofix.ci] apply automated fixes 2026-08-12 19:03:06 +00:00
Souvik Kumar 65198f6082 fix: add clipboard addon to docker container terminal
The docker container terminal did not load xterm's ClipboardAddon, so
pasting into it (e.g. a MariaDB shell) broke the cursor and left the
pasted text uneditable. The web server terminal already loads this addon;
this brings the container terminal in line with it.

Also dispose the terminal on cleanup so its addons don't leak on remount.

Fixes #5065
2026-08-12 23:43:05 +05:30
Narciso E. Núñez Arias 1c9a538457 Merge pull request #4328 from teoobarca/fix/tooltip-volumes-not-pruned
fix: tooltip incorrectly lists volumes among Daily Cleanup targets
2026-08-12 12:17:43 -04:00
Narciso E. Núñez Arias 3e10a8dd6d Merge pull request #4795 from yusoofsh/fix/4794-preserve-compose-mounts
fix(compose): preserve raw remote mounts
2026-08-12 11:47:04 -04:00
Mauricio Siu c2071bbbfd feat: add Images and Disk Usage tabs to docker dashboard
- 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.
2026-08-12 04:30:19 -06:00
Mauricio Siu 9412b52172 fix: disable minimumReleaseAge (broke builds on unrelated AWS SDK deps)
@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.
2026-08-12 04:26:27 -06:00
Mauricio Siu 7825537964 Merge pull request #5059 from Dokploy/feat/docker-events-tab
feat: add Docker events tab to docker dashboard
2026-08-12 04:11:48 -06:00
Mauricio Siu 3be9cdfe65 feat: add go-to-page input to Docker events pagination 2026-08-12 04:11:32 -06:00
Mauricio Siu fa7a54b4eb feat: add sorting and pagination to Docker events table 2026-08-12 04:09:39 -06:00
Mauricio Siu daba2d7fbc feat: add Docker events tab to docker dashboard
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.
2026-08-12 04:07:59 -06:00
Mauricio Siu 02edd6abe7 fix: remove Route53 endpoint override and pin AWS SDK to an aged version
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.
2026-08-12 04:01:01 -06:00
Mauricio Siu 37f0bba43f fix: resolve @ to the zone's apex domain before sending it to the provider
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.
2026-08-12 03:35:11 -06:00
Mauricio Siu 16f0f0eeb4 test: add dnsProvider to the enterprise-resources coverage list 2026-08-12 03:31:20 -06:00
Mauricio Siu 4d58f3987f feat: add DNS provider integration (Cloudflare, AWS Route53)
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
2026-08-12 03:25:25 -06:00
Mauricio Siu 3cad115155 feat: make organization selector larger and searchable (#5052)
Replaces the organization dropdown with a Popover + Command combobox: wider panel and a search input to filter organizations by name.

Closes #5043
2026-08-11 20:55:26 -06:00
Mauricio Siu 3fbd67fe4d fix: invalid replacement placeholder in redirect form (#5050) 2026-08-11 20:22:59 -06:00
Mauricio Siu 5492ed12a0 Add new journal entry for "0184_wonderful_absorbing_man" with version 7 2026-08-11 20:02:29 -06:00