diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php new file mode 100644 index 000000000..de470d39e --- /dev/null +++ b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php @@ -0,0 +1,113 @@ + 'required|url', + 'port' => 'required|numeric', + 'is_static' => 'required|boolean', + 'publish_directory' => 'nullable|string', + ]; + public function mount() + { + if (config('app.env') === 'local') { + $this->repository_url = 'https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify'; + } + $this->parameters = getParameters(); + $this->private_keys = PrivateKey::where('team_id', session('currentTeam')->id)->get(); + $this->servers = session('currentTeam')->load(['servers'])->servers; + } + public function chooseServer($server) + { + $this->chosenServer = $server; + $this->standalone_docker = StandaloneDocker::where('server_id', $server['id'])->get(); + $this->swarm_docker = SwarmDocker::where('server_id', $server['id'])->get(); + } + public function setDestination($destination_uuid, $destination_type) + { + $class = "App\Models\\{$destination_type}"; + $instance = new $class; + $this->chosenDestination = $instance::where('uuid', $destination_uuid)->first(); + } + public function instantSave() + { + if ($this->is_static) { + $this->port = 80; + $this->publish_directory = '/dist'; + } else { + $this->port = 3000; + $this->publish_directory = null; + } + } + public function setPrivateKey($private_key_id) + { + $this->private_key_id = $private_key_id; + } + public function submit() + { + $this->validate(); + $url = Url::fromString($this->repository_url); + $git_host = $url->getHost(); + $git_repository = $url->getSegment(1) . '/' . $url->getSegment(2); + $git_branch = $url->getSegment(4) ?? 'main'; + + if ($this->type === 'project') { + $project = Project::create([ + 'name' => generateRandomName(), + 'team_id' => session('currentTeam')->id, + ]); + $environment = $project->environments->first(); + } else { + $project = Project::where('uuid', $this->parameters['project_uuid'])->firstOrFail(); + $environment = $project->environments->where('name', $this->parameters['environment_name'])->firstOrFail(); + } + $application_init = [ + 'name' => generateRandomName(), + 'git_repository' => $git_repository, + 'git_branch' => $git_branch, + 'git_full_url' => "git@$git_host:$git_repository.git", + 'build_pack' => 'nixpacks', + 'ports_exposes' => $this->port, + 'publish_directory' => $this->publish_directory, + 'environment_id' => $environment->id, + 'destination_id' => $this->chosenDestination->id, + 'destination_type' => $this->chosenDestination->getMorphClass(), + 'private_key_id' => $this->private_key_id, + ]; + $application = Application::create($application_init); + $application->settings->is_static = $this->is_static; + $application->settings->save(); + + return redirect()->route('project.application.configuration', [ + 'project_uuid' => $project->uuid, + 'environment_name' => $environment->name, + 'application_uuid' => $application->uuid, + ]); + } +} diff --git a/app/Http/Livewire/Project/New/PublicGitRepository.php b/app/Http/Livewire/Project/New/PublicGitRepository.php index 22a0bca96..a8ce83b71 100644 --- a/app/Http/Livewire/Project/New/PublicGitRepository.php +++ b/app/Http/Livewire/Project/New/PublicGitRepository.php @@ -14,8 +14,8 @@ class PublicGitRepository extends Component { - public string $public_repository_url; - public int $port; + public string $repository_url; + public int $port = 3000; public string $type; public $parameters; @@ -31,7 +31,7 @@ class PublicGitRepository extends Component public null|string $publish_directory = null; protected $rules = [ - 'public_repository_url' => 'required|url', + 'repository_url' => 'required|url', 'port' => 'required|numeric', 'is_static' => 'required|boolean', 'publish_directory' => 'nullable|string', @@ -39,7 +39,7 @@ class PublicGitRepository extends Component public function mount() { if (config('app.env') === 'local') { - $this->public_repository_url = 'https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify'; + $this->repository_url = 'https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify'; $this->port = 3000; } $this->parameters = getParameters(); @@ -73,7 +73,7 @@ public function instantSave() public function submit() { $this->validate(); - $url = Url::fromString($this->public_repository_url); + $url = Url::fromString($this->repository_url); $git_host = $url->getHost(); $git_repository = $url->getSegment(1) . '/' . $url->getSegment(2); $git_branch = $url->getSegment(4) ?? 'main'; diff --git a/app/Jobs/DeployApplicationJob.php b/app/Jobs/DeployApplicationJob.php index f4a9f27d9..9d0ce017c 100644 --- a/app/Jobs/DeployApplicationJob.php +++ b/app/Jobs/DeployApplicationJob.php @@ -107,7 +107,10 @@ public function handle(): void { try { $coolify_instance_settings = InstanceSettings::find(0); - $this->source = $this->application->source->getMorphClass()::where('id', $this->application->source->id)->first(); + $deployment_type = $this->application->deploymentType(); + if ($this->application->deploymentType() === 'source') { + $this->source = $this->application->source->getMorphClass()::where('id', $this->application->source->id)->first(); + } // Get Wildcard Domain $project_wildcard_domain = data_get($this->application, 'environment.project.settings.wildcard_domain'); @@ -443,29 +446,19 @@ private function setGitImportSettings($git_clone_command) } private function gitImport() { - $source_html_url = data_get($this->application, 'source.html_url'); - $url = parse_url(filter_var($source_html_url, FILTER_SANITIZE_URL)); - $source_html_url_host = $url['host']; - $source_html_url_scheme = $url['scheme']; - $git_clone_command = "git clone -q -b {$this->application->git_branch}"; - if ($this->source->getMorphClass() == 'App\Models\GithubApp') { - if ($this->source->is_public) { - $git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$this->application->git_repository} {$this->workdir}"; - $git_clone_command = $this->setGitImportSettings($git_clone_command); - return [ - $this->execute_in_builder($git_clone_command) - ]; - } else { - if (!$this->source->app_id) { - $private_key = base64_encode($this->source->privateKey->private_key); - $git_clone_command = "GIT_SSH_COMMAND=\"ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} git@$source_html_url_host:{$this->application->git_repository}.git {$this->workdir}"; + if ($this->application->deploymentType() === 'source') { + $source_html_url = data_get($this->application, 'source.html_url'); + $url = parse_url(filter_var($source_html_url, FILTER_SANITIZE_URL)); + $source_html_url_host = $url['host']; + $source_html_url_scheme = $url['scheme']; + + if ($this->source->getMorphClass() == 'App\Models\GithubApp') { + if ($this->source->is_public) { + $git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$this->application->git_repository} {$this->workdir}"; $git_clone_command = $this->setGitImportSettings($git_clone_command); return [ - $this->execute_in_builder("mkdir -p /root/.ssh"), - $this->execute_in_builder("echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"), - $this->execute_in_builder("chmod 600 /root/.ssh/id_rsa"), $this->execute_in_builder($git_clone_command) ]; } else { @@ -476,6 +469,17 @@ private function gitImport() } } } + if ($this->application->deploymentType() === 'deploy_key') { + $private_key = base64_encode($this->application->private_key->private_key); + $git_clone_command = "GIT_SSH_COMMAND=\"ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_full_url} {$this->workdir}"; + $git_clone_command = $this->setGitImportSettings($git_clone_command); + return [ + $this->execute_in_builder("mkdir -p /root/.ssh"), + $this->execute_in_builder("echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"), + $this->execute_in_builder("chmod 600 /root/.ssh/id_rsa"), + $this->execute_in_builder($git_clone_command) + ]; + } } private function nixpacks_build_cmd() { diff --git a/app/Models/Application.php b/app/Models/Application.php index c1a0576ed..2da683512 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -28,6 +28,7 @@ protected static function booted() 'description', 'git_repository', 'git_branch', + 'git_full_url', 'build_pack', 'environment_id', 'destination_id', @@ -37,6 +38,7 @@ protected static function booted() 'ports_mappings', 'ports_exposes', 'publish_directory', + 'private_key_id' ]; public function publishDirectory(): Attribute { @@ -113,6 +115,10 @@ public function nixpacks_environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('key', 'like', 'NIXPACKS_%'); } + public function private_key() + { + return $this->belongsTo(PrivateKey::class); + } public function environment() { return $this->belongsTo(Environment::class); @@ -149,4 +155,14 @@ public function isDeployable(): bool } return false; } + public function deploymentType() + { + if (data_get($this, 'source')) { + return 'source'; + } + if (data_get($this, 'private_key_id')) { + return 'deploy_key'; + } + throw new \Exception('No deployment type found'); + } } diff --git a/database/migrations/2023_03_27_081716_create_applications_table.php b/database/migrations/2023_03_27_081716_create_applications_table.php index 3e5e4ecb0..f79dd6f4e 100644 --- a/database/migrations/2023_03_27_081716_create_applications_table.php +++ b/database/migrations/2023_03_27_081716_create_applications_table.php @@ -23,6 +23,7 @@ public function up(): void $table->string('git_repository'); $table->string('git_branch'); $table->string('git_commit_sha')->default('HEAD'); + $table->string('git_full_url')->nullable(); $table->string('docker_registry_image_name')->nullable(); $table->string('docker_registry_image_tag')->nullable(); @@ -55,8 +56,9 @@ public function up(): void $table->string('status')->default('exited'); $table->nullableMorphs('destination'); - $table->morphs('source'); + $table->nullableMorphs('source'); + $table->foreignId('private_key_id')->nullable(); $table->foreignId('environment_id'); $table->timestamps(); }); diff --git a/resources/views/livewire/project/new/github-private-repository-deploy-key.blade.php b/resources/views/livewire/project/new/github-private-repository-deploy-key.blade.php new file mode 100644 index 000000000..c2a795f05 --- /dev/null +++ b/resources/views/livewire/project/new/github-private-repository-deploy-key.blade.php @@ -0,0 +1,84 @@ +
Did you forget to add a destination on the server?
+ @endforelse + + @isset($chosenServer) + @if ($standalone_docker->count() > 0 || $swarm_docker->count() > 0) +