Commit Graph

7101 Commits

Author SHA1 Message Date
Yash Kumar 52ea2ce071 Merge branch 'Dokploy:canary' into fix/deployments-filter-bar-inline-layout 2026-09-26 09:28:03 +05:30
Mauricio Siu a0e0574bcd Merge pull request #5515 from Dokploy/fix/trial-billing-interval-switch
fix(billing): allow switching billing interval during trial
2026-09-23 15:09:24 -06:00
Mauricio Siu c453ac3a2f fix(billing): allow switching billing interval during trial
Switching plan mid-trial always forced the monthly price and there was no
way to move to annual. Preserve trial_end on the Stripe update so changing
the interval does not reset the billing cycle and end the trial early.
2026-09-23 15:06:54 -06:00
Yash Kumar 3563f585f9 Merge branch 'Dokploy:canary' into fix/deployments-filter-bar-inline-layout 2026-09-20 12:39:36 +05:30
Dokploy Bot f397c1a862 chore: sync hotfix from main into canary [skip ci] 2026-09-18 09:04:20 +00:00
Mauricio Siu 16ac4633f3 Merge pull request #5477 from Dokploy/feat/trial-expiration-emails
fix(billing): pick a plan for the trial and warn before it expires

(cherry picked from commit d7d75f7c5c)

[skip ci]
2026-09-18 09:04:19 +00:00
Mauricio Siu d7d75f7c5c Merge pull request #5477 from Dokploy/feat/trial-expiration-emails
fix(billing): pick a plan for the trial and warn before it expires
2026-09-18 03:04:07 -06:00
Mauricio Siu a0e1001808 feat(trial-notifications): add email notification for expiring trials and integrate with webhook 2026-09-18 03:03:51 -06:00
Mauricio Siu 8236c31fcd Revert "fix(billing): one reminder at 1 day, guarded by an advisory lock"
Revert "fix(billing): stop the reminder claim from rewriting stale metadata"

This reverts commits 037230496 and 14e059784.
2026-09-18 02:49:18 -06:00
Mauricio Siu 037230496c fix(billing): one reminder at 1 day, guarded by an advisory lock
Cloud runs two frontend replicas and node-schedule fires on each, so both
would read the same unset marker and every trial user would get the email
twice. A Postgres advisory lock lets one replica run and the other skip;
it lives in the connection rather than the schema, so no migration.

Drops the 3-day reminder, leaving the single notice before billing starts.
2026-09-18 02:45:46 -06:00
Mauricio Siu 14e059784c fix(billing): stop the reminder claim from rewriting stale metadata
Stripe merges metadata on update, so spreading the snapshot read during
the list call re-asserted stale values over anything written since. Send
only the key being claimed.

The claim is not exclusive and the comment no longer says it is: two
replicas can still read the same unset marker. Marking before the send
only keeps a crash mid-send from resending on the next run.
2026-09-18 02:41:28 -06:00
Mauricio Siu f34151bc12 refactor(billing): drop the runTrialExpirationJob endpoint
Removes the manual trigger and the root guard it needed. The cron job is
the only caller now, so processTrialExpirations goes back to module private.
2026-09-18 02:39:33 -06:00
Mauricio Siu d00ae31920 refactor(billing): drop the sendTestTrialEmail endpoint
The scan endpoint already covers manual runs, so the one-off sender was
redundant. sendTrialExpiringEmail goes back to being module private.
2026-09-18 02:38:02 -06:00
Mauricio Siu 95b2712c26 fix(billing): pick a plan for the trial and warn before it expires
Trials were always Hobby, so a trial user who wanted Startup had to go
through Checkout, which created a second subscription on the same
customer. Seven days later Stripe cancelled the trial sub and the webhook,
matching only on customer id, zeroed serversQuantity and deactivated the
servers of someone who was already paying.

The trial now starts on the plan the user chooses and switching plans
mutates that same subscription, so a customer never holds two.

- startFreeTrial takes a tier; TRIAL_SERVER_LIMIT becomes TRIAL_SERVER_LIMITS
  (Hobby 1 server, Startup 3)
- onboarding offers both plans with a trial and a subscribe button
- billing exposes Switch to Startup/Hobby during the trial and hides the
  checkout CTAs and server steppers that would create a second subscription
- upgradeSubscription caps the server count to the plan's included servers
  while trialing and skips proration, which emitted an orphan invoice
- webhook treats trialing as active instead of disabling servers, and
  guards invoices that carry no subscription
- getBillingStatus reports hasPaymentMethod, so the banners stop asking for
  a card once one is on file
- new cloud-only daily job emails trial users without a payment method at 3
  and 1 days left, deduped through subscription metadata claimed before the
  send so concurrent replicas cannot double-send
2026-09-18 02:35:27 -06:00
Yash Kumar 1e9873b3e4 fix(ui): change filter layout breakpoint to lg to prevent overflow on tablets 2026-09-12 15:59:18 +05:30
Yash Kumar 26317e9126 feat(ui): inline deployments filter bar and fix layout jumping 2026-09-12 15:50:08 +05:30
Mauricio Siu 853ca33659 Merge pull request #5416 from Dokploy/fix/critical-next-rce-16.3.4
fix(deps): bump next to 16.3.4 to patch critical RCE advisories
2026-09-11 02:20:20 -06:00
Mauricio Siu a90c2a662f Merge pull request #5418 from EgerDev/feat/compose-models
feat(compose): support models in Compose specification
2026-09-11 02:20:07 -06:00
EgerDev 45dcdfc5be test(compose): tighten models types and regression tests 2026-09-11 00:11:40 -07:00
EgerDev 29cdc815db feat(compose): support AI models in Compose specification 2026-09-10 20:28:28 -07:00
Narciso E. Núñez Arias 9fa98de9c1 Merge pull request #5350 from RezaRahemtola/fix/ntfy-database-backup-newline
fix(notifications): add missing newline to ntfy database backup message
2026-09-10 19:00:08 -04:00
Dokploy Bot a4a1d15656 chore: sync hotfix from main into canary [skip ci] 2026-09-10 22:40:21 +00:00
Narciso E. Núñez Arias 8075a7ce95 Merge pull request #5358 from KingIronMan2011/patch-1
feat: added missing Railpack versions
(cherry picked from commit 326908869d)

[skip ci]
2026-09-10 22:40:19 +00:00
Narciso E. Núñez Arias 326908869d Merge pull request #5358 from KingIronMan2011/patch-1
feat: added missing Railpack versions
2026-09-10 18:40:09 -04:00
Narciso E. Núñez Arias 18d07c7254 Merge pull request #5364 from maks-oleksyuk/chore/ci-update-actions
chore(ci): update GitHub Actions to latest versions and harden workflows
2026-09-10 18:32:42 -04:00
Narciso 4cd4b83523 fix(deps): bump next to 16.3.4 to patch critical RCE advisories
GHSA-2xp9-vwfh-vxw4 and GHSA-p293-qw3h-jr36
2026-09-10 18:23:38 -04:00
Narciso E. Núñez Arias f91b2e2ca6 Merge pull request #5414 from aspatari/fix/infisical-imported-secrets
fix(vault): read Infisical secrets pulled in through an import
2026-09-10 18:16:08 -04:00
Artur Spatari e70c880612 test(vault): lock the precedence between two imports
Review flagged that multi-import collisions were untested. The order the code
implements is the documented one — Infisical: "If two imports carry a secret
with the same name, the value from the bottom-most import wins" — and the
response lists imports in that order, so sequential assignment matches it.

Added a case with two imports defining the same key. Reversing the merge order
in the client fails it, so the test pins the behaviour rather than restating
the implementation.

vault.test.ts: 58 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 10:32:09 +03:00
Artur Spatari 0c1dfe978c fix(vault): read Infisical secrets pulled in through an import
Fixes #5413. A secret brought into a folder with "Import Secrets" was reported
as not found. Two reasons, and the first is easy to miss:

The list endpoint takes the flag in **snake_case**. `includeImports` is
silently ignored — the request still returns 200, with `imports` present but
empty — so the imported secret looked like it simply did not exist. Measured
against app.infisical.com with a registered import (confirmed via
GET /api/v1/secret-imports):

  expandSecretReferences=true                        imports[] empty
  expandSecretReferences=true&includeImports=true    imports[] empty
  expandSecretReferences=true&include_imports=true   imports[] has the secret

Second, imported secrets never appear in `secrets` — they come back in a
separate `imports` array, one entry per source path, which the client did not
read at all.

Imported entries are merged before the folder's own, so a name defined in both
resolves to the local value, matching how Infisical resolves it.

Also measured, for whoever looks next: `/api/v4/secrets` returns imports with
no flag at all, and single-secret reads (`/raw/{name}`) never see an imported
key — 404 on v3, no such route on v4. So a folder listing is the only way to
reach them.

vault.test.ts: 57 passed. Reverting the fix fails the new merge test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 10:26:52 +03:00
Mauricio Siu 88118cdb3f Merge pull request #5411 from Dokploy/fix/fresh-volumes-danger-zone
fix(compose): move Fresh Volumes into a Danger Zone with typed confirmation
2026-09-09 17:48:16 -06:00
Mauricio Siu 38d157adc0 fix(compose): move Fresh Volumes into a Danger Zone with typed confirmation 2026-09-09 17:47:16 -06:00
Mauricio Siu 3b1fec5409 Merge pull request #5410 from Dokploy/feat/compose-pull-images
feat(compose): pull latest images on deploy toggle
2026-09-09 17:14:43 -06:00
Mauricio Siu 49b8214e5d feat(compose): add pull latest images on deploy toggle 2026-09-09 17:13:24 -06:00
Mauricio Siu ec31739e0e Merge pull request #5396 from Dokploy/feat/transfer-service-between-servers
feat: transfer services between servers
2026-09-09 13:21:27 -06:00
Narciso E. Núñez Arias d5328703fa Merge pull request #5407 from imrja8/fix-sso-flash 2026-09-09 13:15:29 -04:00
Narciso E. Núñez Arias f4cb26cbf4 Merge pull request #5406 from imrja8/fix-settings-layout-width 2026-09-09 13:12:41 -04:00
Yash Kumar a6c1f3048f fix(ui): standardize settings layout widths to full width 2026-09-09 21:24:03 +05:30
Yash Kumar 9cae609a0a fix(auth): prefetch SSO state in SSR to prevent layout flash 2026-09-09 20:09:23 +05:30
Mauricio Siu 2c234d6e20 test(transfer): shrink pipe payload and set an explicit timeout so the suite does not time out in CI 2026-09-09 02:57:51 -06:00
Mauricio Siu 9dcdb53aa1 feat(transfer): move services between servers with their volumes, mounts and config
Adds a Transfer action on every service page that moves an application,
compose or database to another server without S3: volumes, bind mounts
and deployment logs are streamed through the panel (ssh2/spawn pipe),
file mounts and Traefik config are recreated on the target, the source
is cleaned up and the service is deployed on the target. Failures before
cleanup roll back to the source server.
2026-09-09 02:50:29 -06:00
Mauricio Siu bda8124291 Merge pull request #5351 from Dokploy/fix/dependabot-critical-security-updates
fix: resolve 6 critical Dependabot alerts
2026-09-08 16:29:38 -06:00
Mauricio Siu 6dcd0e1859 Merge pull request #5381 from Dokploy/canary
🚀 Release v0.30.6
v0.30.6
2026-09-08 16:24:12 -06:00
Mauricio Siu 85786a3196 Merge pull request #5386 from Dokploy/fix/server-health-address-pools
fix(server-health): detect custom default-address-pools via docker info
2026-09-08 16:04:50 -06:00
Mauricio Siu ea3f9f3b53 fix(server-health): detect custom default-address-pools via docker info
/etc/docker/daemon.json isn't mounted into the dokploy container, only
docker.sock is, so cat-ing it always failed silently. Read the effective
config over the already-mounted socket instead.

Fixes #5383
2026-09-08 16:01:48 -06:00
Narciso E. Núñez Arias e99a98e4fe Merge pull request #5375 from aspatari/feat/infisical-path-in-reference
feat(vault): address an Infisical folder from the reference
2026-09-08 16:54:01 -04:00
Artur Spatari 5611662351 feat(vault): address an Infisical folder from the reference
An Infisical provider is pinned to one non-recursive `secretPath`, so reading
two folders means two providers, two machine identities and two sets of
credentials to rotate. This lets a reference name the folder instead:

    ${{vault.my-provider.external/sentry:SENTRY_DSN}}

`<path>:<KEY>` mirrors the HashiCorp client in this directory, which already
documents that exact format. A relative path resolves against the provider's
`secretPath`, a leading slash is absolute, and a ref without a colon keeps its
current meaning — the whole ref is the secret name at the provider's own path.

A dot cannot be the separator here: Infisical accepts dots inside secret names
(`A.B.C` is a valid key), so `provider.a.b.C` cannot be split unambiguously
and would silently break anyone using such a name.

Refs are grouped by resolved path so each path is listed once, and the login
happens once per batch rather than once per path.

Tests cover the bare ref, relative and absolute paths, a provider at `/`,
grouping with a single login, the error naming the path, and a malformed ref.
2026-09-08 21:38:24 +03:00
Narciso E. Núñez Arias 887a457f15 Merge pull request #5374 from aspatari/fix/infisical-expand-secret-references
fix(vault): expand Infisical secret references when listing secrets
2026-09-08 14:08:52 -04:00
autofix-ci[bot] df4e299545 [autofix.ci] apply automated fixes 2026-09-08 17:43:47 +00:00
Narciso E. Núñez Arias aaff71bbf6 Merge pull request #5382 from imrja8/fix/dns-upsert-preserve-existing-records
fix(dns): match record content in upsertRecord to prevent overwriting existing records
2026-09-08 13:39:32 -04:00
Yash Kumar be128d5a4a Merge remote-tracking branch 'upstream/canary' into fix/dns-upsert-preserve-existing-records
# Conflicts:
#	packages/server/src/utils/dns/infomaniak.ts
2026-09-08 22:54:00 +05:30