Resolve the server and network in Destination::addServer() and
::promote() through ownedByCurrentTeam() before use, authorize the
update against the resource, and pass the validated IDs into
attach()/detach()/update(). Errors are routed through handleError()
to match the sibling removeServer() method.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move Sentinel push handling into a controller and dispatch server update jobs only when container state changes or the force interval elapses. Add opt-in PostgreSQL read/write replica configuration and tune periodic proxy network and storage checks to reduce unnecessary work.
Add feature coverage for replica config, Sentinel push deduplication, deployment log scrolling, and server update job optimizations.
Scope DeleteEnvironment::mount() and delete() lookups through
Environment::ownedByCurrentTeam() so an environment_id that belongs to
another team resolves to a 404 instead of loading the foreign record.
Mark $environment_id as #[Locked] so the public Livewire property can no
longer be reassigned from the client.
Add tests/Feature/DeleteEnvironmentTeamScopingTest.php covering mount,
delete, the #[Locked] guard, and the team-scoped helper for both the
cross-team and own-team cases.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Source component now resolves the supplied private key and Git
source IDs through team-scoped queries before persisting them, so a
selection can only ever reference a resource owned by the current
team. The source type is additionally restricted to the supported
GitHub/GitLab app classes.
The privateKeyId property is marked #[Locked] so it can only change
through the dedicated handler rather than a direct property update.
Adds feature tests covering team-scoped selection of private keys and
Git sources.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Build the global destinations list from actual destination records so empty
servers do not render duplicate empty states. Allow creating Docker destinations
for a selected team server outside the global usable list, authorize swarm
creation correctly, and store discovered swarm network names from the selected
network. Add feature coverage for empty states, selected-server mounting, and
swarm destination creation.
Call the preview environment variable relationship as a query when building the legacy configuration hash, and cover preview deployments with a regression test.
Dispatch configuration change events after saving application source and advanced settings, and refresh the configuration checker before showing redeploy diffs.
Store deployment configuration snapshots on application deployment queues and compare them against the current application state. Surface grouped pending changes in the configuration checker and use build-impact diffs to decide when an existing image can skip the build step.
Add centralized stop grace period resolution for application settings and use it across manual stops, preview stops, and deployments. Validate the Livewire advanced setting against shared min/max constants and cover persistence, fillable creation, and fallback behavior with tests.
Decode base64 custom_nginx_configuration before model assignment so it is not double-encoded, and allow null values when clearing the setting. Add API coverage for create, update, invalid input, and clearing behavior.
Generate pull request preview image tags with both the PR id and commit
so different commits on the same PR do not reuse the same image tag. Sanitize
and truncate generated tags to stay within Docker tag limits.
Require Docker buildx before Railpack builds, normalize environment
variable keys before validation, and align private deploy key API docs with
the supported dockerfile build pack.
Update Railpack seed examples to use the expected Flask start command and Go/Rust exposed ports. Adjust smoke coverage to run Symfony by default and accept reachable 4xx responses, and extend seeder tests for per-example branch and port assertions.
Avoid failing Stripe webhook processing when local subscriptions are missing, and cover ignored invoice/payment/subscription events with feature tests.
Move the deployments indicator inside the app layout state scope so it can react to the sidebar collapsed state, and add a layout test covering the responsive positioning.
Add shared environment variable key validation and normalization for Livewire forms and models, allowing Docker-compatible keys while rejecting invalid entries such as keys containing equals signs. Also quote Railpack build environment and secret arguments safely.
Build Railpack variables from generic build-time vars plus Railpack-specific vars, filter unrelated buildpack control vars, and ensure curl/wget deploy apt packages are present. Add coverage for standard and preview deployments.
Drop the unstable applications/dockercompose route and controller path now that
service creation is handled by POST /api/v1/services. Add coverage to ensure the
deprecated endpoint stays unregistered while the services endpoint remains
available.
Use random_bytes before hex and base64 encoding so generated env values
match the expected decoded byte lengths. Add Pest coverage for HEX and
REALBASE64 magic variables.
- `/mcp/enable` and `/mcp/disable` now use POST (state-mutating ops)
- `ListServices` queries DB directly instead of loading all projects into memory
- `ListApplications` validates tag arg rejects empty string (not just falsy)
Add feature tests covering railpack build pack via REST API and
Livewire UI components, plus a bash smoke test that deploys seeded
railpack-* example apps against the local dev stack and verifies
COOLIFY_*, SOURCE_COMMIT, and RAILPACK_* env vars land correctly.
Replace nested null checks with nullsafe operator chains, add ?Server
return type, drop unreachable database branch, and cover all paths with
feature tests.
Mirrors Nixpacks behavior: inject COOLIFY_* and SOURCE_COMMIT into
railpack build variables so apps (e.g. SPAs baking public URLs) can
read them via /run/secrets/<KEY>.
Rename is_nixpacks → is_buildpack_control to cover both NIXPACKS_ and
RAILPACK_ prefixed keys. Update the env variable view and appends list
accordingly.
Promote generate_coolify_env_variables to protected for testability.
Replace `railpack_environment_variables_collection()` helper (which returned
pre-filtered Eloquent attribute collections) with inline queries on
`environment_variables()` / `environment_variables_preview()` filtered by
`is_buildtime`. This ensures Railpack build variables are sourced from the
same query path as the rest of the deployment pipeline and avoids relying on
a now-removed accessor that silently included all railpack vars regardless of
build context.
Remove RAILPACK_FRONTEND_IMAGE env var from helper Dockerfile and resolve
the image ref at runtime using a new `railpack_version` constant in config.
Eliminates Docker build-time env interpolation for BUILDKIT_SYNTAX arg.
Replace 8× repeated per-type if-blocks in `queryDatabaseByUuidWithinTeam`
and `queryResourcesByUuid` with a single loop over the new
`STANDALONE_DATABASE_MODELS` constant.
Add unit tests to guard the registry against drift (keys mirror
`DATABASE_TYPES`, every entry is a valid Eloquent model with `team()`),
and feature tests covering team-ownership, wrong-team, and unknown-UUID
cases for `queryDatabaseByUuidWithinTeam`.
Replace random string with encrypted JSON payload containing
server_uuid, binding token to its server for validation.
Remove double-encrypt test no longer relevant to new token format.
Replace hard validation error with self-healing token logic. Tokens that
are null, empty, or fail decryption are now regenerated automatically
rather than crashing sentinel startup or metrics reads.
Token format changed from encrypted JSON payload to a plain 64-char
random string (Str::random), eliminating double-encryption issues and
simplifying the validation regex to cover the new character set.
New `ensureValidSentinelToken()` method on ServerSetting centralises
the get-or-regenerate contract; both StartSentinel and HasMetrics now
delegate to it. HasMetrics logs a warning when regeneration occurs so
operators know a sentinel container restart is required.
`isValidSentinelToken()` now accepts `?string` (null → false).
Adds feature tests covering: null/empty/undecryptable stored values,
idempotent return of valid tokens, RuntimeException only when
regeneration itself produces an invalid token, no double-encryption of
newly generated tokens, and cast round-trip consistency.
On cloud, DeploymentException and TimeoutExceededException are expected
failure modes that pollute the Horizon failed jobs UI. Listen to JobFailed
events and scrub the entry via JobRepository::deleteFailed so operators
are not alerted for noise failures. Self-hosted instances are unaffected.