diff --git a/.coderabbit.yaml b/.coderabbit.yaml
new file mode 100644
index 000000000..24c099119
--- /dev/null
+++ b/.coderabbit.yaml
@@ -0,0 +1,2 @@
+reviews:
+ review_status: false
diff --git a/.cursor/rules/frontend-patterns.mdc b/.cursor/rules/frontend-patterns.mdc
index 663490d3b..4730160b2 100644
--- a/.cursor/rules/frontend-patterns.mdc
+++ b/.cursor/rules/frontend-patterns.mdc
@@ -267,18 +267,365 @@ For complete documentation, see **[form-components.mdc](mdc:.cursor/rules/form-c
## Form Handling Patterns
+### Livewire Component Data Synchronization Pattern
+
+**IMPORTANT**: All Livewire components must use the **manual `syncData()` pattern** for synchronizing component properties with Eloquent models.
+
+#### Property Naming Convention
+- **Component properties**: Use camelCase (e.g., `$gitRepository`, `$isStatic`)
+- **Database columns**: Use snake_case (e.g., `git_repository`, `is_static`)
+- **View bindings**: Use camelCase matching component properties (e.g., `id="gitRepository"`)
+
+#### The syncData() Method Pattern
+
+```php
+use Livewire\Attributes\Validate;
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
+
+class MyComponent extends Component
+{
+ use AuthorizesRequests;
+
+ public Application $application;
+
+ // Properties with validation attributes
+ #[Validate(['required'])]
+ public string $name;
+
+ #[Validate(['string', 'nullable'])]
+ public ?string $description = null;
+
+ #[Validate(['boolean', 'required'])]
+ public bool $isStatic = false;
+
+ public function mount()
+ {
+ $this->authorize('view', $this->application);
+ $this->syncData(); // Load from model
+ }
+
+ public function syncData(bool $toModel = false): void
+ {
+ if ($toModel) {
+ $this->validate();
+
+ // Sync TO model (camelCase → snake_case)
+ $this->application->name = $this->name;
+ $this->application->description = $this->description;
+ $this->application->is_static = $this->isStatic;
+
+ $this->application->save();
+ } else {
+ // Sync FROM model (snake_case → camelCase)
+ $this->name = $this->application->name;
+ $this->description = $this->application->description;
+ $this->isStatic = $this->application->is_static;
+ }
+ }
+
+ public function submit()
+ {
+ $this->authorize('update', $this->application);
+ $this->syncData(toModel: true); // Save to model
+ $this->dispatch('success', 'Saved successfully.');
+ }
+}
+```
+
+#### Validation with #[Validate] Attributes
+
+All component properties should have `#[Validate]` attributes:
+
+```php
+// Boolean properties
+#[Validate(['boolean'])]
+public bool $isEnabled = false;
+
+// Required strings
+#[Validate(['string', 'required'])]
+public string $name;
+
+// Nullable strings
+#[Validate(['string', 'nullable'])]
+public ?string $description = null;
+
+// With constraints
+#[Validate(['integer', 'min:1'])]
+public int $timeout;
+```
+
+#### Benefits of syncData() Pattern
+
+- **Explicit Control**: Clear visibility of what's being synchronized
+- **Type Safety**: #[Validate] attributes provide compile-time validation info
+- **Easy Debugging**: Single method to check for data flow issues
+- **Maintainability**: All sync logic in one place
+- **Flexibility**: Can add custom logic (encoding, transformations, etc.)
+
+#### Creating New Form Components with syncData()
+
+#### Step-by-Step Component Creation Guide
+
+**Step 1: Define properties in camelCase with #[Validate] attributes**
+```php
+use Livewire\Attributes\Validate;
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
+use Livewire\Component;
+
+class MyFormComponent extends Component
+{
+ use AuthorizesRequests;
+
+ // The model we're syncing with
+ public Application $application;
+
+ // Component properties in camelCase with validation
+ #[Validate(['string', 'required'])]
+ public string $name;
+
+ #[Validate(['string', 'nullable'])]
+ public ?string $gitRepository = null;
+
+ #[Validate(['string', 'nullable'])]
+ public ?string $installCommand = null;
+
+ #[Validate(['boolean'])]
+ public bool $isStatic = false;
+}
+```
+
+**Step 2: Implement syncData() method**
+```php
+public function syncData(bool $toModel = false): void
+{
+ if ($toModel) {
+ $this->validate();
+
+ // Sync TO model (component camelCase → database snake_case)
+ $this->application->name = $this->name;
+ $this->application->git_repository = $this->gitRepository;
+ $this->application->install_command = $this->installCommand;
+ $this->application->is_static = $this->isStatic;
+
+ $this->application->save();
+ } else {
+ // Sync FROM model (database snake_case → component camelCase)
+ $this->name = $this->application->name;
+ $this->gitRepository = $this->application->git_repository;
+ $this->installCommand = $this->application->install_command;
+ $this->isStatic = $this->application->is_static;
+ }
+}
+```
+
+**Step 3: Implement mount() to load initial data**
+```php
+public function mount()
+{
+ $this->authorize('view', $this->application);
+ $this->syncData(); // Load data from model to component properties
+}
+```
+
+**Step 4: Implement action methods with authorization**
+```php
+public function instantSave()
+{
+ try {
+ $this->authorize('update', $this->application);
+ $this->syncData(toModel: true); // Save component properties to model
+ $this->dispatch('success', 'Settings saved.');
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
+}
+
+public function submit()
+{
+ try {
+ $this->authorize('update', $this->application);
+ $this->syncData(toModel: true); // Save component properties to model
+ $this->dispatch('success', 'Changes saved successfully.');
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
+}
+```
+
+**Step 5: Create Blade view with camelCase bindings**
+```blade
+
+
+
+```
+
+**Key Points**:
+- Use `wire:model="camelCase"` and `id="camelCase"` in Blade views
+- Component properties are camelCase, database columns are snake_case
+- Always include authorization checks (`authorize()`, `canGate`, `canResource`)
+- Use `instantSave` for checkboxes that save immediately without form submission
+
+#### Special Patterns
+
+**Pattern 1: Related Models (e.g., Application → Settings)**
+```php
+public function syncData(bool $toModel = false): void
+{
+ if ($toModel) {
+ $this->validate();
+
+ // Sync main model
+ $this->application->name = $this->name;
+ $this->application->save();
+
+ // Sync related model
+ $this->application->settings->is_static = $this->isStatic;
+ $this->application->settings->save();
+ } else {
+ // From main model
+ $this->name = $this->application->name;
+
+ // From related model
+ $this->isStatic = $this->application->settings->is_static;
+ }
+}
+```
+
+**Pattern 2: Custom Encoding/Decoding**
+```php
+public function syncData(bool $toModel = false): void
+{
+ if ($toModel) {
+ $this->validate();
+
+ // Encode before saving
+ $this->application->custom_labels = base64_encode($this->customLabels);
+ $this->application->save();
+ } else {
+ // Decode when loading
+ $this->customLabels = $this->application->parseContainerLabels();
+ }
+}
+```
+
+**Pattern 3: Error Rollback**
+```php
+public function submit()
+{
+ $this->authorize('update', $this->resource);
+ $original = $this->model->getOriginal();
+
+ try {
+ $this->syncData(toModel: true);
+ $this->dispatch('success', 'Saved successfully.');
+ } catch (\Throwable $e) {
+ // Rollback on error
+ $this->model->setRawAttributes($original);
+ $this->model->save();
+ $this->syncData(); // Reload from model
+ return handleError($e, $this);
+ }
+}
+```
+
+#### Property Type Patterns
+
+**Required Strings**
+```php
+#[Validate(['string', 'required'])]
+public string $name; // No ?, no default, always has value
+```
+
+**Nullable Strings**
+```php
+#[Validate(['string', 'nullable'])]
+public ?string $description = null; // ?, = null, can be empty
+```
+
+**Booleans**
+```php
+#[Validate(['boolean'])]
+public bool $isEnabled = false; // Always has default value
+```
+
+**Integers with Constraints**
+```php
+#[Validate(['integer', 'min:1'])]
+public int $timeout; // Required
+
+#[Validate(['integer', 'min:1', 'nullable'])]
+public ?int $port = null; // Nullable
+```
+
+#### Testing Checklist
+
+After creating a new component with syncData(), verify:
+
+- [ ] All checkboxes save correctly (especially `instantSave` ones)
+- [ ] All form inputs persist to database
+- [ ] Custom encoded fields (like labels) display correctly if applicable
+- [ ] Form validation works for all fields
+- [ ] No console errors in browser
+- [ ] Authorization checks work (`@can` directives and `authorize()` calls)
+- [ ] Error rollback works if exceptions occur
+- [ ] Related models save correctly if applicable (e.g., Application + ApplicationSetting)
+
+#### Common Pitfalls to Avoid
+
+1. **snake_case in component properties**: Always use camelCase for component properties (e.g., `$gitRepository` not `$git_repository`)
+2. **Missing #[Validate] attributes**: Every property should have validation attributes for type safety
+3. **Forgetting to call syncData()**: Must call `syncData()` in `mount()` to load initial data
+4. **Missing authorization**: Always use `authorize()` in methods and `canGate`/`canResource` in views
+5. **View binding mismatch**: Use camelCase in Blade (e.g., `id="gitRepository"` not `id="git_repository"`)
+6. **wire:model vs wire:model.live**: Use `.live` for `instantSave` checkboxes to avoid timing issues
+7. **Validation sync**: If using `rules()` method, keep it in sync with `#[Validate]` attributes
+8. **Related models**: Don't forget to save both main and related models in syncData() method
+
### Livewire Forms
```php
class ServerCreateForm extends Component
{
public $name;
public $ip;
-
+
protected $rules = [
'name' => 'required|min:3',
'ip' => 'required|ip',
];
-
+
public function save()
{
$this->validate();
diff --git a/.github/workflows/chore-lock-closed-issues-discussions-and-prs.yml b/.github/workflows/chore-lock-closed-issues-discussions-and-prs.yml
index d00853964..365842254 100644
--- a/.github/workflows/chore-lock-closed-issues-discussions-and-prs.yml
+++ b/.github/workflows/chore-lock-closed-issues-discussions-and-prs.yml
@@ -4,6 +4,11 @@ on:
schedule:
- cron: '0 1 * * *'
+permissions:
+ issues: write
+ discussions: write
+ pull-requests: write
+
jobs:
lock-threads:
runs-on: ubuntu-latest
@@ -13,5 +18,5 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
issue-inactive-days: '30'
- pr-inactive-days: '30'
discussion-inactive-days: '30'
+ pr-inactive-days: '30'
diff --git a/.github/workflows/chore-manage-stale-issues-and-prs.yml b/.github/workflows/chore-manage-stale-issues-and-prs.yml
index 58a2b7d7e..d61005549 100644
--- a/.github/workflows/chore-manage-stale-issues-and-prs.yml
+++ b/.github/workflows/chore-manage-stale-issues-and-prs.yml
@@ -4,6 +4,10 @@ on:
schedule:
- cron: '0 2 * * *'
+permissions:
+ issues: write
+ pull-requests: write
+
jobs:
manage-stale:
runs-on: ubuntu-latest
diff --git a/.github/workflows/chore-pr-comments.yml b/.github/workflows/chore-pr-comments.yml
index 8836c6632..1d94bec81 100644
--- a/.github/workflows/chore-pr-comments.yml
+++ b/.github/workflows/chore-pr-comments.yml
@@ -3,20 +3,13 @@ on:
pull_request_target:
types:
- labeled
+
+permissions:
+ pull-requests: write
+
jobs:
add-comment:
runs-on: ubuntu-latest
- permissions:
- pull-requests: write
- contents: read
- actions: none
- checks: none
- deployments: none
- issues: none
- packages: none
- repository-projects: none
- security-events: none
- statuses: none
strategy:
matrix:
include:
diff --git a/.github/workflows/chore-remove-labels-and-assignees-on-close.yml b/.github/workflows/chore-remove-labels-and-assignees-on-close.yml
index 194984ddc..8ac199a08 100644
--- a/.github/workflows/chore-remove-labels-and-assignees-on-close.yml
+++ b/.github/workflows/chore-remove-labels-and-assignees-on-close.yml
@@ -8,6 +8,10 @@ on:
pull_request_target:
types: [closed]
+permissions:
+ issues: write
+ pull-requests: write
+
jobs:
remove-labels-and-assignees:
runs-on: ubuntu-latest
diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml
deleted file mode 100644
index a2c92df59..000000000
--- a/.github/workflows/claude-code-review.yml
+++ /dev/null
@@ -1,79 +0,0 @@
-name: Claude Code Review
-
-on:
- pull_request:
- types: [opened, synchronize]
- # Optional: Only run on specific file changes
- # paths:
- # - "src/**/*.ts"
- # - "src/**/*.tsx"
- # - "src/**/*.js"
- # - "src/**/*.jsx"
-
-jobs:
- claude-review:
- if: false
- # Optional: Filter by PR author
- # if: |
- # github.event.pull_request.user.login == 'external-contributor' ||
- # github.event.pull_request.user.login == 'new-developer' ||
- # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
-
- runs-on: ubuntu-latest
- permissions:
- contents: read
- pull-requests: read
- issues: read
- id-token: write
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
- with:
- fetch-depth: 1
-
- - name: Run Claude Code Review
- id: claude-review
- uses: anthropics/claude-code-action@beta
- with:
- claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
-
- # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1)
- # model: "claude-opus-4-1-20250805"
-
- # Direct prompt for automated review (no @claude mention needed)
- direct_prompt: |
- Please review this pull request and provide feedback on:
- - Code quality and best practices
- - Potential bugs or issues
- - Performance considerations
- - Security concerns
- - Test coverage
-
- Be constructive and helpful in your feedback.
-
- # Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR
- # use_sticky_comment: true
-
- # Optional: Customize review based on file types
- # direct_prompt: |
- # Review this PR focusing on:
- # - For TypeScript files: Type safety and proper interface usage
- # - For API endpoints: Security, input validation, and error handling
- # - For React components: Performance, accessibility, and best practices
- # - For tests: Coverage, edge cases, and test quality
-
- # Optional: Different prompts for different authors
- # direct_prompt: |
- # ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' &&
- # 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' ||
- # 'Please provide a thorough code review focusing on our coding standards and best practices.' }}
-
- # Optional: Add specific tools for running tests or linting
- # allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"
-
- # Optional: Skip review for certain conditions
- # if: |
- # !contains(github.event.pull_request.title, '[skip-review]') &&
- # !contains(github.event.pull_request.title, '[WIP]')
-
diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml
deleted file mode 100644
index 9daf0e90e..000000000
--- a/.github/workflows/claude.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-name: Claude Code
-
-on:
- issue_comment:
- types: [created]
- pull_request_review_comment:
- types: [created]
- issues:
- types: [opened, assigned]
- pull_request_review:
- types: [submitted]
-
-jobs:
- claude:
- if: |
- (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
- (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
- (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
- (github.event_name == 'issues' && github.event.action == 'labeled' && github.event.label.name == 'Claude') ||
- (github.event_name == 'pull_request' && github.event.action == 'labeled' && github.event.label.name == 'Claude') ||
- (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
- runs-on: ubuntu-latest
- permissions:
- contents: read
- pull-requests: read
- issues: read
- id-token: write
- actions: read # Required for Claude to read CI results on PRs
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
- with:
- fetch-depth: 1
-
- - name: Run Claude Code
- id: claude
- uses: anthropics/claude-code-action@v1
- with:
- anthropic_api_key: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
-
- # This is an optional setting that allows Claude to read CI results on PRs
- additional_permissions: |
- actions: read
-
- # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1)
- # model: "claude-opus-4-1-20250805"
-
- # Optional: Customize the trigger phrase (default: @claude)
- # trigger_phrase: "/claude"
-
- # Optional: Trigger when specific user is assigned to an issue
- # assignee_trigger: "claude-bot"
-
- # Optional: Allow Claude to run specific commands
- # allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)"
-
- # Optional: Add custom instructions for Claude to customize its behavior for your project
- # custom_instructions: |
- # Follow our coding standards
- # Ensure all new code has tests
- # Use TypeScript for new files
-
- # Optional: Custom environment variables for Claude
- # claude_env: |
- # NODE_ENV: test
diff --git a/.github/workflows/cleanup-ghcr-untagged.yml b/.github/workflows/cleanup-ghcr-untagged.yml
index 394fba68f..a86cedcb0 100644
--- a/.github/workflows/cleanup-ghcr-untagged.yml
+++ b/.github/workflows/cleanup-ghcr-untagged.yml
@@ -1,17 +1,14 @@
name: Cleanup Untagged GHCR Images
on:
- workflow_dispatch: # Manual trigger only
+ workflow_dispatch:
-env:
- GITHUB_REGISTRY: ghcr.io
+permissions:
+ packages: write
jobs:
cleanup-all-packages:
runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
strategy:
matrix:
package: ['coolify', 'coolify-helper', 'coolify-realtime', 'coolify-testing-host']
diff --git a/.github/workflows/coolify-helper-next.yml b/.github/workflows/coolify-helper-next.yml
index a4a2a21f6..fec54d54a 100644
--- a/.github/workflows/coolify-helper-next.yml
+++ b/.github/workflows/coolify-helper-next.yml
@@ -7,19 +7,31 @@ on:
- .github/workflows/coolify-helper-next.yml
- docker/coolify-helper/Dockerfile
+permissions:
+ contents: read
+ packages: write
+
env:
GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify-helper"
jobs:
- amd64:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
+ build-push:
+ strategy:
+ matrix:
+ include:
+ - arch: amd64
+ platform: linux/amd64
+ runner: ubuntu-24.04
+ - arch: aarch64
+ platform: linux/aarch64
+ runner: ubuntu-24.04-arm
+ runs-on: ${{ matrix.runner }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
@@ -40,66 +52,27 @@ jobs:
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getHelperVersion.php)"|xargs >> $GITHUB_OUTPUT
- - name: Build and Push Image
+ - name: Build and Push Image (${{ matrix.arch }})
uses: docker/build-push-action@v6
with:
context: .
file: docker/coolify-helper/Dockerfile
- platforms: linux/amd64
+ platforms: ${{ matrix.platform }}
push: true
tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
- labels: |
- coolify.managed=true
- aarch64:
- runs-on: [ self-hosted, arm64 ]
- permissions:
- contents: read
- packages: write
- steps:
- - uses: actions/checkout@v4
-
- - name: Login to ${{ env.GITHUB_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.GITHUB_REGISTRY }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Login to ${{ env.DOCKER_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.DOCKER_REGISTRY }}
- username: ${{ secrets.DOCKER_USERNAME }}
- password: ${{ secrets.DOCKER_TOKEN }}
-
- - name: Get Version
- id: version
- run: |
- echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getHelperVersion.php)"|xargs >> $GITHUB_OUTPUT
-
- - name: Build and Push Image
- uses: docker/build-push-action@v6
- with:
- context: .
- file: docker/coolify-helper/Dockerfile
- platforms: linux/aarch64
- push: true
- tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-${{ matrix.arch }}
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-${{ matrix.arch }}
labels: |
coolify.managed=true
merge-manifest:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- needs: [ amd64, aarch64 ]
+ runs-on: ubuntu-24.04
+ needs: build-push
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
+
- uses: docker/setup-buildx-action@v3
- name: Login to ${{ env.GITHUB_REGISTRY }}
@@ -124,14 +97,16 @@ jobs:
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-amd64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-amd64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next
diff --git a/.github/workflows/coolify-helper.yml b/.github/workflows/coolify-helper.yml
index 56c3eaa17..0c9996ec8 100644
--- a/.github/workflows/coolify-helper.yml
+++ b/.github/workflows/coolify-helper.yml
@@ -7,19 +7,31 @@ on:
- .github/workflows/coolify-helper.yml
- docker/coolify-helper/Dockerfile
+permissions:
+ contents: read
+ packages: write
+
env:
GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify-helper"
jobs:
- amd64:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
+ build-push:
+ strategy:
+ matrix:
+ include:
+ - arch: amd64
+ platform: linux/amd64
+ runner: ubuntu-24.04
+ - arch: aarch64
+ platform: linux/aarch64
+ runner: ubuntu-24.04-arm
+ runs-on: ${{ matrix.runner }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
@@ -40,65 +52,25 @@ jobs:
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getHelperVersion.php)"|xargs >> $GITHUB_OUTPUT
- - name: Build and Push Image
+ - name: Build and Push Image (${{ matrix.arch }})
uses: docker/build-push-action@v6
with:
context: .
file: docker/coolify-helper/Dockerfile
- platforms: linux/amd64
+ platforms: ${{ matrix.platform }}
push: true
tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
- labels: |
- coolify.managed=true
- aarch64:
- runs-on: [ self-hosted, arm64 ]
- permissions:
- contents: read
- packages: write
- steps:
- - uses: actions/checkout@v4
-
- - name: Login to ${{ env.GITHUB_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.GITHUB_REGISTRY }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Login to ${{ env.DOCKER_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.DOCKER_REGISTRY }}
- username: ${{ secrets.DOCKER_USERNAME }}
- password: ${{ secrets.DOCKER_TOKEN }}
-
- - name: Get Version
- id: version
- run: |
- echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getHelperVersion.php)"|xargs >> $GITHUB_OUTPUT
-
- - name: Build and Push Image
- uses: docker/build-push-action@v6
- with:
- context: .
- file: docker/coolify-helper/Dockerfile
- platforms: linux/aarch64
- push: true
- tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-${{ matrix.arch }}
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-${{ matrix.arch }}
labels: |
coolify.managed=true
merge-manifest:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- needs: [ amd64, aarch64 ]
+ runs-on: ubuntu-24.04
+ needs: build-push
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- uses: docker/setup-buildx-action@v3
@@ -124,14 +96,16 @@ jobs:
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-amd64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-amd64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
diff --git a/.github/workflows/coolify-production-build.yml b/.github/workflows/coolify-production-build.yml
index cd1f002b8..21871b103 100644
--- a/.github/workflows/coolify-production-build.yml
+++ b/.github/workflows/coolify-production-build.yml
@@ -14,16 +14,31 @@ on:
- templates/**
- CHANGELOG.md
+permissions:
+ contents: read
+ packages: write
+
env:
GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify"
jobs:
- amd64:
- runs-on: ubuntu-latest
+ build-push:
+ strategy:
+ matrix:
+ include:
+ - arch: amd64
+ platform: linux/amd64
+ runner: ubuntu-24.04
+ - arch: aarch64
+ platform: linux/aarch64
+ runner: ubuntu-24.04-arm
+ runs-on: ${{ matrix.runner }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
@@ -44,60 +59,24 @@ jobs:
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT
- - name: Build and Push Image
+ - name: Build and Push Image (${{ matrix.arch }})
uses: docker/build-push-action@v6
with:
context: .
file: docker/production/Dockerfile
- platforms: linux/amd64
+ platforms: ${{ matrix.platform }}
push: true
tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
-
- aarch64:
- runs-on: [self-hosted, arm64]
- steps:
- - uses: actions/checkout@v4
-
- - name: Login to ${{ env.GITHUB_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.GITHUB_REGISTRY }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Login to ${{ env.DOCKER_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.DOCKER_REGISTRY }}
- username: ${{ secrets.DOCKER_USERNAME }}
- password: ${{ secrets.DOCKER_TOKEN }}
-
- - name: Get Version
- id: version
- run: |
- echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT
-
- - name: Build and Push Image
- uses: docker/build-push-action@v6
- with:
- context: .
- file: docker/production/Dockerfile
- platforms: linux/aarch64
- push: true
- tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-${{ matrix.arch }}
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-${{ matrix.arch }}
merge-manifest:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- needs: [amd64, aarch64]
+ runs-on: ubuntu-24.04
+ needs: build-push
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- uses: docker/setup-buildx-action@v3
@@ -123,14 +102,16 @@ jobs:
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-amd64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-amd64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
diff --git a/.github/workflows/coolify-realtime-next.yml b/.github/workflows/coolify-realtime-next.yml
index ad590146b..7ab4dcc42 100644
--- a/.github/workflows/coolify-realtime-next.yml
+++ b/.github/workflows/coolify-realtime-next.yml
@@ -11,19 +11,31 @@ on:
- docker/coolify-realtime/package-lock.json
- docker/coolify-realtime/soketi-entrypoint.sh
+permissions:
+ contents: read
+ packages: write
+
env:
GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify-realtime"
jobs:
- amd64:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
+ build-push:
+ strategy:
+ matrix:
+ include:
+ - arch: amd64
+ platform: linux/amd64
+ runner: ubuntu-24.04
+ - arch: aarch64
+ platform: linux/aarch64
+ runner: ubuntu-24.04-arm
+ runs-on: ${{ matrix.runner }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
@@ -44,67 +56,26 @@ jobs:
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getRealtimeVersion.php)"|xargs >> $GITHUB_OUTPUT
- - name: Build and Push Image
+ - name: Build and Push Image (${{ matrix.arch }})
uses: docker/build-push-action@v6
with:
context: .
file: docker/coolify-realtime/Dockerfile
- platforms: linux/amd64
+ platforms: ${{ matrix.platform }}
push: true
tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
- labels: |
- coolify.managed=true
-
- aarch64:
- runs-on: [ self-hosted, arm64 ]
- permissions:
- contents: read
- packages: write
- steps:
- - uses: actions/checkout@v4
-
- - name: Login to ${{ env.GITHUB_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.GITHUB_REGISTRY }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Login to ${{ env.DOCKER_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.DOCKER_REGISTRY }}
- username: ${{ secrets.DOCKER_USERNAME }}
- password: ${{ secrets.DOCKER_TOKEN }}
-
- - name: Get Version
- id: version
- run: |
- echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getRealtimeVersion.php)"|xargs >> $GITHUB_OUTPUT
-
- - name: Build and Push Image
- uses: docker/build-push-action@v6
- with:
- context: .
- file: docker/coolify-realtime/Dockerfile
- platforms: linux/aarch64
- push: true
- tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-${{ matrix.arch }}
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-${{ matrix.arch }}
labels: |
coolify.managed=true
merge-manifest:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- needs: [ amd64, aarch64 ]
+ runs-on: ubuntu-24.04
+ needs: build-push
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- uses: docker/setup-buildx-action@v3
@@ -130,14 +101,16 @@ jobs:
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-amd64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-amd64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next
diff --git a/.github/workflows/coolify-realtime.yml b/.github/workflows/coolify-realtime.yml
index d00621cc2..5efe445c5 100644
--- a/.github/workflows/coolify-realtime.yml
+++ b/.github/workflows/coolify-realtime.yml
@@ -11,19 +11,31 @@ on:
- docker/coolify-realtime/package-lock.json
- docker/coolify-realtime/soketi-entrypoint.sh
+permissions:
+ contents: read
+ packages: write
+
env:
GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify-realtime"
jobs:
- amd64:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
+ build-push:
+ strategy:
+ matrix:
+ include:
+ - arch: amd64
+ platform: linux/amd64
+ runner: ubuntu-24.04
+ - arch: aarch64
+ platform: linux/aarch64
+ runner: ubuntu-24.04-arm
+ runs-on: ${{ matrix.runner }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
@@ -44,67 +56,26 @@ jobs:
run: |
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getRealtimeVersion.php)"|xargs >> $GITHUB_OUTPUT
- - name: Build and Push Image
+ - name: Build and Push Image (${{ matrix.arch }})
uses: docker/build-push-action@v6
with:
context: .
file: docker/coolify-realtime/Dockerfile
- platforms: linux/amd64
+ platforms: ${{ matrix.platform }}
push: true
tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
- labels: |
- coolify.managed=true
-
- aarch64:
- runs-on: [ self-hosted, arm64 ]
- permissions:
- contents: read
- packages: write
- steps:
- - uses: actions/checkout@v4
-
- - name: Login to ${{ env.GITHUB_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.GITHUB_REGISTRY }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Login to ${{ env.DOCKER_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.DOCKER_REGISTRY }}
- username: ${{ secrets.DOCKER_USERNAME }}
- password: ${{ secrets.DOCKER_TOKEN }}
-
- - name: Get Version
- id: version
- run: |
- echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getRealtimeVersion.php)"|xargs >> $GITHUB_OUTPUT
-
- - name: Build and Push Image
- uses: docker/build-push-action@v6
- with:
- context: .
- file: docker/coolify-realtime/Dockerfile
- platforms: linux/aarch64
- push: true
- tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-${{ matrix.arch }}
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-${{ matrix.arch }}
labels: |
coolify.managed=true
merge-manifest:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- needs: [ amd64, aarch64 ]
+ runs-on: ubuntu-24.04
+ needs: build-push
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- uses: docker/setup-buildx-action@v3
@@ -130,14 +101,16 @@ jobs:
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-amd64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-amd64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
diff --git a/.github/workflows/coolify-staging-build.yml b/.github/workflows/coolify-staging-build.yml
index c6aa2dd90..67b7b03e8 100644
--- a/.github/workflows/coolify-staging-build.yml
+++ b/.github/workflows/coolify-staging-build.yml
@@ -17,16 +17,31 @@ on:
- templates/**
- CHANGELOG.md
+permissions:
+ contents: read
+ packages: write
+
env:
GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify"
jobs:
- amd64:
- runs-on: ubuntu-latest
+ build-push:
+ strategy:
+ matrix:
+ include:
+ - arch: amd64
+ platform: linux/amd64
+ runner: ubuntu-24.04
+ - arch: aarch64
+ platform: linux/aarch64
+ runner: ubuntu-24.04-arm
+ runs-on: ${{ matrix.runner }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- name: Sanitize branch name for Docker tag
id: sanitize
@@ -35,6 +50,9 @@ jobs:
SANITIZED_NAME=$(echo "${{ github.ref_name }}" | sed 's/[\/]/-/g')
echo "tag=${SANITIZED_NAME}" >> $GITHUB_OUTPUT
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
with:
@@ -49,65 +67,28 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- - name: Build and Push Image
+ - name: Build and Push Image (${{ matrix.arch }})
uses: docker/build-push-action@v6
with:
context: .
file: docker/production/Dockerfile
- platforms: linux/amd64
+ platforms: ${{ matrix.platform }}
push: true
tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}
-
- aarch64:
- runs-on: [self-hosted, arm64]
- permissions:
- contents: read
- packages: write
- steps:
- - uses: actions/checkout@v4
-
- - name: Sanitize branch name for Docker tag
- id: sanitize
- run: |
- # Replace slashes and other invalid characters with dashes
- SANITIZED_NAME=$(echo "${{ github.ref_name }}" | sed 's/[\/]/-/g')
- echo "tag=${SANITIZED_NAME}" >> $GITHUB_OUTPUT
-
- - name: Login to ${{ env.GITHUB_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.GITHUB_REGISTRY }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Login to ${{ env.DOCKER_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.DOCKER_REGISTRY }}
- username: ${{ secrets.DOCKER_USERNAME }}
- password: ${{ secrets.DOCKER_TOKEN }}
-
- - name: Build and Push Image
- uses: docker/build-push-action@v6
- with:
- context: .
- file: docker/production/Dockerfile
- platforms: linux/aarch64
- push: true
- tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}-aarch64
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}-aarch64
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}-${{ matrix.arch }}
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}-${{ matrix.arch }}
+ cache-from: |
+ type=gha,scope=build-${{ matrix.arch }}
+ type=registry,ref=${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-${{ matrix.arch }}
+ cache-to: type=gha,mode=max,scope=build-${{ matrix.arch }}
merge-manifest:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- needs: [amd64, aarch64]
+ runs-on: ubuntu-24.04
+ needs: build-push
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- name: Sanitize branch name for Docker tag
id: sanitize
@@ -135,13 +116,15 @@ jobs:
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}-aarch64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}-amd64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}-aarch64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}-amd64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sanitize.outputs.tag }}
- uses: sarisia/actions-status-discord@v1
diff --git a/.github/workflows/coolify-testing-host.yml b/.github/workflows/coolify-testing-host.yml
index 95a228114..24133887a 100644
--- a/.github/workflows/coolify-testing-host.yml
+++ b/.github/workflows/coolify-testing-host.yml
@@ -7,19 +7,31 @@ on:
- .github/workflows/coolify-testing-host.yml
- docker/testing-host/Dockerfile
+permissions:
+ contents: read
+ packages: write
+
env:
GITHUB_REGISTRY: ghcr.io
DOCKER_REGISTRY: docker.io
IMAGE_NAME: "coollabsio/coolify-testing-host"
jobs:
- amd64:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
+ build-push:
+ strategy:
+ matrix:
+ include:
+ - arch: amd64
+ platform: linux/amd64
+ runner: ubuntu-24.04
+ - arch: aarch64
+ platform: linux/aarch64
+ runner: ubuntu-24.04-arm
+ runs-on: ${{ matrix.runner }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- name: Login to ${{ env.GITHUB_REGISTRY }}
uses: docker/login-action@v3
@@ -35,62 +47,26 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- - name: Build and Push Image
+ - name: Build and Push Image (${{ matrix.arch }})
uses: docker/build-push-action@v6
with:
context: .
file: docker/testing-host/Dockerfile
- platforms: linux/amd64
+ platforms: ${{ matrix.platform }}
push: true
tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- labels: |
- coolify.managed=true
-
- aarch64:
- runs-on: [ self-hosted, arm64 ]
- permissions:
- contents: read
- packages: write
- steps:
- - uses: actions/checkout@v4
-
- - name: Login to ${{ env.GITHUB_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.GITHUB_REGISTRY }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Login to ${{ env.DOCKER_REGISTRY }}
- uses: docker/login-action@v3
- with:
- registry: ${{ env.DOCKER_REGISTRY }}
- username: ${{ secrets.DOCKER_USERNAME }}
- password: ${{ secrets.DOCKER_TOKEN }}
-
- - name: Build and Push Image
- uses: docker/build-push-action@v6
- with:
- context: .
- file: docker/testing-host/Dockerfile
- platforms: linux/aarch64
- push: true
- tags: |
- ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64
- ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-${{ matrix.arch }}
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-${{ matrix.arch }}
labels: |
coolify.managed=true
merge-manifest:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- needs: [ amd64, aarch64 ]
+ runs-on: ubuntu-24.04
+ needs: build-push
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
- uses: docker/setup-buildx-action@v3
@@ -111,13 +87,15 @@ jobs:
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-amd64 \
+ ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 \
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
run: |
docker buildx imagetools create \
- --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-amd64 \
+ ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 \
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- uses: sarisia/actions-status-discord@v1
diff --git a/.gitignore b/.gitignore
index 65b7faa1b..935ea548e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,4 @@ scripts/load-test/*
docker/coolify-realtime/node_modules
.DS_Store
CHANGELOG.md
+/.workspaces
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a0641f32..2980c7401 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,80 +4,164 @@ # Changelog
## [unreleased]
+### 🐛 Bug Fixes
+
+- Update syncData method to use data_get for safer property access
+- Update version numbers to 4.0.0-beta.441 and 4.0.0-beta.442
+- Enhance menu item styles and update theme color meta tag
+- Clean up input attributes for PostgreSQL settings in general.blade.php
+- Update docker stop command to use --time instead of --timeout
+- Clean up utility classes and improve readability in Blade templates
+- Enhance styling for page width component in Blade template
+- Remove debugging output from StartPostgresql command handling
+
### 📚 Documentation
- Update changelog
-## [4.0.0-beta.436] - 2025-10-17
-
-### 🚀 Features
-
-- Implement TrustHosts middleware to handle FQDN and IP address trust logic
-- Implement TrustHosts middleware to handle FQDN and IP address trust logic
-- Allow safe environment variable defaults in array-format volumes
-- Add signoz template
-- *(signoz)* Replace png icon by svg icon
-- *(signoz)* Remove explicit 'networks' setting
-- *(signoz)* Add predefined environment variables to configure Telemetry, SMTP and email sending for Alert Manager
-- *(signoz)* Generate URLs for `otel-collector` service
-- *(signoz)* Update documentation link
-- *(signoz)* Add healthcheck to otel-collector service
-- *(signoz)* Use latest tag instead of hardcoded versions
-- *(signoz)* Remove redundant users.xml volume from clickhouse container
-- *(signoz)* Replace clickhouse' config.xml volume with simpler configuration
-- *(signoz)* Remove deprecated parameters of signoz container
-- *(signoz)* Remove volumes from signoz.yaml
-- *(signoz)* Assume there is a single zookeeper container
-- *(signoz)* Update Clickhouse config to include all settings required by Signoz
-- *(signoz)* Update config.xml and users.xml to ensure clickhouse boots correctly
-- *(signoz)* Update otel-collector configuration to match upstream
-- *(signoz)* Fix otel-collector config for version v0.128.0
-- *(signoz)* Remove unecessary port mapping for otel-collector
-- *(signoz)* Add SIGNOZ_JWT_SECRET env var generation
-- *(signoz)* Upgrade clickhouse image to 25.5.6
-- *(signoz)* Use latest tag for signoz/zookeeper
-- *(signoz)* Update variables for SMTP configuration
-- *(signoz)* Replace deprecated `TELEMETRY_ENABLED` by `SIGNOZ_STATSREPORTER_ENABLED`
-- *(signoz)* Pin service image tags and `exclude_from_hc` flag to services excluded from health checks
-- *(templates)* Add SMTP configuration to ente-photos compose templates
-- *(templates)* Add SMTP encryption configuration to ente-photos compose templates
+## [4.0.0-beta.440] - 2025-11-04
### 🐛 Bug Fixes
-- Use wasChanged() instead of isDirty() in updated hooks
-- Prevent command injection in git ls-remote operations
-- Handle null environment variable values in bash escaping
-- Critical privilege escalation in team invitation system
-- Add authentication context to TeamPolicyTest
-- Ensure negative cache results are stored in TrustHosts middleware
-- Use wasChanged() instead of isDirty() in updated hook
-- Prevent command injection in Docker Compose parsing - add pre-save validation
-- Use canonical parser for Windows path validation
-- Correct variable name typo in generateGitLsRemoteCommands method
-- Update version numbers to 4.0.0-beta.436 and 4.0.0-beta.437
-- Ensure authorization checks are in place for viewing and updating the application
-- Ensure authorization check is performed during component mount
-- *(signoz)* Remove example secrets to avoid triggering GitGuardian
-- *(signoz)* Remove hardcoded container names
-- *(signoz)* Remove HTTP collector FQDN in otel-collector
-- *(n8n)* Add DB_SQLITE_POOL_SIZE environment variable for configuration
+- Fix SPA toggle nginx regeneration and add confirmation modal
+
+### 📚 Documentation
+
+- Update changelog
+
+## [4.0.0-beta.439] - 2025-11-03
+
+### 📚 Documentation
+
+- Update changelog
+
+## [4.0.0-beta.438] - 2025-10-29
+
+### 🚀 Features
+
+- Display service logos in original colors with consistent sizing
+- Add warnings for system-wide GitHub Apps
+- Show message when no resources use GitHub App
+- Add dynamic viewport-based height for compose editor
+- Add funding information for Coollabs including sponsorship plans and channels
+- Update Evolution API slogan to better reflect its capabilities
+- *(templates)* Update plane compose to v1.0.0
+- Add token validation functionality for Hetzner and DigitalOcean providers
+- Add dev_helper_version to instance settings and update related functionality
+- Add RestoreDatabase command for PostgreSQL dump restoration
+- Update ApplicationSetting model to include additional boolean casts
+- Enhance General component with additional properties and validation rules
+- Update version numbers to 4.0.0-beta.440 and 4.0.0-beta.441
+
+### 🐛 Bug Fixes
+
+- Handle redis_password in API database creation
+- Make modals scrollable on small screens
+- Resolve Livewire wire:model binding error in domains input
+- Make environment variable forms responsive
+- Make proxy logs page responsive
+- Improve proxy logs form layout for better responsive behavior
+- Prevent horizontal overflow in log text
+- Use break-all to force line wrapping in logs
+- Ensure deployment failure notifications are sent reliably
+- GitHub source creation and configuration issues
+- Make system-wide warning reactive in Create view
+- Prevent system-wide warning callout from making modal too wide
+- Constrain callout width with max-w-2xl and wrap text properly
+- Center system-wide warning callout in modal
+- Left-align callout on regular view, keep centered in modal
+- Allow callout to take full width in regular view
+- Change app_id and installation_id to integer values in createGithubAppManually method
+- Use x-cloak instead of inline style to prevent FOUC
+- Clarify warning message for allowed IPs configuration
+- Server URL generation in ServerPatchCheck notification
+- Monaco editor empty for docker compose applications
+- Update sponsor link from Darweb to Dade2 in README
+- *(database)* Prevent malformed URLs when server IP is empty
+- Optimize caching in Dockerfile and GitHub Actions workflow
+- Remove wire:ignore from modal and add wire:key to EditCompose component
+- Add wire:ignore directive to modal component for improved functionality
+- Clean up formatting and remove unnecessary key binding in stack form component
+- Add null checks and validation to OAuth bulk update method
+- *(docs)* Update documentation URL to version 2 in evolution-api.yaml
+- *(templates)* Remove volumes from Plane's compose
+- *(templates)* Add redis env to live service in Plane
+- *(templates)* Update minio image to use coollabsio fork in Plane
+- Prevent login rate limit bypass via spoofed headers
+- Correct login rate limiter key format to include IP address
+- Change SMTP port input type to number for better validation
+- Remove unnecessary step attribute from maximum storage input fields
+- Update boarding flow logic to complete onboarding when server is created
+- Convert network aliases to string for display
+- Improve custom_network_aliases handling and testing
+- Remove duplicate custom_labels from config hash calculation
+- Improve run script and enhance sticky header style
+
+### 💼 Other
+
+- *(deps-dev)* Bump vite from 6.3.6 to 6.4.1
### 🚜 Refactor
-- Improve validation error handling and coding standards
-- Preserve exception chain in validation error handling
-- Harden and deduplicate validateShellSafePath
-- Replace random ID generation with Cuid2 for unique HTML IDs in form components
+- Remove deprecated next() method
+- Replace allowed IPs validation logic with regex
+- Remove redundant
+- Streamline allowed IPs validation and enhance UI warnings for API access
+- Remove staging URL logic from ServerPatchCheck constructor
+- Streamline Docker build process with matrix strategy for multi-architecture support
+- Simplify project data retrieval and enhance OAuth settings handling
+- Improve handling of custom network aliases
+- Remove unused submodules
+- Update subproject commit hashes
+- Remove SynchronizesModelData trait and implement syncData method for model synchronization
+
+### 📚 Documentation
+
+- Update changelog
+- Update changelog
+- Update changelog
+- Update changelog
+- Update changelog
+- Update changelog
+- Update changelog
+- Add service & database deployment logging plan
### 🧪 Testing
-- Add coverage for newline and tab rejection in volume strings
+- Add unit tests for ServerPatchCheck notification URL generation
+- Fix ServerPatchCheckNotification tests to avoid global state pollution
### ⚙️ Miscellaneous Tasks
-- *(signoz)* Remove unused ports
-- *(signoz)* Bump version to 0.77.0
-- *(signoz)* Bump version to 0.78.1
+- Add category field to siyuan.yaml
+- Update siyuan category in service templates
+- Add spacing and format callout text in modal
+- Update version numbers to 4.0.0-beta.439 and 4.0.0-beta.440
+- Add .workspaces to .gitignore
+
+## [4.0.0-beta.437] - 2025-10-21
+
+### 🚀 Features
+
+- *(templates)* Add sparkyfitness compose template and logo
+- *(servide)* Add siyuan template
+- Add onboarding guide link to global search no results state
+- Add category filter dropdown to service selection
+
+### 🐛 Bug Fixes
+
+- *(service)* Update image version & healthcheck start period
+- Filter deprecated server types for Hetzner
+- Eliminate dark mode white screen flicker on page transitions
+
+### 💼 Other
+
+- Preserve clean docker_compose_raw without Coolify additions
+
+### 📚 Documentation
+
+- Update changelog
+- Update changelog
## [4.0.0-beta.435] - 2025-10-15
@@ -143,6 +227,35 @@ ### 🚀 Features
- Add Hetzner affiliate link to token form
- Update Hetzner affiliate link text and URL
- Add CPU vendor information to server types in Hetzner integration
+- Implement TrustHosts middleware to handle FQDN and IP address trust logic
+- Implement TrustHosts middleware to handle FQDN and IP address trust logic
+- Allow safe environment variable defaults in array-format volumes
+- Add signoz template
+- *(signoz)* Replace png icon by svg icon
+- *(signoz)* Remove explicit 'networks' setting
+- *(signoz)* Add predefined environment variables to configure Telemetry, SMTP and email sending for Alert Manager
+- *(signoz)* Generate URLs for `otel-collector` service
+- *(signoz)* Update documentation link
+- *(signoz)* Add healthcheck to otel-collector service
+- *(signoz)* Use latest tag instead of hardcoded versions
+- *(signoz)* Remove redundant users.xml volume from clickhouse container
+- *(signoz)* Replace clickhouse' config.xml volume with simpler configuration
+- *(signoz)* Remove deprecated parameters of signoz container
+- *(signoz)* Remove volumes from signoz.yaml
+- *(signoz)* Assume there is a single zookeeper container
+- *(signoz)* Update Clickhouse config to include all settings required by Signoz
+- *(signoz)* Update config.xml and users.xml to ensure clickhouse boots correctly
+- *(signoz)* Update otel-collector configuration to match upstream
+- *(signoz)* Fix otel-collector config for version v0.128.0
+- *(signoz)* Remove unecessary port mapping for otel-collector
+- *(signoz)* Add SIGNOZ_JWT_SECRET env var generation
+- *(signoz)* Upgrade clickhouse image to 25.5.6
+- *(signoz)* Use latest tag for signoz/zookeeper
+- *(signoz)* Update variables for SMTP configuration
+- *(signoz)* Replace deprecated `TELEMETRY_ENABLED` by `SIGNOZ_STATSREPORTER_ENABLED`
+- *(signoz)* Pin service image tags and `exclude_from_hc` flag to services excluded from health checks
+- *(templates)* Add SMTP configuration to ente-photos compose templates
+- *(templates)* Add SMTP encryption configuration to ente-photos compose templates
### 🐛 Bug Fixes
@@ -230,6 +343,25 @@ ### 🐛 Bug Fixes
- Use computed imageTag variable for digest-based Docker images
- Improve Docker image digest handling and add auto-parse feature
- 'new image' quick action not progressing to resource selection
+- Use wasChanged() instead of isDirty() in updated hooks
+- Prevent command injection in git ls-remote operations
+- Handle null environment variable values in bash escaping
+- Critical privilege escalation in team invitation system
+- Add authentication context to TeamPolicyTest
+- Ensure negative cache results are stored in TrustHosts middleware
+- Use wasChanged() instead of isDirty() in updated hook
+- Prevent command injection in Docker Compose parsing - add pre-save validation
+- Use canonical parser for Windows path validation
+- Correct variable name typo in generateGitLsRemoteCommands method
+- Update version numbers to 4.0.0-beta.436 and 4.0.0-beta.437
+- Ensure authorization checks are in place for viewing and updating the application
+- Ensure authorization check is performed during component mount
+- *(signoz)* Remove example secrets to avoid triggering GitGuardian
+- *(signoz)* Remove hardcoded container names
+- *(signoz)* Remove HTTP collector FQDN in otel-collector
+- *(n8n)* Add DB_SQLITE_POOL_SIZE environment variable for configuration
+- *(template)* Remove default values for environment variables
+- Update metamcp image version and clean up environment variable syntax
### 💼 Other
@@ -242,6 +374,8 @@ ### 💼 Other
- Remove volumes
- Add ray logging for Hetzner createServer API request/response
- Escape all shell directory paths in Git deployment commands
+- Remove content from docker_compose_raw to prevent file overwrites
+- *(templates)* Metamcp app
### 🚜 Refactor
@@ -269,6 +403,10 @@ ### 🚜 Refactor
- Migrate database components from legacy model binding to explicit properties
- Volumes set back to ./pds-data:/pds
- *(campfire)* Streamline environment variable definitions in Docker Compose file
+- Improve validation error handling and coding standards
+- Preserve exception chain in validation error handling
+- Harden and deduplicate validateShellSafePath
+- Replace random ID generation with Cuid2 for unique HTML IDs in form components
### 📚 Documentation
@@ -292,12 +430,16 @@ ### 🎨 Styling
### 🧪 Testing
- Improve Git ls-remote parsing tests with uppercase SHA and negative cases
+- Add coverage for newline and tab rejection in volume strings
### ⚙️ Miscellaneous Tasks
- *(versions)* Update Coolify version numbers to 4.0.0-beta.435 and 4.0.0-beta.436
- Update package-lock.json
- *(service)* Update convex template and image
+- *(signoz)* Remove unused ports
+- *(signoz)* Bump version to 0.77.0
+- *(signoz)* Bump version to 0.78.1
## [4.0.0-beta.434] - 2025-10-03
diff --git a/CLAUDE.md b/CLAUDE.md
index 34149d28a..6434ef877 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -146,6 +146,7 @@ ### Livewire Component Structure
- State management handled on the server
- Use wire:model for two-way data binding
- Dispatch events for component communication
+- **CRITICAL**: Livewire component views **MUST** have exactly ONE root element. ALL content must be contained within this single root element. Placing ANY elements (`