v4.0.0-beta.416 (#5729)

* feat(README): add InterviewPal sponsorship link and corresponding SVG icon

* chore(versions): update coolify version to 4.0.0-beta.413 and nightly version to 4.0.0-beta.414 in configuration files

* fix(terminal): enhance WebSocket client verification with authorized IPs in terminal server

* chore(versions): update realtime version to 1.0.8 in versions.json

* chore(versions): update realtime version to 1.0.8 in versions.json

* chore(docker): update soketi image version to 1.0.8 in production configuration files

* chore(versions): update coolify version to 4.0.0-beta.414 and nightly version to 4.0.0-beta.415 in configuration files

* fix(ApplicationDeploymentJob): ensure source is an object before checking GitHub app properties

* fix(ui): Disable livewire navigate feature (causing spam of setInterval())

* fix(ui): Remove required attribute from image input in service application view

* fix(ui): Change application image validation to be nullable in service application view

* fix(Server): Correct proxy path formatting for Traefik proxy type

* chore(versions): update coolify version to 4.0.0-beta.416 and nightly version to 4.0.0-beta.417 in configuration files; fix links in deployment view

* feat(Service): Add functionality to convert between applications and databases in docker-compose based applications
fix(ui): Fix service layout refresh on compose change

* fix(service): graceful shutdown of old container (#5731)

* refactor(Database): streamline container shutdown process and reduce timeout duration

* fix(ServerCheck): enhance proxy container check to ensure it is running before proceeding

* chore(seeder): update git branch from 'main' to 'v4.x' for multiple examples in ApplicationSeeder

* fix(applications): include pull_request_id in deployment queue check to prevent duplicate deployments

* refactor(core): streamline container stopping process and reduce timeout duration; update related methods for consistency

* fix(database): update label for image input field to improve clarity

* feat(migration): add 'is_migrated' and 'custom_type' columns to service_applications and service_databases tables

* feat(backup): implement custom database type selection and enhance scheduled backups management

* fix(ServerCheck): set default proxy status to 'exited' to handle missing container state

* fix(database): reduce container stop timeout from 300 to 30 seconds for improved responsiveness

* refactor(database): update DB facade usage for consistency across service files

* Update app/Livewire/Project/Service/Database.php

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* refactor(database): enhance application conversion logic and add existence checks for databases and applications

* refactor(actions): standardize method naming for network and configuration deletion across application and service classes

* refactor(logdrain): consolidate log drain stopping logic to reduce redundancy

* refactor(StandaloneMariadb): add type hint for destination method to improve code clarity

* refactor(DeleteResourceJob): streamline resource deletion logic and improve conditional checks for database types

* refactor(jobs): update middleware to prevent job release after expiration for CleanupInstanceStuffsJob, RestartProxyJob, and ServerCheckJob

* fix(ui): system theming for charts (#5740)

* chore(deps-dev): bump vite from 6.2.6 to 6.3.4 (#5743)

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.2.6 to 6.3.4.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.3.4/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.3.4
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix(dev): mount points?!

* fix(dev): proxy mount point

* fix(ui): allow adding scheduled backups for non-migrated databases

* fix(DatabaseBackupJob): escape PostgreSQL password in backup command (#5759)

* fix(ui): correct closing div tag in service index view

* Revert "fix(dev): mount points?!"

This reverts commit 365bf3cbf0.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Jérémy <jeremy.derdaele@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Best Codes <106822363+The-Best-Codes@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: busybox <29630035+busybox11@users.noreply.github.com>
This commit is contained in:
Andras Bacsai
2025-05-05 09:04:09 +02:00
committed by GitHub
parent 9921c02367
commit ba8689fb82
62 changed files with 495 additions and 437 deletions

View File

@@ -83,6 +83,9 @@
function checkTheme() {
theme = localStorage.theme
if (theme == 'system') {
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}
if (theme == 'dark') {
baseColor = '#FCD452'
textColor = '#ffffff'

View File

@@ -91,8 +91,7 @@
<div x-data="{ expanded: false }">
<div class="flex items-center gap-2">
<span class="font-medium">Commit:</span>
<a .prevent
href="{{ $application->gitCommitLink(data_get($deployment, 'commit')) }}"
<a href="{{ $application->gitCommitLink(data_get($deployment, 'commit')) }}"
target="_blank" class="underline">
{{ substr(data_get($deployment, 'commit'), 0, 7) }}
</a>
@@ -117,8 +116,7 @@
@endif
@if ($deployment->commitMessage())
<span class="text-gray-600 dark:text-gray-400">-</span>
<a .prevent
href="{{ $application->gitCommitLink(data_get($deployment, 'commit')) }}"
<a href="{{ $application->gitCommitLink(data_get($deployment, 'commit')) }}"
target="_blank"
class="text-gray-600 dark:text-gray-400 truncate max-w-md underline">
{{ Str::before($deployment->commitMessage(), "\n") }}

View File

@@ -117,7 +117,8 @@
@script
<script>
$wire.$on('stopEvent', () => {
$wire.$dispatch('info', 'Stopping application.');
$wire.$dispatch('info',
'Gracefully stopping application, it could take a while depending on the application.');
$wire.$call('stop');
});
</script>

View File

@@ -1,33 +1,52 @@
<div>
<div class="flex flex-col gap-2">
@forelse($database->scheduledBackups as $backup)
@if ($type == 'database')
<a class="box"
href="{{ route('project.database.backup.execution', [...$parameters, 'backup_uuid' => $backup->uuid]) }}">
<div class="flex flex-col">
<div>Frequency: {{ $backup->frequency }}
({{ data_get($backup->server(), 'settings.server_timezone', 'Instance timezone') }})
</div>
<div>Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}</div>
@if ($database->is_migrated && blank($database->custom_type))
<div>
<div>Select the type of
database to enable automated backups.</div>
<div class="pb-4"> If your database is not listed, automated backups are not supported.</div>
<form wire:submit="setCustomType" class="flex gap-2 items-end">
<div class="w-96">
<x-forms.select label="Type" id="custom_type">
<option selected value="mysql">MySQL</option>
<option value="mariadb">MariaDB</option>
<option value="postgresql">PostgreSQL</option>
<option value="mongodb">MongoDB</option>
</x-forms.select>
</div>
</a>
@else
<div class="box" wire:click="setSelectedBackup('{{ data_get($backup, 'id') }}')">
<div @class([
'border-coollabs' =>
data_get($backup, 'id') === data_get($selectedBackup, 'id'),
'flex flex-col border-l-2 border-transparent',
])>
<div>Frequency: {{ $backup->frequency }}
({{ data_get($backup->server(), 'settings.server_timezone', 'Instance timezone') }})
<x-forms.button type="submit">Set</x-forms.button>
</form>
</div>
@else
@forelse($database->scheduledBackups as $backup)
@if ($type == 'database')
<a class="box"
href="{{ route('project.database.backup.execution', [...$parameters, 'backup_uuid' => $backup->uuid]) }}">
<div class="flex flex-col">
<div>Frequency: {{ $backup->frequency }}
({{ data_get($backup->server(), 'settings.server_timezone', 'Instance timezone') }})
</div>
<div>Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}</div>
</div>
</a>
@else
<div class="box" wire:click="setSelectedBackup('{{ data_get($backup, 'id') }}')">
<div @class([
'border-coollabs' =>
data_get($backup, 'id') === data_get($selectedBackup, 'id'),
'flex flex-col border-l-2 border-transparent',
])>
<div>Frequency: {{ $backup->frequency }}
({{ data_get($backup->server(), 'settings.server_timezone', 'Instance timezone') }})
</div>
<div>Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}</div>
</div>
<div>Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}</div>
</div>
</div>
@endif
@empty
<div>No scheduled backups configured.</div>
@endforelse
@endif
@empty
<div>No scheduled backups configured.</div>
@endforelse
@endif
</div>
@if ($type === 'service-database' && $selectedBackup)
<div class="pt-10">

View File

@@ -39,7 +39,7 @@
<div class="grid grid-cols-1 gap-2 pt-4 xl:grid-cols-1" wire:poll.10000ms="check_status">
@foreach ($applications as $application)
<div @class([
'border-l border-dashed border-red-500 ' => str(
'border-l border-dashed border-red-500' => str(
$application->status)->contains(['exited']),
'border-l border-dashed border-success' => str(
$application->status)->contains(['running']),
@@ -138,7 +138,7 @@
<div class="text-xs">{{ $database->status }}</div>
</div>
<div class="flex items-center px-4">
@if ($database->isBackupSolutionAvailable())
@if ($database->isBackupSolutionAvailable() || $database->is_migrated)
<a class="mx-4 text-xs font-bold hover:underline"
href="{{ route('project.service.index', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'service_uuid' => $service->uuid, 'stack_service_uuid' => $database->uuid]) }}#backups">
Backups

View File

@@ -7,6 +7,11 @@
<h2>{{ Str::headline($database->name) }}</h2>
@endif
<x-forms.button type="submit">Save</x-forms.button>
<x-modal-confirmation wire:click="convertToApplication" title="Convert to Application"
buttonTitle="Convert to Application" submitAction="convertToApplication" :actions="['The selected resource will be converted to an application.']"
confirmationText="{{ Str::headline($database->name) }}"
confirmationLabel="Please confirm the execution of the actions by entering the Service Database Name below"
shortConfirmationLabel="Service Database Name" step3ButtonText="Permanently Delete" />
<x-modal-confirmation title="Confirm Service Database Deletion?" buttonTitle="Delete" isErrorButton
submitAction="delete" :actions="['The selected service database container will be stopped and permanently deleted.']" confirmationText="{{ Str::headline($database->name) }}"
confirmationLabel="Please confirm the execution of the actions by entering the Service Database Name below"
@@ -18,7 +23,7 @@
<x-forms.input label="Description" id="database.description"></x-forms.input>
<x-forms.input required
helper="You can change the image you would like to deploy.<br><br><span class='dark:text-warning'>WARNING. You could corrupt your data. Only do it if you know what you are doing.</span>"
label="Image Tag" id="database.image"></x-forms.input>
label="Image" id="database.image"></x-forms.input>
</div>
<div class="flex items-end gap-2">
<x-forms.input placeholder="5432" disabled="{{ $database->is_public }}" id="database.public_port"

View File

@@ -10,7 +10,7 @@
<a class="menu-item" :class="activeTab === 'general' && 'menu-item-active'"
@click.prevent="activeTab = 'general'; window.location.hash = 'general'; if(window.location.search) window.location.search = ''"
href="#">General</a>
@if ($serviceDatabase?->isBackupSolutionAvailable())
@if ($serviceDatabase?->isBackupSolutionAvailable() || $serviceDatabase?->is_migrated)
<a :class="activeTab === 'backups' && 'menu-item-active'" class="menu-item"
@click.prevent="activeTab = 'backups'; window.location.hash = 'backups'" href="#backups">Backups</a>
@endif
@@ -33,18 +33,20 @@
<div x-cloak x-show="activeTab === 'general'" class="h-full">
<livewire:project.service.database :database="$serviceDatabase" />
</div>
@if ($serviceDatabase->isBackupSolutionAvailable())
@if ($serviceDatabase?->isBackupSolutionAvailable() || $serviceDatabase?->is_migrated)
<div x-cloak x-show="activeTab === 'backups'">
<div class="flex gap-2 ">
<h2 class="pb-4">Scheduled Backups</h2>
<x-modal-input buttonTitle="+ Add" title="New Scheduled Backup">
<livewire:project.database.create-scheduled-backup :database="$serviceDatabase" />
</x-modal-input>
@if (filled($serviceDatabase->custom_type) || !$serviceDatabase->is_migrated)
<x-modal-input buttonTitle="+ Add" title="New Scheduled Backup">
<livewire:project.database.create-scheduled-backup :database="$serviceDatabase" />
</x-modal-input>
@endif
</div>
<livewire:project.database.scheduled-backups :database="$serviceDatabase" />
</div>
@endif
</div>
@endisset
@endisset
</div>
</div>
</div>
</div>

View File

@@ -138,7 +138,7 @@
@script
<script>
$wire.$on('stopEvent', () => {
$wire.$dispatch('info', 'Stopping service.');
$wire.$dispatch('info', 'Gracefully stopping service, it could take a while depending on the service.');
$wire.$call('stop');
});
$wire.$on('startEvent', async () => {

View File

@@ -7,11 +7,15 @@
<h2>{{ Str::headline($application->name) }}</h2>
@endif
<x-forms.button type="submit">Save</x-forms.button>
<x-modal-confirmation title="Confirm Service Application Deletion?" buttonTitle="Delete" isErrorButton
submitAction="delete" {{-- :checkboxes="$checkboxes" --}} :actions="['The selected service application container will be stopped and permanently deleted.']"
<x-modal-confirmation wire:click="convertToDatabase" title="Convert to Database"
buttonTitle="Convert to Database" submitAction="convertToDatabase" :actions="['The selected resource will be converted to a service database.']"
confirmationText="{{ Str::headline($application->name) }}"
confirmationLabel="Please confirm the execution of the actions by entering the Service Application Name below"
shortConfirmationLabel="Service Application Name" step3ButtonText="Permanently Delete" />
<x-modal-confirmation title="Confirm Service Application Deletion?" buttonTitle="Delete" isErrorButton
submitAction="delete" :actions="['The selected service application container will be stopped and permanently deleted.']" confirmationText="{{ Str::headline($application->name) }}"
confirmationLabel="Please confirm the execution of the actions by entering the Service Application Name below"
shortConfirmationLabel="Service Application Name" step3ButtonText="Permanently Delete" />
</div>
<div class="flex flex-col gap-2">
<div class="flex gap-2">