270 Commits
Author SHA1 Message Date
Andras Bacsai 1d0f7daa81 fix(ui): rename the old Security labels to Keys & Tokens 2026-10-24 22:35:34 +02:00
Andras Bacsai 6022073519 fix(notifications): use instance URL in volume backup notification links
Volume backup notifications built links with route(), which uses APP_URL
in queue jobs and gave http://localhost links. Build them from base_url().

Closes #12285
2026-10-23 20:05:23 +02:00
e0f6b41dac chore: merge main into release/v4.5 (#12206)
Co-authored-by: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Andras Bacsai <andrasbacsai@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 13:26:07 +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 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
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 Bacsai 448dc8ea0a feat(logging): strengthen secret redaction and add admin controls (#12151) 2026-10-13 20:43:19 +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 Bacsai 5246427b03 fix(upgrade): remove disk space checks that block Coolify updates 2026-10-09 20:03:49 +02:00
Andras BacsaiandClaude Opus 5.5 376e7aab24 feat(upgrade): block upgrades when the disk is almost full
An upgrade pulls new images and recreates the Coolify containers. A full
disk during an upgrade can leave Coolify broken.

- Measure free space on the Docker root dir and /data/coolify of localhost;
  require 5 GB. An unknown value does not block.
- Manual upgrade: show the free and required space, with Run Docker cleanup,
  Check again, and a confirmed Upgrade anyway override.
- Automatic upgrade: skip it and notify the team (disk usage channels, at
  most once per 24 hours per server).
- upgrade.sh: stop before any change when the disk is low. A new 5th
  argument skips the check (used by the override).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:26:53 +02:00
Andras Bacsai 407c384b09 feat(backups): add configurable missing volume backup alerts
Check enabled volume backup schedules hourly and notify teams when no
execution occurs within the configured number of days. Expose the alert
threshold in the UI and API, with alerts disabled by default.

Route volume backup results and warnings to the appropriate Telegram
backup threads.
2026-10-07 09:37:35 +02:00
Andras Bacsai 58db0eba6f feat(backups): notify teams of volume backup results
Send success and failure notifications through enabled backup channels.
Route successful backups with warnings through failure channels.
2026-10-07 09:24:10 +02:00
Andras Bacsai ed6d6b1e45 fix(server): reset disk alerts only after usage recovers
Require usage to fall five percentage points below the threshold before releasing the notification throttle. Reset it after Sentinel reports recovery so a new spike alerts immediately.

Add regression coverage for recovery and usage fluctuating near the threshold.
2026-10-05 23:14:52 +02:00
Andras Bacsai 4227ec6ebf fix(storage): require deploy permission for external host writes
Require deploy or root token access when creating managed mounts outside
resource directories or changing their file contents through the API.

Synchronize KeyDB and Dragonfly passwords with local and shared
REDIS_PASSWORD values while preserving secret manager resolution.
2026-10-05 12:03:37 +02:00
Andras Bacsai 99c840922c fix(notifications): throttle repeated notifications per resource
High disk usage notifications were sent every ~10 minutes on Coolify Cloud
because the cache rate limiter did not hold across Sentinel-triggered checks.

- Add a notification_throttles table and NotificationThrottle helper that
  atomically records when a notification was sent for a resource.
- Add the ThrottledNotification contract; Team::notify() skips a throttled
  notification that was already sent within its interval.
- High disk usage: configurable per-server interval
  (server_disk_usage_notification_interval_hours, default 24h) in
  Server > Advanced and the servers API.
- Container restarted (coolify-proxy, database TCP proxy): at most one
  notification per hour per server/database during a restart loop.
- Move the unreachable and missing-backup markers into the new table and
  migrate existing data (servers.unreachable_notification_sent and
  scheduled_database_backups.missing_backup_notification_sent_at).
- Regenerate OpenAPI files.
2026-09-29 11:29:39 +02:00
Andras BacsaiandClaude Opus 5.5 575a97b6b7 chore(deps): update resend-laravel to 1.5 (resend-php 1.16)
resend-php 1.x reads the statusCode of Resend errors and knows more error
names. Coolify only uses emails->send and the exception classes, which did
not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:29:01 +02:00
Andras BacsaiandClaude Opus 5.5 d404de87d7 fix(email): show Resend errors instead of failing in the error handler
resend-php 0.18 reads a "code" key that the Resend API does not send
(it sends statusCode), so every Resend error failed with Undefined array
key "code". Errors with names that the SDK does not know were returned as
a normal response and counted as a sent email. Read statusCode and name from
the error, and treat a response without an email id as an error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:13:20 +02:00
Andras Bacsai 7c86e53422 fix(service): support metadata-only deletion on unreachable servers
Add a Coolify-only deletion path, improve Docker cleanup handling, and notify teams when service deletion fails.
2026-09-23 10:50:31 +02:00
Andras Bacsai 0b462f6a58 feat(backups): alert when scheduled backups are missing (#11433) 2026-09-07 14:09:42 +02:00
peaklabs-dev 9f6ed823ce fix(notifications): add toWebhook payload to Hetzner deletion failure notification 2026-09-05 12:33:06 +02:00
peaklabs-dev 5303ff1246 fix(notifications): hetzner deletion failure channel name 2026-09-05 12:32:25 +02:00
peaklabs-dev 27c7dc6a24 chore(notifications): remove broken notification interface 2026-09-05 12:29:14 +02:00
peaklabs-dev 0ae8539b80 Merge remote-tracking branch 'origin/main' into pr/11528 2026-09-04 18:25:18 +02:00
peaklabs-dev 0eb9d5e5a8 fix(notifications): urls for ssl renewal notifications 2026-09-04 15:07:26 +02:00
peaklabs-dev 85ec70643f refactor(notifications): build scheduled task links from the instance url
- replace the taskLink() helpers on Application and Service with links built from base_url() in the task notifications
2026-09-04 15:04:51 +02:00
peaklabs-dev 306d4833a9 fix(notifications): build restart limit links from the instance url 2026-09-04 15:03:27 +02:00
peaklabs-dev 6abbf84520 fix(notifications): build api token expiry notification link from the instance url 2026-09-04 14:44:07 +02:00
Devin Dissanayaka 45466b5069 fix(notifications): send traefik outdated alerts to the correct topic id (#11526) 2026-09-03 18:35:07 +02:00
Andras Bacsai 67b33c27a9 fix(applications): persist restart limit state for stopped containers (#11566) 2026-08-31 13:13:26 +02:00
Ousama Ben Younes f9f53f2fea fix(notifications): implement toWebhook() for always-send notifications
WebhookChannel::send() calls toWebhook() unconditionally, but the five
notifications reachable through alwaysSendEvents did not implement it, so
enabling the webhook channel turned those events into fatal queued jobs.
2026-08-27 04:45:39 +00:00
Andras Bacsai 59be75bdac fix(email): prevent Proton SMTP From header folding (#11400) 2026-08-19 11:52:59 +02:00
Andras Bacsai 849ba8f34c fix(email): support custom SMTP EHLO domains (#11398) 2026-08-19 11:25:46 +02:00
Andras Bacsai ae85688651 fix(email): respect disabled SMTP encryption in test emails (#11384) 2026-08-19 10:55:10 +02:00
Andras Bacsai 41f7152441 fix(email): apply configured sender identity (#11393) 2026-08-19 10:43:25 +02:00
Andras Bacsai 2a0183bfad Revert "feat(notifications): deduplicate repeated email alerts"
This reverts commit 8c1405e168.
2026-07-09 13:19:48 +02:00
Andras Bacsai 8c1405e168 feat(notifications): deduplicate repeated email alerts
Add notification-level deduplication keys and TTLs for deployment, backup,
server, container, scheduled task, SSL, token, and transactional emails.
Apply deduplication in email channels before sending rendered messages.
2026-07-08 15:23:14 +02:00
Andras Bacsai 9b060958aa fix(ray): remove Ray debug hooks from runtime (#10847) 2026-07-03 11:40:20 +02:00
Andras Bacsai aaa540421f feat(application): preserve crash restart limit status
Stop applications after they hit the crash restart limit without clearing
restart tracking, surface the stopped-limit warning in status UI, and use
the application link in restart limit notifications.
2026-06-03 11:01:28 +02:00
Andras Bacsai d581abb284 Merge remote-tracking branch 'origin/next' into jean/add-restart-loop-limit 2026-06-03 10:43:57 +02:00
Andras BacsaiandClaude Opus 4.7 90ddbb3572 feat(security): support expiration on API tokens with warning notifications
Add optional expiration to personal API tokens. Users pick a duration
(1/7/30/60/90 days or Never) at creation time. Expired tokens are
rejected by Sanctum, pruned hourly by sanctum:prune-expired, and a
team notification fires ~24h before expiry so owners can rotate
before API calls start failing.

- ApiTokens Livewire component stores expires_at from expiresInDays
- Rework issued-tokens UI from card grid to table (matches other views)
- New ApiTokenExpirationWarningJob scheduled hourly (idempotent via RateLimiter)
- New ApiTokenExpiringNotification (email/discord/telegram/slack/pushover)
- api_token_expiring added to alwaysSendEvents so users cannot silence
  expiry warnings from the per-event notification toggle UI
- sanctum:prune-expired cadence moved from daily to hourly

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 14:28:38 +02:00
ShadowArcanist 31ae8dd9db fix(notification): updated cloud subscription links to valid url 2026-03-30 11:37:28 +05:30
ShadowArcanist 886d01405f feat(applications): add configurable restart loop limit 2026-03-28 17:48:10 +05:30
Andras BacsaiandClaude Opus 4.6 e1d4b4682e fix: harden TrustHosts middleware and use base_url() for password reset links
- Fix circular cache dependency in TrustHosts where handle() checked cache
  before hosts() could populate it, causing host validation to never activate
- Validate both Host and X-Forwarded-Host headers against trusted hosts list
  (X-Forwarded-Host is checked before TrustProxies applies it to the request)
- Use base_url() instead of url() for password reset link generation so the
  URL is derived from server-side config (FQDN / public IP) instead of the
  request context
- Strip port from X-Forwarded-Host before matching (e.g. host:443 → host)
- Add tests for host validation, cache population, and reset URL generation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 18:39:54 +01:00
Andras BacsaiandClaude Haiku 4.5 546256b22c Fix: Allow test emails to be sent to any email address
Test emails should work with any recipient email address for verification purposes, not just team members. Added an isTestNotification flag to both Test notification classes and modified EmailChannel to skip team membership validation for test notifications.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-12 11:12:19 +01:00
Andras BacsaiandClaude 4b119726d9 Fix Traefik email notification with clickable server links
- Add URL generation to notification class using base_url() helper
- Replace config('app.url') with proper base_url() for accurate instance URL
- Make server names clickable links to proxy configuration page
- Use data_get() with fallback values for safer template data access
- Add comprehensive tests for URL generation and email rendering

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 13:08:40 +01:00
Andras BacsaiandClaude 6593b2a553 feat(proxy): enhance Traefik version notifications to show patch and minor upgrades
- Store both patch update and newer minor version information simultaneously
- Display patch update availability alongside minor version upgrades in notifications
- Add newer_branch_target and newer_branch_latest fields to traefik_outdated_info
- Update all notification channels (Discord, Telegram, Slack, Pushover, Email, Webhook)
- Show minor version in format (e.g., v3.6) for upgrade targets instead of patch version
- Enhance UI callouts with clearer messaging about available upgrades
- Remove verbose logging in favor of cleaner code structure
- Handle edge case where SSH command returns empty response

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 09:59:17 +01:00
Andras Bacsai 8c77c63043 feat(proxy): add Traefik version tracking with notifications and dismissible UI warnings
- Add automated Traefik version checking job running weekly on Sundays
- Implement version detection from running containers and comparison with versions.json
- Add notifications across all channels (Email, Discord, Slack, Telegram, Pushover, Webhook) for outdated versions
- Create dismissible callout component with localStorage persistence
- Display cross-branch upgrade warnings (e.g., v3.5 -> v3.6) with changelog links
- Show patch update notifications within same branch
- Add warning icon that appears when callouts are dismissed
- Prevent duplicate notifications during proxy restart by adding restarting parameter
- Fix notification spam with transition-based logic for status changes
- Enable system email settings by default in development mode
- Track last saved/applied proxy settings to detect configuration drift
2025-11-14 11:35:22 +01:00
Andras Bacsai 0d14bc1df7 feat(EmailChannel): enhance error handling with user-friendly messages for Resend API errors 2025-11-11 13:23:45 +01:00
Cinzya bceef418c8 refactor: remove staging URL logic from ServerPatchCheck constructor 2025-10-26 21:52:51 +01:00
Cinzya e29b517fef fix: server URL generation in ServerPatchCheck notification 2025-10-26 02:50:41 +02:00