diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php
index dc3bd8db6..810c7cc42 100644
--- a/app/Http/Livewire/Project/Application/General.php
+++ b/app/Http/Livewire/Project/Application/General.php
@@ -3,12 +3,9 @@
namespace App\Http\Livewire\Project\Application;
use App\Models\Application;
-use App\Models\InstanceSettings;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Livewire\Component;
-use Spatie\Url\Url;
-use Symfony\Component\Yaml\Yaml;
class General extends Component
{
@@ -23,6 +20,9 @@ class General extends Component
public ?string $git_commit_sha = null;
public string $build_pack;
+ public $customLabels;
+ public bool $labelsChanged = false;
+
public bool $is_static;
public bool $is_git_submodules_enabled;
public bool $is_git_lfs_enabled;
@@ -52,6 +52,7 @@ class General extends Component
'application.docker_registry_image_name' => 'nullable',
'application.docker_registry_image_tag' => 'nullable',
'application.dockerfile_location' => 'nullable',
+ 'application.custom_labels' => 'nullable',
];
protected $validationAttributes = [
'application.name' => 'name',
@@ -73,16 +74,43 @@ class General extends Component
'application.docker_registry_image_name' => 'Docker registry image name',
'application.docker_registry_image_tag' => 'Docker registry image tag',
'application.dockerfile_location' => 'Dockerfile location',
-
+ 'application.custom_labels' => 'Custom labels',
];
- public function updatedApplicationBuildPack(){
+ public function mount()
+ {
+ if (is_null(data_get($this->application, 'custom_labels'))) {
+ $this->customLabels = str(implode(",", generateLabelsApplication($this->application)))->replace(',', "\n");
+ } else {
+ $this->customLabels = str($this->application->custom_labels)->replace(',', "\n");
+ }
+ if (data_get($this->application, 'settings')) {
+ $this->is_static = $this->application->settings->is_static;
+ $this->is_git_submodules_enabled = $this->application->settings->is_git_submodules_enabled;
+ $this->is_git_lfs_enabled = $this->application->settings->is_git_lfs_enabled;
+ $this->is_debug_enabled = $this->application->settings->is_debug_enabled;
+ $this->is_preview_deployments_enabled = $this->application->settings->is_preview_deployments_enabled;
+ $this->is_auto_deploy_enabled = $this->application->settings->is_auto_deploy_enabled;
+ $this->is_force_https_enabled = $this->application->settings->is_force_https_enabled;
+ }
+ $this->checkLabelUpdates();
+ }
+ public function updatedApplicationBuildPack()
+ {
if ($this->application->build_pack !== 'nixpacks') {
$this->application->settings->is_static = $this->is_static = false;
$this->application->settings->save();
}
$this->submit();
}
+ public function checkLabelUpdates()
+ {
+ if (md5($this->application->custom_labels) !== md5(implode(",", generateLabelsApplication($this->application)))) {
+ $this->labelsChanged = true;
+ } else {
+ $this->labelsChanged = false;
+ }
+ }
public function instantSave()
{
// @TODO: find another way - if possible
@@ -102,37 +130,35 @@ class General extends Component
$this->application->save();
$this->application->refresh();
$this->emit('success', 'Application settings updated!');
+ $this->checkLabelUpdates();
}
- public function getWildcardDomain() {
+ public function getWildcardDomain()
+ {
$server = data_get($this->application, 'destination.server');
if ($server) {
$fqdn = generateFqdn($server, $this->application->uuid);
- ray($fqdn);
$this->application->fqdn = $fqdn;
$this->application->save();
$this->emit('success', 'Application settings updated!');
}
-
}
- public function mount()
+ public function resetDefaultLabels($showToaster = true)
{
- if (data_get($this->application,'settings')) {
- $this->is_static = $this->application->settings->is_static;
- $this->is_git_submodules_enabled = $this->application->settings->is_git_submodules_enabled;
- $this->is_git_lfs_enabled = $this->application->settings->is_git_lfs_enabled;
- $this->is_debug_enabled = $this->application->settings->is_debug_enabled;
- $this->is_preview_deployments_enabled = $this->application->settings->is_preview_deployments_enabled;
- $this->is_auto_deploy_enabled = $this->application->settings->is_auto_deploy_enabled;
- $this->is_force_https_enabled = $this->application->settings->is_force_https_enabled;
- }
+ $this->customLabels = str(implode(",", generateLabelsApplication($this->application)))->replace(',', "\n");
+ $this->submit($showToaster);
}
- public function submit()
+ public function updatedApplicationFqdn()
+ {
+ $this->resetDefaultLabels(false);
+ $this->emit('success', 'Labels reseted to default!');
+ }
+ public function submit($showToaster = true)
{
try {
$this->validate();
- if (data_get($this->application,'build_pack') === 'dockerimage') {
+ if (data_get($this->application, 'build_pack') === 'dockerimage') {
$this->validate([
'application.docker_registry_image_name' => 'required',
'application.docker_registry_image_tag' => 'required',
@@ -156,10 +182,16 @@ class General extends Component
if ($this->application->publish_directory && $this->application->publish_directory !== '/') {
$this->application->publish_directory = rtrim($this->application->publish_directory, '/');
}
+ if (gettype($this->customLabels) === 'string') {
+ $this->customLabels = str($this->customLabels)->replace(',', "\n");
+ }
+ $this->application->custom_labels = $this->customLabels->explode("\n")->implode(',');
$this->application->save();
- $this->emit('success', 'Application settings updated!');
+ $showToaster && $this->emit('success', 'Application settings updated!');
} catch (\Throwable $e) {
return handleError($e, $this);
+ } finally {
+ $this->checkLabelUpdates();
}
}
}
diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php
index 09e7c510d..636adb35a 100644
--- a/app/Jobs/ApplicationDeploymentJob.php
+++ b/app/Jobs/ApplicationDeploymentJob.php
@@ -54,7 +54,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
private ApplicationPreview|null $preview = null;
private string $container_name;
- private string|null $currently_running_container_name = null;
+ private ?string $currently_running_container_name = null;
private string $basedir;
private string $workdir;
private ?string $build_pack = null;
@@ -166,7 +166,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
// Get user home directory
$this->serverUserHomeDir = instant_remote_process(["echo \$HOME"], $this->server);
- ray("test -f {$this->serverUserHomeDir}/.docker/config.json && echo 'OK' || echo 'NOK'");
$this->dockerConfigFileExists = instant_remote_process(["test -f {$this->serverUserHomeDir}/.docker/config.json && echo 'OK' || echo 'NOK'"], $this->server);
try {
if ($this->application->dockerfile) {
@@ -650,6 +649,10 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
$environment_variables = $this->generate_environment_variables($ports);
+ $labels = generateLabelsApplication($this->application, $this->preview);
+ if (data_get($this->application, 'custom_labels')) {
+ $labels = str($this->application->custom_labels)->explode(',')->toArray();
+ }
$docker_compose = [
'version' => '3.8',
'services' => [
@@ -658,7 +661,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
'container_name' => $this->container_name,
'restart' => RESTART_MODE,
'environment' => $environment_variables,
- 'labels' => generateLabelsApplication($this->application, $this->preview, $ports),
+ 'labels' => $labels,
'expose' => $ports,
'networks' => [
$this->destination->network,
diff --git a/app/Models/Service.php b/app/Models/Service.php
index 4fbb6a1f7..95fe826fb 100644
--- a/app/Models/Service.php
+++ b/app/Models/Service.php
@@ -538,7 +538,7 @@ class Service extends BaseModel
$serviceLabels = $serviceLabels->merge($defaultLabels);
if (!$isDatabase && $fqdns->count() > 0) {
if ($fqdns) {
- $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($fqdns, true));
+ $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($this->uuid, $fqdns, true));
}
}
data_set($service, 'labels', $serviceLabels->toArray());
@@ -568,7 +568,7 @@ class Service extends BaseModel
'networks' => $topLevelNetworks->toArray(),
];
$this->docker_compose_raw = Yaml::dump($yaml, 10, 2);
- $this->docker_compose = Yaml::dump($finalServices, 10, 2);
+ $this->docker_compose = Yaml::dump($finalServices, 10, 2);
$this->save();
$this->saveComposeConfigs();
return collect([]);
diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php
index adf1761f1..dfa4c1788 100644
--- a/bootstrap/helpers/docker.php
+++ b/bootstrap/helpers/docker.php
@@ -147,12 +147,11 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica
}
return $labels;
}
-function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled, $onlyPort = null)
+function fqdnLabelsForTraefik($uuid, Collection $domains, bool $is_force_https_enabled, $onlyPort = null)
{
$labels = collect([]);
$labels->push('traefik.enable=true');
foreach ($domains as $domain) {
- $uuid = (string)new Cuid2(7);
$url = Url::fromString($domain);
$host = $url->getHost();
$path = $url->getPath();
@@ -205,20 +204,21 @@ function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled,
return $labels;
}
-function generateLabelsApplication(Application $application, ?ApplicationPreview $preview = null, $ports): array
+function generateLabelsApplication(Application $application, ?ApplicationPreview $preview = null): array
{
+ $ports = $application->settings->is_static ? [80] : $application->ports_exposes_array;
$onlyPort = null;
if (count($ports) === 1) {
$onlyPort = $ports[0];
}
$pull_request_id = data_get($preview, 'pull_request_id', 0);
- $container_name = generateApplicationContainerName($application, $pull_request_id);
+ // $container_name = generateApplicationContainerName($application, $pull_request_id);
$appId = $application->id;
if ($pull_request_id !== 0 && $pull_request_id !== null) {
$appId = $appId . '-pr-' . $pull_request_id;
}
$labels = collect([]);
- $labels = $labels->merge(defaultLabels($appId, $container_name, $pull_request_id));
+ $labels = $labels->merge(defaultLabels($appId, $application->uuid, $pull_request_id));
if ($application->fqdn) {
if ($pull_request_id !== 0) {
$domains = Str::of(data_get($preview, 'fqdn'))->explode(',');
@@ -226,7 +226,7 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview
$domains = Str::of(data_get($application, 'fqdn'))->explode(',');
}
// Add Traefik labels no matter which proxy is selected
- $labels = $labels->merge(fqdnLabelsForTraefik($domains, $application->settings->is_force_https_enabled,$onlyPort));
+ $labels = $labels->merge(fqdnLabelsForTraefik($application->uuid, $domains, $application->settings->is_force_https_enabled, $onlyPort));
}
return $labels->all();
}
diff --git a/database/migrations/2023_10_18_072519_add_custom_labels_applications_table.php b/database/migrations/2023_10_18_072519_add_custom_labels_applications_table.php
new file mode 100644
index 000000000..f993e35ee
--- /dev/null
+++ b/database/migrations/2023_10_18_072519_add_custom_labels_applications_table.php
@@ -0,0 +1,28 @@
+text('custom_labels')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('applications', function (Blueprint $table) {
+ $table->dropColumn('custom_labels');
+ });
+ }
+};
diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php
index 2962cdaa9..b554b8ff5 100644
--- a/resources/views/livewire/project/application/general.blade.php
+++ b/resources/views/livewire/project/application/general.blade.php
@@ -93,6 +93,12 @@