Merge pull request #1723 from stooit/feat/post-deploy-command
Adds basic support for pre/post-deployment commands.
This commit is contained in:
		@@ -274,6 +274,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                    ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::FINISHED);
 | 
					                    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);
 | 
					            $this->application->isConfigurationChanged(true);
 | 
				
			||||||
        } catch (Exception $e) {
 | 
					        } catch (Exception $e) {
 | 
				
			||||||
            if ($this->pull_request_id !== 0 && $this->application->is_github_based()) {
 | 
					            if ($this->pull_request_id !== 0 && $this->application->is_github_based()) {
 | 
				
			||||||
@@ -874,8 +875,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
            [
 | 
					            [
 | 
				
			||||||
                "command" => executeInDocker($this->deployment_uuid, "mkdir -p {$this->basedir}")
 | 
					                "command" => executeInDocker($this->deployment_uuid, "mkdir -p {$this->basedir}")
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					        $this->run_pre_deployment_command();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    private function deploy_to_additional_destinations()
 | 
					    private function deploy_to_additional_destinations()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -1690,6 +1691,57 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
 | 
				
			|||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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)
 | 
					    private function next(string $status)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        queue_next_deployment($this->application);
 | 
					        queue_next_deployment($this->application);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,6 +66,10 @@ class General extends Component
 | 
				
			|||||||
        'application.docker_compose_custom_build_command' => 'nullable',
 | 
					        'application.docker_compose_custom_build_command' => 'nullable',
 | 
				
			||||||
        'application.custom_labels' => 'nullable',
 | 
					        'application.custom_labels' => 'nullable',
 | 
				
			||||||
        'application.custom_docker_run_options' => '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_static' => 'boolean|required',
 | 
				
			||||||
        'application.settings.is_raw_compose_deployment_enabled' => 'boolean|required',
 | 
					        'application.settings.is_raw_compose_deployment_enabled' => 'boolean|required',
 | 
				
			||||||
        'application.settings.is_build_server_enabled' => 'boolean|required',
 | 
					        'application.settings.is_build_server_enabled' => 'boolean|required',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					<?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('applications', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $table->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');
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -250,6 +250,20 @@
 | 
				
			|||||||
                <x-forms.textarea label="Container Labels" rows="15" id="customLabels"></x-forms.textarea>
 | 
					                <x-forms.textarea label="Container Labels" rows="15" id="customLabels"></x-forms.textarea>
 | 
				
			||||||
                <x-forms.button wire:click="resetDefaultLabels">Reset to Coolify Generated Labels</x-forms.button>
 | 
					                <x-forms.button wire:click="resetDefaultLabels">Reset to Coolify Generated Labels</x-forms.button>
 | 
				
			||||||
            @endif
 | 
					            @endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <h3 class="pt-8">Deployment scripts</h3>
 | 
				
			||||||
 | 
					            <div class="flex flex-col gap-2 xl:flex-row">
 | 
				
			||||||
 | 
					                    <x-forms.input placeholder="" id="application.pre_deployment_command" label="Pre deployment command"
 | 
				
			||||||
 | 
					                        helper="An optional script or command to execute in the existing container before the deployment begins." />
 | 
				
			||||||
 | 
					                    <x-forms.input placeholder="" id="application.pre_deployment_command_container" label="Container name"
 | 
				
			||||||
 | 
					                        helper="The name of the container to execute within. You can leave it blank if your application only has one container." />
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="flex flex-col gap-2 xl:flex-row">
 | 
				
			||||||
 | 
					                    <x-forms.input placeholder="php artisan migrate" id="application.post_deployment_command" label="Post deployment command"
 | 
				
			||||||
 | 
					                        helper="An optional script or command to execute in the newly built container after the deployment completes." />
 | 
				
			||||||
 | 
					                    <x-forms.input placeholder="php" id="application.post_deployment_command_container" label="Container name"
 | 
				
			||||||
 | 
					                        helper="The name of the container to execute within. You can leave it blank if your application only has one container." />
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </form>
 | 
					    </form>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user