fix(application): defer Docker Compose loading and preserve domains

Load the compose file only after the user confirms its location, initialize the default compose path when switching build packs, and retain existing application domains.
This commit is contained in:
Andras Bacsai
2026-08-31 21:12:28 +02:00
parent c97649bda2
commit ff8b019296
4 changed files with 47 additions and 21 deletions
+3 -19
View File
@@ -321,17 +321,6 @@ class General extends Component
}
}
$this->initialDockerComposeLocation = $this->application->docker_compose_location;
if ($this->application->build_pack === 'dockercompose' && ! $this->application->docker_compose_raw) {
// Only load compose file if user has update permission
try {
$this->authorize('update', $this->application);
$this->initLoadingCompose = true;
$this->dispatch('info', 'Loading docker compose file.');
} catch (AuthorizationException $e) {
// User doesn't have update permission, skip loading compose file
}
}
if (str($this->application->status)->startsWith('running') && is_null($this->application->config_hash)) {
$this->dispatch('configurationChanged');
}
@@ -608,14 +597,9 @@ class General extends Component
$this->resetDefaultLabels(false);
}
if ($this->buildPack === 'dockercompose') {
// Only update if user has permission
try {
$this->authorize('update', $this->application);
$this->fqdn = null;
$this->application->fqdn = null;
$this->application->settings->save();
} catch (AuthorizationException $e) {
// User doesn't have update permission, just continue without saving
if (blank($this->dockerComposeLocation)) {
$this->dockerComposeLocation = '/docker-compose.yaml';
$this->application->docker_compose_location = $this->dockerComposeLocation;
}
}
if ($this->buildPack === 'static') {
@@ -119,8 +119,7 @@
@else
<div class="flex flex-col gap-5">
@if ($buildPack === 'dockercompose')
<div class="flex flex-col gap-2"
@can('update', $application) x-init="$wire.dispatch('loadCompose', true)" @endcan>
<div class="flex flex-col gap-2">
<div x-data="{
baseDir: @entangle('baseDirectory'),
composeLocation: @entangle('dockerComposeLocation'),
@@ -15,6 +15,19 @@ use Livewire\Livewire;
uses(RefreshDatabase::class);
class GeneralWithoutBuildpackSubmitSideEffects extends General
{
public function render(): mixed
{
return view('livewire.project.application.general');
}
public function submit($showToaster = true): void
{
$this->application->save();
}
}
beforeEach(function () {
$this->team = Team::factory()->create();
$this->user = User::factory()->create();
@@ -85,3 +98,25 @@ test('existing application shows railpack without beta label in build pack selec
->assertDontSee('Railpack (Beta)')
->assertDontSee('Railpack (beta)');
});
test('switching from railpack to compose preserves the existing application domains', function () {
$application = Application::factory()->create([
'environment_id' => $this->environment->id,
'destination_id' => $this->destination->id,
'destination_type' => StandaloneDocker::class,
'build_pack' => 'railpack',
'static_image' => 'nginx:alpine',
'base_directory' => '/',
'fqdn' => 'https://example.com,https://www.example.com',
'is_http_basic_auth_enabled' => false,
'redirect' => 'no',
]);
Livewire::test(GeneralWithoutBuildpackSubmitSideEffects::class, ['application' => $application])
->assertSuccessful()
->set('buildPack', 'dockercompose')
->assertSet('dockerComposeLocation', '/docker-compose.yaml');
expect($application->refresh()->fqdn)
->toBe('https://example.com,https://www.example.com');
});
@@ -13,6 +13,14 @@ test('compose actions are grouped with the application details header', function
->toContain('Reload compose');
});
test('compose file loading waits for the user to confirm the file location', function () {
$view = file_get_contents(resource_path('views/livewire/project/application/general.blade.php'));
expect($view)
->toContain('x-on:click="$wire.dispatch(\'loadCompose\', false)"')
->not->toContain('x-init="$wire.dispatch(\'loadCompose\', true)"');
});
test('docker compose heading separates its title and action', function () {
$view = file_get_contents(resource_path('views/livewire/project/application/general.blade.php'));