- Skip TrimStrings and ConvertEmptyStringsToNull on the import route; an empty shared variable failed the whole import
- Keep compose parser versions, static ports, legacy variable keys, and only the bundle's variables and destinations
- Give the transfer back token the deploy permission that the import needs
- Move the Cloudflare tunnel DNS record with the server and park it on the source
- Refuse cloud server deletes, power on, tunnel and DNS changes, and scp for archives; skip their backup alerts and provider polling
- Add a column-level round-trip test, archive guard tests, and a live full-coverage transfer test
- Advance the GitLab App sequence in the dev seeder
- Retry CDN requests only for transient errors and honor Retry-After
(Cloudflare error 1200 sends 60 s), with jitter.
- Read helper and Sentinel versions from the local versions.json, which
the hourly update check refreshes, instead of fetching per job/server.
- Replace the random 0-600 s delay with a stable per-instance offset
inside the cron interval (max 1 h).
- Manual update checks and upgrades make one CDN attempt only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Build a valid compose device request (device_ids list, options mapping, blank driver)
- Map --gpus N to count and drop --gpus when GPU settings are enabled
- Validate only changed GPU values so stored legacy values keep working
- Detect NVIDIA GPUs and the container toolkit with the server details
- Show detected GPUs with a refresh button in the application GPU section
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Security updates: apt marks a package from a "-security" suite (Debian
12 now reports oldstable-security). dnf reads `dnf updateinfo list
--security` (dnf5 keeps updateinfo as an alias of advisory). zypper
uses `zypper -x patch --dry-run --category security`, because
`zypper -x list-patches` ignores --category and has no package names.
pacman and apk cannot tell, so they show no security count.
https://dnf5.readthedocs.io/en/latest/commands/advisory.8.htmlhttps://github.com/openSUSE/zypper/blob/master/doc/zypper.8.txt
- Reboot required: /var/run/reboot-required, `needrestart -b` (KSTA 2
or 3), `dnf needs-restarting -r` (matched by text, because a missing
plugin also exits 1), and `zypper needs-rebooting` (exit 102).
https://github.com/liske/needrestart/blob/master/README.batch.mdhttps://dnf-plugins-core.readthedocs.io/en/latest/needs_restarting.html
- An explicit risk list per package manager (Docker engine, kernels,
libc/glibc/musl, systemd, dbus, openssh) replaces the "name contains
docker/kernel" guess on the page and in every notification channel.
- The page shows security and reboot badges, a security count, and the
risk of each package. "Reboot server" (with confirmation, update
policy on the loaded server) schedules the reboot with systemd-run and
checks the server again five minutes later. Archived (transferred)
servers are never touched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- server_settings gets patch_check_result (JSON), patch_check_error,
patch_checked_at, and patch_check_frequency.
- The patches page shows the saved result and "Last checked" on load.
"Check for updates" queues ServerPatchCheckJob (manual) instead of
running SSH in the Livewire request. The job saves the result and
broadcasts ServerPatchCheckFinished on the server team channel; the
page reloads the saved result (with a 10 s poll as a fallback).
- A finished package update (callEventOnFinish) queues a new check on
the server side, so the page no longer depends on the browser.
ServerPackageUpdated is removed.
- The check frequency is a server setting (cron or preset, at most once
per hour). Empty keeps the staggered weekly default.
- The failure notification is sent only when the state changes from ok
to error, not on every check.
- Page access needs viewSecurity and every action needs update on the
loaded server; a member gets 403. Updates accept only a package from
the saved result.
- Server transfer: the frequency moves, the last result stays on the
source (runtime).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rollback now also lists the commit images of the last 10 successful
deployments when the application pushes to a Docker registry. The
deployment pulls such an image when the server no longer has it.
The page and the API share GetRollbackImages, and the API returns a
source field (local or registry).
GNU tar exits with 1 when a file changes while it is read. The archive
is still valid, so only exit codes above 1 fail the backup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Add a per-task overlap lock to ScheduledTaskJob that outlives the worker
timeout, so a long or killed run cannot overlap the next cron run.
- Mark the dropped occurrence as skipped instead of releasing the job.
Closes#11648
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Skip the pre-stop pull when a custom build command runs without a build server, and pull only services whose image does not come from a build, including services that reuse the image of a build service.
Closes#11773
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mc release in coolify-helper 1.0.17 panics on `mc pipe --quiet`.
Drop the flag and keep the progress bar out of failure messages by
printing only real errors and the last progress frame.
Closes#11995
The docblocks for reapOrphan and removeMultiplexFile now name
SSH_MUX_ORPHAN_REAP_ENABLED as the flag behind the dry-run default.
Operators can see which setting turns on real reaping.
GitHub reports team-granted and private org members as CONTRIBUTOR or
NONE, so their same-repository PRs were silently skipped when public PR
deployments were off. A same-repository branch already requires push
access, so gate only on fork status, treat an unknown head repository as
a fork, and log skipped fork PRs.
Closes#9271
Retry the installation token request on GitHub 5xx and connection errors,
and report the HTTP status when GitHub sends no error message. Retry the
repository import when SSH drops the connection (exit code 255), after
stopping the interrupted clone and removing the partial checkout.
Closes#8004
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CheckHelperImageJob now logs a warning and returns when the versions
endpoint fails instead of sending an internal notification and
rethrowing. The next scheduled run retries. PullTemplatesFromCDN also
no longer sends internal notifications on non-success responses or
exceptions; it still logs them.
Add tests checking that the stored helper version is kept and that no
notification is sent when the CDN is unavailable.
- Fetch every page of pull request files so watch paths match PRs with more than 30 files.
- Deploy the preview and log a warning when the changed-file list is unknown (API error or truncated compare list).
- Log when watch paths decline a preview deployment.
- Keep the GitHub App installation token in memory per instance, so a deployment requests one token instead of 3-5.
Closes#12169
Add a /dashboard/canvas page that renders every team server with its
resources and their running or queued deployments, backed by a new
ServerCanvasController::dashboard endpoint and a per-server usage
endpoint for zone headers. The dashboard remembers the list/canvas
choice and each section (projects, servers) its own table/grid view.
- Show Deploying/Queued pills on canvas cards and a foldable recent
deployments panel; add shared CanvasControls component
- Allow backup downloads from the server host via the S3 download
storage (PrepareFileDownloadJob accepts a null container)
- Extract backup toggle/run actions into ManagesDatabaseBackup and
surface them in backup execution headers; merge S3 and retention
sections into the general backup settings
- Move deployments indicator to the top bar and add a main nav
resource menu with submenus; simplify breadcrumbs and settings
layouts
- Add shared variables overview canvas and scheduled task modals
- Add feature tests for dashboard canvas, view modes, navbar
submenus, backup S3 downloads and scheduled task modals
Count invalid keys, tokens, and deleted webhooks in a new failure_count column
on each notification settings table, like servers.unreachable_count. After 3
failures in a row the channel is disabled and the team is told by instance
email and its other channels. Rate limits and server errors are retried and
not counted; test notifications never count.
Use the helper's RAILPACK_VERSION, falling back to the installed CLI
version, instead of a hardcoded frontend version. Add regression tests
for both version sources and application-variable isolation.
Store server IPs in one form (no brackets, short lower-case IPv6) and
write each address in the form its context needs:
- URLs and host:port (Sentinel, database URLs, SFTP backup download,
DNS servers, SMTP, webhook base URLs, links, health checks) get
brackets through formatHostForUrl().
- Traefik Host() rules use the address without brackets, so IPv6
domains no longer return 404; saved labels are fixed at deploy.
Caddy keeps the brackets.
- SSH keeps the plain address.
- Hetzner gives an IPv6 /64 network; IPv6-only servers now get the
server address (prefix::1) instead of the unusable prefix::64.
- sslip labels, registry image names with an IPv6 host, the API domain
list, allowlist matching and duplicate checks handle IPv6.
A migration normalizes stored IPv6 server addresses, repairs Hetzner
servers saved as ::64 that are not reachable, and adds brackets to
saved Sentinel URLs.
mc --resolve applies per invocation and is not stored in the alias, so
mc cp resolved the S3 host again inside the helper container. On hosts
with split DNS this failed with "no such host", and the upload did not
use the IP validated by SafeWebhookUrl.
Fixes#12129