Commit Graph
18028 Commits
Author SHA1 Message Date
Andras BacsaiandClaude Opus 5.5 3bc7e47a86 feat(patches): confirm before turning automatic security updates on or off
Automatic security updates now have their own "Turn on" / "Turn off"
action with a confirmation, instead of a field that the Save bar
applied. The confirmation explains what can stop:

- Docker from the operating system packages (docker.io, moby-engine)
  restarts on a security update, so all containers stop and start.
- Docker CE from the Docker repository is not updated: its repository
  has no security origin (apt) and no security advisories (dnf).
  Checked on Debian 12 (unattended-upgrade --dry-run skips docker-ce)
  and CentOS Stream 9.
- Services that use an updated library can restart; a new kernel is
  installed without a reboot.

The on/off state is locked, so only the confirmed action can change it.
A new maintenance window is applied to the server on Save only when the
updates are on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 13:51:21 +02:00
Andras BacsaiandClaude Opus 5.5 d6f7353fda chore(patches): mark Server patching as beta instead of experimental
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 13:44:20 +02:00
Andras BacsaiandClaude Opus 5.5 3c0c7cc93d refactor(patches): move schedule and automatic updates into the Server patching section
The check frequency, automatic security updates, and maintenance window
are now fields of the first section, in one row, instead of two extra
boxes. The "not supported" note moved into the existing callout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 13:43:31 +02:00
Andras BacsaiandClaude Opus 5.5 f32ecca44c feat(patches): record package updates, reboots, and auto-update changes in the audit log
- ui.server.packages_update_requested: user, server, packages (or all),
  package manager, and the activity of the update.
- ui.server.packages_update_finished: written when the remote process
  finishes (also when it fails), with the result and the exit code of
  the activity. The update gets a fresh type_uuid (an indexed activity
  property), so the listener finds exactly this activity. The actor
  comes from the request, because the listener runs in the queue.
- ui.server.reboot_requested with result started or failed.
- ui.server.auto_security_updates_updated (enabled, time, package
  manager, result) and ui.server.patch_settings_updated for a changed
  check frequency.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:44:03 +02:00
Andras BacsaiandClaude Opus 5.5 83ea5cc1f7 feat(servers): show the patch status of each server in the server list
- ServerSetting::patchStatus() summarizes the saved patch check
  (updates, security updates, reboot required, error). Results saved
  before security and reboot detection count as 0 and false.
- Grid cards show "N security updates", "N updates", "Patch check
  failed", and "Reboot required" badges; the table gets a Patches
  column from lg. The badge text is searchable.
- The toolbar shows a one-line team summary, for example "Patches: 2
  servers with updates · 1 with security updates · 1 needs a reboot".
- Badges and the summary are shown only for servers where the user can
  view the security pages (viewSecurity on the server), so members do
  not see them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:41:59 +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
Andras Bacsai 3d8cea9e3c feat(rollback): list Docker registry images of recent deployments
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).
2026-10-19 10:10:48 +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
Andras Bacsai 0fb816bcb5 fix(api): require deploy ability for Hostinger setup options
Require deploy permission when setting a post-install script or extra SSH keys, document the 403 response, and cover both denial and allowed deployment cases.
2026-10-19 00:02:52 +02:00
Andras BacsaiandClaude Opus 5.5 0eeb630ccd fix(compose): use explicit compose file paths and remove volumes by name (#12199)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 00:00:48 +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 Bacsai 9355728d03 fix(log-drains): validate custom log drain configuration (#12197) 2026-10-18 23:40:54 +02:00
Andras Bacsai a16994a88f fix(api): require deploy permission for proxy and custom log drain changes (#12198) 2026-10-18 23:35:25 +02:00
Andras Bacsai 5227693885 fix(deployments): scope deployment queries to team applications (#12195) 2026-10-18 23:32:14 +02:00
Andras Bacsai 8ab10c66de fix(api): require deploy ability to run scheduled tasks (#12194) 2026-10-18 23:27:05 +02:00
Andras Bacsai aae27629d4 Merge remote-tracking branch 'origin/main' 2026-10-18 23:24:00 +02:00
Andras Bacsai c781cddbab fix(server-transfer): require update access to export bundles 2026-10-18 23:21:16 +02:00
Andras Bacsai ecce3cb9b4 refactor(api): check token abilities through the token in ApiAbility (#12193) 2026-10-18 23:16:38 +02:00
09cfe2d211 fix(api): honour force_domain_override for docker_compose_domains on create (#12032)
Co-authored-by: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 23:07:46 +02:00
Andras Bacsai 6d2ad920d4 chore(deps): override postcss selector parser to 7.1.6 2026-10-18 23:01:56 +02:00
dependabot[bot] abd19a2692 chore(deps): bump source-map-js from 1.2.1 to 1.2.2 (#12114)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-18 22:06:23 +02:00
5dddcfd276 chore: merge main into release/v4.5 (#12175)
Co-authored-by: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 22:05:45 +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 BacsaiandClaude Opus 5.5 8ed31bb96e feat(env): restore Coolify default variables with a per-resource option
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:55:53 +02:00
Andras Bacsai 4553454f89 feat(webhooks): accept GitLab system hook events for deployments (#12185) 2026-10-18 12:49:16 +02:00
Andras Bacsai 6099c0b4a3 fix(service): repair forgejo templates and enable forgejo with runner
- Database variants: use the same database name in Forgejo and the database
  container (`forgejo` by default); Postgres stayed unhealthy and MySQL/MariaDB
  installs failed with access denied.
- SSH: publish ${FORGEJO_SSH_PORT:-22222} and set SSH_PORT, DOMAIN and
  SSH_DOMAIN, so clone URLs are correct and several instances fit on a server.
- Runner variants: start Forgejo from /usr/bin/s6-svscan, lock the install
  with a generated admin, register runner 13.2.0 with a generated shared
  secret, and enable the templates.

Closes #11924
2026-10-18 12:45:49 +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 6d4551faec test(parsers): add golden tests for the compose parsers
ServiceParserReferenceTest parses reference fixtures for serviceParser and
applicationParser (one service per feature, with setting variations and error
cases) and every template, and compares the output with expected files.
scripts/parser-snapshot-diff shows how a code change alters the output of all
cases (save / baseline). Template expected files are gitignored.
2026-10-18 11:29:39 +02:00
Andras Bacsai fc4562ede7 fix(services): treat SERVICE_FQDN_ twin as a copy of SERVICE_URL_ declaration
A service that declares SERVICE_FQDN_X_PORT while the named service declares
SERVICE_URL_X_PORT (same value) now counts as a copy, like an exact copy, so it
does not take the named service's domain. Also replace the Postgres-only
regex in the magic variable loop with the same check in PHP.
2026-10-18 11:29:39 +02:00
Andras BacsaiandClaude Opus 5.5 4e7d73e6e2 fix(webhooks): save manual webhook secret when generated
Generate now stores the new secret at once. The unsaved bar compares
fields with the saved secrets, so other drafts stay marked as unsaved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 11:24:52 +02:00
Andras Bacsai 6964714b5d fix(api): persist service URLs set via API across compose re-parse
Call updateCompose() after saving an application's fqdn in the services
API urls handler so the domain is written back to the compose file.
Without this, StartService re-parsing the compose before deploy would
drop the domain and its SERVICE_URL_*/SERVICE_FQDN_* variables.

Add a feature test covering persistence after a second parse.
2026-10-16 23:05:31 +02:00
Andras Bacsai 38e191dca6 fix(service): update appwrite to 2.5.0 and route api and realtime to port 80
The template port 3003 sent API and realtime traffic to a port that the
containers do not listen on (502). Use port 80 as upstream does, update
images and env to the official 2.5.0 compose, drop the removed assistant
service, and default _APP_OPTIONS_FORCE_HTTPS to disabled (upstream
default) so installs on http domains reach the API.
2026-10-16 23:05:10 +02:00
Andras Bacsai 699cd361b4 fix(services): keep SERVICE_URL_* on the named service domain
When a compose service copies another service's SERVICE_URL_/SERVICE_FQDN_
declaration (old Twenty template: worker repeats SERVICE_URL_TWENTY_3000),
the parser and updateCompose wrote the variable from the copier's generated
domain, so a custom domain on the named service was lost on every deploy.
Skip exact copies; declarations with another path or port are unchanged.

Closes #11924
2026-10-16 23:05:06 +02:00
Andras BacsaiandClaude Opus 5.5 35d4888c1a test: consolidate webhook repository URL tests and cover compose location save
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 22:41:15 +02:00
Andras BacsaiandClaude Opus 5.5 3aa6ff1fdd fix(ui): let the desktop sidebar scroll on short screens
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 22:41:15 +02:00
Andras BacsaiandClaude Opus 5.5 449d099bd3 fix(backups): accept tar exit code 1 in volume backups
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>
2026-10-16 22:41:15 +02:00
Andras Bacsai 44774f7b93 fix(service): update hermes agent and webui template images
Closes #11410
2026-10-16 21:48:29 +02:00
Andras BacsaiandClaude Opus 5.5 21dc34ae61 fix(scheduler): spread CDN update checks over a random delay
All instances share the same default update cron, so they request the
CDN at the same second and Cloudflare rejects the burst (error 1200).
Queue the CDN fetching jobs with a random 0-600s delay to spread the load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:38:39 +02:00
Andras BacsaiandClaude Opus 5.5 154b50647e test(deployments): cover large compose write over SSH stdin
Closes #11737

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:35:54 +02:00
Andras Bacsai a052a72923 test(git): cover deploy key setup with custom ssh username
Closes #11665
2026-10-16 21:35:19 +02:00
Andras Bacsai b5e1995cac fix(services): link Website button to project page, not host root
Closes #11752
2026-10-16 21:35:02 +02:00
Andras BacsaiandClaude Opus 5.5 ed8271eb9f fix(scheduled-tasks): skip a run while the previous run is still running
- 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>
2026-10-16 21:34:40 +02:00
Andras Bacsai 528754043e fix(api-tokens): allow token creation for MCP when REST API is disabled
Closes #11281
2026-10-16 21:29:51 +02:00
Andras Bacsai 412e0e5863 docs(watch-paths): state that patterns are one per line
Closes #11323
2026-10-16 21:28:57 +02:00
Andras Bacsai 492b174767 fix(github): route webhooks to the source of their app installation
Closes #11271
2026-10-16 21:28:40 +02:00
Andras BacsaiandClaude Opus 5.5 4ce231702e fix(service): skip the predefined network connect for connected containers
A single service deploy with an unchanged config keeps the running
container, which is already on the network. The connect then logged a
false "already exists" error and a warning. Check the container's
networks first.

Closes #11295

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:28:38 +02:00