Commit graph

696 commits

Author SHA1 Message Date
b9174f8d09 feat(auth): notify MapleDeploy on first-user registration
After the first user registers, clears the setup token and dispatches
NotifySetupCompleteJob to POST the token to MapleDeploy's callback URL.
Adds setup_callback_url column to instance_settings.
2026-03-14 00:18:29 -04:00
cff8339b0f feat(auth): gate first-user registration with setup token
Require a setup_token query parameter to access the registration page
when no users exist, preventing admin hijacking on new instances.
2026-03-14 00:18:23 -04:00
88fab3e119 feat: add update pipeline with MapleDeploy CDN and versioning
Route all Coolify update artifacts (versions.json, upgrade.sh,
compose files) through updates.mapledeploy.ca instead of upstream
cdn.coollabs.io. Extend CI to publish artifacts to Bunny CDN
storage zone and purge cache on each build.

- Point CDN_URL, versions_url, upgrade_script_url to updates.mapledeploy.ca
- Hardcode helper/realtime images to ghcr.io (not mirrored to Forgejo)
- Pass registry_url as 3rd arg to upgrade.sh for main image pulls
- Adopt versioning scheme 4.0.0-beta.X.N (bump to 4.0.0-beta.463.1)
- Add CI steps: generate versions.json, upload to Bunny, purge cache
2026-03-14 00:15:55 -04:00
a8ea8c9548 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-14 00:15:16 -04:00
Andras Bacsai
6488751fd2 feat(proxy): add database-backed config storage with disk backups
- Store proxy configuration in database as primary source for faster access
- Implement automatic timestamped backups when configuration changes
- Add backfill migration logic to recover configs from disk for legacy servers
- Simplify UI by removing loading states (config now readily available)
- Add comprehensive logging for debugging configuration generation and recovery
- Include unit tests for config recovery scenarios
2026-03-11 14:11:31 +01:00
Andras Bacsai
fcd574e1eb fix(log-drain): prevent command injection by base64-encoding environment variables
Replace direct shell interpolation of environment values with base64 encoding
to prevent command injection attacks. Environment configuration is now built as
a single string, base64-encoded, then decoded to file atomically.

Also add regex validation to restrict environment field values to safe
characters (alphanumeric, underscore, hyphen, dot) at the application layer.

Fixes GHSA-3xm2-hqg8-4m2p
2026-03-10 22:22:51 +01:00
Andras Bacsai
096d4369e5 fix(sentinel): add token validation to prevent command injection
Add validation to ensure sentinel tokens contain only safe characters
(alphanumeric, dots, hyphens, underscores, plus, forward slash, equals),
preventing OS command injection vulnerabilities when tokens are
interpolated into shell commands.

- Add ServerSetting::isValidSentinelToken() validation method
- Validate tokens in StartSentinel action and metrics queries
- Improve shell argument escaping with escapeshellarg()
- Add comprehensive test coverage for token validation
2026-03-10 22:19:19 +01:00
Andras Bacsai
0a1782175a Merge remote-tracking branch 'origin/next' into 8826-investigate-postgresql-restart 2026-03-10 21:46:03 +01:00
Andras Bacsai
e41dbde46b chore: prepare for PR 2026-03-10 18:34:37 +01:00
Andras Bacsai
9702543e20 chore: prepare for PR 2026-03-10 18:32:19 +01:00
Andras Bacsai
27e2680d70 Merge remote-tracking branch 'origin/next' into fix/configurable-proxy-timeout 2026-03-10 10:01:46 +01:00
Andras Bacsai
184fbb98f3 fix(proxy): add validation and normalization for database proxy timeout
- Extract proxy timeout configuration logic into dedicated method
- Add min:1 validation rule for publicPortTimeout
- Normalize invalid timeout values (null, 0, negative) to default 3600s
- Add tests for timeout configuration normalization and validation
2026-03-10 09:59:19 +01:00
Andras Bacsai
4615cfd007 Merge remote-tracking branch 'origin/next' into fix/configurable-proxy-timeout 2026-03-06 08:04:07 +01:00
Andras Bacsai
31caef990d Merge remote-tracking branch 'origin/next' into fix/dev-dbproxy 2026-03-06 08:04:06 +01:00
Andras Bacsai
d3b8d70f08 fix(subscription): harden quantity updates and proxy trust behavior
Centralize min/max server limits in Stripe quantity updates and wire them into
Livewire subscription actions with price preview/update handling.

Also improve host/proxy middleware behavior by trusting loopback hosts when FQDN
is set and auto-enabling secure session cookies for HTTPS requests behind
proxies when session.secure is unset.

Includes feature tests for loopback trust and secure cookie auto-detection.
2026-03-03 12:28:16 +01:00
Andras Bacsai
76ae720c36 feat(subscription): add Stripe server limit quantity adjustment flow
Introduce a new `UpdateSubscriptionQuantity` Stripe action to:
- preview prorated due-now and next-cycle recurring costs
- update subscription item quantity with proration invoicing
- revert quantity and void invoice when payment is not completed

Wire the flow into the Livewire subscription actions UI with a new adjust-limit modal,
price preview loading, and confirmation-based updates. Also refactor the subscription
management section layout and fix modal confirmation behavior for temporary 2FA bypass.

Add `Subscription::billingInterval()` helper and comprehensive Pest coverage for
quantity updates, preview calculations, failure/revert paths, and billing interval logic.
2026-03-03 12:24:13 +01:00
Brendan G. Lim
040658c142 fix: address review feedback on proxy timeout
- Fix disable logic: timeout editable when proxy is stopped
- Remove hardcoded proxy_connect_timeout (60s is nginx default)
- Remove misleading '0 for no timeout' helper text
- Add min:1 validation for timeout value
2026-02-27 14:24:04 -08:00
Cinzya
34c5eb9e10 fix(proxy): mounting error for nginx.conf in dev 2026-02-27 22:07:37 +01:00
Brendan G. Lim
30c1d9bbd0 feat: add configurable timeout for public database TCP proxy
Adds a per-database 'Proxy Timeout' setting for publicly exposed databases.
The nginx stream proxy_timeout can now be configured in the UI, defaulting
to 3600s (1 hour) instead of nginx's 10min default. Set to 0 for no timeout.

Fixes #7743
2026-02-26 21:12:58 -08:00
Andras Bacsai
8f2800a9e5 chore: prepare for PR 2026-02-26 18:22:03 +01:00
Andras Bacsai
fe36b70680 chore: prepare for PR 2026-02-25 12:00:24 +01:00
Andras Bacsai
76a6960f44 chore: prepare for PR 2026-02-23 13:26:01 +01:00
Andras Bacsai
b7480fbe38 chore: prepare for PR 2026-02-15 13:46:08 +01: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