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 +
+
+ + + + + + + + + + Save Changes + + +
+``` + +**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 (` -
+}" x-init="calculateEditorHeight(); window.addEventListener('resize', () => calculateEditorHeight())">
Volume names are updated upon save. The service UUID will be added as a prefix to all volumes, to prevent name collision.
To see the actual volume names, check the Deployable Compose file, or go to Storage menu.
-
+
- +
@@ -22,7 +32,7 @@
- +
diff --git a/resources/views/livewire/project/service/edit-domain.blade.php b/resources/views/livewire/project/service/edit-domain.blade.php index a126eca5b..0691146f6 100644 --- a/resources/views/livewire/project/service/edit-domain.blade.php +++ b/resources/views/livewire/project/service/edit-domain.blade.php @@ -1,7 +1,13 @@
-
Note: If a service has a defined port, do not delete it.
If you want to use your custom - domain, you can add it with a port.
+ @if($requiredPort) + + This service requires port {{ $requiredPort }} to function correctly. All domains must include this port number (or any other port if you know what you're doing). +

+ Example: http://app.coolify.io:{{ $requiredPort }} +
+ @endif + @@ -18,4 +24,61 @@ + + @if ($showPortWarningModal) +
+ +
+ @endif
diff --git a/resources/views/livewire/project/service/service-application-view.blade.php b/resources/views/livewire/project/service/service-application-view.blade.php index b95dc6540..5fb4a62d0 100644 --- a/resources/views/livewire/project/service/service-application-view.blade.php +++ b/resources/views/livewire/project/service/service-application-view.blade.php @@ -22,6 +22,14 @@ @endcan
+ @if($requiredPort && !$application->serviceType()?->contains(str($application->image)->before(':'))) + + This service requires port {{ $requiredPort }} to function correctly. All domains must include this port number (or any other port if you know what you're doing). +

+ Example: http://app.coolify.io:{{ $requiredPort }} +
+ @endif +
@@ -68,9 +76,9 @@
-
    @@ -81,4 +89,61 @@
+ + @if ($showPortWarningModal) +
+ +
+ @endif
diff --git a/resources/views/livewire/project/service/stack-form.blade.php b/resources/views/livewire/project/service/stack-form.blade.php index 5a8a3e420..8972345bc 100644 --- a/resources/views/livewire/project/service/stack-form.blade.php +++ b/resources/views/livewire/project/service/stack-form.blade.php @@ -5,7 +5,8 @@ @if (isDev())
{{ $service->compose_parsing_version }}
@endif - Save + Save @can('update', $service) @@ -15,11 +16,13 @@
Configuration
- +
-
@if ($fields->count() > 0) @@ -36,10 +39,11 @@ class="font-bold">{{ data_get($field, 'serviceName') }}{{ data_get($field @endif - @endforeach @endif - + \ No newline at end of file diff --git a/resources/views/livewire/project/shared/environment-variable/show.blade.php b/resources/views/livewire/project/shared/environment-variable/show.blade.php index 4524abb82..1995bda9c 100644 --- a/resources/views/livewire/project/shared/environment-variable/show.blade.php +++ b/resources/views/livewire/project/shared/environment-variable/show.blade.php @@ -23,7 +23,7 @@ @can('update', $this->env)
-
+
@if (!$is_redis_credential) @if ($type === 'service') @else
-
+
@if (!$is_redis_credential) @if ($type === 'service') env)
-
+
@if (!$is_redis_credential) @if ($type === 'service') @else
-
+
@if (!$is_redis_credential) @if ($type === 'service')
- @if ($resource?->type() === 'application' || str($resource?->type())->startsWith('standalone')) + @if ($displayName) +

{{ $displayName }}

+ @elseif ($resource?->type() === 'application' || str($resource?->type())->startsWith('standalone'))

{{ $container }}

@else

{{ str($container)->beforeLast('-')->headline() }}

@@ -46,17 +48,19 @@ @endif
-
-
+ +
- Refresh - - +
+ Refresh + + +
-
@if ($outputs) -
{{ $outputs }}
+
{{ $outputs }}
@else -
Refresh to get the logs...
+
Refresh to get the logs...
@endif
diff --git a/resources/views/livewire/project/shared/scheduled-task/add.blade.php b/resources/views/livewire/project/shared/scheduled-task/add.blade.php index 0c4b8a4d6..6fa04c28b 100644 --- a/resources/views/livewire/project/shared/scheduled-task/add.blade.php +++ b/resources/views/livewire/project/shared/scheduled-task/add.blade.php @@ -4,6 +4,9 @@ + @if ($type === 'application') @if ($containerNames->count() > 1) diff --git a/resources/views/livewire/project/shared/scheduled-task/show.blade.php b/resources/views/livewire/project/shared/scheduled-task/show.blade.php index 1ede7775a..fa2ce0ad9 100644 --- a/resources/views/livewire/project/shared/scheduled-task/show.blade.php +++ b/resources/views/livewire/project/shared/scheduled-task/show.blade.php @@ -35,6 +35,8 @@ + @if ($type === 'application') - + @if (auth()->user()->currentTeam()->cloudProviderTokens->where('provider', $provider)->isEmpty())
Create an API token in the {{ ucfirst($provider) }} Console → choose + href='{{ $provider === 'hetzner' ? 'https://console.hetzner.com/projects' : '#' }}' + target='_blank' class='underline dark:text-white'>{{ ucfirst($provider) }} Console → choose Project → Security → API Tokens. @if ($provider === 'hetzner')

@@ -28,7 +29,7 @@ class='underline dark:text-white'>{{ ucfirst($provider) }} Console → choos class='underline dark:text-white'>Sign up here
(Coolify's affiliate link, only new accounts - supports us (€10) - and gives you €20) + and gives you €20) @endif
@endif @@ -49,7 +50,8 @@ class='underline dark:text-white'>Sign up here
- + @if (auth()->user()->currentTeam()->cloudProviderTokens->where('provider', $provider)->isEmpty())
Create an API token in the Hetzner Console → choose Project → Sec class='underline dark:text-white'>Sign up here
(Coolify's affiliate link, only new accounts - supports us (€10) - and gives you €20) + and gives you €20)
@endif
diff --git a/resources/views/livewire/security/cloud-provider-tokens.blade.php b/resources/views/livewire/security/cloud-provider-tokens.blade.php index b3239c4a8..32a2cd2ab 100644 --- a/resources/views/livewire/security/cloud-provider-tokens.blade.php +++ b/resources/views/livewire/security/cloud-provider-tokens.blade.php @@ -20,16 +20,24 @@ class="flex flex-col gap-1 p-2 border dark:border-coolgray-200 hover:no-underlin
Created: {{ $savedToken->created_at->diffForHumans() }}
- @can('delete', $savedToken) - - @endcan +
+ @can('view', $savedToken) + + Validate Token + + @endcan + + @can('delete', $savedToken) + + @endcan +
@empty
diff --git a/resources/views/livewire/server/new/by-ip.blade.php b/resources/views/livewire/server/new/by-ip.blade.php index 94d0fccbd..e41342ca2 100644 --- a/resources/views/livewire/server/new/by-ip.blade.php +++ b/resources/views/livewire/server/new/by-ip.blade.php @@ -31,45 +31,9 @@ class="font-bold underline" target="_blank" helper="Build servers are used to build your applications, so you cannot deploy applications to it." label="Use it as a build server?" />
-
-

Swarm (experimental)

-
Read the docs here.
- @if ($is_swarm_worker || $is_build_server) - - @else - - @endif - @if ($is_swarm_manager || $is_build_server) - - @else - - @endif - @if ($is_swarm_worker && count($swarm_managers) > 0) -
- - @foreach ($swarm_managers as $server) - @if ($loop->first) - - @else - - @endif - @endforeach - -
- @endif -
Continue @endif -
+
\ No newline at end of file diff --git a/resources/views/livewire/server/proxy/logs.blade.php b/resources/views/livewire/server/proxy/logs.blade.php index ea4a68674..17fe65f4c 100644 --- a/resources/views/livewire/server/proxy/logs.blade.php +++ b/resources/views/livewire/server/proxy/logs.blade.php @@ -7,7 +7,7 @@

Logs

- +
diff --git a/resources/views/livewire/server/security/patches.blade.php b/resources/views/livewire/server/security/patches.blade.php index fd7b61ad9..7627cf91f 100644 --- a/resources/views/livewire/server/security/patches.blade.php +++ b/resources/views/livewire/server/security/patches.blade.php @@ -56,48 +56,53 @@ step2ButtonText="Update All Packages" />
- - - - - @if ($packageManager !== 'dnf') - - @endif - - - - - - @foreach ($updates as $update) +
+
PackageCurrent VersionNew VersionAction
+ - - @if ($packageManager !== 'dnf') - - @endif - - + + + - @endforeach - -
- @if (data_get_str($update, 'package')->contains('docker') || data_get_str($update, 'package')->contains('kernel')) - - - - - - - - - @endif - {{ data_get($update, 'package') }} - {{ data_get($update, 'current_version') }}{{ data_get($update, 'new_version') }} - Update - PackageVersionAction
+ + + @foreach ($updates as $update) + + +
+ @if (data_get_str($update, 'package')->contains('docker') || data_get_str($update, 'package')->contains('kernel')) + + + + + + + + + @endif + {{ data_get($update, 'package') }} +
+ + +
+ {{ data_get($update, 'new_version') }} + @if ($packageManager !== 'dnf' && data_get($update, 'current_version')) + + @endif +
+ + + Update + + + @endforeach + + +
@endif @endif
diff --git a/resources/views/livewire/server/show.blade.php b/resources/views/livewire/server/show.blade.php index 5f99ad97f..4cce11e20 100644 --- a/resources/views/livewire/server/show.blade.php +++ b/resources/views/livewire/server/show.blade.php @@ -337,7 +337,7 @@ class="w-full input opacity-50 cursor-not-allowed" Sentinel Logs + container="coolify-sentinel" displayName="Sentinel" lazy /> Logs @@ -353,7 +353,7 @@ class="w-full input opacity-50 cursor-not-allowed" Sentinel Logs + container="coolify-sentinel" displayName="Sentinel" lazy /> Logs diff --git a/resources/views/livewire/settings-email.blade.php b/resources/views/livewire/settings-email.blade.php index 81cbcd09c..c58ea189d 100644 --- a/resources/views/livewire/settings-email.blade.php +++ b/resources/views/livewire/settings-email.blade.php @@ -42,7 +42,7 @@
- + diff --git a/resources/views/livewire/settings-oauth.blade.php b/resources/views/livewire/settings-oauth.blade.php index 6a967504d..7650a5654 100644 --- a/resources/views/livewire/settings-oauth.blade.php +++ b/resources/views/livewire/settings-oauth.blade.php @@ -16,33 +16,33 @@
@foreach ($oauth_settings_map as $oauth_setting)
-

{{ ucfirst($oauth_setting->provider) }}

+

{{ ucfirst($oauth_setting['provider']) }}

- +
- - - - @if ($oauth_setting->provider == 'azure') - + @if ($oauth_setting['provider'] == 'azure') + @endif - @if ($oauth_setting->provider == 'google') - @endif @if ( - $oauth_setting->provider == 'authentik' || - $oauth_setting->provider == 'clerk' || - $oauth_setting->provider == 'zitadel' || - $oauth_setting->provider == 'gitlab') - @endif
diff --git a/resources/views/livewire/settings/advanced.blade.php b/resources/views/livewire/settings/advanced.blade.php index 65d7181c6..c47c2cfef 100644 --- a/resources/views/livewire/settings/advanced.blade.php +++ b/resources/views/livewire/settings/advanced.blade.php @@ -1,77 +1,93 @@
Advanced Settings | Coolify - - -
- -
-
-

Advanced

- - Save - -
-
Advanced settings for your Coolify instance.
- -
- - -

DNS Settings

- - -

API Settings

- - -

Confirmation Settings

-
- + + +
+ + +
+

Advanced

+ + Save +
-
-
- @if ($disable_two_step_confirmation) -
- +
Advanced settings for your Coolify instance.
+ +
+
+
- @else -
- - +
+
- - Disabling two step confirmation reduces security (as anyone can easily delete anything) and - increases the risk of accidental actions. This is not recommended for production servers. - - @endif -
- -
-
+

DNS Settings

+
+ +
+ + +

API Settings

+
+ +
+ + @if (empty($allowed_ips) || in_array('0.0.0.0', array_map('trim', explode(',', $allowed_ips ?? '')))) + + Using 0.0.0.0 (or empty) allows API access from anywhere. This is not recommended for production + environments! + + @endif +

Confirmation Settings

+
+ +
+
+
+ @if ($disable_two_step_confirmation) +
+ +
+ @else +
+ + +
+ + Disabling two step confirmation reduces security (as anyone can easily delete anything) and + increases the risk of accidental actions. This is not recommended for production servers. + + @endif +
+ +
+
\ No newline at end of file diff --git a/resources/views/livewire/settings/index.blade.php b/resources/views/livewire/settings/index.blade.php index 61a73d25c..4ceb2043a 100644 --- a/resources/views/livewire/settings/index.blade.php +++ b/resources/views/livewire/settings/index.blade.php @@ -76,6 +76,13 @@ class="px-4 py-2 text-gray-800 cursor-pointer hover:bg-gray-100 dark:hover:bg-co helper="Enter the IPv6 address of the instance.

It is useful if you have several IPv6 addresses and Coolify could not detect the correct one." placeholder="2001:db8::1" autocomplete="new-password" />
+ @if(isDev()) +
+ +
+ @endif
diff --git a/resources/views/livewire/source/github/change.blade.php b/resources/views/livewire/source/github/change.blade.php index 7e6256259..0758afb70 100644 --- a/resources/views/livewire/source/github/change.blade.php +++ b/resources/views/livewire/source/github/change.blade.php @@ -1,7 +1,7 @@
@if (data_get($github_app, 'app_id'))
-
+

GitHub App

@if (data_get($github_app, 'installation_id')) @@ -40,8 +40,8 @@ @else
-
-
+
+
Sync Name @@ -72,24 +72,29 @@ class="bg-transparent border-transparent hover:bg-transparent hover:border-trans helper="If checked, this GitHub App will be available for everyone in this Coolify instance." instantSave id="isSystemWide" />
+ @if ($isSystemWide) + + System-wide GitHub Apps are shared across all teams on this Coolify instance. This means any team can use this GitHub App to deploy applications from your repositories. For better security and isolation, it's recommended to create team-specific GitHub Apps instead. + + @endif @endif -
+
-
+
-
+
-
+
+

Permissions

@can('view', $github_app) Refetch @@ -120,7 +125,7 @@ class="bg-transparent border-transparent hover:bg-transparent hover:border-trans @endcan
-
+
Here you can find all resources that are using this source.
-
+ @if ($applications->isEmpty()) +
+ No resources are currently using this GitHub App. +
+ @else
-
-
-
- - - - - - - - - - - @forelse ($applications->sortBy('name',SORT_NATURAL) as $resource) +
+
+
+
+
- Project - - EnvironmentName - Type -
+ - - - - + + + + - @empty - @endforelse - -
- {{ data_get($resource->project(), 'name') }} - - {{ data_get($resource, 'environment.name') }} - {{ $resource->name }} - - - {{ str($resource->type())->headline() }} + Project + + EnvironmentName + Type +
+ + + @foreach ($applications->sortBy('name',SORT_NATURAL) as $resource) + + + {{ data_get($resource->project(), 'name') }} + + + {{ data_get($resource, 'environment.name') }} + + {{ $resource->name }} + + + + {{ str($resource->type())->headline() }} + + @endforeach + + +
-
+ @endif
@endif @else -
+

GitHub App

@can('delete', $github_app) @@ -228,7 +238,7 @@ class=""
@can('create', $github_app) @if (!isCloud() || isDev()) -
+
@if ($ipv4) @@ -250,7 +260,7 @@ class=""
@else -
+

Register a GitHub App

@@ -261,11 +271,11 @@ class="" @endif
- - - {{-- --}}
@else diff --git a/resources/views/livewire/source/github/create.blade.php b/resources/views/livewire/source/github/create.blade.php index f47575784..9d5189b43 100644 --- a/resources/views/livewire/source/github/create.blade.php +++ b/resources/views/livewire/source/github/create.blade.php @@ -9,17 +9,28 @@ placeholder="If empty, your GitHub user will be used." id="organization" label="Organization (on GitHub)" />
@if (!isCloud()) -
- +
+
+ +
+
+ +
+ System-wide GitHub Apps are shared across all teams on this Coolify instance. This means any team + can use this GitHub App to deploy applications from your repositories. For better security and + isolation, it's recommended to create team-specific GitHub Apps instead. +
+
+
@endif
+ activeAccordion: '', + setActiveAccordion(id) { + this.activeAccordion = (this.activeAccordion == id) ? '' : id + } + }" class="relative w-full py-2 mx-auto overflow-hidden text-sm font-normal rounded-md">