- Every channel has a block of its own, every version after this one reads only these blocks
- Every stable sync also fills the coolify and traefik keys older instances read
- An instance keeps a copy of versions.json and reads upstream.json of the image until it has one
A non-root SSH user cannot open redirects, expand globs, or cd into
/data/coolify (9999:root 0700). Several remote commands relied on that
and failed on non-root servers.
- Write README files with `tee` instead of shell redirects in database
starts and application deployments
- Clear Postgres init scripts with `find` instead of a glob
- Split the proxy config backfill if/else so each branch gets sudo
- Start the log drain with `docker compose -f` instead of `cd`
- Wrap the preserved-repository compose start in `sh -c` for non-root
- Stage clone archives outside /data/coolify via StagesCloneArchives
- Extend the sudo parser and add non-root command tests
Remove tests that copy app logic into the test, grep PHP source as
text, only check literals, constants, class_exists or PHP built-ins,
duplicate other tests, or are always skipped. Keep source checks that
guard security and authorization rules.
Rename a duplicate Pest helper so the full suite loads, drop the
missing v5/Browser path, and remove the CLAUDE.md symlink in favor of
AGENTS.md. Correct AGENTS.md: Dusk is not installed and the upgrade
script is scripts/upgrade.sh.
remote_process() stored the full shell command as plain text in
activity_log and kept it for 60 days. Database starts store the compose file
with the database passwords, imports store S3 keys, and the Cloudflare
tunnel setup stores its token.
- Store the command encrypted. The queue worker decrypts it right before the
SSH call and still reads plain commands of tasks queued before the upgrade.
- Remove the command when the task is finished: after a successful run, in
failed() when no attempt is left, and for a stopped import. A failed attempt
that the queue retries keeps it.
- Do not write a command preview into the error log.
- Migration: remove stored commands from activities that no longer run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Changed from `->before('-')` to `->beforeLast('-')` to correctly parse service
names with hyphens. This fixes prerequisite application for ~230+ services
containing hyphens in their template names (e.g., docker-registry,
elasticsearch-with-kibana).
Added comprehensive test coverage for hyphenated service names and fixed
existing tests to use realistic CUID2 UUID format. All unit tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## 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>