feat(application): add SPA configuration and update Nginx generation logic

This commit is contained in:
Andras Bacsai
2025-03-31 15:10:50 +02:00
parent d6d1c9ad82
commit fcfd00eebe
5 changed files with 88 additions and 14 deletions

View File

@@ -2026,9 +2026,13 @@ RUN rm -f /usr/share/nginx/html/.env
COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
if (str($this->application->custom_nginx_configuration)->isNotEmpty()) { if (str($this->application->custom_nginx_configuration)->isNotEmpty()) {
$nginx_config = base64_encode($this->application->custom_nginx_configuration); $nginx_config = base64_encode($this->application->custom_nginx_configuration);
} else {
if ($this->application->settings->is_spa) {
$nginx_config = base64_encode(defaultNginxConfiguration('spa'));
} else { } else {
$nginx_config = base64_encode(defaultNginxConfiguration()); $nginx_config = base64_encode(defaultNginxConfiguration());
} }
}
} else { } else {
if ($this->application->build_pack === 'nixpacks') { if ($this->application->build_pack === 'nixpacks') {
$this->nixpacks_plan = base64_encode($this->nixpacks_plan); $this->nixpacks_plan = base64_encode($this->nixpacks_plan);
@@ -2093,10 +2097,14 @@ COPY --from=$this->build_image_name /app/{$this->application->publish_directory}
COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
if (str($this->application->custom_nginx_configuration)->isNotEmpty()) { if (str($this->application->custom_nginx_configuration)->isNotEmpty()) {
$nginx_config = base64_encode($this->application->custom_nginx_configuration); $nginx_config = base64_encode($this->application->custom_nginx_configuration);
} else {
if ($this->application->settings->is_spa) {
$nginx_config = base64_encode(defaultNginxConfiguration('spa'));
} else { } else {
$nginx_config = base64_encode(defaultNginxConfiguration()); $nginx_config = base64_encode(defaultNginxConfiguration());
} }
} }
}
$build_command = "docker build {$this->addHosts} --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t {$this->production_image_name} {$this->workdir}"; $build_command = "docker build {$this->addHosts} --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t {$this->production_image_name} {$this->workdir}";
$base64_build_command = base64_encode($build_command); $base64_build_command = base64_encode($build_command);
$this->execute_remote_command( $this->execute_remote_command(

View File

@@ -86,6 +86,7 @@ class General extends Component
'application.post_deployment_command_container' => 'nullable', 'application.post_deployment_command_container' => 'nullable',
'application.custom_nginx_configuration' => 'nullable', 'application.custom_nginx_configuration' => 'nullable',
'application.settings.is_static' => 'boolean|required', 'application.settings.is_static' => 'boolean|required',
'application.settings.is_spa' => 'boolean|required',
'application.settings.is_build_server_enabled' => 'boolean|required', 'application.settings.is_build_server_enabled' => 'boolean|required',
'application.settings.is_container_label_escape_enabled' => 'boolean|required', 'application.settings.is_container_label_escape_enabled' => 'boolean|required',
'application.settings.is_container_label_readonly_enabled' => 'boolean|required', 'application.settings.is_container_label_readonly_enabled' => 'boolean|required',
@@ -124,6 +125,7 @@ class General extends Component
'application.docker_compose_custom_build_command' => 'Docker compose custom build command', 'application.docker_compose_custom_build_command' => 'Docker compose custom build command',
'application.custom_nginx_configuration' => 'Custom Nginx configuration', 'application.custom_nginx_configuration' => 'Custom Nginx configuration',
'application.settings.is_static' => 'Is static', 'application.settings.is_static' => 'Is static',
'application.settings.is_spa' => 'Is SPA',
'application.settings.is_build_server_enabled' => 'Is build server enabled', 'application.settings.is_build_server_enabled' => 'Is build server enabled',
'application.settings.is_container_label_escape_enabled' => 'Is container label escape enabled', 'application.settings.is_container_label_escape_enabled' => 'Is container label escape enabled',
'application.settings.is_container_label_readonly_enabled' => 'Is container label readonly', 'application.settings.is_container_label_readonly_enabled' => 'Is container label readonly',
@@ -171,6 +173,9 @@ class General extends Component
public function instantSave() public function instantSave()
{ {
if ($this->application->settings->isDirty('is_spa')) {
$this->generateNginxConfiguration($this->application->settings->is_spa ? 'spa' : 'static');
}
$this->application->settings->save(); $this->application->settings->save();
$this->dispatch('success', 'Settings saved.'); $this->dispatch('success', 'Settings saved.');
$this->application->refresh(); $this->application->refresh();
@@ -190,6 +195,7 @@ class General extends Component
if ($this->application->settings->is_container_label_readonly_enabled) { if ($this->application->settings->is_container_label_readonly_enabled) {
$this->resetDefaultLabels(false); $this->resetDefaultLabels(false);
} }
} }
public function loadComposeFile($isInit = false) public function loadComposeFile($isInit = false)
@@ -287,9 +293,9 @@ class General extends Component
} }
} }
public function generateNginxConfiguration() public function generateNginxConfiguration($type = 'static')
{ {
$this->application->custom_nginx_configuration = defaultNginxConfiguration(); $this->application->custom_nginx_configuration = defaultNginxConfiguration($type);
$this->application->save(); $this->application->save();
$this->dispatch('success', 'Nginx configuration generated.'); $this->dispatch('success', 'Nginx configuration generated.');
} }

View File

@@ -4061,9 +4061,35 @@ function isEmailRateLimited(string $limiterKey, int $decaySeconds = 3600, ?calla
return $rateLimited; return $rateLimited;
} }
function defaultNginxConfiguration(): string function defaultNginxConfiguration(string $type = 'static'): string
{ {
return 'server { if ($type === 'spa') {
return <<<'NGINX'
server {
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
# Handle 404 errors
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
internal;
}
# Handle server errors (50x)
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
internal;
}
}
NGINX;
} else {
return <<<'NGINX'
server {
location / { location / {
root /usr/share/nginx/html; root /usr/share/nginx/html;
index index.html index.htm; index index.html index.htm;
@@ -4083,7 +4109,9 @@ function defaultNginxConfiguration(): string
root /usr/share/nginx/html; root /usr/share/nginx/html;
internal; internal;
} }
}'; }
NGINX;
}
} }
function convertGitUrl(string $gitRepository, string $deploymentType, ?GithubApp $source = null): array function convertGitUrl(string $gitRepository, string $deploymentType, ?GithubApp $source = null): array

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('application_settings', function (Blueprint $table) {
$table->boolean('is_spa')->default(false);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('application_settings', function (Blueprint $table) {
$table->dropColumn('is_spa');
});
}
};

View File

@@ -69,6 +69,17 @@
<x-forms.button wire:click="generateNginxConfiguration">Generate Default Nginx <x-forms.button wire:click="generateNginxConfiguration">Generate Default Nginx
Configuration</x-forms.button> Configuration</x-forms.button>
@endif @endif
<div class="w-96 pb-8">
@if ($application->could_set_build_commands())
<x-forms.checkbox instantSave id="application.settings.is_static" label="Is it a static site?"
helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
@endif
@if ($application->settings->is_static && $application->build_pack !== 'static')
<x-forms.checkbox label="Is it a SPA (Single Page Application)?"
helper="If your application is a SPA, enable this." id="application.settings.is_spa"
instantSave></x-forms.checkbox>
@endif
</div>
@if ($application->build_pack !== 'dockercompose') @if ($application->build_pack !== 'dockercompose')
<div class="flex items-end gap-2"> <div class="flex items-end gap-2">
@if ($application->settings->is_container_label_readonly_enabled == false) @if ($application->settings->is_container_label_readonly_enabled == false)
@@ -274,13 +285,6 @@
label="Use a Build Server?" /> label="Use a Build Server?" />
</div> </div>
@endif @endif
@if ($application->could_set_build_commands())
<div class="w-96">
<x-forms.checkbox instantSave id="application.settings.is_static"
label="Is it a static site?"
helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
</div>
@endif
@endif @endif
</div> </div>
@endif @endif