Commit graph

674 commits

Author SHA1 Message Date
104f8ae4e4 feat(branding): apply MapleDeploy branding to Coolify
Replace Coolify branding with MapleDeploy throughout the UI: logos,
favicon, fonts (Overlock 900), color scheme, help links, and page
titles. Remove GitHub Actions workflows and add Forgejo CI build
workflow. Strip cloud-only features (subscription prompts, sponsor
links, server creation cloud options).
2026-03-08 19:49:38 -04:00
Andras Bacsai
fc229c4889 chore: prepare for PR 2026-02-03 15:32:03 +01:00
Andras Bacsai
e7db637a5d fix(docker): use dynamic OS ID for Docker repository URL
Replace hardcoded 'debian' with ${ID} from /etc/os-release to use
the correct Docker repository for Ubuntu, Debian, and Raspbian servers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 10:04:42 +01:00
Andras Bacsai
cc53e9476e fix(docker): add fallback for Docker Swarm container labels 2026-01-07 14:57:13 +01:00
Andras Bacsai
29c62cb38f fix(service): use database UUID for ServiceDatabase proxy container name
The proxy container was incorrectly named using the service UUID instead
of the database UUID, causing proxy logs to query the wrong container.
Each ServiceDatabase should have its own uniquely named proxy container.
2026-01-02 16:49:24 +01:00
Andras Bacsai
75d8ebe803 fix(restart): reset restart count when resource is manually stopped
When a database or application was in a restart loop, the restart count
persisted even after the user manually stopped the resource. This caused
the UI to continue showing "(Xx restarts)" after user intervention.

Now resets restart_count, last_restart_at, and last_restart_type when:
- User stops a database (StopDatabase action)
- User stops an application (StopApplication action)

The existing reset in GetContainersStatus is still needed for containers
that exit on their own (crash without recovery, Docker giving up).

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-27 15:21:19 +01:00
Andras Bacsai
9a1020d5be fix(database): replace temporary file handling with base64 encoding for Keydb and Redis configuration 2025-12-25 18:17:42 +01:00
Andras Bacsai
d04d0ab499 Refactor restart tracking and add missing model casts
- Consolidate duplicate restart tracking logic in GetContainersStatus
- Add last_restart_type string cast to all 8 standalone database models

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 17:45:58 +01:00
Andras Bacsai
6d47d24169 Fix standalone database "restarting" status flickering and add restart tracking
- Fix status flickering: Track databases in active/transient states (restarting, starting, created, paused) not just running
- Add isActiveOrTransient() helper to distinguish between active states and terminal states (exited, dead)
- Add safeguard: Protect updateNotFoundDatabaseStatus() from marking as exited when containers collection is empty
- Add restart_count tracking: New migration adds restart_count, last_restart_at, last_restart_type to all standalone database tables
- Update 8 database models with $casts for new restart tracking fields
- Update GetContainersStatus to extract RestartCount from Docker and update database models
- Reset restart tracking when database exits completely

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-17 16:25:41 +01:00
Andras Bacsai
d4a403278d
Added ClickHouse Migration Support (#7392) 2025-12-17 11:37:53 +01:00
Andras Bacsai
6a9027dcbf Add human-friendly output to upgrade script
- Show clear progress with numbered steps (1/6 through 6/6)
- Display header and footer banners
- Show individual image pull progress
- Show which containers are being stopped
- Display final success message with version and log location
- Keep detailed logging to file for debugging

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 15:18:57 +01:00
Andras Bacsai
6ea563c6ac Fix: Prevent coolify-helper and coolify-realtime images from being pruned
Current version of infrastructure images (coolify-helper, coolify-realtime) are now protected from deletion during docker cleanup, regardless of which registry they're pulled from (ghcr.io, docker.io, or Docker Hub implicit). Old versions continue to be cleaned up as intended.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-11 13:38:52 +01:00
Andras Bacsai
5d38147899 feat(api): Improve OpenAPI spec and add rate limit handling for Hetzner
- Add 429 response with Retry-After header for Hetzner server creation
- Create RateLimitException for proper rate limit error handling
- Rename cloud_provider_token_id to cloud_provider_token_uuid with deprecation
- Fix prices array schema in server-types endpoint with proper items definition
- Add explicit default: true to autogenerate_domain properties
- Add timeout and retry options to Docker install curl commands
- Fix race condition in deployment status update using atomic query
2025-12-11 12:12:43 +01:00
Andras Bacsai
206a9c03d2 Remove duplicate getArchDockerInstallCommand() method
The method was defined twice with the first (outdated) definition using
-Syyy and lacking proper flags. Keep the improved version that uses -Syu
with --needed for idempotency and proper systemctl ordering.
2025-12-11 09:25:35 +01:00
Andras Bacsai
86a02a12e6
Update app/Actions/Application/CleanupPreviewDeployment.php
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-12-08 17:35:13 +01:00
Andras Bacsai
d27070b215 fix: Add comprehensive PR cleanup to GitLab, Bitbucket, and Gitea webhooks
Create a shared CleanupPreviewDeployment action that unifies PR cleanup logic across all Git providers. Previously, GitHub had comprehensive cleanup (cancels active deployments, kills helper containers, removes all PR containers), while GitLab, Bitbucket, and Gitea only did basic cleanup (delete preview record and remove one container by name).

This fix ensures all providers properly clean up orphaned PR containers when a PR is closed/merged, preventing security issues and resource waste. Also fixes early return bug in GitLab webhook handler.

Fixes #2610

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 17:10:39 +01:00
Andras Bacsai
bb83f4e5c3
Add Arch Linux server support and fix package sanitization (#7531) 2025-12-08 09:18:14 +01:00
Andras Bacsai
089007919d Add package validation guard and make pacman idempotent
- Add explicit validation in UpdatePackage to require package name when
  'all' is false, preventing empty package commands being sent to servers
- Add --needed flag to pacman install in InstallDocker for idempotent
  Docker installation on Arch Linux

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 09:17:24 +01:00
Andras Bacsai
9bb77da9a4 Add Arch Linux server support and fix package sanitization
- Add Arch Linux (pacman) support to server operations: CheckUpdates, InstallDocker, InstallPrerequisites, UpdatePackage
- Implement parsePacmanOutput() to parse 'pacman -Qu' output format
- Add security improvement: package name sanitization to prevent command injection
- Initialize variables in CheckUpdates to prevent undefined variable errors in catch block
- Use proper Arch pacman flags: -Syu for full system upgrade before operations

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 09:02:00 +01:00
Andras Bacsai
847c4f4627
fix: add Arch Linux support for Docker installation (#7408) 2025-12-07 19:08:20 +01:00
Andras Bacsai
62aa7397da Fix grep regex escaping for extended regex (ERE)
Replace preg_quote() with proper ERE escaping since grep -E uses
extended regex syntax, not PHP/PCRE. This ensures special characters
in registry URLs (dots, etc.) are properly escaped.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 12:57:57 +01:00
Andras Bacsai
511415770a Add server-level toggle to disable application image retention
Adds a new server-level setting that allows administrators to disable
per-application image retention globally for all applications on a server.
When enabled, Docker cleanup will only keep the currently running image
regardless of individual application retention settings.

Changes:
- Add migration for disable_application_image_retention boolean field
- Update ServerSetting model with cast
- Add checkbox in DockerCleanup page (Advanced section)
- Modify CleanupDocker action to check server-level setting
- Update Rollback page to show warning and disable inputs when server
  retention is disabled
- Add helper text noting server-level override capability

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 12:22:20 +01:00
Andras Bacsai
710dc3ca4b Add Docker Compose support for image retention during cleanup
Support for Docker Compose applications with build: directives that create
images with uuid_servicename naming pattern (e.g., app-uuid_web:commit).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 11:17:23 +01:00
Andras Bacsai
4ed7a4238a Add per-application Docker image retention for rollback capability
Implement a per-application setting (`docker_images_to_keep`) in `application_settings` table to control how many Docker images are preserved during cleanup. The cleanup process now:

- Respects per-application retention settings (default: 2 images)
- Preserves the N most recent images per application for easy rollback
- Always deletes PR images and keeps the currently running image
- Dynamically excludes application images from general Docker image prune
- Cleans up non-Coolify unused images to prevent disk bloat

Fixes issues where cleanup would delete all images needed for rollback.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 11:02:07 +01:00
Andras Bacsai
c53988e91d Fix: Cancel in-progress deployments when stopping service
When stopping a service that's currently deploying, mark any IN_PROGRESS or QUEUED activities as CANCELLED. This prevents the status from remaining stuck at "starting" after containers are stopped.

Follows the existing pattern used in forceDeploy().
2025-12-04 08:23:32 +01:00
Andras Bacsai
66e81d6d96 Fix container status display: preserve "Restarting" for applications and sub-resources
Add preserveRestarting parameter to ContainerStatusAggregator to allow applications
and service sub-resources to display "Restarting" status instead of being marked as
"Degraded". This gives better visibility into container restart behavior.

- Update ContainerStatusAggregator to accept preserveRestarting parameter (defaults to false)
- Update GetContainersStatus to use preserveRestarting: true for applications and service sub-resources
- Update PushServerUpdateJob to use preserveRestarting: true for applications and service sub-resources
- Add comprehensive documentation explaining the parameter behavior and when to use it

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 08:23:35 +01:00
Murat Aslan
eedc9e586d fix: add Arch Linux support for Docker installation
Arch Linux was listed in SUPPORTED_OS but InstallDocker.php had no
specific handler for it, causing 'Unsupported OS' errors when trying
to add Arch Linux servers.

This adds:
- Detection of 'arch' OS type in the install flow
- New getArchDockerInstallCommand() method using pacman:
  - pacman -Syyy (refresh package databases)
  - pacman -S docker docker-compose (install Docker)
  - systemctl start/enable docker

Fixes #4523
2025-11-29 15:22:58 +03:00
Andras Bacsai
cd10796612 Fix: Version downgrade prevention - validate cache and add running version checks
## Changes
- **CheckForUpdatesJob**: Add triple version comparison (CDN vs cache vs running)
  - Never allows version downgrade from currently running version
  - Uses data_set() for safer nested array mutation
  - Prevents incorrect new_version_available flag setting

- **UpdateCoolify**: Add cache validation before fallback
  - Validates cache against running version on CDN failure
  - Throws exception if cache is corrupted/older than running
  - Applies to both manual and automated updates

- **Tests**: Add comprehensive test coverage
  - tests/Unit/CheckForUpdatesJobTest.php (5 tests)
  - tests/Unit/UpdateCoolifyTest.php (3 tests)

## Impact
- Prevents all downgrade scenarios (CDN rollback, corrupted cache, etc.)
- Maintains backward compatibility
- Provides clear logging for debugging

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 16:05:41 +01:00
Andras Bacsai
d9774d2968 Fix: Prevent version downgrades and centralize CDN configuration (#7383)
## Root Cause
Between Nov 25-26, a CDN redirect was added without curl's `-L` flag,
causing version cache corruption and automatic downgrades.

## Three Critical Bugs Fixed

### Bug #1: CheckForUpdatesJob could overwrite newer cached version
- Problem: CDN serving older version would overwrite local cache
- Solution: Smart version merge - keep max Coolify version, update other components
- Location: app/Jobs/CheckForUpdatesJob.php:33-52

### Bug #2: Manual updates bypassed downgrade protection
- Problem: Downgrade guard only applied to auto-updates
- Solution: Always block downgrades for both manual and auto-updates
- Location: app/Actions/Server/UpdateCoolify.php:65-75

### Bug #3: Updates used stale local cache
- Problem: Never validated cache against CDN at update time
- Solution: Fetch fresh CDN data before executing updates
- Location: app/Actions/Server/UpdateCoolify.php:34-49

## Additional Improvement: Centralized CDN Configuration

Added three new config keys for easy CDN management:
- `cdn_url` - Base CDN URL (default: https://cdn.coollabs.io)
- `versions_url` - Full versions.json URL
- `upgrade_script_url` - Full upgrade.sh URL

All configurable via environment variables:
```bash
CDN_URL=https://cdn.coolify.io
VERSIONS_URL=https://custom-cdn.example.com/versions.json
UPGRADE_SCRIPT_URL=https://custom-cdn.example.com/upgrade.sh
```

## Files Modified
- config/constants.php - CDN configuration
- app/Jobs/CheckForUpdatesJob.php - Smart version merge + centralized URL
- app/Actions/Server/UpdateCoolify.php - Downgrade protection + fresh fetch + centralized URLs
- app/Jobs/CheckHelperImageJob.php - Centralized URL
- bootstrap/helpers/shared.php - Centralized URL

## Testing
-  All modified files pass Pint formatting
-  78 unit tests pass (2 pre-existing failures unrelated to changes)

## Impact
- No breaking changes - defaults to current CDN
- Easy CDN migration via environment variables
- Prevents all downgrade scenarios
- Maintains independent Sentinel/Helper/Traefik updates

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 15:20:33 +01:00
Andras Bacsai
f42d076f31
Merge branch 'next' into fix-docker-time-database-v2 2025-11-28 13:12:00 +01:00
EbinJose2002
f37eef8266 - Made necessary changes to the migration and created new one as well.
- Updated the Clickhouse service template to use the official `clickhouse/clickhouse-server` image.
- Removed the usage of the deprecated `bitnamilegacy/clickhouse` image.

- fixes #7110
2025-11-28 17:12:11 +05:30
Andras Bacsai
c136724838 fix(docker): migrate database start actions from --time to -t flag
Migrates 8 database start action files from deprecated --time=10 to compatible -t 10 flag for Docker v28+ compatibility. Also updates test expectations in StopProxyTest.php.

Docker deprecated the --time flag in v28.0. The -t shorthand works on all Docker versions (pre-28 and 28+), ensuring backward and forward compatibility.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 11:18:12 +01:00
Andras Bacsai
9503da60b4
Revert "fix(docker): migrate database start actions from --time to -t flag" 2025-11-28 11:15:55 +01:00
Andras Bacsai
5b7a6d9a76 fix(docker): migrate database start actions from --time to -t flag
Migrates 8 database start action files from deprecated --time=10 to compatible -t 10 flag for Docker v28+ compatibility. Also updates test expectations in StopProxyTest.php.

Docker deprecated the --time flag in v28.0. The -t shorthand works on all Docker versions (pre-28 and 28+), ensuring backward and forward compatibility.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 11:08:20 +01:00
Andras Bacsai
1d054b23b8
Merge branch 'next' into shadow/fix-docker-time-command 2025-11-28 10:25:42 +01:00
Andras Bacsai
246e3cd8a2 fix: resolve Docker validation race conditions and sudo prefix bug
- Fix sudo prefix bug: Use word boundary matching to prevent 'do' keyword from matching 'docker' commands
- Add ensureProxyNetworksExist() helper to create networks before docker compose up
- Ensure networks exist synchronously before dispatching async proxy startup to prevent race conditions
- Update comprehensive unit tests for sudo parsing (50 tests passing)

This resolves issues where Docker commands failed to execute with sudo on non-root servers and where proxy networks were not created before the proxy container started.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 09:04:42 +01:00
Andras Bacsai
bf428a0e1c
fix: don't show health status for exited containers (#7317) 2025-11-24 10:29:57 +01:00
Andras Bacsai
1149d0f746
feat: implement prerequisite validation and installation for server setup (#7297) 2025-11-24 10:28:10 +01:00
Andras Bacsai
ac9eca3c05 fix: don't show health status for exited containers
Exited containers don't run health checks, so showing "(unhealthy)" is
misleading. This fix ensures exited status displays without health
suffixes across all monitoring systems (SSH, Sentinel, services, etc.)
and at the UI layer for backward compatibility with existing data.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 09:09:37 +01:00
Andras Bacsai
29135e00ba feat: enhance prerequisite validation to return detailed results 2025-11-21 13:14:48 +01:00
Andras Bacsai
01957f2752 feat: implement prerequisite validation and installation for server setup 2025-11-21 09:49:33 +01:00
Andras Bacsai
355dcc186c
fix: correct status for excluded health check containers (#7283) 2025-11-21 09:17:26 +01:00
Andras Bacsai
ae6eef3cdb feat(tests): add comprehensive tests for ContainerStatusAggregator and serverStatus accessor
- Introduced tests for ContainerStatusAggregator to validate status aggregation logic across various container states.
- Implemented tests to ensure serverStatus accessor correctly checks server infrastructure health without being affected by container status.
- Updated ExcludeFromHealthCheckTest to verify excluded status handling in various components.
- Removed obsolete PushServerUpdateJobStatusAggregationTest as its functionality is covered elsewhere.
- Updated version number for sentinel to 0.0.17 in versions.json.
2025-11-20 17:31:07 +01:00
Andras Bacsai
2f3052a283 Fix database restart to skip unnecessary Docker cleanup
Prevents removal and re-download of database images on every restart. Docker cleanup was removing Docker Hub images (postgres, mysql, redis, etc.) that lack the coolify.managed=true label, causing them to be immediately re-pulled. Restart now preserves images while stopping/starting containers.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 17:15:45 +01:00
Andras Bacsai
14bba8ba86 fix: correct Sentinel default health status and remove debug logging
This commit addresses container status reporting issues and removes debug logging:

**Primary Fix:**
- Changed PushServerUpdateJob to default to 'unknown' instead of 'unhealthy' when health_status field is missing from Sentinel data
- This ensures containers WITHOUT healthcheck defined are correctly reported as "unknown" not "unhealthy"
- Matches SSH path behavior (GetContainersStatus) which already defaulted to 'unknown'

**Service Multi-Container Aggregation:**
- Implemented service container status aggregation (same pattern as applications)
- Added serviceContainerStatuses collection to both Sentinel and SSH paths
- Services now aggregate status using priority: unhealthy > unknown > healthy
- Prevents race conditions where last-processed container would win

**Debug Logging Cleanup:**
- Removed all [STATUS-DEBUG] logging statements (25 total)
- Removed all ray() debugging calls (3 total)
- Removed proof_unknown_preserved and health_status_was_null debug fields
- Code is now production-ready

**Test Coverage:**
- Added 2 new tests for Sentinel default health status behavior
- Added 5 new tests for service aggregation in SSH path
- All 16 tests pass (66 assertions)

**Note:** The root cause was identified as Sentinel (Go binary) also defaulting to "unhealthy". That will need a separate fix in the Sentinel codebase.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 11:10:34 +01:00
Andras Bacsai
d2d9c1b2bc debug: add comprehensive status change logging
Added detailed debug logging to all status update paths to help
diagnose why "unhealthy" status appears in the UI.

## Logging Added

### 1. PushServerUpdateJob (Sentinel updates)
**Location**: Lines 303-315
**Logs**: Status changes from Sentinel push updates
**Data tracked**:
- Old vs new status
- Container statuses that led to aggregation
- Status flags (hasRunning, hasUnhealthy, hasUnknown)

### 2. GetContainersStatus (SSH updates)
**Location**: Lines 441-449, 346-354, 358-365
**Logs**: Status changes from SSH-based checks
**Scenarios**:
- Normal status aggregation
- Recently restarted containers (kept as degraded)
- Applications not running (set to exited)
**Data tracked**:
- Old vs new status
- Container statuses
- Restart count and timing
- Whether containers exist

### 3. Application Model Status Accessor
**Location**: Lines 706-712, 726-732
**Logs**: When status is set without explicit health information
**Issue**: Highlights cases where health defaults to "unhealthy"
**Data tracked**:
- Raw value passed to setter
- Final result after default applied

## How to Use

### Enable Debug Logging
Edit `.env` or `config/logging.php` to set log level to debug:
```
LOG_LEVEL=debug
```

### Monitor Logs
```bash
tail -f storage/logs/laravel.log | grep STATUS-DEBUG
```

### Log Format
All logs use `[STATUS-DEBUG]` prefix for easy filtering:
```
[2025-11-19 13:00:00] local.DEBUG: [STATUS-DEBUG] Sentinel status change
{
  "source": "PushServerUpdateJob",
  "app_id": 123,
  "app_name": "my-app",
  "old_status": "running:unknown",
  "new_status": "running:healthy",
  "container_statuses": [...],
  "flags": {...}
}
```

## What to Look For

1. **Default to unhealthy**: Check Application model accessor logs
2. **Status flipping**: Compare timestamps between Sentinel and SSH updates
3. **Incorrect aggregation**: Check flags and container_statuses
4. **Stale database values**: Check if old_status persists across multiple logs

## Next Steps

After gathering logs, we can:
1. Identify the exact source of "unhealthy" status
2. Determine if it's a default issue, aggregation bug, or timing problem
3. Apply targeted fix based on evidence

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 13:52:08 +01:00
Andras Bacsai
e3746a4b88 fix: preserve unknown health state and handle edge case container states
This commit fixes container health status aggregation to correctly handle
unknown health states and edge case container states across all resource types.

Changes:

1. **Preserve Unknown Health State**
   - Add three-way priority: unhealthy > unknown > healthy
   - Detect containers without healthchecks (null health) as unknown
   - Apply across GetContainersStatus, ComplexStatusCheck, and Service models

2. **Handle Edge Case Container States**
   - Add support for: created, starting, paused, dead, removing
   - Map to appropriate statuses: starting (unknown), paused (unknown), degraded (unhealthy)
   - Prevent containers in transitional states from showing incorrect status

3. **Add :excluded Suffix for Excluded Containers**
   - Parse exclude_from_hc flag from docker-compose YAML
   - Append :excluded suffix to individual container statuses
   - Skip :excluded containers in non-excluded aggregation sections
   - Strip :excluded suffix in excluded aggregation sections
   - Makes it clear in UI which containers are excluded from monitoring

Files Modified:
- app/Actions/Docker/GetContainersStatus.php
- app/Actions/Shared/ComplexStatusCheck.php
- app/Models/Service.php
- tests/Unit/ContainerHealthStatusTest.php

Tests: 18 passed (82 assertions)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 13:19:25 +01:00
Andras Bacsai
498b189286 fix: correct status for services with all containers excluded from health checks
When all containers are excluded from health checks, display their actual status
with :excluded suffix instead of misleading hardcoded statuses. This prevents
broken UI state with incorrect action buttons and provides clarity that monitoring
is disabled.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 10:54:51 +01:00
Andras Bacsai
f81640e316 fix: correct status for services with all containers excluded from health checks
When all services in a Docker Compose file have `exclude_from_hc: true`,
the status aggregation logic was returning invalid states causing broken UI.

**Problems fixed:**
- ComplexStatusCheck returned 'running:healthy' for apps with no monitored containers
- Service model returned ':' (null status) when all services excluded
- UI showed active start/stop buttons for non-running services

**Changes:**
- ComplexStatusCheck: Return 'exited:healthy' when relevantContainerCount is 0
- Service model: Return 'exited:healthy' when both status and health are null
- Added comprehensive unit tests to verify the fixes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 23:24:22 +01:00
Andras Bacsai
1270136da9 merge: merge next branch into feat-traefik-version-checker
Merged latest changes from the next branch to keep the feature branch
up to date. No conflicts were encountered during the merge.

Changes from next branch:
- Updated application deployment job error logging
- Updated server manager job and instance settings
- Removed PullHelperImageJob in favor of updated approach
- Database migration refinements
- Updated versions.json with latest component versions

All automatic merges were successful and no manual conflict resolution
was required.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 14:56:24 +01:00