diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php
index 38b57a9db..4c0da8d4d 100644
--- a/app/Jobs/ApplicationDeploymentJob.php
+++ b/app/Jobs/ApplicationDeploymentJob.php
@@ -1331,9 +1331,11 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
if ($this->pull_request_id !== 0) {
$labels = collect(generateLabelsApplication($this->application, $this->preview));
}
- $labels = $labels->map(function ($value, $key) {
- return escapeDollarSign($value);
- });
+ if ($this->application->settings->is_container_label_escape_enabled) {
+ $labels = $labels->map(function ($value, $key) {
+ return escapeDollarSign($value);
+ });
+ }
$labels = $labels->merge(defaultLabels($this->application->id, $this->application->uuid, $this->pull_request_id))->toArray();
// Check for custom HEALTHCHECK
diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php
index 885f84247..66c59cff5 100644
--- a/app/Livewire/Project/Application/General.php
+++ b/app/Livewire/Project/Application/General.php
@@ -22,6 +22,7 @@ class General extends Component
public ?string $git_commit_sha = null;
public string $build_pack;
public ?string $ports_exposes = null;
+ public bool $is_container_label_escape_enabled = true;
public $customLabels;
public bool $labelsChanged = false;
@@ -74,6 +75,7 @@ class General extends Component
'application.post_deployment_command_container' => 'nullable',
'application.settings.is_static' => 'boolean|required',
'application.settings.is_build_server_enabled' => 'boolean|required',
+ 'application.settings.is_container_label_escape_enabled' => 'boolean|required',
'application.watch_paths' => 'nullable',
];
protected $validationAttributes = [
@@ -109,6 +111,7 @@ class General extends Component
'application.docker_compose_custom_build_command' => 'Docker compose custom build command',
'application.settings.is_static' => 'Is static',
'application.settings.is_build_server_enabled' => 'Is build server enabled',
+ 'application.settings.is_container_label_escape_enabled' => 'Is container label escape enabled',
'application.watch_paths' => 'Watch paths',
];
public function mount()
@@ -124,6 +127,7 @@ class General extends Component
}
$this->parsedServiceDomains = $this->application->docker_compose_domains ? json_decode($this->application->docker_compose_domains, true) : [];
$this->ports_exposes = $this->application->ports_exposes;
+ $this->is_container_label_escape_enabled = $this->application->settings->is_container_label_escape_enabled;
$this->customLabels = $this->application->parseContainerLabels();
if (!$this->customLabels && $this->application->destination->server->proxyType() !== 'NONE') {
$this->customLabels = str(implode("|", generateLabelsApplication($this->application)))->replace("|", "\n");
@@ -145,7 +149,7 @@ class General extends Component
$this->application->settings->save();
$this->dispatch('success', 'Settings saved.');
$this->application->refresh();
- if ($this->ports_exposes !== $this->application->ports_exposes) {
+ if ($this->ports_exposes !== $this->application->ports_exposes || $this->is_container_label_escape_enabled !== $this->application->settings->is_container_label_escape_enabled) {
$this->resetDefaultLabels(false);
}
}
@@ -204,6 +208,9 @@ class General extends Component
$this->application->docker_compose_domains = json_encode($this->parsedServiceDomains);
$this->application->save();
$this->dispatch('success', 'Domain generated.');
+ if ($this->application->build_pack === 'dockercompose') {
+ $this->loadComposeFile();
+ }
return $domain;
}
public function updatedApplicationBaseDirectory()
@@ -257,9 +264,12 @@ class General extends Component
{
$this->customLabels = str(implode("|", generateLabelsApplication($this->application)))->replace("|", "\n");
$this->ports_exposes = $this->application->ports_exposes;
-
+ $this->is_container_label_escape_enabled = $this->application->settings->is_container_label_escape_enabled;
$this->application->custom_labels = base64_encode($this->customLabels);
$this->application->save();
+ if ($this->application->build_pack === 'dockercompose') {
+ $this->loadComposeFile();
+ }
}
public function checkFqdns($showToaster = true)
@@ -300,11 +310,11 @@ class General extends Component
if ($this->application->build_pack === 'dockercompose' && $this->initialDockerComposeLocation !== $this->application->docker_compose_location) {
$compose_return = $this->loadComposeFile();
if ($compose_return instanceof \Livewire\Features\SupportEvents\Event) {
- return;
+ return;
}
}
$this->validate();
- if ($this->ports_exposes !== $this->application->ports_exposes) {
+ if ($this->ports_exposes !== $this->application->ports_exposes || $this->is_container_label_escape_enabled !== $this->application->settings->is_container_label_escape_enabled) {
$this->resetDefaultLabels();
}
if (data_get($this->application, 'build_pack') === 'dockerimage') {
diff --git a/app/Livewire/Project/Service/EditCompose.php b/app/Livewire/Project/Service/EditCompose.php
index 0f9c449f9..d6e867956 100644
--- a/app/Livewire/Project/Service/EditCompose.php
+++ b/app/Livewire/Project/Service/EditCompose.php
@@ -12,6 +12,7 @@ class EditCompose extends Component
protected $rules = [
'service.docker_compose_raw' => 'required',
'service.docker_compose' => 'required',
+ 'service.is_container_label_escape_enabled' => 'required',
];
public function mount()
{
@@ -23,6 +24,14 @@ class EditCompose extends Component
$this->dispatch('info', "Saving new docker compose...");
$this->dispatch('saveCompose', $this->service->docker_compose_raw);
}
+ public function instantSave()
+ {
+ $this->validate([
+ 'service.is_container_label_escape_enabled' => 'required',
+ ]);
+ $this->service->save(['is_container_label_escape_enabled' => $this->service->is_container_label_escape_enabled]);
+ $this->dispatch('success', "Service updated successfully");
+ }
public function render()
{
return view('livewire.project.service.edit-compose');
diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php
index 183d9d2ec..7a960066c 100644
--- a/bootstrap/helpers/shared.php
+++ b/bootstrap/helpers/shared.php
@@ -1174,9 +1174,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
]
]);
}
- $serviceLabels = $serviceLabels->map(function ($value, $key) {
- return escapeDollarSign($value);
- });
+ if ($serviceLabels->count() > 0) {
+ if ($resource->is_container_label_escape_enabled) {
+ $serviceLabels = $serviceLabels->map(function ($value, $key) {
+ return escapeDollarSign($value);
+ });
+ }
+ }
data_set($service, 'labels', $serviceLabels->toArray());
data_forget($service, 'is_database');
if (!data_get($service, 'restart')) {
@@ -1279,11 +1283,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$serviceLabels->push("$removedLabelName=$removedLabel");
}
}
- if ($serviceLabels->count() > 0) {
- $serviceLabels = $serviceLabels->map(function ($value, $key) {
- return escapeDollarSign($value);
- });
- }
+
$baseName = generateApplicationContainerName($resource, $pull_request_id);
$containerName = "$serviceName-$baseName";
if (count($serviceVolumes) > 0) {
@@ -1663,6 +1663,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
]
]);
}
+ if ($serviceLabels->count() > 0) {
+ if ($resource->settings->is_container_label_escape_enabled) {
+ $serviceLabels = $serviceLabels->map(function ($value, $key) {
+ return escapeDollarSign($value);
+ });
+ }
+ }
data_set($service, 'labels', $serviceLabels->toArray());
data_forget($service, 'is_database');
if (!data_get($service, 'restart')) {
diff --git a/database/migrations/2024_05_15_151236_add_container_escape_toggle.php b/database/migrations/2024_05_15_151236_add_container_escape_toggle.php
new file mode 100644
index 000000000..aa1384518
--- /dev/null
+++ b/database/migrations/2024_05_15_151236_add_container_escape_toggle.php
@@ -0,0 +1,34 @@
+boolean('is_container_label_escape_enabled')->default(true);
+ });
+ Schema::table('services', function (Blueprint $table) {
+ $table->boolean('is_container_label_escape_enabled')->default(true);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('application_settings', function (Blueprint $table) {
+ $table->dropColumn('is_container_label_escape_enabled');
+ });
+ Schema::table('services', function (Blueprint $table) {
+ $table->dropColumn('is_container_label_escape_enabled');
+ });
+ }
+};
diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php
index 37869621d..b9a971124 100644
--- a/resources/views/livewire/project/application/general.blade.php
+++ b/resources/views/livewire/project/application/general.blade.php
@@ -219,6 +219,11 @@