diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php
index 3e6230336..894df686d 100644
--- a/app/Jobs/ApplicationDeploymentJob.php
+++ b/app/Jobs/ApplicationDeploymentJob.php
@@ -274,6 +274,7 @@ public function handle(): void
ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::FINISHED);
}
}
+ $this->run_post_deployment_command();
$this->application->isConfigurationChanged(true);
} catch (Exception $e) {
if ($this->pull_request_id !== 0 && $this->application->is_github_based()) {
@@ -874,8 +875,8 @@ private function prepare_builder_image()
[
"command" => executeInDocker($this->deployment_uuid, "mkdir -p {$this->basedir}")
],
-
);
+ $this->run_pre_deployment_command();
}
private function deploy_to_additional_destinations()
{
@@ -1690,6 +1691,57 @@ private function add_build_env_variables_to_dockerfile()
]);
}
+ private function run_pre_deployment_command()
+ {
+ if (empty($this->application->pre_deployment_command)) {
+ return;
+ }
+ $containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);
+ if ($containers->count() == 0) {
+ return;
+ }
+ $this->application_deployment_queue->addLogEntry("Executing pre deployment command: {$this->application->post_deployment_command}");
+
+ foreach ($containers as $container) {
+ $containerName = data_get($container, 'Names');
+ if ($containers->count() == 1 || str_starts_with($containerName, $this->application->pre_deployment_command_container. '-' . $this->application->uuid)) {
+ $cmd = 'sh -c "' . str_replace('"', '\"', $this->application->pre_deployment_command) . '"';
+ $exec = "docker exec {$containerName} {$cmd}";
+ $this->execute_remote_command(
+ [
+ executeInDocker($this->deployment_uuid, $exec), 'hidden' => true
+ ],
+ );
+ return;
+ }
+ }
+ throw new RuntimeException('Pre deployment command: Could not find a valid container. Is the container name correct?');
+ }
+
+ private function run_post_deployment_command()
+ {
+ if (empty($this->application->post_deployment_command)) {
+ return;
+ }
+ $this->application_deployment_queue->addLogEntry("Executing post deployment command: {$this->application->post_deployment_command}");
+
+ $containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);
+ foreach ($containers as $container) {
+ $containerName = data_get($container, 'Names');
+ if ($containers->count() == 1 || str_starts_with($containerName, $this->application->post_deployment_command_container. '-' . $this->application->uuid)) {
+ $cmd = 'sh -c "' . str_replace('"', '\"', $this->application->post_deployment_command) . '"';
+ $exec = "docker exec {$containerName} {$cmd}";
+ $this->execute_remote_command(
+ [
+ executeInDocker($this->deployment_uuid, $exec), 'hidden' => true
+ ],
+ );
+ return;
+ }
+ }
+ throw new RuntimeException('Post deployment command: Could not find a valid container. Is the container name correct?');
+ }
+
private function next(string $status)
{
queue_next_deployment($this->application);
diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php
index 92b452a42..e530a0698 100644
--- a/app/Livewire/Project/Application/General.php
+++ b/app/Livewire/Project/Application/General.php
@@ -66,6 +66,10 @@ class General extends Component
'application.docker_compose_custom_build_command' => 'nullable',
'application.custom_labels' => 'nullable',
'application.custom_docker_run_options' => 'nullable',
+ 'application.pre_deployment_command' => 'nullable',
+ 'application.pre_deployment_command_container' => 'nullable',
+ 'application.post_deployment_command' => 'nullable',
+ 'application.post_deployment_command_container' => 'nullable',
'application.settings.is_static' => 'boolean|required',
'application.settings.is_raw_compose_deployment_enabled' => 'boolean|required',
'application.settings.is_build_server_enabled' => 'boolean|required',
diff --git a/database/migrations/2024_02_08_075523_add_post_deployment_to_applications.php b/database/migrations/2024_02_08_075523_add_post_deployment_to_applications.php
new file mode 100644
index 000000000..6d3a74896
--- /dev/null
+++ b/database/migrations/2024_02_08_075523_add_post_deployment_to_applications.php
@@ -0,0 +1,34 @@
+string('post_deployment_command')->nullable();
+ $table->string('post_deployment_command_container')->nullable();
+ $table->string('pre_deployment_command')->nullable();
+ $table->string('pre_deployment_command_container')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('applications', function (Blueprint $table) {
+ $table->dropColumn('post_deployment_command');
+ $table->dropColumn('post_deployment_command_container');
+ $table->dropColumn('pre_deployment_command');
+ $table->dropColumn('pre_deployment_command_container');
+ });
+ }
+};
diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php
index 5410156ee..2c00fa842 100644
--- a/resources/views/livewire/project/application/general.blade.php
+++ b/resources/views/livewire/project/application/general.blade.php
@@ -250,6 +250,20 @@ class="underline" href="https://coolify.io/docs/docker/registry"