Merge branch 'next' into set-default-message-queue-type-twenty
This commit is contained in:
		
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							@@ -4,5 +4,5 @@ contact_links:
 | 
			
		||||
    url: https://coollabs.io/discord
 | 
			
		||||
    about: Reach out to us on Discord.
 | 
			
		||||
  - name: 🙋♂️ Feature Requests
 | 
			
		||||
    url: https://github.com/coollabsio/coolify/discussions/categories/feature-requests-ideas
 | 
			
		||||
    url: https://github.com/coollabsio/coolify/discussions/categories/new-features
 | 
			
		||||
    about: All feature requests will be discussed here.
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,11 @@ class CleanupDatabase extends Command
 | 
			
		||||
        } else {
 | 
			
		||||
            echo "Running database cleanup in dry-run mode...\n";
 | 
			
		||||
        }
 | 
			
		||||
        if (isCloud()) {
 | 
			
		||||
            $keep_days = 60;
 | 
			
		||||
        } else {
 | 
			
		||||
            $keep_days = 60;
 | 
			
		||||
        }
 | 
			
		||||
        echo "Keep days: $keep_days\n";
 | 
			
		||||
        // Cleanup failed jobs table
 | 
			
		||||
        $failed_jobs = DB::table('failed_jobs')->where('failed_at', '<', now()->subDays(1));
 | 
			
		||||
 
 | 
			
		||||
@@ -739,7 +739,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
            $application->isConfigurationChanged(true);
 | 
			
		||||
 | 
			
		||||
            if ($instantDeploy) {
 | 
			
		||||
                $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                $deployment_uuid = new Cuid2;
 | 
			
		||||
 | 
			
		||||
                queue_application_deployment(
 | 
			
		||||
                    application: $application,
 | 
			
		||||
@@ -835,7 +835,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
            $application->isConfigurationChanged(true);
 | 
			
		||||
 | 
			
		||||
            if ($instantDeploy) {
 | 
			
		||||
                $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                $deployment_uuid = new Cuid2;
 | 
			
		||||
 | 
			
		||||
                queue_application_deployment(
 | 
			
		||||
                    application: $application,
 | 
			
		||||
@@ -927,7 +927,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
            $application->isConfigurationChanged(true);
 | 
			
		||||
 | 
			
		||||
            if ($instantDeploy) {
 | 
			
		||||
                $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                $deployment_uuid = new Cuid2;
 | 
			
		||||
 | 
			
		||||
                queue_application_deployment(
 | 
			
		||||
                    application: $application,
 | 
			
		||||
@@ -947,7 +947,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
            ]));
 | 
			
		||||
        } elseif ($type === 'dockerfile') {
 | 
			
		||||
            if (! $request->has('name')) {
 | 
			
		||||
                $request->offsetSet('name', 'dockerfile-'.new Cuid2(7));
 | 
			
		||||
                $request->offsetSet('name', 'dockerfile-'.new Cuid2);
 | 
			
		||||
            }
 | 
			
		||||
            $validator = customApiValidator($request->all(), [
 | 
			
		||||
                sharedDataApplications(),
 | 
			
		||||
@@ -1009,7 +1009,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
            $application->isConfigurationChanged(true);
 | 
			
		||||
 | 
			
		||||
            if ($instantDeploy) {
 | 
			
		||||
                $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                $deployment_uuid = new Cuid2;
 | 
			
		||||
 | 
			
		||||
                queue_application_deployment(
 | 
			
		||||
                    application: $application,
 | 
			
		||||
@@ -1025,7 +1025,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
            ]));
 | 
			
		||||
        } elseif ($type === 'dockerimage') {
 | 
			
		||||
            if (! $request->has('name')) {
 | 
			
		||||
                $request->offsetSet('name', 'docker-image-'.new Cuid2(7));
 | 
			
		||||
                $request->offsetSet('name', 'docker-image-'.new Cuid2);
 | 
			
		||||
            }
 | 
			
		||||
            $validator = customApiValidator($request->all(), [
 | 
			
		||||
                sharedDataApplications(),
 | 
			
		||||
@@ -1067,7 +1067,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
            $application->isConfigurationChanged(true);
 | 
			
		||||
 | 
			
		||||
            if ($instantDeploy) {
 | 
			
		||||
                $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                $deployment_uuid = new Cuid2;
 | 
			
		||||
 | 
			
		||||
                queue_application_deployment(
 | 
			
		||||
                    application: $application,
 | 
			
		||||
@@ -1099,7 +1099,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
                ], 422);
 | 
			
		||||
            }
 | 
			
		||||
            if (! $request->has('name')) {
 | 
			
		||||
                $request->offsetSet('name', 'service'.new Cuid2(7));
 | 
			
		||||
                $request->offsetSet('name', 'service'.new Cuid2);
 | 
			
		||||
            }
 | 
			
		||||
            $validator = customApiValidator($request->all(), [
 | 
			
		||||
                sharedDataApplications(),
 | 
			
		||||
@@ -1320,7 +1320,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
    #[OA\Patch(
 | 
			
		||||
        summary: 'Update',
 | 
			
		||||
        description: 'Update application by UUID.',
 | 
			
		||||
        path: '/applications',
 | 
			
		||||
        path: '/applications/{uuid}',
 | 
			
		||||
        security: [
 | 
			
		||||
            ['bearerAuth' => []],
 | 
			
		||||
        ],
 | 
			
		||||
@@ -2322,7 +2322,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
            return response()->json(['message' => 'Application not found.'], 404);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $deployment_uuid = new Cuid2(7);
 | 
			
		||||
        $deployment_uuid = new Cuid2;
 | 
			
		||||
 | 
			
		||||
        queue_application_deployment(
 | 
			
		||||
            application: $application,
 | 
			
		||||
@@ -2479,7 +2479,7 @@ class ApplicationsController extends Controller
 | 
			
		||||
            return response()->json(['message' => 'Application not found.'], 404);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $deployment_uuid = new Cuid2(7);
 | 
			
		||||
        $deployment_uuid = new Cuid2;
 | 
			
		||||
 | 
			
		||||
        queue_application_deployment(
 | 
			
		||||
            application: $application,
 | 
			
		||||
 
 | 
			
		||||
@@ -84,7 +84,7 @@ class DeployController extends Controller
 | 
			
		||||
        ],
 | 
			
		||||
        tags: ['Deployments'],
 | 
			
		||||
        parameters: [
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Deployment Uuid', schema: new OA\Schema(type: 'integer')),
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Deployment Uuid', schema: new OA\Schema(type: 'string')),
 | 
			
		||||
        ],
 | 
			
		||||
        responses: [
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
@@ -290,7 +290,7 @@ class DeployController extends Controller
 | 
			
		||||
        }
 | 
			
		||||
        switch ($resource?->getMorphClass()) {
 | 
			
		||||
            case 'App\Models\Application':
 | 
			
		||||
                $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                $deployment_uuid = new Cuid2;
 | 
			
		||||
                queue_application_deployment(
 | 
			
		||||
                    application: $resource,
 | 
			
		||||
                    deployment_uuid: $deployment_uuid,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ namespace App\Http\Controllers\Api;
 | 
			
		||||
use OpenApi\Attributes as OA;
 | 
			
		||||
 | 
			
		||||
#[OA\Info(title: 'Coolify', version: '0.1')]
 | 
			
		||||
#[OA\Server(url: 'https://app.coolify.io/api/v1')]
 | 
			
		||||
#[OA\Server(url: 'https://app.coolify.io/api/v1', description: 'Coolify Cloud API. Change the host to your own instance if you are self-hosting.')]
 | 
			
		||||
#[OA\SecurityScheme(
 | 
			
		||||
    type: 'http',
 | 
			
		||||
    scheme: 'bearer',
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,7 @@ class ProjectController extends Controller
 | 
			
		||||
        ],
 | 
			
		||||
        tags: ['Projects'],
 | 
			
		||||
        parameters: [
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'integer')),
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')),
 | 
			
		||||
        ],
 | 
			
		||||
        responses: [
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
@@ -107,7 +107,7 @@ class ProjectController extends Controller
 | 
			
		||||
        ],
 | 
			
		||||
        tags: ['Projects'],
 | 
			
		||||
        parameters: [
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'integer')),
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')),
 | 
			
		||||
            new OA\Parameter(name: 'environment_name', in: 'path', required: true, description: 'Environment name', schema: new OA\Schema(type: 'string')),
 | 
			
		||||
        ],
 | 
			
		||||
        responses: [
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ class SecurityController extends Controller
 | 
			
		||||
        ],
 | 
			
		||||
        tags: ['Private Keys'],
 | 
			
		||||
        parameters: [
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Private Key Uuid', schema: new OA\Schema(type: 'integer')),
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Private Key Uuid', schema: new OA\Schema(type: 'string')),
 | 
			
		||||
        ],
 | 
			
		||||
        responses: [
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
@@ -318,7 +318,7 @@ class SecurityController extends Controller
 | 
			
		||||
        ],
 | 
			
		||||
        tags: ['Private Keys'],
 | 
			
		||||
        parameters: [
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Private Key Uuid', schema: new OA\Schema(type: 'integer')),
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Private Key Uuid', schema: new OA\Schema(type: 'string')),
 | 
			
		||||
        ],
 | 
			
		||||
        responses: [
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
 
 | 
			
		||||
@@ -105,7 +105,7 @@ class ServersController extends Controller
 | 
			
		||||
        ],
 | 
			
		||||
        tags: ['Servers'],
 | 
			
		||||
        parameters: [
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s Uuid', schema: new OA\Schema(type: 'integer')),
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s Uuid', schema: new OA\Schema(type: 'string')),
 | 
			
		||||
        ],
 | 
			
		||||
        responses: [
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
@@ -182,7 +182,7 @@ class ServersController extends Controller
 | 
			
		||||
        ],
 | 
			
		||||
        tags: ['Servers'],
 | 
			
		||||
        parameters: [
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s Uuid', schema: new OA\Schema(type: 'integer')),
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s Uuid', schema: new OA\Schema(type: 'string')),
 | 
			
		||||
        ],
 | 
			
		||||
        responses: [
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
@@ -259,7 +259,7 @@ class ServersController extends Controller
 | 
			
		||||
        ],
 | 
			
		||||
        tags: ['Servers'],
 | 
			
		||||
        parameters: [
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s Uuid', schema: new OA\Schema(type: 'integer')),
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s Uuid', schema: new OA\Schema(type: 'string')),
 | 
			
		||||
        ],
 | 
			
		||||
        responses: [
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
@@ -732,7 +732,7 @@ class ServersController extends Controller
 | 
			
		||||
        ],
 | 
			
		||||
        tags: ['Servers'],
 | 
			
		||||
        parameters: [
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server UUID', schema: new OA\Schema(type: 'integer')),
 | 
			
		||||
            new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server UUID', schema: new OA\Schema(type: 'string')),
 | 
			
		||||
        ],
 | 
			
		||||
        responses: [
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
 
 | 
			
		||||
@@ -103,7 +103,7 @@ class Bitbucket extends Controller
 | 
			
		||||
                if ($x_bitbucket_event === 'repo:push') {
 | 
			
		||||
                    if ($application->isDeployable()) {
 | 
			
		||||
                        ray('Deploying '.$application->name.' with branch '.$branch);
 | 
			
		||||
                        $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                        $deployment_uuid = new Cuid2;
 | 
			
		||||
                        queue_application_deployment(
 | 
			
		||||
                            application: $application,
 | 
			
		||||
                            deployment_uuid: $deployment_uuid,
 | 
			
		||||
@@ -127,7 +127,7 @@ class Bitbucket extends Controller
 | 
			
		||||
                if ($x_bitbucket_event === 'pullrequest:created') {
 | 
			
		||||
                    if ($application->isPRDeployable()) {
 | 
			
		||||
                        ray('Deploying preview for '.$application->name.' with branch '.$branch.' and base branch '.$base_branch.' and pull request id '.$pull_request_id);
 | 
			
		||||
                        $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                        $deployment_uuid = new Cuid2;
 | 
			
		||||
                        $found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
 | 
			
		||||
                        if (! $found) {
 | 
			
		||||
                            if ($application->build_pack === 'dockercompose') {
 | 
			
		||||
 
 | 
			
		||||
@@ -123,7 +123,7 @@ class Gitea extends Controller
 | 
			
		||||
                        $is_watch_path_triggered = $application->isWatchPathsTriggered($changed_files);
 | 
			
		||||
                        if ($is_watch_path_triggered || is_null($application->watch_paths)) {
 | 
			
		||||
                            ray('Deploying '.$application->name.' with branch '.$branch);
 | 
			
		||||
                            $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                            $deployment_uuid = new Cuid2;
 | 
			
		||||
                            queue_application_deployment(
 | 
			
		||||
                                application: $application,
 | 
			
		||||
                                deployment_uuid: $deployment_uuid,
 | 
			
		||||
@@ -162,7 +162,7 @@ class Gitea extends Controller
 | 
			
		||||
                if ($x_gitea_event === 'pull_request') {
 | 
			
		||||
                    if ($action === 'opened' || $action === 'synchronize' || $action === 'reopened') {
 | 
			
		||||
                        if ($application->isPRDeployable()) {
 | 
			
		||||
                            $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                            $deployment_uuid = new Cuid2;
 | 
			
		||||
                            $found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
 | 
			
		||||
                            if (! $found) {
 | 
			
		||||
                                if ($application->build_pack === 'dockercompose') {
 | 
			
		||||
 
 | 
			
		||||
@@ -128,7 +128,7 @@ class Github extends Controller
 | 
			
		||||
                        $is_watch_path_triggered = $application->isWatchPathsTriggered($changed_files);
 | 
			
		||||
                        if ($is_watch_path_triggered || is_null($application->watch_paths)) {
 | 
			
		||||
                            ray('Deploying '.$application->name.' with branch '.$branch);
 | 
			
		||||
                            $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                            $deployment_uuid = new Cuid2;
 | 
			
		||||
                            queue_application_deployment(
 | 
			
		||||
                                application: $application,
 | 
			
		||||
                                deployment_uuid: $deployment_uuid,
 | 
			
		||||
@@ -167,7 +167,7 @@ class Github extends Controller
 | 
			
		||||
                if ($x_github_event === 'pull_request') {
 | 
			
		||||
                    if ($action === 'opened' || $action === 'synchronize' || $action === 'reopened') {
 | 
			
		||||
                        if ($application->isPRDeployable()) {
 | 
			
		||||
                            $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                            $deployment_uuid = new Cuid2;
 | 
			
		||||
                            $found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
 | 
			
		||||
                            if (! $found) {
 | 
			
		||||
                                if ($application->build_pack === 'dockercompose') {
 | 
			
		||||
@@ -357,7 +357,7 @@ class Github extends Controller
 | 
			
		||||
                        $is_watch_path_triggered = $application->isWatchPathsTriggered($changed_files);
 | 
			
		||||
                        if ($is_watch_path_triggered || is_null($application->watch_paths)) {
 | 
			
		||||
                            ray('Deploying '.$application->name.' with branch '.$branch);
 | 
			
		||||
                            $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                            $deployment_uuid = new Cuid2;
 | 
			
		||||
                            queue_application_deployment(
 | 
			
		||||
                                application: $application,
 | 
			
		||||
                                deployment_uuid: $deployment_uuid,
 | 
			
		||||
@@ -396,7 +396,7 @@ class Github extends Controller
 | 
			
		||||
                if ($x_github_event === 'pull_request') {
 | 
			
		||||
                    if ($action === 'opened' || $action === 'synchronize' || $action === 'reopened') {
 | 
			
		||||
                        if ($application->isPRDeployable()) {
 | 
			
		||||
                            $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                            $deployment_uuid = new Cuid2;
 | 
			
		||||
                            $found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
 | 
			
		||||
                            if (! $found) {
 | 
			
		||||
                                ApplicationPreview::create([
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +137,7 @@ class Gitlab extends Controller
 | 
			
		||||
                        $is_watch_path_triggered = $application->isWatchPathsTriggered($changed_files);
 | 
			
		||||
                        if ($is_watch_path_triggered || is_null($application->watch_paths)) {
 | 
			
		||||
                            ray('Deploying '.$application->name.' with branch '.$branch);
 | 
			
		||||
                            $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                            $deployment_uuid = new Cuid2;
 | 
			
		||||
                            queue_application_deployment(
 | 
			
		||||
                                application: $application,
 | 
			
		||||
                                deployment_uuid: $deployment_uuid,
 | 
			
		||||
@@ -177,7 +177,7 @@ class Gitlab extends Controller
 | 
			
		||||
                if ($x_gitlab_event === 'merge_request') {
 | 
			
		||||
                    if ($action === 'open' || $action === 'opened' || $action === 'synchronize' || $action === 'reopened' || $action === 'reopen' || $action === 'update') {
 | 
			
		||||
                        if ($application->isPRDeployable()) {
 | 
			
		||||
                            $deployment_uuid = new Cuid2(7);
 | 
			
		||||
                            $deployment_uuid = new Cuid2;
 | 
			
		||||
                            $found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
 | 
			
		||||
                            if (! $found) {
 | 
			
		||||
                                if ($application->build_pack === 'dockercompose') {
 | 
			
		||||
 
 | 
			
		||||
@@ -307,14 +307,6 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
 | 
			
		||||
                ]
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            // $this->execute_remote_command(
 | 
			
		||||
            //     [
 | 
			
		||||
            //         "docker image prune -f >/dev/null 2>&1",
 | 
			
		||||
            //         "hidden" => true,
 | 
			
		||||
            //         "ignore_errors" => true,
 | 
			
		||||
            //     ]
 | 
			
		||||
            // );
 | 
			
		||||
 | 
			
		||||
            ApplicationStatusChanged::dispatch(data_get($this->application, 'environment.project.team.id'));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -497,13 +489,13 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->write_deployment_configurations();
 | 
			
		||||
                $server_workdir = $this->application->workdir();
 | 
			
		||||
                $this->docker_compose_location = '/docker-compose.yaml';
 | 
			
		||||
 | 
			
		||||
                $command = "{$this->coolify_variables} docker compose";
 | 
			
		||||
                if ($this->env_filename) {
 | 
			
		||||
                    $command .= " --env-file {$this->workdir}/{$this->env_filename}";
 | 
			
		||||
                    $command .= " --env-file {$server_workdir}/{$this->env_filename}";
 | 
			
		||||
                }
 | 
			
		||||
                $command .= " --project-directory {$server_workdir} -f {$server_workdir}{$this->docker_compose_location} up -d";
 | 
			
		||||
 | 
			
		||||
                $this->execute_remote_command(
 | 
			
		||||
                    ['command' => $command, 'hidden' => true],
 | 
			
		||||
                );
 | 
			
		||||
@@ -636,21 +628,26 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
 | 
			
		||||
                $this->server = $this->original_server;
 | 
			
		||||
            }
 | 
			
		||||
            $readme = generate_readme_file($this->application->name, $this->application_deployment_queue->updated_at);
 | 
			
		||||
 | 
			
		||||
            $mainDir = $this->configuration_dir;
 | 
			
		||||
            if ($this->application->settings->is_raw_compose_deployment_enabled) {
 | 
			
		||||
                $mainDir = $this->application->workdir();
 | 
			
		||||
            }
 | 
			
		||||
            if ($this->pull_request_id === 0) {
 | 
			
		||||
                $composeFileName = "$this->configuration_dir/docker-compose.yaml";
 | 
			
		||||
                $composeFileName = "$mainDir/docker-compose.yaml";
 | 
			
		||||
            } else {
 | 
			
		||||
                $composeFileName = "$this->configuration_dir/docker-compose-pr-{$this->pull_request_id}.yaml";
 | 
			
		||||
                $composeFileName = "$mainDir/docker-compose-pr-{$this->pull_request_id}.yaml";
 | 
			
		||||
                $this->docker_compose_location = "/docker-compose-pr-{$this->pull_request_id}.yaml";
 | 
			
		||||
            }
 | 
			
		||||
            $this->execute_remote_command(
 | 
			
		||||
                [
 | 
			
		||||
                    "mkdir -p $this->configuration_dir",
 | 
			
		||||
                    "mkdir -p $mainDir",
 | 
			
		||||
                ],
 | 
			
		||||
                [
 | 
			
		||||
                    "echo '{$this->docker_compose_base64}' | base64 -d | tee $composeFileName > /dev/null",
 | 
			
		||||
                ],
 | 
			
		||||
                [
 | 
			
		||||
                    "echo '{$readme}' > $this->configuration_dir/README.md",
 | 
			
		||||
                    "echo '{$readme}' > $mainDir/README.md",
 | 
			
		||||
                ]
 | 
			
		||||
            );
 | 
			
		||||
            if ($this->use_build_server) {
 | 
			
		||||
 
 | 
			
		||||
@@ -90,6 +90,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            BackupCreated::dispatch($this->team->id);
 | 
			
		||||
 | 
			
		||||
            // Check if team is exists
 | 
			
		||||
            if (is_null($this->team)) {
 | 
			
		||||
                $this->backup->update(['status' => 'failed']);
 | 
			
		||||
@@ -476,7 +477,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
 | 
			
		||||
            } else {
 | 
			
		||||
                $network = $this->database->destination->network;
 | 
			
		||||
            }
 | 
			
		||||
            $commands[] = "docker run --pull=always -d --network {$network} --name backup-of-{$this->backup->uuid} --rm -v $this->backup_location:$this->backup_location:ro ghcr.io/coollabsio/coolify-helper";
 | 
			
		||||
            $commands[] = "docker run -d --network {$network} --name backup-of-{$this->backup->uuid} --rm -v $this->backup_location:$this->backup_location:ro ghcr.io/coollabsio/coolify-helper";
 | 
			
		||||
            $commands[] = "docker exec backup-of-{$this->backup->uuid} mc config host add temporary {$endpoint} $key $secret";
 | 
			
		||||
            $commands[] = "docker exec backup-of-{$this->backup->uuid} mc cp $this->backup_location temporary/$bucket{$this->backup_dir}/";
 | 
			
		||||
            instant_remote_process($commands, $this->server);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										486
									
								
								app/Jobs/ServerCheckJob.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										486
									
								
								app/Jobs/ServerCheckJob.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,486 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Jobs;
 | 
			
		||||
 | 
			
		||||
use App\Actions\Database\StartDatabaseProxy;
 | 
			
		||||
use App\Actions\Proxy\CheckProxy;
 | 
			
		||||
use App\Actions\Proxy\StartProxy;
 | 
			
		||||
use App\Actions\Server\InstallLogDrain;
 | 
			
		||||
use App\Models\ApplicationPreview;
 | 
			
		||||
use App\Models\Server;
 | 
			
		||||
use App\Models\ServiceDatabase;
 | 
			
		||||
use App\Notifications\Container\ContainerRestarted;
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
use Illuminate\Support\Arr;
 | 
			
		||||
 | 
			
		||||
class ServerCheckJob implements ShouldBeEncrypted, ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
			
		||||
 | 
			
		||||
    public $tries = 3;
 | 
			
		||||
 | 
			
		||||
    public $containers;
 | 
			
		||||
 | 
			
		||||
    public $applications;
 | 
			
		||||
 | 
			
		||||
    public $databases;
 | 
			
		||||
 | 
			
		||||
    public $services;
 | 
			
		||||
 | 
			
		||||
    public $previews;
 | 
			
		||||
 | 
			
		||||
    public function backoff(): int
 | 
			
		||||
    {
 | 
			
		||||
        return isDev() ? 1 : 3;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __construct(public Server $server) {}
 | 
			
		||||
 | 
			
		||||
    public function middleware(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [(new WithoutOverlapping($this->server->uuid))];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function uniqueId(): int
 | 
			
		||||
    {
 | 
			
		||||
        return $this->server->uuid;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            $up = $this->serverStatus();
 | 
			
		||||
            if (! $up) {
 | 
			
		||||
                ray('Server is not reachable.');
 | 
			
		||||
 | 
			
		||||
                return 'Server is not reachable.';
 | 
			
		||||
            }
 | 
			
		||||
            if (! $this->server->isFunctional()) {
 | 
			
		||||
                ray('Server is not ready.');
 | 
			
		||||
 | 
			
		||||
                return 'Server is not ready.';
 | 
			
		||||
            }
 | 
			
		||||
            $this->checkSentinel();
 | 
			
		||||
            $this->getContainers();
 | 
			
		||||
 | 
			
		||||
            if (is_null($this->containers)) {
 | 
			
		||||
                return 'No containers found.';
 | 
			
		||||
            }
 | 
			
		||||
            $this->checkLogDrainContainer();
 | 
			
		||||
            $this->containerStatus();
 | 
			
		||||
 | 
			
		||||
        } catch (\Throwable $e) {
 | 
			
		||||
            ray($e->getMessage());
 | 
			
		||||
 | 
			
		||||
            return handleError($e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function checkSentinel()
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->server->isSentinelEnabled()) {
 | 
			
		||||
            $sentinelContainerFound = $this->containers->filter(function ($value, $key) {
 | 
			
		||||
                return data_get($value, 'Name') === '/coolify-sentinel';
 | 
			
		||||
            })->first();
 | 
			
		||||
            if ($sentinelContainerFound) {
 | 
			
		||||
                $status = data_get($sentinelContainerFound, 'State.Status');
 | 
			
		||||
                if ($status !== 'running') {
 | 
			
		||||
                    PullSentinelImageJob::dispatch($this);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function serverStatus()
 | 
			
		||||
    {
 | 
			
		||||
        $this->removeUnnevessaryCoolifyYaml();
 | 
			
		||||
        ['uptime' => $uptime] = $this->server->validateConnection();
 | 
			
		||||
        if ($uptime) {
 | 
			
		||||
            if ($this->server->unreachable_notification_sent === true) {
 | 
			
		||||
                $this->server->update(['unreachable_notification_sent' => false]);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            foreach ($this->applications as $application) {
 | 
			
		||||
                $application->update(['status' => 'exited']);
 | 
			
		||||
            }
 | 
			
		||||
            foreach ($this->databases as $database) {
 | 
			
		||||
                $database->update(['status' => 'exited']);
 | 
			
		||||
            }
 | 
			
		||||
            foreach ($this->services as $service) {
 | 
			
		||||
                $apps = $service->applications()->get();
 | 
			
		||||
                $dbs = $service->databases()->get();
 | 
			
		||||
                foreach ($apps as $app) {
 | 
			
		||||
                    $app->update(['status' => 'exited']);
 | 
			
		||||
                }
 | 
			
		||||
                foreach ($dbs as $db) {
 | 
			
		||||
                    $db->update(['status' => 'exited']);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function removeUnnevessaryCoolifyYaml()
 | 
			
		||||
    {
 | 
			
		||||
        // This will remote the coolify.yaml file from the server as it is not needed on cloud servers
 | 
			
		||||
        if (isCloud() && $this->server->id !== 0) {
 | 
			
		||||
            $file = $this->server->proxyPath().'/dynamic/coolify.yaml';
 | 
			
		||||
 | 
			
		||||
            return instant_remote_process([
 | 
			
		||||
                "rm -f $file",
 | 
			
		||||
            ], $this->server, false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function checkLogDrainContainer()
 | 
			
		||||
    {
 | 
			
		||||
        $foundLogDrainContainer = $this->containers->filter(function ($value, $key) {
 | 
			
		||||
            return data_get($value, 'Name') === '/coolify-log-drain';
 | 
			
		||||
        })->first();
 | 
			
		||||
        if ($foundLogDrainContainer) {
 | 
			
		||||
            $status = data_get($foundLogDrainContainer, 'State.Status');
 | 
			
		||||
            if ($status !== 'running') {
 | 
			
		||||
                InstallLogDrain::dispatch($this->server);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            InstallLogDrain::dispatch($this->server);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getContainers()
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->server->isSwarm()) {
 | 
			
		||||
            $this->containers = instant_remote_process(["docker service inspect $(docker service ls -q) --format '{{json .}}'"], $this->server, false);
 | 
			
		||||
            $this->containers = format_docker_command_output_to_json($this->containers);
 | 
			
		||||
            $containerReplicates = instant_remote_process(["docker service ls --format '{{json .}}'"], $this->server, false);
 | 
			
		||||
            if ($containerReplicates) {
 | 
			
		||||
                $containerReplicates = format_docker_command_output_to_json($containerReplicates);
 | 
			
		||||
                foreach ($containerReplicates as $containerReplica) {
 | 
			
		||||
                    $name = data_get($containerReplica, 'Name');
 | 
			
		||||
                    $this->containers = $this->containers->map(function ($container) use ($name, $containerReplica) {
 | 
			
		||||
                        if (data_get($container, 'Spec.Name') === $name) {
 | 
			
		||||
                            $replicas = data_get($containerReplica, 'Replicas');
 | 
			
		||||
                            $running = str($replicas)->explode('/')[0];
 | 
			
		||||
                            $total = str($replicas)->explode('/')[1];
 | 
			
		||||
                            if ($running === $total) {
 | 
			
		||||
                                data_set($container, 'State.Status', 'running');
 | 
			
		||||
                                data_set($container, 'State.Health.Status', 'healthy');
 | 
			
		||||
                            } else {
 | 
			
		||||
                                data_set($container, 'State.Status', 'starting');
 | 
			
		||||
                                data_set($container, 'State.Health.Status', 'unhealthy');
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        return $container;
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->containers = instant_remote_process(["docker container inspect $(docker container ls -q) --format '{{json .}}'"], $this->server, false);
 | 
			
		||||
            $this->containers = format_docker_command_output_to_json($this->containers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function containerStatus()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        $this->applications = $this->server->applications();
 | 
			
		||||
        $this->databases = $this->server->databases();
 | 
			
		||||
        $this->services = $this->server->services()->get();
 | 
			
		||||
        $this->previews = $this->server->previews();
 | 
			
		||||
 | 
			
		||||
        $foundApplications = [];
 | 
			
		||||
        $foundApplicationPreviews = [];
 | 
			
		||||
        $foundDatabases = [];
 | 
			
		||||
        $foundServices = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($this->containers as $container) {
 | 
			
		||||
            if ($this->server->isSwarm()) {
 | 
			
		||||
                $labels = data_get($container, 'Spec.Labels');
 | 
			
		||||
                $uuid = data_get($labels, 'coolify.name');
 | 
			
		||||
            } else {
 | 
			
		||||
                $labels = data_get($container, 'Config.Labels');
 | 
			
		||||
            }
 | 
			
		||||
            $containerStatus = data_get($container, 'State.Status');
 | 
			
		||||
            $containerHealth = data_get($container, 'State.Health.Status', 'unhealthy');
 | 
			
		||||
            $containerStatus = "$containerStatus ($containerHealth)";
 | 
			
		||||
            $labels = Arr::undot(format_docker_labels_to_json($labels));
 | 
			
		||||
            $applicationId = data_get($labels, 'coolify.applicationId');
 | 
			
		||||
            if ($applicationId) {
 | 
			
		||||
                $pullRequestId = data_get($labels, 'coolify.pullRequestId');
 | 
			
		||||
                if ($pullRequestId) {
 | 
			
		||||
                    if (str($applicationId)->contains('-')) {
 | 
			
		||||
                        $applicationId = str($applicationId)->before('-');
 | 
			
		||||
                    }
 | 
			
		||||
                    $preview = ApplicationPreview::where('application_id', $applicationId)->where('pull_request_id', $pullRequestId)->first();
 | 
			
		||||
                    if ($preview) {
 | 
			
		||||
                        $foundApplicationPreviews[] = $preview->id;
 | 
			
		||||
                        $statusFromDb = $preview->status;
 | 
			
		||||
                        if ($statusFromDb !== $containerStatus) {
 | 
			
		||||
                            $preview->update(['status' => $containerStatus]);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        //Notify user that this container should not be there.
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    $application = $this->applications->where('id', $applicationId)->first();
 | 
			
		||||
                    if ($application) {
 | 
			
		||||
                        $foundApplications[] = $application->id;
 | 
			
		||||
                        $statusFromDb = $application->status;
 | 
			
		||||
                        if ($statusFromDb !== $containerStatus) {
 | 
			
		||||
                            $application->update(['status' => $containerStatus]);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        //Notify user that this container should not be there.
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                $uuid = data_get($labels, 'com.docker.compose.service');
 | 
			
		||||
                $type = data_get($labels, 'coolify.type');
 | 
			
		||||
 | 
			
		||||
                if ($uuid) {
 | 
			
		||||
                    if ($type === 'service') {
 | 
			
		||||
                        $database_id = data_get($labels, 'coolify.service.subId');
 | 
			
		||||
                        if ($database_id) {
 | 
			
		||||
                            $service_db = ServiceDatabase::where('id', $database_id)->first();
 | 
			
		||||
                            if ($service_db) {
 | 
			
		||||
                                $uuid = data_get($service_db, 'service.uuid');
 | 
			
		||||
                                if ($uuid) {
 | 
			
		||||
                                    $isPublic = data_get($service_db, 'is_public');
 | 
			
		||||
                                    if ($isPublic) {
 | 
			
		||||
                                        $foundTcpProxy = $this->containers->filter(function ($value, $key) use ($uuid) {
 | 
			
		||||
                                            if ($this->server->isSwarm()) {
 | 
			
		||||
                                                return data_get($value, 'Spec.Name') === "coolify-proxy_$uuid";
 | 
			
		||||
                                            } else {
 | 
			
		||||
                                                return data_get($value, 'Name') === "/$uuid-proxy";
 | 
			
		||||
                                            }
 | 
			
		||||
                                        })->first();
 | 
			
		||||
                                        if (! $foundTcpProxy) {
 | 
			
		||||
                                            StartDatabaseProxy::run($service_db);
 | 
			
		||||
                                            // $this->server->team?->notify(new ContainerRestarted("TCP Proxy for {$service_db->service->name}", $this->server));
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        $database = $this->databases->where('uuid', $uuid)->first();
 | 
			
		||||
                        if ($database) {
 | 
			
		||||
                            $isPublic = data_get($database, 'is_public');
 | 
			
		||||
                            $foundDatabases[] = $database->id;
 | 
			
		||||
                            $statusFromDb = $database->status;
 | 
			
		||||
                            if ($statusFromDb !== $containerStatus) {
 | 
			
		||||
                                $database->update(['status' => $containerStatus]);
 | 
			
		||||
                            }
 | 
			
		||||
                            if ($isPublic) {
 | 
			
		||||
                                $foundTcpProxy = $this->containers->filter(function ($value, $key) use ($uuid) {
 | 
			
		||||
                                    if ($this->server->isSwarm()) {
 | 
			
		||||
                                        return data_get($value, 'Spec.Name') === "coolify-proxy_$uuid";
 | 
			
		||||
                                    } else {
 | 
			
		||||
                                        return data_get($value, 'Name') === "/$uuid-proxy";
 | 
			
		||||
                                    }
 | 
			
		||||
                                })->first();
 | 
			
		||||
                                if (! $foundTcpProxy) {
 | 
			
		||||
                                    StartDatabaseProxy::run($database);
 | 
			
		||||
                                    $this->server->team?->notify(new ContainerRestarted("TCP Proxy for {$database->name}", $this->server));
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        } else {
 | 
			
		||||
                            // Notify user that this container should not be there.
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (data_get($container, 'Name') === '/coolify-db') {
 | 
			
		||||
                    $foundDatabases[] = 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            $serviceLabelId = data_get($labels, 'coolify.serviceId');
 | 
			
		||||
            if ($serviceLabelId) {
 | 
			
		||||
                $subType = data_get($labels, 'coolify.service.subType');
 | 
			
		||||
                $subId = data_get($labels, 'coolify.service.subId');
 | 
			
		||||
                $service = $this->services->where('id', $serviceLabelId)->first();
 | 
			
		||||
                if (! $service) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if ($subType === 'application') {
 | 
			
		||||
                    $service = $service->applications()->where('id', $subId)->first();
 | 
			
		||||
                } else {
 | 
			
		||||
                    $service = $service->databases()->where('id', $subId)->first();
 | 
			
		||||
                }
 | 
			
		||||
                if ($service) {
 | 
			
		||||
                    $foundServices[] = "$service->id-$service->name";
 | 
			
		||||
                    $statusFromDb = $service->status;
 | 
			
		||||
                    if ($statusFromDb !== $containerStatus) {
 | 
			
		||||
                        // ray('Updating status: ' . $containerStatus);
 | 
			
		||||
                        $service->update(['status' => $containerStatus]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $exitedServices = collect([]);
 | 
			
		||||
        foreach ($this->services as $service) {
 | 
			
		||||
            $apps = $service->applications()->get();
 | 
			
		||||
            $dbs = $service->databases()->get();
 | 
			
		||||
            foreach ($apps as $app) {
 | 
			
		||||
                if (in_array("$app->id-$app->name", $foundServices)) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else {
 | 
			
		||||
                    $exitedServices->push($app);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            foreach ($dbs as $db) {
 | 
			
		||||
                if (in_array("$db->id-$db->name", $foundServices)) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else {
 | 
			
		||||
                    $exitedServices->push($db);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $exitedServices = $exitedServices->unique('id');
 | 
			
		||||
        foreach ($exitedServices as $exitedService) {
 | 
			
		||||
            if (str($exitedService->status)->startsWith('exited')) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            $name = data_get($exitedService, 'name');
 | 
			
		||||
            $fqdn = data_get($exitedService, 'fqdn');
 | 
			
		||||
            if ($name) {
 | 
			
		||||
                if ($fqdn) {
 | 
			
		||||
                    $containerName = "$name, available at $fqdn";
 | 
			
		||||
                } else {
 | 
			
		||||
                    $containerName = $name;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                if ($fqdn) {
 | 
			
		||||
                    $containerName = $fqdn;
 | 
			
		||||
                } else {
 | 
			
		||||
                    $containerName = null;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            $projectUuid = data_get($service, 'environment.project.uuid');
 | 
			
		||||
            $serviceUuid = data_get($service, 'uuid');
 | 
			
		||||
            $environmentName = data_get($service, 'environment.name');
 | 
			
		||||
 | 
			
		||||
            if ($projectUuid && $serviceUuid && $environmentName) {
 | 
			
		||||
                $url = base_url().'/project/'.$projectUuid.'/'.$environmentName.'/service/'.$serviceUuid;
 | 
			
		||||
            } else {
 | 
			
		||||
                $url = null;
 | 
			
		||||
            }
 | 
			
		||||
            // $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
 | 
			
		||||
            $exitedService->update(['status' => 'exited']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $notRunningApplications = $this->applications->pluck('id')->diff($foundApplications);
 | 
			
		||||
        foreach ($notRunningApplications as $applicationId) {
 | 
			
		||||
            $application = $this->applications->where('id', $applicationId)->first();
 | 
			
		||||
            if (str($application->status)->startsWith('exited')) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            $application->update(['status' => 'exited']);
 | 
			
		||||
 | 
			
		||||
            $name = data_get($application, 'name');
 | 
			
		||||
            $fqdn = data_get($application, 'fqdn');
 | 
			
		||||
 | 
			
		||||
            $containerName = $name ? "$name ($fqdn)" : $fqdn;
 | 
			
		||||
 | 
			
		||||
            $projectUuid = data_get($application, 'environment.project.uuid');
 | 
			
		||||
            $applicationUuid = data_get($application, 'uuid');
 | 
			
		||||
            $environment = data_get($application, 'environment.name');
 | 
			
		||||
 | 
			
		||||
            if ($projectUuid && $applicationUuid && $environment) {
 | 
			
		||||
                $url = base_url().'/project/'.$projectUuid.'/'.$environment.'/application/'.$applicationUuid;
 | 
			
		||||
            } else {
 | 
			
		||||
                $url = null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
 | 
			
		||||
        }
 | 
			
		||||
        $notRunningApplicationPreviews = $this->previews->pluck('id')->diff($foundApplicationPreviews);
 | 
			
		||||
        foreach ($notRunningApplicationPreviews as $previewId) {
 | 
			
		||||
            $preview = $this->previews->where('id', $previewId)->first();
 | 
			
		||||
            if (str($preview->status)->startsWith('exited')) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            $preview->update(['status' => 'exited']);
 | 
			
		||||
 | 
			
		||||
            $name = data_get($preview, 'name');
 | 
			
		||||
            $fqdn = data_get($preview, 'fqdn');
 | 
			
		||||
 | 
			
		||||
            $containerName = $name ? "$name ($fqdn)" : $fqdn;
 | 
			
		||||
 | 
			
		||||
            $projectUuid = data_get($preview, 'application.environment.project.uuid');
 | 
			
		||||
            $environmentName = data_get($preview, 'application.environment.name');
 | 
			
		||||
            $applicationUuid = data_get($preview, 'application.uuid');
 | 
			
		||||
 | 
			
		||||
            if ($projectUuid && $applicationUuid && $environmentName) {
 | 
			
		||||
                $url = base_url().'/project/'.$projectUuid.'/'.$environmentName.'/application/'.$applicationUuid;
 | 
			
		||||
            } else {
 | 
			
		||||
                $url = null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
 | 
			
		||||
        }
 | 
			
		||||
        $notRunningDatabases = $this->databases->pluck('id')->diff($foundDatabases);
 | 
			
		||||
        foreach ($notRunningDatabases as $database) {
 | 
			
		||||
            $database = $this->databases->where('id', $database)->first();
 | 
			
		||||
            if (str($database->status)->startsWith('exited')) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            $database->update(['status' => 'exited']);
 | 
			
		||||
 | 
			
		||||
            $name = data_get($database, 'name');
 | 
			
		||||
            $fqdn = data_get($database, 'fqdn');
 | 
			
		||||
 | 
			
		||||
            $containerName = $name;
 | 
			
		||||
 | 
			
		||||
            $projectUuid = data_get($database, 'environment.project.uuid');
 | 
			
		||||
            $environmentName = data_get($database, 'environment.name');
 | 
			
		||||
            $databaseUuid = data_get($database, 'uuid');
 | 
			
		||||
 | 
			
		||||
            if ($projectUuid && $databaseUuid && $environmentName) {
 | 
			
		||||
                $url = base_url().'/project/'.$projectUuid.'/'.$environmentName.'/database/'.$databaseUuid;
 | 
			
		||||
            } else {
 | 
			
		||||
                $url = null;
 | 
			
		||||
            }
 | 
			
		||||
            // $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check if proxy is running
 | 
			
		||||
        $this->server->proxyType();
 | 
			
		||||
        $foundProxyContainer = $this->containers->filter(function ($value, $key) {
 | 
			
		||||
            if ($this->server->isSwarm()) {
 | 
			
		||||
                return data_get($value, 'Spec.Name') === 'coolify-proxy_traefik';
 | 
			
		||||
            } else {
 | 
			
		||||
                return data_get($value, 'Name') === '/coolify-proxy';
 | 
			
		||||
            }
 | 
			
		||||
        })->first();
 | 
			
		||||
        if (! $foundProxyContainer) {
 | 
			
		||||
            try {
 | 
			
		||||
                $shouldStart = CheckProxy::run($this->server);
 | 
			
		||||
                if ($shouldStart) {
 | 
			
		||||
                    StartProxy::run($this->server, false);
 | 
			
		||||
                    $this->server->team?->notify(new ContainerRestarted('coolify-proxy', $this->server));
 | 
			
		||||
                }
 | 
			
		||||
            } catch (\Throwable $e) {
 | 
			
		||||
                ray($e);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->server->proxy->status = data_get($foundProxyContainer, 'State.Status');
 | 
			
		||||
            $this->server->save();
 | 
			
		||||
            $connectProxyToDockerNetworks = connectProxyToNetworks($this->server);
 | 
			
		||||
            instant_remote_process($connectProxyToDockerNetworks, $this->server, false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -52,7 +52,7 @@ class Docker extends Component
 | 
			
		||||
        if (request()->query('network_name')) {
 | 
			
		||||
            $this->network = request()->query('network_name');
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->network = new Cuid2(7);
 | 
			
		||||
            $this->network = new Cuid2;
 | 
			
		||||
        }
 | 
			
		||||
        if ($this->servers->count() > 0) {
 | 
			
		||||
            $this->name = str("{$this->servers->first()->name}-{$this->network}")->kebab();
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ class MonacoEditor extends Component
 | 
			
		||||
    public function render()
 | 
			
		||||
    {
 | 
			
		||||
        if (is_null($this->id)) {
 | 
			
		||||
            $this->id = new Cuid2(7);
 | 
			
		||||
            $this->id = new Cuid2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_null($this->name)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -96,6 +96,20 @@ class Advanced extends Component
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->application->settings->custom_internal_name = null;
 | 
			
		||||
        }
 | 
			
		||||
        $customInternalName = $this->application->settings->custom_internal_name;
 | 
			
		||||
        $server = $this->application->destination->server;
 | 
			
		||||
        $allApplications = $server->applications();
 | 
			
		||||
 | 
			
		||||
        $foundSameInternalName = $allApplications->filter(function ($application) {
 | 
			
		||||
            return $application->id !== $this->application->id && $application->settings->custom_internal_name === $this->application->settings->custom_internal_name;
 | 
			
		||||
        });
 | 
			
		||||
        if ($foundSameInternalName->isNotEmpty()) {
 | 
			
		||||
            $this->dispatch('error', 'This custom container name is already in use by another application on this server.');
 | 
			
		||||
            $this->application->settings->custom_internal_name = $customInternalName;
 | 
			
		||||
            $this->application->settings->refresh();
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        $this->application->settings->save();
 | 
			
		||||
        $this->dispatch('success', 'Custom name saved.');
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -228,7 +228,7 @@ class General extends Component
 | 
			
		||||
 | 
			
		||||
    public function generateDomain(string $serviceName)
 | 
			
		||||
    {
 | 
			
		||||
        $uuid = new Cuid2(7);
 | 
			
		||||
        $uuid = new Cuid2;
 | 
			
		||||
        $domain = generateFqdn($this->application->destination->server, $uuid);
 | 
			
		||||
        $this->parsedServiceDomains[$serviceName]['domain'] = $domain;
 | 
			
		||||
        $this->application->docker_compose_domains = json_encode($this->parsedServiceDomains);
 | 
			
		||||
 
 | 
			
		||||
@@ -102,7 +102,7 @@ class Heading extends Component
 | 
			
		||||
 | 
			
		||||
    protected function setDeploymentUuid()
 | 
			
		||||
    {
 | 
			
		||||
        $this->deploymentUuid = new Cuid2(7);
 | 
			
		||||
        $this->deploymentUuid = new Cuid2;
 | 
			
		||||
        $this->parameters['deployment_uuid'] = $this->deploymentUuid;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -85,7 +85,7 @@ class Previews extends Component
 | 
			
		||||
        $template = $this->application->preview_url_template;
 | 
			
		||||
        $host = $url->getHost();
 | 
			
		||||
        $schema = $url->getScheme();
 | 
			
		||||
        $random = new Cuid2(7);
 | 
			
		||||
        $random = new Cuid2;
 | 
			
		||||
        $preview_fqdn = str_replace('{{random}}', $random, $template);
 | 
			
		||||
        $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
 | 
			
		||||
        $preview_fqdn = str_replace('{{pr_id}}', $preview->pull_request_id, $preview_fqdn);
 | 
			
		||||
@@ -170,7 +170,7 @@ class Previews extends Component
 | 
			
		||||
 | 
			
		||||
    protected function setDeploymentUuid()
 | 
			
		||||
    {
 | 
			
		||||
        $this->deployment_uuid = new Cuid2(7);
 | 
			
		||||
        $this->deployment_uuid = new Cuid2;
 | 
			
		||||
        $this->parameters['deployment_uuid'] = $this->deployment_uuid;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ class PreviewsCompose extends Component
 | 
			
		||||
            $template = $this->preview->application->preview_url_template;
 | 
			
		||||
            $host = $url->getHost();
 | 
			
		||||
            $schema = $url->getScheme();
 | 
			
		||||
            $random = new Cuid2(7);
 | 
			
		||||
            $random = new Cuid2;
 | 
			
		||||
            $preview_fqdn = str_replace('{{random}}', $random, $template);
 | 
			
		||||
            $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
 | 
			
		||||
            $preview_fqdn = str_replace('{{pr_id}}', $this->preview->pull_request_id, $preview_fqdn);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ class Rollback extends Component
 | 
			
		||||
 | 
			
		||||
    public function rollbackImage($commit)
 | 
			
		||||
    {
 | 
			
		||||
        $deployment_uuid = new Cuid2(7);
 | 
			
		||||
        $deployment_uuid = new Cuid2;
 | 
			
		||||
 | 
			
		||||
        queue_application_deployment(
 | 
			
		||||
            application: $this->application,
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ class CloneMe extends Component
 | 
			
		||||
        $this->environment = $this->project->environments->where('name', $this->environment_name)->first();
 | 
			
		||||
        $this->project_id = $this->project->id;
 | 
			
		||||
        $this->servers = currentTeam()->servers;
 | 
			
		||||
        $this->newName = str($this->project->name.'-clone-'.(string) new Cuid2(7))->slug();
 | 
			
		||||
        $this->newName = str($this->project->name.'-clone-'.(string) new Cuid2)->slug();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function render()
 | 
			
		||||
@@ -106,7 +106,7 @@ class CloneMe extends Component
 | 
			
		||||
            $databases = $this->environment->databases();
 | 
			
		||||
            $services = $this->environment->services;
 | 
			
		||||
            foreach ($applications as $application) {
 | 
			
		||||
                $uuid = (string) new Cuid2(7);
 | 
			
		||||
                $uuid = (string) new Cuid2;
 | 
			
		||||
                $newApplication = $application->replicate()->fill([
 | 
			
		||||
                    'uuid' => $uuid,
 | 
			
		||||
                    'fqdn' => generateFqdn($this->server, $uuid),
 | 
			
		||||
@@ -133,7 +133,7 @@ class CloneMe extends Component
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            foreach ($databases as $database) {
 | 
			
		||||
                $uuid = (string) new Cuid2(7);
 | 
			
		||||
                $uuid = (string) new Cuid2;
 | 
			
		||||
                $newDatabase = $database->replicate()->fill([
 | 
			
		||||
                    'uuid' => $uuid,
 | 
			
		||||
                    'status' => 'exited',
 | 
			
		||||
@@ -161,7 +161,7 @@ class CloneMe extends Component
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            foreach ($services as $service) {
 | 
			
		||||
                $uuid = (string) new Cuid2(7);
 | 
			
		||||
                $uuid = (string) new Cuid2;
 | 
			
		||||
                $newService = $service->replicate()->fill([
 | 
			
		||||
                    'uuid' => $uuid,
 | 
			
		||||
                    'environment_id' => $environment->id,
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@ class DockerImage extends Component
 | 
			
		||||
        $environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
 | 
			
		||||
        ray($image, $tag);
 | 
			
		||||
        $application = Application::create([
 | 
			
		||||
            'name' => 'docker-image-'.new Cuid2(7),
 | 
			
		||||
            'name' => 'docker-image-'.new Cuid2,
 | 
			
		||||
            'repository_project_id' => 0,
 | 
			
		||||
            'git_repository' => 'coollabsio/coolify',
 | 
			
		||||
            'git_branch' => 'main',
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ CMD ["nginx", "-g", "daemon off;"]
 | 
			
		||||
            $port = 80;
 | 
			
		||||
        }
 | 
			
		||||
        $application = Application::create([
 | 
			
		||||
            'name' => 'dockerfile-'.new Cuid2(7),
 | 
			
		||||
            'name' => 'dockerfile-'.new Cuid2,
 | 
			
		||||
            'repository_project_id' => 0,
 | 
			
		||||
            'git_repository' => 'coollabsio/coolify',
 | 
			
		||||
            'git_branch' => 'main',
 | 
			
		||||
 
 | 
			
		||||
@@ -63,6 +63,8 @@ class Navbar extends Component
 | 
			
		||||
    public function checkDeployments()
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            // TODO: This is a temporary solution. We need to refactor this.
 | 
			
		||||
            // We need to delete null bytes somehow.
 | 
			
		||||
            $activity = Activity::where('properties->type_uuid', $this->service->uuid)->latest()->first();
 | 
			
		||||
            $status = data_get($activity, 'properties.status');
 | 
			
		||||
            if ($status === 'queued' || $status === 'in_progress') {
 | 
			
		||||
@@ -70,7 +72,7 @@ class Navbar extends Component
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->isDeploymentProgress = false;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (\Exception $e) {
 | 
			
		||||
        } catch (\Throwable $e) {
 | 
			
		||||
            $this->isDeploymentProgress = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ class Danger extends Component
 | 
			
		||||
 | 
			
		||||
    public function mount()
 | 
			
		||||
    {
 | 
			
		||||
        $this->modalId = new Cuid2(7);
 | 
			
		||||
        $this->modalId = new Cuid2;
 | 
			
		||||
        $parameters = get_route_parameters();
 | 
			
		||||
        $this->projectUuid = data_get($parameters, 'project_uuid');
 | 
			
		||||
        $this->environmentName = data_get($parameters, 'environment_name');
 | 
			
		||||
 
 | 
			
		||||
@@ -67,7 +67,7 @@ class Destination extends Component
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        $deployment_uuid = new Cuid2(7);
 | 
			
		||||
        $deployment_uuid = new Cuid2;
 | 
			
		||||
        $server = Server::find($server_id);
 | 
			
		||||
        $destination = StandaloneDocker::find($network_id);
 | 
			
		||||
        queue_application_deployment(
 | 
			
		||||
 
 | 
			
		||||
@@ -48,14 +48,14 @@ class Add extends Component
 | 
			
		||||
    public function submit()
 | 
			
		||||
    {
 | 
			
		||||
        $this->validate();
 | 
			
		||||
        if (str($this->value)->startsWith('{{') && str($this->value)->endsWith('}}')) {
 | 
			
		||||
            $type = str($this->value)->after('{{')->before('.')->value;
 | 
			
		||||
            if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
 | 
			
		||||
                $this->dispatch('error', 'Invalid  shared variable type.', 'Valid types are: team, project, environment.');
 | 
			
		||||
        // if (str($this->value)->startsWith('{{') && str($this->value)->endsWith('}}')) {
 | 
			
		||||
        //     $type = str($this->value)->after('{{')->before('.')->value;
 | 
			
		||||
        //     if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
 | 
			
		||||
        //         $this->dispatch('error', 'Invalid  shared variable type.', 'Valid types are: team, project, environment.');
 | 
			
		||||
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        //         return;
 | 
			
		||||
        //     }
 | 
			
		||||
        // }
 | 
			
		||||
        $this->dispatch('saveKey', [
 | 
			
		||||
            'key' => $this->key,
 | 
			
		||||
            'value' => $this->value,
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ class All extends Component
 | 
			
		||||
        if (str($this->resourceClass)->contains($resourceWithPreviews) && ! $simpleDockerfile) {
 | 
			
		||||
            $this->showPreview = true;
 | 
			
		||||
        }
 | 
			
		||||
        $this->modalId = new Cuid2(7);
 | 
			
		||||
        $this->modalId = new Cuid2;
 | 
			
		||||
        $this->sortMe();
 | 
			
		||||
        $this->getDevView();
 | 
			
		||||
    }
 | 
			
		||||
@@ -125,14 +125,14 @@ class All extends Component
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                $found->value = $variable;
 | 
			
		||||
                if (str($found->value)->startsWith('{{') && str($found->value)->endsWith('}}')) {
 | 
			
		||||
                    $type = str($found->value)->after('{{')->before('.')->value;
 | 
			
		||||
                    if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
 | 
			
		||||
                        $this->dispatch('error', 'Invalid  shared variable type.', 'Valid types are: team, project, environment.');
 | 
			
		||||
                // if (str($found->value)->startsWith('{{') && str($found->value)->endsWith('}}')) {
 | 
			
		||||
                //     $type = str($found->value)->after('{{')->before('.')->value;
 | 
			
		||||
                //     if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
 | 
			
		||||
                //         $this->dispatch('error', 'Invalid  shared variable type.', 'Valid types are: team, project, environment.');
 | 
			
		||||
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                //         return;
 | 
			
		||||
                //     }
 | 
			
		||||
                // }
 | 
			
		||||
                $found->save();
 | 
			
		||||
 | 
			
		||||
                continue;
 | 
			
		||||
@@ -140,14 +140,14 @@ class All extends Component
 | 
			
		||||
                $environment = new EnvironmentVariable;
 | 
			
		||||
                $environment->key = $key;
 | 
			
		||||
                $environment->value = $variable;
 | 
			
		||||
                if (str($environment->value)->startsWith('{{') && str($environment->value)->endsWith('}}')) {
 | 
			
		||||
                    $type = str($environment->value)->after('{{')->before('.')->value;
 | 
			
		||||
                    if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
 | 
			
		||||
                        $this->dispatch('error', 'Invalid  shared variable type.', 'Valid types are: team, project, environment.');
 | 
			
		||||
                // if (str($environment->value)->startsWith('{{') && str($environment->value)->endsWith('}}')) {
 | 
			
		||||
                //     $type = str($environment->value)->after('{{')->before('.')->value;
 | 
			
		||||
                //     if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
 | 
			
		||||
                //         $this->dispatch('error', 'Invalid  shared variable type.', 'Valid types are: team, project, environment.');
 | 
			
		||||
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                //         return;
 | 
			
		||||
                //     }
 | 
			
		||||
                // }
 | 
			
		||||
                $environment->is_build_time = false;
 | 
			
		||||
                $environment->is_multiline = false;
 | 
			
		||||
                $environment->is_preview = $isPreview ? true : false;
 | 
			
		||||
 
 | 
			
		||||
@@ -58,7 +58,7 @@ class Show extends Component
 | 
			
		||||
        if ($this->env->getMorphClass() === 'App\Models\SharedEnvironmentVariable') {
 | 
			
		||||
            $this->isSharedVariable = true;
 | 
			
		||||
        }
 | 
			
		||||
        $this->modalId = new Cuid2(7);
 | 
			
		||||
        $this->modalId = new Cuid2;
 | 
			
		||||
        $this->parameters = get_route_parameters();
 | 
			
		||||
        $this->checkEnvs();
 | 
			
		||||
    }
 | 
			
		||||
@@ -108,14 +108,14 @@ class Show extends Component
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->validate();
 | 
			
		||||
            }
 | 
			
		||||
            if (str($this->env->value)->startsWith('{{') && str($this->env->value)->endsWith('}}')) {
 | 
			
		||||
                $type = str($this->env->value)->after('{{')->before('.')->value;
 | 
			
		||||
                if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
 | 
			
		||||
                    $this->dispatch('error', 'Invalid  shared variable type.', 'Valid types are: team, project, environment.');
 | 
			
		||||
            // if (str($this->env->value)->startsWith('{{') && str($this->env->value)->endsWith('}}')) {
 | 
			
		||||
            //     $type = str($this->env->value)->after('{{')->before('.')->value;
 | 
			
		||||
            //     if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
 | 
			
		||||
            //         $this->dispatch('error', 'Invalid  shared variable type.', 'Valid types are: team, project, environment.');
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            //         return;
 | 
			
		||||
            //     }
 | 
			
		||||
            // }
 | 
			
		||||
            $this->serialize();
 | 
			
		||||
            $this->env->save();
 | 
			
		||||
            $this->dispatch('success', 'Environment variable updated.');
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ class ResourceOperations extends Component
 | 
			
		||||
        if (! $new_destination) {
 | 
			
		||||
            return $this->addError('destination_id', 'Destination not found.');
 | 
			
		||||
        }
 | 
			
		||||
        $uuid = (string) new Cuid2(7);
 | 
			
		||||
        $uuid = (string) new Cuid2;
 | 
			
		||||
        $server = $new_destination->server;
 | 
			
		||||
        if ($this->resource->getMorphClass() === 'App\Models\Application') {
 | 
			
		||||
            $new_resource = $this->resource->replicate()->fill([
 | 
			
		||||
@@ -87,7 +87,7 @@ class ResourceOperations extends Component
 | 
			
		||||
            $this->resource->getMorphClass() === 'App\Models\StandaloneDragonfly' ||
 | 
			
		||||
            $this->resource->getMorphClass() === 'App\Models\StandaloneClickhouse'
 | 
			
		||||
        ) {
 | 
			
		||||
            $uuid = (string) new Cuid2(7);
 | 
			
		||||
            $uuid = (string) new Cuid2;
 | 
			
		||||
            $new_resource = $this->resource->replicate()->fill([
 | 
			
		||||
                'uuid' => $uuid,
 | 
			
		||||
                'name' => $this->resource->name.'-clone-'.$uuid,
 | 
			
		||||
@@ -121,7 +121,7 @@ class ResourceOperations extends Component
 | 
			
		||||
 | 
			
		||||
            return redirect()->to($route);
 | 
			
		||||
        } elseif ($this->resource->type() === 'service') {
 | 
			
		||||
            $uuid = (string) new Cuid2(7);
 | 
			
		||||
            $uuid = (string) new Cuid2;
 | 
			
		||||
            $new_resource = $this->resource->replicate()->fill([
 | 
			
		||||
                'uuid' => $uuid,
 | 
			
		||||
                'name' => $this->resource->name.'-clone-'.$uuid,
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ class Show extends Component
 | 
			
		||||
            $this->resource = Service::where('uuid', $this->parameters['service_uuid'])->firstOrFail();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->modalId = new Cuid2(7);
 | 
			
		||||
        $this->modalId = new Cuid2;
 | 
			
		||||
        $this->task = ModelsScheduledTask::where('uuid', request()->route('task_uuid'))->first();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -232,12 +232,24 @@ class Application extends BaseModel
 | 
			
		||||
    public function failedTaskLink($task_uuid)
 | 
			
		||||
    {
 | 
			
		||||
        if (data_get($this, 'environment.project.uuid')) {
 | 
			
		||||
            return route('project.application.scheduled-tasks', [
 | 
			
		||||
            $route = route('project.application.scheduled-tasks', [
 | 
			
		||||
                'project_uuid' => data_get($this, 'environment.project.uuid'),
 | 
			
		||||
                'environment_name' => data_get($this, 'environment.name'),
 | 
			
		||||
                'application_uuid' => data_get($this, 'uuid'),
 | 
			
		||||
                'task_uuid' => $task_uuid,
 | 
			
		||||
            ]);
 | 
			
		||||
            $settings = InstanceSettings::get();
 | 
			
		||||
            if (data_get($settings, 'fqdn')) {
 | 
			
		||||
                $url = Url::fromString($route);
 | 
			
		||||
                $url = $url->withPort(null);
 | 
			
		||||
                $fqdn = data_get($settings, 'fqdn');
 | 
			
		||||
                $fqdn = str_replace(['http://', 'https://'], '', $fqdn);
 | 
			
		||||
                $url = $url->withHost($fqdn);
 | 
			
		||||
 | 
			
		||||
                return $url->__toString();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $route;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
@@ -275,12 +287,20 @@ class Application extends BaseModel
 | 
			
		||||
        return Attribute::make(
 | 
			
		||||
            get: function () {
 | 
			
		||||
                if (! is_null($this->source?->html_url) && ! is_null($this->git_repository) && ! is_null($this->git_branch)) {
 | 
			
		||||
                    if (str($this->git_repository)->contains('bitbucket')) {
 | 
			
		||||
                        return "{$this->source->html_url}/{$this->git_repository}/src/{$this->git_branch}";
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return "{$this->source->html_url}/{$this->git_repository}/tree/{$this->git_branch}";
 | 
			
		||||
                }
 | 
			
		||||
                // Convert the SSH URL to HTTPS URL
 | 
			
		||||
                if (strpos($this->git_repository, 'git@') === 0) {
 | 
			
		||||
                    $git_repository = str_replace(['git@', ':', '.git'], ['', '/', ''], $this->git_repository);
 | 
			
		||||
 | 
			
		||||
                    if (str($this->git_repository)->contains('bitbucket')) {
 | 
			
		||||
                        return "https://{$git_repository}/src/{$this->git_branch}";
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return "https://{$git_repository}/tree/{$this->git_branch}";
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -431,6 +451,11 @@ class Application extends BaseModel
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isRunning()
 | 
			
		||||
    {
 | 
			
		||||
        return (bool) str($this->status)->startsWith('running');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isExited()
 | 
			
		||||
    {
 | 
			
		||||
        return (bool) str($this->status)->startsWith('exited');
 | 
			
		||||
@@ -1270,7 +1295,7 @@ class Application extends BaseModel
 | 
			
		||||
            $template = $this->preview_url_template;
 | 
			
		||||
            $host = $url->getHost();
 | 
			
		||||
            $schema = $url->getScheme();
 | 
			
		||||
            $random = new Cuid2(7);
 | 
			
		||||
            $random = new Cuid2;
 | 
			
		||||
            $preview_fqdn = str_replace('{{random}}', $random, $template);
 | 
			
		||||
            $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
 | 
			
		||||
            $preview_fqdn = str_replace('{{pr_id}}', $pull_request_id, $preview_fqdn);
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,11 @@ class ApplicationPreview extends BaseModel
 | 
			
		||||
        return self::where('application_id', $application_id)->where('pull_request_id', $pull_request_id)->firstOrFail();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isRunning()
 | 
			
		||||
    {
 | 
			
		||||
        return (bool) str($this->status)->startsWith('running');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function application()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->belongsTo(Application::class);
 | 
			
		||||
@@ -49,7 +54,7 @@ class ApplicationPreview extends BaseModel
 | 
			
		||||
            $template = $this->application->preview_url_template;
 | 
			
		||||
            $host = $url->getHost();
 | 
			
		||||
            $schema = $url->getScheme();
 | 
			
		||||
            $random = new Cuid2(7);
 | 
			
		||||
            $random = new Cuid2;
 | 
			
		||||
            $preview_fqdn = str_replace('{{random}}', $random, $template);
 | 
			
		||||
            $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
 | 
			
		||||
            $preview_fqdn = str_replace('{{pr_id}}', $this->pull_request_id, $preview_fqdn);
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ abstract class BaseModel extends Model
 | 
			
		||||
        static::creating(function (Model $model) {
 | 
			
		||||
            // Generate a UUID if one isn't set
 | 
			
		||||
            if (! $model->uuid) {
 | 
			
		||||
                $model->uuid = (string) new Cuid2(7);
 | 
			
		||||
                $model->uuid = (string) new Cuid2;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@ namespace App\Models;
 | 
			
		||||
use App\Models\EnvironmentVariable as ModelsEnvironmentVariable;
 | 
			
		||||
use Illuminate\Database\Eloquent\Casts\Attribute;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
use OpenApi\Attributes as OA;
 | 
			
		||||
use Symfony\Component\Yaml\Yaml;
 | 
			
		||||
use Visus\Cuid2\Cuid2;
 | 
			
		||||
@@ -200,28 +199,33 @@ class EnvironmentVariable extends Model
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        $environment_variable = trim($environment_variable);
 | 
			
		||||
        $type = str($environment_variable)->after('{{')->before('.')->value;
 | 
			
		||||
        if (str($environment_variable)->startsWith('{{'.$type) && str($environment_variable)->endsWith('}}')) {
 | 
			
		||||
            $variable = Str::after($environment_variable, "{$type}.");
 | 
			
		||||
            $variable = Str::before($variable, '}}');
 | 
			
		||||
            $variable = str($variable)->trim()->value;
 | 
			
		||||
            if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
 | 
			
		||||
                return $variable;
 | 
			
		||||
        $sharedEnvsFound = str($environment_variable)->matchAll('/{{(.*?)}}/');
 | 
			
		||||
        if ($sharedEnvsFound->isEmpty()) {
 | 
			
		||||
            return $environment_variable;
 | 
			
		||||
        }
 | 
			
		||||
            if ($type === 'environment') {
 | 
			
		||||
        foreach ($sharedEnvsFound as $sharedEnv) {
 | 
			
		||||
            $type = str($sharedEnv)->match('/(.*?)\./');
 | 
			
		||||
            if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            $variable = str($sharedEnv)->match('/\.(.*)/');
 | 
			
		||||
            if ($type->value() === 'environment') {
 | 
			
		||||
                $id = $resource->environment->id;
 | 
			
		||||
            } elseif ($type === 'project') {
 | 
			
		||||
            } elseif ($type->value() === 'project') {
 | 
			
		||||
                $id = $resource->environment->project->id;
 | 
			
		||||
            } else {
 | 
			
		||||
            } elseif ($type->value() === 'team') {
 | 
			
		||||
                $id = $resource->team()->id;
 | 
			
		||||
            }
 | 
			
		||||
            if (is_null($id)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            $environment_variable_found = SharedEnvironmentVariable::where('type', $type)->where('key', $variable)->where('team_id', $resource->team()->id)->where("{$type}_id", $id)->first();
 | 
			
		||||
            if ($environment_variable_found) {
 | 
			
		||||
                return $environment_variable_found;
 | 
			
		||||
                $environment_variable = str($environment_variable)->replace("{{{$sharedEnv}}}", $environment_variable_found->value);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $environment_variable;
 | 
			
		||||
        return str($environment_variable)->value();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function get_environment_variables(?string $environment_variable = null): ?string
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
 | 
			
		||||
use Illuminate\Database\Eloquent\SoftDeletes;
 | 
			
		||||
use Illuminate\Support\Collection;
 | 
			
		||||
use OpenApi\Attributes as OA;
 | 
			
		||||
use Spatie\Url\Url;
 | 
			
		||||
use Symfony\Component\Yaml\Yaml;
 | 
			
		||||
 | 
			
		||||
#[OA\Schema(
 | 
			
		||||
@@ -76,6 +77,11 @@ class Service extends BaseModel
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isRunning()
 | 
			
		||||
    {
 | 
			
		||||
        return (bool) str($this->status())->contains('running');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isExited()
 | 
			
		||||
    {
 | 
			
		||||
        return (bool) str($this->status())->contains('exited');
 | 
			
		||||
@@ -575,6 +581,30 @@ class Service extends BaseModel
 | 
			
		||||
 | 
			
		||||
                    $fields->put('Vaultwarden', $data);
 | 
			
		||||
                    break;
 | 
			
		||||
                case str($image)->contains('gitlab/gitlab'):
 | 
			
		||||
                    $password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_GITLAB')->first();
 | 
			
		||||
                    $data = collect([]);
 | 
			
		||||
                    if ($password) {
 | 
			
		||||
                        $data = $data->merge([
 | 
			
		||||
                            'Root Password' => [
 | 
			
		||||
                                'key' => data_get($password, 'key'),
 | 
			
		||||
                                'value' => data_get($password, 'value'),
 | 
			
		||||
                                'rules' => 'required',
 | 
			
		||||
                                'isPassword' => true,
 | 
			
		||||
                            ],
 | 
			
		||||
                        ]);
 | 
			
		||||
                    }
 | 
			
		||||
                    $data = $data->merge([
 | 
			
		||||
                        'Root User' => [
 | 
			
		||||
                            'key' => 'N/A',
 | 
			
		||||
                            'value' => 'root',
 | 
			
		||||
                            'rules' => 'required',
 | 
			
		||||
                            'isPassword' => true,
 | 
			
		||||
                        ],
 | 
			
		||||
                    ]);
 | 
			
		||||
 | 
			
		||||
                    $fields->put('GitLab', $data->toArray());
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $databases = $this->databases()->get();
 | 
			
		||||
@@ -764,12 +794,24 @@ class Service extends BaseModel
 | 
			
		||||
    public function failedTaskLink($task_uuid)
 | 
			
		||||
    {
 | 
			
		||||
        if (data_get($this, 'environment.project.uuid')) {
 | 
			
		||||
            return route('project.service.scheduled-tasks', [
 | 
			
		||||
            $route = route('project.service.scheduled-tasks', [
 | 
			
		||||
                'project_uuid' => data_get($this, 'environment.project.uuid'),
 | 
			
		||||
                'environment_name' => data_get($this, 'environment.name'),
 | 
			
		||||
                'service_uuid' => data_get($this, 'uuid'),
 | 
			
		||||
                'task_uuid' => $task_uuid,
 | 
			
		||||
            ]);
 | 
			
		||||
            $settings = InstanceSettings::get();
 | 
			
		||||
            if (data_get($settings, 'fqdn')) {
 | 
			
		||||
                $url = Url::fromString($route);
 | 
			
		||||
                $url = $url->withPort(null);
 | 
			
		||||
                $fqdn = data_get($settings, 'fqdn');
 | 
			
		||||
                $fqdn = str_replace(['http://', 'https://'], '', $fqdn);
 | 
			
		||||
                $url = $url->withHost($fqdn);
 | 
			
		||||
 | 
			
		||||
                return $url->__toString();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $route;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
 
 | 
			
		||||
@@ -180,6 +180,10 @@ class User extends Authenticatable implements SendsEmail
 | 
			
		||||
    {
 | 
			
		||||
        $found_root_team = auth()->user()->teams->filter(function ($team) {
 | 
			
		||||
            if ($team->id == 0) {
 | 
			
		||||
                if (! auth()->user()->isAdmin()) {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ class Datalist extends Component
 | 
			
		||||
    public function render(): View|Closure|string
 | 
			
		||||
    {
 | 
			
		||||
        if (is_null($this->id)) {
 | 
			
		||||
            $this->id = new Cuid2(7);
 | 
			
		||||
            $this->id = new Cuid2;
 | 
			
		||||
        }
 | 
			
		||||
        if (is_null($this->name)) {
 | 
			
		||||
            $this->name = $this->id;
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ class Input extends Component
 | 
			
		||||
    public function render(): View|Closure|string
 | 
			
		||||
    {
 | 
			
		||||
        if (is_null($this->id)) {
 | 
			
		||||
            $this->id = new Cuid2(7);
 | 
			
		||||
            $this->id = new Cuid2;
 | 
			
		||||
        }
 | 
			
		||||
        if (is_null($this->name)) {
 | 
			
		||||
            $this->name = $this->id;
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ class Select extends Component
 | 
			
		||||
    public function render(): View|Closure|string
 | 
			
		||||
    {
 | 
			
		||||
        if (is_null($this->id)) {
 | 
			
		||||
            $this->id = new Cuid2(7);
 | 
			
		||||
            $this->id = new Cuid2;
 | 
			
		||||
        }
 | 
			
		||||
        if (is_null($this->name)) {
 | 
			
		||||
            $this->name = $this->id;
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ class Textarea extends Component
 | 
			
		||||
    public function render(): View|Closure|string
 | 
			
		||||
    {
 | 
			
		||||
        if (is_null($this->id)) {
 | 
			
		||||
            $this->id = new Cuid2(7);
 | 
			
		||||
            $this->id = new Cuid2;
 | 
			
		||||
        }
 | 
			
		||||
        if (is_null($this->name)) {
 | 
			
		||||
            $this->name = $this->id;
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ use Visus\Cuid2\Cuid2;
 | 
			
		||||
 | 
			
		||||
function generate_database_name(string $type): string
 | 
			
		||||
{
 | 
			
		||||
    $cuid = new Cuid2(7);
 | 
			
		||||
    $cuid = new Cuid2;
 | 
			
		||||
 | 
			
		||||
    return $type.'-database-'.$cuid;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -338,7 +338,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
 | 
			
		||||
    foreach ($domains as $loop => $domain) {
 | 
			
		||||
        try {
 | 
			
		||||
            if ($generate_unique_uuid) {
 | 
			
		||||
                $uuid = new Cuid2(7);
 | 
			
		||||
                $uuid = new Cuid2;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $url = Url::fromString($domain);
 | 
			
		||||
 
 | 
			
		||||
@@ -36,16 +36,23 @@ function collectDockerNetworksByServer(Server $server)
 | 
			
		||||
    }
 | 
			
		||||
    // Service networks
 | 
			
		||||
    foreach ($server->services()->get() as $service) {
 | 
			
		||||
        if ($service->isRunning()) {
 | 
			
		||||
            $networks->push($service->networks());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // Docker compose based apps
 | 
			
		||||
    $docker_compose_apps = $server->dockerComposeBasedApplications();
 | 
			
		||||
    foreach ($docker_compose_apps as $app) {
 | 
			
		||||
        if ($app->isRunning()) {
 | 
			
		||||
            $networks->push($app->uuid);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // Docker compose based preview deployments
 | 
			
		||||
    $docker_compose_previews = $server->dockerComposeBasedPreviewDeployments();
 | 
			
		||||
    foreach ($docker_compose_previews as $preview) {
 | 
			
		||||
        if (! $preview->isRunning()) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        $pullRequestId = $preview->pull_request_id;
 | 
			
		||||
        $applicationId = $preview->application_id;
 | 
			
		||||
        $application = Application::find($applicationId);
 | 
			
		||||
 
 | 
			
		||||
@@ -200,7 +200,7 @@ function generate_random_name(?string $cuid = null): string
 | 
			
		||||
        ]
 | 
			
		||||
    );
 | 
			
		||||
    if (is_null($cuid)) {
 | 
			
		||||
        $cuid = new Cuid2(7);
 | 
			
		||||
        $cuid = new Cuid2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Str::kebab("{$generator->getName()}-$cuid");
 | 
			
		||||
@@ -236,7 +236,7 @@ function formatPrivateKey(string $privateKey)
 | 
			
		||||
function generate_application_name(string $git_repository, string $git_branch, ?string $cuid = null): string
 | 
			
		||||
{
 | 
			
		||||
    if (is_null($cuid)) {
 | 
			
		||||
        $cuid = new Cuid2(7);
 | 
			
		||||
        $cuid = new Cuid2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Str::kebab("$git_repository:$git_branch-$cuid");
 | 
			
		||||
@@ -2022,7 +2022,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
 | 
			
		||||
                                    $template = $resource->preview_url_template;
 | 
			
		||||
                                    $host = $url->getHost();
 | 
			
		||||
                                    $schema = $url->getScheme();
 | 
			
		||||
                                    $random = new Cuid2(7);
 | 
			
		||||
                                    $random = new Cuid2;
 | 
			
		||||
                                    $preview_fqdn = str_replace('{{random}}', $random, $template);
 | 
			
		||||
                                    $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
 | 
			
		||||
                                    $preview_fqdn = str_replace('{{pr_id}}', $pull_request_id, $preview_fqdn);
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ return [
 | 
			
		||||
 | 
			
		||||
    // The release version of your application
 | 
			
		||||
    // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
 | 
			
		||||
    'release' => '4.0.0-beta.319',
 | 
			
		||||
    'release' => '4.0.0-beta.320',
 | 
			
		||||
    // When left empty or `null` the Laravel environment will be used
 | 
			
		||||
    'environment' => config('app.env'),
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,3 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return '4.0.0-beta.319';
 | 
			
		||||
return '4.0.0-beta.320';
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										457
									
								
								openapi.yaml
									
									
									
									
									
								
							
							
						
						
									
										457
									
								
								openapi.yaml
									
									
									
									
									
								
							@@ -5,6 +5,7 @@ info:
 | 
			
		||||
servers:
 | 
			
		||||
  -
 | 
			
		||||
    url: 'https://app.coolify.io/api/v1'
 | 
			
		||||
    description: 'Coolify Cloud API. Change the host to your own instance if you are self-hosting.'
 | 
			
		||||
paths:
 | 
			
		||||
  /applications:
 | 
			
		||||
    get:
 | 
			
		||||
@@ -29,225 +30,6 @@ paths:
 | 
			
		||||
      security:
 | 
			
		||||
        -
 | 
			
		||||
          bearerAuth: []
 | 
			
		||||
    patch:
 | 
			
		||||
      tags:
 | 
			
		||||
        - Applications
 | 
			
		||||
      summary: Update
 | 
			
		||||
      description: 'Update application by UUID.'
 | 
			
		||||
      operationId: ff28a22d25b1f658c40b54d2073abbca
 | 
			
		||||
      requestBody:
 | 
			
		||||
        description: 'Application updated.'
 | 
			
		||||
        required: true
 | 
			
		||||
        content:
 | 
			
		||||
          application/json:
 | 
			
		||||
            schema:
 | 
			
		||||
              properties:
 | 
			
		||||
                project_uuid:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The project UUID.'
 | 
			
		||||
                server_uuid:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The server UUID.'
 | 
			
		||||
                environment_name:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The environment name.'
 | 
			
		||||
                github_app_uuid:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Github App UUID.'
 | 
			
		||||
                git_repository:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The git repository URL.'
 | 
			
		||||
                git_branch:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The git branch.'
 | 
			
		||||
                ports_exposes:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The ports to expose.'
 | 
			
		||||
                destination_uuid:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The destination UUID.'
 | 
			
		||||
                build_pack:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  enum: [nixpacks, static, dockerfile, dockercompose]
 | 
			
		||||
                  description: 'The build pack type.'
 | 
			
		||||
                name:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The application name.'
 | 
			
		||||
                description:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The application description.'
 | 
			
		||||
                domains:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The application domains.'
 | 
			
		||||
                git_commit_sha:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The git commit SHA.'
 | 
			
		||||
                docker_registry_image_name:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The docker registry image name.'
 | 
			
		||||
                docker_registry_image_tag:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The docker registry image tag.'
 | 
			
		||||
                is_static:
 | 
			
		||||
                  type: boolean
 | 
			
		||||
                  description: 'The flag to indicate if the application is static.'
 | 
			
		||||
                install_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The install command.'
 | 
			
		||||
                build_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The build command.'
 | 
			
		||||
                start_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The start command.'
 | 
			
		||||
                ports_mappings:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The ports mappings.'
 | 
			
		||||
                base_directory:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The base directory for all commands.'
 | 
			
		||||
                publish_directory:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The publish directory.'
 | 
			
		||||
                health_check_enabled:
 | 
			
		||||
                  type: boolean
 | 
			
		||||
                  description: 'Health check enabled.'
 | 
			
		||||
                health_check_path:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Health check path.'
 | 
			
		||||
                health_check_port:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  nullable: true
 | 
			
		||||
                  description: 'Health check port.'
 | 
			
		||||
                health_check_host:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  nullable: true
 | 
			
		||||
                  description: 'Health check host.'
 | 
			
		||||
                health_check_method:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Health check method.'
 | 
			
		||||
                health_check_return_code:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Health check return code.'
 | 
			
		||||
                health_check_scheme:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Health check scheme.'
 | 
			
		||||
                health_check_response_text:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  nullable: true
 | 
			
		||||
                  description: 'Health check response text.'
 | 
			
		||||
                health_check_interval:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Health check interval in seconds.'
 | 
			
		||||
                health_check_timeout:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Health check timeout in seconds.'
 | 
			
		||||
                health_check_retries:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Health check retries count.'
 | 
			
		||||
                health_check_start_period:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Health check start period in seconds.'
 | 
			
		||||
                limits_memory:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Memory limit.'
 | 
			
		||||
                limits_memory_swap:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Memory swap limit.'
 | 
			
		||||
                limits_memory_swappiness:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Memory swappiness.'
 | 
			
		||||
                limits_memory_reservation:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Memory reservation.'
 | 
			
		||||
                limits_cpus:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'CPU limit.'
 | 
			
		||||
                limits_cpuset:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  nullable: true
 | 
			
		||||
                  description: 'CPU set.'
 | 
			
		||||
                limits_cpu_shares:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'CPU shares.'
 | 
			
		||||
                custom_labels:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Custom labels.'
 | 
			
		||||
                custom_docker_run_options:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Custom docker run options.'
 | 
			
		||||
                post_deployment_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Post deployment command.'
 | 
			
		||||
                post_deployment_command_container:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Post deployment command container.'
 | 
			
		||||
                pre_deployment_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Pre deployment command.'
 | 
			
		||||
                pre_deployment_command_container:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Pre deployment command container.'
 | 
			
		||||
                manual_webhook_secret_github:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Manual webhook secret for Github.'
 | 
			
		||||
                manual_webhook_secret_gitlab:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Manual webhook secret for Gitlab.'
 | 
			
		||||
                manual_webhook_secret_bitbucket:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Manual webhook secret for Bitbucket.'
 | 
			
		||||
                manual_webhook_secret_gitea:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Manual webhook secret for Gitea.'
 | 
			
		||||
                redirect:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  nullable: true
 | 
			
		||||
                  description: 'How to set redirect with Traefik / Caddy. www<->non-www.'
 | 
			
		||||
                  enum: [www, non-www, both]
 | 
			
		||||
                instant_deploy:
 | 
			
		||||
                  type: boolean
 | 
			
		||||
                  description: 'The flag to indicate if the application should be deployed instantly.'
 | 
			
		||||
                dockerfile:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Dockerfile content.'
 | 
			
		||||
                docker_compose_location:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Docker Compose location.'
 | 
			
		||||
                docker_compose_raw:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Docker Compose raw content.'
 | 
			
		||||
                docker_compose_custom_start_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Docker Compose custom start command.'
 | 
			
		||||
                docker_compose_custom_build_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Docker Compose custom build command.'
 | 
			
		||||
                docker_compose_domains:
 | 
			
		||||
                  type: array
 | 
			
		||||
                  description: 'The Docker Compose domains.'
 | 
			
		||||
                watch_paths:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The watch paths.'
 | 
			
		||||
              type: object
 | 
			
		||||
      responses:
 | 
			
		||||
        '200':
 | 
			
		||||
          description: 'Application updated.'
 | 
			
		||||
          content:
 | 
			
		||||
            application/json:
 | 
			
		||||
              schema:
 | 
			
		||||
                properties:
 | 
			
		||||
                  uuid: { type: string }
 | 
			
		||||
                type: object
 | 
			
		||||
        '401':
 | 
			
		||||
          $ref: '#/components/responses/401'
 | 
			
		||||
        '400':
 | 
			
		||||
          $ref: '#/components/responses/400'
 | 
			
		||||
        '404':
 | 
			
		||||
          $ref: '#/components/responses/404'
 | 
			
		||||
      security:
 | 
			
		||||
        -
 | 
			
		||||
          bearerAuth: []
 | 
			
		||||
  /applications/public:
 | 
			
		||||
    post:
 | 
			
		||||
      tags:
 | 
			
		||||
@@ -1369,6 +1151,225 @@ paths:
 | 
			
		||||
      security:
 | 
			
		||||
        -
 | 
			
		||||
          bearerAuth: []
 | 
			
		||||
    patch:
 | 
			
		||||
      tags:
 | 
			
		||||
        - Applications
 | 
			
		||||
      summary: Update
 | 
			
		||||
      description: 'Update application by UUID.'
 | 
			
		||||
      operationId: 62a3b1775e8cba5d39a236ebb69830b7
 | 
			
		||||
      requestBody:
 | 
			
		||||
        description: 'Application updated.'
 | 
			
		||||
        required: true
 | 
			
		||||
        content:
 | 
			
		||||
          application/json:
 | 
			
		||||
            schema:
 | 
			
		||||
              properties:
 | 
			
		||||
                project_uuid:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The project UUID.'
 | 
			
		||||
                server_uuid:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The server UUID.'
 | 
			
		||||
                environment_name:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The environment name.'
 | 
			
		||||
                github_app_uuid:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Github App UUID.'
 | 
			
		||||
                git_repository:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The git repository URL.'
 | 
			
		||||
                git_branch:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The git branch.'
 | 
			
		||||
                ports_exposes:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The ports to expose.'
 | 
			
		||||
                destination_uuid:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The destination UUID.'
 | 
			
		||||
                build_pack:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  enum: [nixpacks, static, dockerfile, dockercompose]
 | 
			
		||||
                  description: 'The build pack type.'
 | 
			
		||||
                name:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The application name.'
 | 
			
		||||
                description:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The application description.'
 | 
			
		||||
                domains:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The application domains.'
 | 
			
		||||
                git_commit_sha:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The git commit SHA.'
 | 
			
		||||
                docker_registry_image_name:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The docker registry image name.'
 | 
			
		||||
                docker_registry_image_tag:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The docker registry image tag.'
 | 
			
		||||
                is_static:
 | 
			
		||||
                  type: boolean
 | 
			
		||||
                  description: 'The flag to indicate if the application is static.'
 | 
			
		||||
                install_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The install command.'
 | 
			
		||||
                build_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The build command.'
 | 
			
		||||
                start_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The start command.'
 | 
			
		||||
                ports_mappings:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The ports mappings.'
 | 
			
		||||
                base_directory:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The base directory for all commands.'
 | 
			
		||||
                publish_directory:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The publish directory.'
 | 
			
		||||
                health_check_enabled:
 | 
			
		||||
                  type: boolean
 | 
			
		||||
                  description: 'Health check enabled.'
 | 
			
		||||
                health_check_path:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Health check path.'
 | 
			
		||||
                health_check_port:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  nullable: true
 | 
			
		||||
                  description: 'Health check port.'
 | 
			
		||||
                health_check_host:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  nullable: true
 | 
			
		||||
                  description: 'Health check host.'
 | 
			
		||||
                health_check_method:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Health check method.'
 | 
			
		||||
                health_check_return_code:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Health check return code.'
 | 
			
		||||
                health_check_scheme:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Health check scheme.'
 | 
			
		||||
                health_check_response_text:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  nullable: true
 | 
			
		||||
                  description: 'Health check response text.'
 | 
			
		||||
                health_check_interval:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Health check interval in seconds.'
 | 
			
		||||
                health_check_timeout:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Health check timeout in seconds.'
 | 
			
		||||
                health_check_retries:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Health check retries count.'
 | 
			
		||||
                health_check_start_period:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Health check start period in seconds.'
 | 
			
		||||
                limits_memory:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Memory limit.'
 | 
			
		||||
                limits_memory_swap:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Memory swap limit.'
 | 
			
		||||
                limits_memory_swappiness:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'Memory swappiness.'
 | 
			
		||||
                limits_memory_reservation:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Memory reservation.'
 | 
			
		||||
                limits_cpus:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'CPU limit.'
 | 
			
		||||
                limits_cpuset:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  nullable: true
 | 
			
		||||
                  description: 'CPU set.'
 | 
			
		||||
                limits_cpu_shares:
 | 
			
		||||
                  type: integer
 | 
			
		||||
                  description: 'CPU shares.'
 | 
			
		||||
                custom_labels:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Custom labels.'
 | 
			
		||||
                custom_docker_run_options:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Custom docker run options.'
 | 
			
		||||
                post_deployment_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Post deployment command.'
 | 
			
		||||
                post_deployment_command_container:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Post deployment command container.'
 | 
			
		||||
                pre_deployment_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Pre deployment command.'
 | 
			
		||||
                pre_deployment_command_container:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Pre deployment command container.'
 | 
			
		||||
                manual_webhook_secret_github:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Manual webhook secret for Github.'
 | 
			
		||||
                manual_webhook_secret_gitlab:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Manual webhook secret for Gitlab.'
 | 
			
		||||
                manual_webhook_secret_bitbucket:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Manual webhook secret for Bitbucket.'
 | 
			
		||||
                manual_webhook_secret_gitea:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'Manual webhook secret for Gitea.'
 | 
			
		||||
                redirect:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  nullable: true
 | 
			
		||||
                  description: 'How to set redirect with Traefik / Caddy. www<->non-www.'
 | 
			
		||||
                  enum: [www, non-www, both]
 | 
			
		||||
                instant_deploy:
 | 
			
		||||
                  type: boolean
 | 
			
		||||
                  description: 'The flag to indicate if the application should be deployed instantly.'
 | 
			
		||||
                dockerfile:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Dockerfile content.'
 | 
			
		||||
                docker_compose_location:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Docker Compose location.'
 | 
			
		||||
                docker_compose_raw:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Docker Compose raw content.'
 | 
			
		||||
                docker_compose_custom_start_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Docker Compose custom start command.'
 | 
			
		||||
                docker_compose_custom_build_command:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The Docker Compose custom build command.'
 | 
			
		||||
                docker_compose_domains:
 | 
			
		||||
                  type: array
 | 
			
		||||
                  description: 'The Docker Compose domains.'
 | 
			
		||||
                watch_paths:
 | 
			
		||||
                  type: string
 | 
			
		||||
                  description: 'The watch paths.'
 | 
			
		||||
              type: object
 | 
			
		||||
      responses:
 | 
			
		||||
        '200':
 | 
			
		||||
          description: 'Application updated.'
 | 
			
		||||
          content:
 | 
			
		||||
            application/json:
 | 
			
		||||
              schema:
 | 
			
		||||
                properties:
 | 
			
		||||
                  uuid: { type: string }
 | 
			
		||||
                type: object
 | 
			
		||||
        '401':
 | 
			
		||||
          $ref: '#/components/responses/401'
 | 
			
		||||
        '400':
 | 
			
		||||
          $ref: '#/components/responses/400'
 | 
			
		||||
        '404':
 | 
			
		||||
          $ref: '#/components/responses/404'
 | 
			
		||||
      security:
 | 
			
		||||
        -
 | 
			
		||||
          bearerAuth: []
 | 
			
		||||
  '/applications/{uuid}/envs':
 | 
			
		||||
    get:
 | 
			
		||||
      tags:
 | 
			
		||||
@@ -2833,7 +2834,7 @@ paths:
 | 
			
		||||
          description: 'Deployment Uuid'
 | 
			
		||||
          required: true
 | 
			
		||||
          schema:
 | 
			
		||||
            type: integer
 | 
			
		||||
            type: string
 | 
			
		||||
      responses:
 | 
			
		||||
        '200':
 | 
			
		||||
          description: 'Get deployment by UUID.'
 | 
			
		||||
@@ -3062,7 +3063,7 @@ paths:
 | 
			
		||||
          description: 'Project UUID'
 | 
			
		||||
          required: true
 | 
			
		||||
          schema:
 | 
			
		||||
            type: integer
 | 
			
		||||
            type: string
 | 
			
		||||
      responses:
 | 
			
		||||
        '200':
 | 
			
		||||
          description: 'Project details'
 | 
			
		||||
@@ -3166,7 +3167,7 @@ paths:
 | 
			
		||||
          description: 'Project UUID'
 | 
			
		||||
          required: true
 | 
			
		||||
          schema:
 | 
			
		||||
            type: integer
 | 
			
		||||
            type: string
 | 
			
		||||
        -
 | 
			
		||||
          name: environment_name
 | 
			
		||||
          in: path
 | 
			
		||||
@@ -3325,7 +3326,7 @@ paths:
 | 
			
		||||
          description: 'Private Key Uuid'
 | 
			
		||||
          required: true
 | 
			
		||||
          schema:
 | 
			
		||||
            type: integer
 | 
			
		||||
            type: string
 | 
			
		||||
      responses:
 | 
			
		||||
        '200':
 | 
			
		||||
          description: 'Get all private keys.'
 | 
			
		||||
@@ -3357,7 +3358,7 @@ paths:
 | 
			
		||||
          description: 'Private Key Uuid'
 | 
			
		||||
          required: true
 | 
			
		||||
          schema:
 | 
			
		||||
            type: integer
 | 
			
		||||
            type: string
 | 
			
		||||
      responses:
 | 
			
		||||
        '200':
 | 
			
		||||
          description: 'Private Key deleted.'
 | 
			
		||||
@@ -3477,7 +3478,7 @@ paths:
 | 
			
		||||
          description: "Server's Uuid"
 | 
			
		||||
          required: true
 | 
			
		||||
          schema:
 | 
			
		||||
            type: integer
 | 
			
		||||
            type: string
 | 
			
		||||
      responses:
 | 
			
		||||
        '200':
 | 
			
		||||
          description: 'Get server by UUID'
 | 
			
		||||
@@ -3597,7 +3598,7 @@ paths:
 | 
			
		||||
          description: "Server's Uuid"
 | 
			
		||||
          required: true
 | 
			
		||||
          schema:
 | 
			
		||||
            type: integer
 | 
			
		||||
            type: string
 | 
			
		||||
      responses:
 | 
			
		||||
        '200':
 | 
			
		||||
          description: 'Get resources by server'
 | 
			
		||||
@@ -3629,7 +3630,7 @@ paths:
 | 
			
		||||
          description: "Server's Uuid"
 | 
			
		||||
          required: true
 | 
			
		||||
          schema:
 | 
			
		||||
            type: integer
 | 
			
		||||
            type: string
 | 
			
		||||
      responses:
 | 
			
		||||
        '200':
 | 
			
		||||
          description: 'Get domains by server'
 | 
			
		||||
@@ -3661,7 +3662,7 @@ paths:
 | 
			
		||||
          description: 'Server UUID'
 | 
			
		||||
          required: true
 | 
			
		||||
          schema:
 | 
			
		||||
            type: integer
 | 
			
		||||
            type: string
 | 
			
		||||
      responses:
 | 
			
		||||
        '201':
 | 
			
		||||
          description: 'Server validation started.'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								public/svgs/gitlab.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								public/svgs/gitlab.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 380"><defs><style>.cls-1{fill:#e24329;}.cls-2{fill:#fc6d26;}.cls-3{fill:#fca326;}</style></defs><g id="LOGO"><path class="cls-1" d="M282.83,170.73l-.27-.69-26.14-68.22a6.81,6.81,0,0,0-2.69-3.24,7,7,0,0,0-8,.43,7,7,0,0,0-2.32,3.52l-17.65,54H154.29l-17.65-54A6.86,6.86,0,0,0,134.32,99a7,7,0,0,0-8-.43,6.87,6.87,0,0,0-2.69,3.24L97.44,170l-.26.69a48.54,48.54,0,0,0,16.1,56.1l.09.07.24.17,39.82,29.82,19.7,14.91,12,9.06a8.07,8.07,0,0,0,9.76,0l12-9.06,19.7-14.91,40.06-30,.1-.08A48.56,48.56,0,0,0,282.83,170.73Z"/><path class="cls-2" d="M282.83,170.73l-.27-.69a88.3,88.3,0,0,0-35.15,15.8L190,229.25c19.55,14.79,36.57,27.64,36.57,27.64l40.06-30,.1-.08A48.56,48.56,0,0,0,282.83,170.73Z"/><path class="cls-3" d="M153.43,256.89l19.7,14.91,12,9.06a8.07,8.07,0,0,0,9.76,0l12-9.06,19.7-14.91S209.55,244,190,229.25C170.45,244,153.43,256.89,153.43,256.89Z"/><path class="cls-2" d="M132.58,185.84A88.19,88.19,0,0,0,97.44,170l-.26.69a48.54,48.54,0,0,0,16.1,56.1l.09.07.24.17,39.82,29.82s17-12.85,36.57-27.64Z"/></g></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.0 KiB  | 
@@ -1,5 +1,6 @@
 | 
			
		||||
<form wire:submit.prevent='submit' class="flex flex-col w-full gap-2">
 | 
			
		||||
    <div class="pb-2">Note: If a service has a defined port, do not delete it. <br>If you want to use your custom domain, you can add it with a port.</div>
 | 
			
		||||
    <div class="pb-2">Note: If a service has a defined port, do not delete it. <br>If you want to use your custom
 | 
			
		||||
        domain, you can add it with a port.</div>
 | 
			
		||||
    <x-forms.input placeholder="https://app.coolify.io" label="Domains" id="application.fqdn"
 | 
			
		||||
        helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io,https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. "></x-forms.input>
 | 
			
		||||
    <x-forms.button type="submit">Save</x-forms.button>
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@
 | 
			
		||||
                        Traefik
 | 
			
		||||
                    </x-forms.button>
 | 
			
		||||
                    <x-forms.button class="box" wire:click="select_proxy('CADDY')">
 | 
			
		||||
                        Caddy (experimental)
 | 
			
		||||
                        Caddy
 | 
			
		||||
                    </x-forms.button>
 | 
			
		||||
                    <x-forms.button disabled class="box">
 | 
			
		||||
                        Nginx
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,8 @@ services:
 | 
			
		||||
      - GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
 | 
			
		||||
      - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
 | 
			
		||||
      - ASSET_PREFIX_URL=${ASSET_PREFIX_URL}
 | 
			
		||||
      - CRON_SECRET=$SERVICE_BASE64_64_CRON
 | 
			
		||||
      - ENCRYPTION_KEY=$SERVICE_BASE64_64_ENCRYPTION
 | 
			
		||||
    volumes:
 | 
			
		||||
      - formbricks-uploads:/apps/web/uploads/
 | 
			
		||||
    depends_on:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								templates/compose/gitlab.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								templates/compose/gitlab.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
# documentation: https://docs.gitlab.com/ee/install/docker.html
 | 
			
		||||
# slogan: The all-in-one DevOps platform for seamless collaboration and continuous delivery.
 | 
			
		||||
# tags: gitlab, devops, continuousintegration, continuousdelivery, versioncontrol, collaboration, ci/cd, sourcecodemanagement, automation, codereview, agiledevelopment, projectmanagement, opensource, repositoryhosting, pipelineautomation, git, softwaredevelopment, issuetracking, teamcollaboration, deploymentautomation, securityintegration
 | 
			
		||||
# logo: svgs/gitlab.svg
 | 
			
		||||
# port: 80
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  gitlab:
 | 
			
		||||
    image: "gitlab/gitlab-ce:latest"
 | 
			
		||||
    environment:
 | 
			
		||||
      - SERVICE_FQDN_GITLAB_80
 | 
			
		||||
      - TZ=${TZ:-UTC}
 | 
			
		||||
      - GITLAB_TIMEZONE=${GITLAB_TIMEZONE:-UTC}
 | 
			
		||||
      - GITLAB_ROOT_PASSWORD=$SERVICE_PASSWORD_GITLAB
 | 
			
		||||
      - EXTERNAL_URL=$SERVICE_FQDN_GITLAB
 | 
			
		||||
      - GITLAB_HOST=$SERVICE_FQDN_GITLAB
 | 
			
		||||
      - GITLAB_SMTP_ENABLE=${GITLAB_SMTP_ENABLE:-false}
 | 
			
		||||
      - GITLAB_SMTP_ADDRESS=$GITLAB_SMTP_ADDRESS
 | 
			
		||||
      - GITLAB_SMTP_PORT=${GITLAB_SMTP_PORT:-587}
 | 
			
		||||
      - GITLAB_SMTP_USER_NAME=${GITLAB_SMTP_USER_NAME}
 | 
			
		||||
      - GITLAB_SMTP_PASSWORD=${GITLAB_SMTP_PASSWORD}
 | 
			
		||||
      - GITLAB_SMTP_DOMAIN=${GITLAB_SMTP_DOMAIN}
 | 
			
		||||
      - GITLAB_STARTTLS_AUTO=${GITLAB_STARTTLS_AUTO:-true}
 | 
			
		||||
      - GITLAB_SMTP_TLS=${GITLAB_SMTP_TLS:-false}
 | 
			
		||||
      - GITLAB_EMAIL_FROM=${GITLAB_EMAIL_FROM}
 | 
			
		||||
      - GITLAB_EMAIL_REPLY_TO=$GITLAB_EMAIL_REPLY_TO
 | 
			
		||||
      - 'GITLAB_OMNIBUS_CONFIG=external_url "${SERVICE_FQDN_GITLAB}"; nginx["listen_https"] = false; nginx["listen_port"] = 80; gitlab_rails["gitlab_shell_ssh_port"] = 2222; gitlab_rails["smtp_enable"] = ${GITLAB_SMTP_ENABLE}; gitlab_rails["smtp_address"] = "${GITLAB_SMTP_ADDRESS}"; gitlab_rails["smtp_port"] = ${GITLAB_SMTP_PORT}; gitlab_rails["smtp_user_name"] = "${GITLAB_SMTP_USER_NAME}"; gitlab_rails["smtp_password"] = "${GITLAB_SMTP_PASSWORD}"; gitlab_rails["smtp_domain"] = "${GITLAB_SMTP_DOMAIN}"; gitlab_rails["smtp_authentication"] = "login"; gitlab_rails["smtp_enable_starttls_auto"] = ${GITLAB_STARTTLS_AUTO}; gitlab_rails["smtp_tls"] = ${GITLAB_SMTP_TLS}; gitlab_rails["gitlab_email_from"] = "${GITLAB_EMAIL_FROM}"; gitlab_rails["gitlab_email_reply_to"] = "${GITLAB_EMAIL_REPLY_TO}";'
 | 
			
		||||
    ports:
 | 
			
		||||
      - "2222:22"
 | 
			
		||||
    volumes:
 | 
			
		||||
      - "gitlab-config:/etc/gitlab"
 | 
			
		||||
      - "gitlab-logs:/var/log/gitlab"
 | 
			
		||||
      - "gitlab-data:/var/opt/gitlab"
 | 
			
		||||
    shm_size: 256m
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "coolify": {
 | 
			
		||||
        "v4": {
 | 
			
		||||
            "version": "4.0.0-beta.319"
 | 
			
		||||
            "version": "4.0.0-beta.320"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user