865 Commits
Author SHA1 Message Date
Andras Bacsai 3bfeb14b7d style(logs): show deployment status dots like the service menu
Deployment options get the same status dot and Stopped caption as
services instead of colored badges, so the listbox no longer needs
labelClass.
2026-10-23 12:25:57 +02:00
Andras Bacsai 2e7cf8633b feat(logs): pick runtime log streams from service selectors
Replace the container accordion with Deployment and Service selectors
that show one stream, merging replica containers by timestamp. The
viewer fills the page, opens in text view, keeps whitespace, and only
lets grid rows expand when the detail shows more than the row.

Based on the proposal in discussion #12176 by PhilippMolitor.
2026-10-23 11:55:44 +02:00
Andras BacsaiandClaude Opus 5.5 6977d454ed style(ui): group small settings cards into sub-sections
Add a settings-subsection component and merge small cards on the
advanced settings, application advanced, healthcheck, Docker cleanup,
and GitLab/Gitea source pages. Update outdated tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 10:55:30 +02:00
Andras Bacsai c454f84545 fix(server-transfer): keep imported data exact and guard archived servers
- 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
2026-10-22 15:52:20 +02:00
Andras BacsaiandClaude Opus 5.5 dbc3fb91bf fix(cdn): fetch versions.json once per hour, spread evenly across instances
- 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>
2026-10-21 18:10:48 +02:00
Andras BacsaiandClaude Opus 5.5 b1f2abf868 fix(cloud): refresh local versions.json hourly on every node
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 17:18:56 +02:00
Andras Bacsai 0732e74553 fix(server-transfer): require deploy permission for import checks
Require write and deploy abilities on the import check endpoint, and clarify the target token permissions in transfer messages and UI.
2026-10-20 14:15:30 +02:00
Andras BacsaiandClaude Opus 5.5 65a7bd5c05 chore: merge main into release/v4.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 13:37:20 +02:00
Andras Bacsai 57faba1b96 fix(logs): prevent URL redaction from spanning log lines (#12238) 2026-10-20 10:49:29 +02:00
Andras Bacsai bf957e425f fix(docker): parse quoted and hyphenated custom docker option values (#12208) 2026-10-19 23:12:16 +02:00
Andras Bacsai cf71fda5c1 feat(gitea): add Gitea App sources and private repo deployments (#12234) 2026-10-19 21:58:30 +02:00
Andras Bacsai 62be8674bc feat(proxy): add optional permanent redirects for apps and services (#12233) 2026-10-19 21:46:12 +02:00
Andras Bacsai fb6d3e7c9b fix(proxy): exclude SSE streams from Traefik compression (#12229) 2026-10-19 21:43:51 +02:00
Andras Bacsai 54315b10e5 fix(compose): strip UTF-8 BOM before parsing Docker Compose YAML (#12223) 2026-10-19 21:21:15 +02:00
Andras Bacsai dd456625ec Merge remote-tracking branch 'origin/release/v4.5' into release/v4.5 2026-10-19 15:03:38 +02:00
Andras BacsaiandClaude Opus 5.5 4ca0b4415c feat(patches): add automatic security updates per server
- New server settings: is_auto_security_updates_enabled and
  auto_security_updates_time (maintenance window, HH:MM in the time zone
  of the server). Both move with a server transfer.
- Debian/Ubuntu: install unattended-upgrades and write
  52coolify-unattended-upgrades. `#clear` drops the distro origin lists,
  so only the security origins stay (Debian <codename>-security, Ubuntu
  <codename>-security, and the Ubuntu Pro ESM security origins). A
  drop-in for apt-daily-upgrade.timer sets the time.
  https://manpages.debian.org/bookworm/apt/apt.conf.5.en.html
  https://github.com/mvo5/unattended-upgrades/blob/master/README.md
- RHEL family: install dnf-automatic (dnf5-plugin-automatic on dnf5),
  set upgrade_type = security and apply_updates = yes in
  /etc/dnf/automatic.conf, and add a drop-in for dnf-automatic.timer
  (dnf4) or dnf5-automatic.timer (dnf5).
  https://dnf.readthedocs.io/en/latest/automatic.html
  https://dnf5.readthedocs.io/en/latest/dnf5_plugins/automatic.8.html
- Off removes the Coolify files, so the operating system default comes
  back. Other package managers show "not supported".
- The schedule and the automatic updates share one form and one
  unsaved bar. The remote commands run only when the automatic update
  settings change; a failure keeps the old setting.
- Commands are written for non-root SSH users (tee and single sh -c
  scripts) and were run in Debian 12, Ubuntu 24.04, Rocky 9, and Fedora
  containers as root and as a sudo user.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:41:42 +02:00
Andras BacsaiandClaude Opus 5.5 3da85e2c07 feat(patches): mark security updates, reboot state, and risky packages
- 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.html
  https://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.md
  https://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>
2026-10-19 10:39:51 +02:00
Andras BacsaiandClaude Opus 5.5 6806ed31fa feat(patches): save check results and run checks in a queued job
- 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>
2026-10-19 10:28:51 +02:00
Andras BacsaiandClaude Opus 5.5 df17797d8f fix(patches): run apt without prompts, check pacman safely, show dnf versions
- apt: use apt-get with DEBIAN_FRONTEND=noninteractive and keep changed
  configuration files (--force-confdef/--force-confold). A single package
  uses install --only-upgrade, so it is never installed when missing.
- pacman: do not run `pacman -Sy` on the live database during the check.
  Use checkupdates (with fakeroot) or a temporary sync database, the same
  method checkupdates uses. pacman 7 downloads as the alpm user, so the
  temporary directory is 755. Arch allows only "Update all" (-Syu), because
  partial upgrades are unsupported.
  https://man.archlinux.org/man/checkupdates.8
  https://wiki.archlinux.org/title/System_maintenance#Partial_upgrades_are_unsupported
- dnf: list upgrades with `repoquery --upgrades --latest-limit 1 --qf`
  (dnf5 needs the explicit \n, dnf4 prints empty lines) and read the
  current versions from `rpm -qa`. The package name has no .arch suffix.
  https://dnf5.readthedocs.io/en/latest/changes_from_dnf4.html

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:21:59 +02:00
22a8c09dd6 Next (#12202)
Co-authored-by: Aditya Tripathi <aditya@climactic.co>
Co-authored-by: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rosslh <ross@rosshill.ca>
Co-authored-by: Abdulfetah Suudi <suudiabdulfetah@gmail.com>
Co-authored-by: Dharmveer <51308779+dharmveer97@users.noreply.github.com>
Co-authored-by: Maxwell <136101+mxswd@users.noreply.github.com>
2026-10-19 10:07:23 +02:00
Andras BacsaiandClaude Opus 5.5 a82d32c946 chore: merge main into release/v4.5
Resolve conflicts between main's security fixes and v4.5 features:
- Keep v4.5 features (log redaction, multi-S3 backups, transfer flow,
  scheduled task modal, sidebar) and port main's fixes into them.
- Reuse RequiresDeployAbility for the Hostinger create endpoint.
- Align MCP tool abilities and descriptions with main's new deploy
  requirements, and use deploy tokens in the affected MCP tests.
- Drop the duplicate DockerCleanupJobTest helper and tests, and the
  exportBundle test for a method v4.5 removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:00:05 +02:00
Andras Bacsai 7fe40f4cf6 fix(api): require deploy ability for server side effects
Require deploy permission for API changes that trigger server side effects, including resource deletion, storage access, provider operations, and database imports. Also escape Docker cleanup filters and sanitize log drain server names.
2026-10-19 09:07:42 +02:00
e3d4411ff2 chore: merge main into release/v4.5 (#12192)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Furox <177975472+Furox-Art@users.noreply.github.com>
Co-authored-by: johandenhollander <johan.den.hollander@finalist.nl>
Co-authored-by: João Cruz <161638790+SrJooJ@users.noreply.github.com>
Co-authored-by: Saim Hashmi <hashmisaim037@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-18 23:43:20 +02:00
Andras BacsaiandClaude Opus 5.5 7c14c0098e feat(server-transfer): run instance migration as a background job (#12180)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 22:03:45 +02:00
Andras Bacsai 34b3a18307 fix(compose): resolve ../ bind sources in raw compose mode
oldRawParser made the bind directory of a long-syntax source like
../data at {workdir}./data, next to the path that Docker Compose uses.
Resolve the source with replaceLocalSource(), as the compose parsers do,
so Coolify makes the directory that the container mounts. A source that
resolves above / now stops the deployment before remote work.

Closes #4055
2026-10-18 12:09:42 +02:00
Andras Bacsai 420692c020 fix(upgrade): keep Coolify running when Docker reports IPv6 gateways with a prefix
Docker Engine 27.0 to 28.0.0 reports an IPv6 network gateway with its
prefix length (fd00::1/64) until the daemon restarts (moby/moby#49520).
The Docker CLI 29 and Compose 5 in the helper image reject it, so
deployments failed and the upgrade left Coolify stopped.

- Stop the upgrade before it changes containers when the coolify network
  has such a gateway, and tell the user to restart or upgrade Docker.
- Create a new coolify network again without IPv6 when Docker reports
  its gateway with a prefix.
- Report an error, not "Upgrade complete", when the new Coolify
  containers do not start.
- Add the fix to deployment errors that contain this ParseAddr failure.

Fixes #11583
2026-10-16 21:19:35 +02:00
Andras BacsaiandClaude Opus 5.5 69e448dac9 fix(installer): do not restart Docker with running containers
Merge log rotation and the network pool into the existing daemon.json
instead of overwriting it. Skip the change and the Docker restart when
containers are running, unless DOCKER_POOL_FORCE_OVERRIDE=true.

Closes #11221

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:10:35 +02:00
Andras BacsaiandClaude Opus 5.5 f5c88f7e4f fix(deploy): do not pull locally built compose images before stop
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>
2026-10-16 00:19:17 +02:00
Andras BacsaiandClaude Opus 5.5 97f451cc2a fix(installer): change data directories only after checks and downloads
install.sh created the resource directories and ran chown -R and
chmod -R on source, ssh, and images before step 1. When a check or a
CDN download failed, the changed owners and modes stayed although
nothing was installed.

Create only /data/coolify and source (for the log and the downloads)
at the start. Create the other directories and set the permissions in
the SSH key step, after the checks and downloads succeed.

Closes #11973

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 00:09:47 +02:00
Andras BacsaiandClaude Opus 5.5 6b3f60c7d6 fix(docker): ship versions.json in production image
Closes #11868

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 23:38:06 +02:00
Andras Bacsai 12fd9e448b fix(upgrade): retry rate limited image pulls and spread auto updates
Closes #11890
2026-10-15 23:36:47 +02:00
Andras BacsaiandClaude Opus 5.5 3414b88e0d fix(applications): ignore missing health on additional server status
Closes #11892

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 23:33:52 +02:00
Andras BacsaiandClaude Opus 5.5 3fbb8da5ff fix(service): add seadoc server to seafile template for wikis
Closes #11976

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 23:27:15 +02:00
Andras BacsaiandClaude Opus 5.5 2a202d9fe9 fix(domains): apply noindex to domains that include a port
Closes #11965

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 23:20:23 +02:00
Andras BacsaiandFurox 6cf1516749 fix(server): accept OS derivatives through ID_LIKE in validateOS
validateOS matched only ID from /etc/os-release, so derivatives such as
Omarchy, CachyOS, Manjaro or Linux Mint failed validation before the
Docker checks ran. Check ID first, then each ID_LIKE entry, and keep the
exactly-one-match rule. Move the parsing into a testable function.

Closes #12033

Co-authored-by: Furox <177975472+Furox-Art@users.noreply.github.com>
2026-10-15 22:35:45 +02:00
Andras BacsaiandClaude Opus 5.5 7466da12a2 fix(git): accept ssh:// repository URLs with custom ports
The repository URL rule rejected ssh://user@host:port/path, so deploy-key
resources on servers with a custom SSH port needed a manual URL edit after
creation. Accept ssh:// URLs and keep them unchanged for deploy keys so the
port reaches the clone. Rename scpStyleGitUrlToHttps to sshGitUrlToHttps and
let it convert ssh:// URLs too, so public flows, repository links and GitHub
App repository slugs handle them.

Closes #12161

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 22:30:26 +02:00
cf6350e665 feat(analytics): city-level traffic analytics, sortable tables, lighter globe (#12158)
Co-authored-by: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 15:24:06 +02:00
Andras Bacsai 521b3cb90f feat(mcp): add REST-backed resource management tools (#12163) 2026-10-14 13:26:12 +02:00
github-actions[bot] cc6378177c Merge remote-tracking branch 'origin/main' into release/v4.5 2026-10-14 08:27:56 +00:00
Andras Bacsai d080bf35e6 refactor(policies): remove unused authorization methods (#12165) 2026-10-14 10:18:05 +02:00
Andras Bacsai 448dc8ea0a feat(logging): strengthen secret redaction and add admin controls (#12151) 2026-10-13 20:43:19 +02:00
Andras Bacsai f63726279c Merge remote-tracking branch 'origin/release/v4.5' into sentinel-metrics-sidebar-page 2026-10-13 11:57:47 +02:00
Andras Bacsai d77580cb35 fix(metrics): fetch fleet data concurrently and refresh server access
Run metric requests in batches of eight workers, isolate endpoint failures,
and preserve CPU and memory history when Sentinel lacks a summary endpoint.
Repair Sentinel tokens before creating workers and bound SSH fetch timeouts.

Reauthorize team servers on refresh and hydration, clear stale metrics after
transfers or deletions, and resolve container metadata for team ID zero.

Use only root filesystem samples when mount fields are present, while
supporting legacy disk data. Add regression coverage for concurrent workers,
access changes, endpoint failures, and disk mapping.
2026-10-13 11:56:39 +02:00
Andras Bacsai 83384a7b95 Merge remote-tracking branch 'origin/release/v4.5' into automation/sync-main-to-release-v4.5 2026-10-12 22:30:41 +02:00
Andras Bacsai 200af07225 Merge remote-tracking branch 'origin/release/v4.5' into automation/sync-main-to-release-v4.5 2026-10-12 21:38:45 +02:00
Andras Bacsai 7837a07ba2 fix(notifications): disable channels after repeated configuration failures
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.
2026-10-12 14:37:58 +02:00
Andras BacsaiandClaude Opus 5.5 213a61b7ab fix(env): pass exact env values to containers, keep old escaping for existing variables (#12024)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:06:45 +02:00
🏔️ Peak 856735613d feat(backups): back up the coolify database before an update (#12093) 2026-10-12 00:59:14 +02:00
Andras Bacsai cdd8f82840 fix(compose): preserve environment variable semantics (#11794) 2026-10-11 21:02:11 +02:00
Andras Bacsai 1e42284db0 feat(proxy): override the Traefik certificate resolver per resource
Applications and service applications can now use the server resolver,
no resolver ("none"), or a custom resolver name. This allows servers
that mix Let's Encrypt domains with domains that use their own
certificates, such as Cloudflare Origin CA. The setting is available in
the UI and the API.

Closes #12138
2026-10-11 19:01:27 +02:00