diff --git a/.env.example b/.env.example index dd4f03d08..f24762fab 100644 --- a/.env.example +++ b/.env.example @@ -8,7 +8,6 @@ GROUPID= ############################################################################################################ APP_NAME=Laravel -APP_SERVICE=php APP_ENV=local APP_KEY= APP_DEBUG=true diff --git a/app/Http/Livewire/DemoDeployApplication.php b/app/Http/Livewire/DemoDeployApplication.php new file mode 100644 index 000000000..7b7308dd2 --- /dev/null +++ b/app/Http/Livewire/DemoDeployApplication.php @@ -0,0 +1,71 @@ +isKeepAliveOn = true; + + $this->coolify_instance_settings = CoolifyInstanceSettings::find(1); + $this->application = Application::where('uuid', $this->application_uuid)->first(); + $this->destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first(); + $project_wildcard_domain = data_get($this->application, 'environment.project.settings.wildcard_domain'); + $global_wildcard_domain = data_get($this->coolify_instance_settings, 'wildcard_domain'); + $this->wildcard_domain = $project_wildcard_domain ?? $global_wildcard_domain ?? null; + + $source = $this->application->source->getMorphClass()::where('id', $this->application->source->id)->first(); + $deployment_id = new Cuid2(10); + + $workdir = $this->get_workdir('application', $this->application->uuid, $deployment_id); + + $command[] = "echo 'Starting deployment of {$this->application->name} ({$this->application->uuid})'"; + $command[] = 'mkdirs -p ' . $workdir; + $command[] = "git clone -b {$this->application->git_branch} {$source->html_url}/{$this->application->git_repository}.git {$workdir}"; + + if (!file_exists($workdir) && $workdir != "/") { + $command[] = "echo 'Removing {$workdir}'"; + $command[] = "rm -rf {$workdir}"; + } + $this->activity = remoteProcess(implode("\n", $command), $this->destination->server->name); + + Deployment::create([ + 'uuid' => $deployment_id, + 'type_id' => $this->application->id, + 'type_type' => Application::class, + 'activity_log_id' => $this->activity->id, + ]); + } + public function polling() + { + $this->activity?->refresh(); + if (data_get($this->activity, 'properties.exitCode') !== null) { + $this->isKeepAliveOn = false; + } + } + public function render() + { + return view('livewire.demo-deploy-application'); + } +} diff --git a/app/Http/Livewire/RunCommand.php b/app/Http/Livewire/RunCommand.php index f29b5a29d..3e4db9e97 100755 --- a/app/Http/Livewire/RunCommand.php +++ b/app/Http/Livewire/RunCommand.php @@ -15,13 +15,15 @@ class RunCommand extends Component public $command = 'ls'; - public $server = 'testing-host'; + public $server; public $servers = []; public function mount() { $this->servers = Server::all()->pluck('name')->toArray(); + $this->server = $this->servers[0]; + } public function render() { diff --git a/app/Models/Application.php b/app/Models/Application.php index 8f8c4391b..78d3d9c96 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -8,6 +8,10 @@ public function environment() { return $this->belongsTo(Environment::class); } + public function settings() + { + return $this->hasOne(ApplicationSetting::class); + } public function destination() { return $this->morphTo(); @@ -16,4 +20,8 @@ public function source() { return $this->morphTo(); } + public function deployments() + { + return $this->morphMany(Deployment::class, 'type'); + } } diff --git a/app/Models/ApplicationSetting.php b/app/Models/ApplicationSetting.php new file mode 100644 index 000000000..d5f9b6f4e --- /dev/null +++ b/app/Models/ApplicationSetting.php @@ -0,0 +1,9 @@ +morphTo(); } + public function deployments() + { + return $this->morphMany(Deployment::class, 'type'); + } } diff --git a/app/Models/Deployment.php b/app/Models/Deployment.php new file mode 100644 index 000000000..c8751e1fe --- /dev/null +++ b/app/Models/Deployment.php @@ -0,0 +1,24 @@ +morphTo(); + } + public function activity() + { + return $this->belongsTo(Activity::class, 'activity_log_id'); + } +} diff --git a/app/Models/Environment.php b/app/Models/Environment.php index 86e784ef2..29f34208b 100644 --- a/app/Models/Environment.php +++ b/app/Models/Environment.php @@ -4,6 +4,10 @@ class Environment extends BaseModel { + public function project() + { + return $this->belongsTo(Project::class); + } public function applications() { return $this->hasMany(Application::class); diff --git a/app/Models/StandaloneDocker.php b/app/Models/StandaloneDocker.php index 5d6f8ef4e..05724fc54 100644 --- a/app/Models/StandaloneDocker.php +++ b/app/Models/StandaloneDocker.php @@ -8,4 +8,8 @@ public function applications() { return $this->morphMany(Application::class, 'destination'); } + public function server() + { + return $this->belongsTo(Server::class); + } } diff --git a/app/Traits/Shared.php b/app/Traits/Shared.php new file mode 100644 index 000000000..c6884a7a0 --- /dev/null +++ b/app/Traits/Shared.php @@ -0,0 +1,14 @@ +team_id); - $temp_file = 'id.rsa_'.'root'.'@'.$found_server->ip; + $temp_file = 'id.rsa_' . 'root' . '@' . $found_server->ip; Storage::disk('local')->put($temp_file, $found_server->privateKey->private_key, 'private'); - $private_key_location = '/var/www/html/storage/app/'.$temp_file; + $private_key_location = '/var/www/html/storage/app/' . $temp_file; return resolve(DispatchRemoteProcess::class, [ 'remoteProcessArgs' => new RemoteProcessArgs( destination: $found_server->ip, private_key_location: $private_key_location, - command: $command, + command: <<port, user: $found_server->user, ), ])(); } - function checkServer(string $destination){ + function checkServer(string $destination) + { // @TODO: Use UUID instead of name $found_server = Server::where('name', $destination)->first(); if (!$found_server) { @@ -41,11 +44,11 @@ function checkServer(string $destination){ }; return $found_server; } - function checkTeam(string $team_id){ + function checkTeam(string $team_id) + { $found_team = auth()->user()->teams->pluck('id')->contains($team_id); if (!$found_team) { throw new \RuntimeException('You do not have access to this server.'); } - } } diff --git a/database/migrations/2023_03_20_112813_create_coolify_instance_settings_table.php b/database/migrations/2023_03_20_112813_create_coolify_instance_settings_table.php new file mode 100644 index 000000000..7c81fb26b --- /dev/null +++ b/database/migrations/2023_03_20_112813_create_coolify_instance_settings_table.php @@ -0,0 +1,41 @@ +id(); + $table->string('fqdn')->nullable(); + $table->string('wildcard_domain')->nullable(); + $table->string('redirect_url')->nullable(); + // $table->string('preview_domain_separator')->default('.'); + $table->integer('public_port_min')->default(9000); + $table->integer('public_port_max')->default(9100); + // $table->string('custom_dns_servers')->default('1.1.1.1,8.8.8.8'); + + $table->boolean('do_not_track')->default(false); + + $table->boolean('is_auto_update_enabled')->default(true); + // $table->boolean('is_dns_check_enabled')->default(true); + $table->boolean('is_registration_enabled')->default(true); + $table->boolean('is_https_forced')->default(true); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('coolify_instance_settings'); + } +}; 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 5e86f09ce..57515e4fc 100644 --- a/database/migrations/2023_03_27_081716_create_applications_table.php +++ b/database/migrations/2023_03_27_081716_create_applications_table.php @@ -16,8 +16,47 @@ public function up(): void $table->string('uuid')->unique(); $table->string('name'); + $table->string('fqdn')->unique()->nullable(); + $table->string('config_hash')->nullable(); + + $table->string('git_repository'); + $table->string('git_branch'); + $table->string('git_commit_sha')->nullable(); + + $table->string('docker_registry_image_name')->nullable(); + $table->string('docker_registry_image_tag')->nullable(); + + $table->string('build_pack'); + $table->string('base_image')->nullable(); + $table->string('build_image')->nullable(); + + $table->string('install_command')->nullable(); + $table->string('build_command')->nullable(); + $table->string('start_command')->nullable(); + + $table->string('ports_exposes'); + $table->string('ports_mappings')->nullable(); + + $table->string('base_directory')->default('/'); + $table->string('publish_directory')->nullable(); + + $table->string('health_check_path')->nullable(); + $table->string('health_check_port')->nullable(); + $table->string('health_check_host')->default('localhost'); + $table->string('health_check_method')->default('GET'); + $table->integer('health_check_return_code')->default(200); + $table->string('health_check_scheme')->default('http'); + $table->string('health_check_response_text')->nullable(); + $table->integer('health_check_interval')->default(5); + $table->integer('health_check_timeout')->default(5); + $table->integer('health_check_retries')->default(10); + $table->integer('health_check_start_period')->default(5); + + $table->string('status')->default('killed'); + $table->morphs('destination'); $table->morphs('source'); + $table->foreignId('environment_id'); $table->timestamps(); diff --git a/database/migrations/2023_03_27_081717_create_application_settings_table.php b/database/migrations/2023_03_27_081717_create_application_settings_table.php new file mode 100644 index 000000000..dbb94446f --- /dev/null +++ b/database/migrations/2023_03_27_081717_create_application_settings_table.php @@ -0,0 +1,37 @@ +id(); + $table->boolean('is_git_submodules_allowed')->default(true); + $table->boolean('is_git_lfs_allowed')->default(true); + $table->boolean('is_auto_deploy')->default(true); + $table->boolean('is_dual_cert')->default(false); + $table->boolean('is_debug')->default(false); + $table->boolean('is_previews')->default(false); + $table->boolean('is_bot')->default(false); + $table->boolean('is_custom_ssl')->default(false); + $table->boolean('is_http2')->default(false); + $table->foreignId('application_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('application_settings'); + } +}; diff --git a/database/migrations/2023_03_27_083622_create_deployments_table.php b/database/migrations/2023_03_27_083622_create_deployments_table.php new file mode 100644 index 000000000..8a0becc33 --- /dev/null +++ b/database/migrations/2023_03_27_083622_create_deployments_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('uuid')->unique(); + $table->morphs('type'); + $table->foreignId('activity_log_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('deployments'); + } +}; diff --git a/database/seeders/ApplicationSeeder.php b/database/seeders/ApplicationSeeder.php index 6436edeef..91b954834 100644 --- a/database/seeders/ApplicationSeeder.php +++ b/database/seeders/ApplicationSeeder.php @@ -3,6 +3,7 @@ namespace Database\Seeders; use App\Models\Application; +use App\Models\ApplicationSetting; use App\Models\Environment; use App\Models\GithubApp; use App\Models\StandaloneDocker; @@ -24,20 +25,25 @@ public function run(): void Application::create([ 'id' => 1, 'name' => 'My first application', + 'git_repository' => 'coollabsio/coolify-examples', + 'git_branch' => 'nodejs-fastify', + 'build_pack' => 'nixpacks', + 'ports_exposes' => '3000', + 'ports_mappings' => '3000:3000,3010:3001', 'environment_id' => $environment_1->id, 'destination_id' => $standalone_docker_1->id, 'destination_type' => StandaloneDocker::class, 'source_id' => $github_public_source->id, 'source_type' => GithubApp::class, ]); - Application::create([ - 'id' => 2, - 'name' => 'My second application (Swarm)', - 'environment_id' => $environment_1->id, - 'destination_id' => $swarm_docker_1->id, - 'destination_type' => SwarmDocker::class, - 'source_id' => $github_public_source->id, - 'source_type' => GithubApp::class, - ]); + // Application::create([ + // 'id' => 2, + // 'name' => 'My second application (Swarm)', + // 'environment_id' => $environment_1->id, + // 'destination_id' => $swarm_docker_1->id, + // 'destination_type' => SwarmDocker::class, + // 'source_id' => $github_public_source->id, + // 'source_type' => GithubApp::class, + // ]); } } diff --git a/database/seeders/ApplicationSettingsSeeder.php b/database/seeders/ApplicationSettingsSeeder.php new file mode 100644 index 000000000..760306b07 --- /dev/null +++ b/database/seeders/ApplicationSettingsSeeder.php @@ -0,0 +1,26 @@ + 1, + 'application_id' => $application_1->id, + ]); + } +} diff --git a/database/seeders/CoolifyInstanceSettingsSeeder.php b/database/seeders/CoolifyInstanceSettingsSeeder.php new file mode 100644 index 000000000..8f5625d60 --- /dev/null +++ b/database/seeders/CoolifyInstanceSettingsSeeder.php @@ -0,0 +1,28 @@ + 1, + 'wildcard_domain' => 'coolify.io', + 'is_https_forced' => false, + 'is_registration_enabled' => true, + ]); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index c2bf8ac21..00797ca1c 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -9,6 +9,7 @@ class DatabaseSeeder extends Seeder public function run(): void { $this->call([ + CoolifyInstanceSettingsSeeder::class, UserSeeder::class, TeamSeeder::class, PrivateKeySeeder::class, @@ -22,6 +23,7 @@ public function run(): void GithubAppSeeder::class, GitlabAppSeeder::class, ApplicationSeeder::class, + ApplicationSettingsSeeder::class, DBSeeder::class, ServiceSeeder::class, ]); diff --git a/database/seeders/ServerSeeder.php b/database/seeders/ServerSeeder.php index 28f4e42fa..f40912b64 100644 --- a/database/seeders/ServerSeeder.php +++ b/database/seeders/ServerSeeder.php @@ -5,9 +5,7 @@ use App\Models\PrivateKey; use App\Models\Server; use App\Models\Team; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; -use Illuminate\Support\Facades\DB; class ServerSeeder extends Seeder { @@ -18,9 +16,10 @@ public function run(): void { $root_team = Team::find(1); $private_key_1 = PrivateKey::find(1); + Server::create([ 'id' => 1, - 'name' => "testing-host", + 'name' => "testing-local-docker-container", 'description' => "This is a test docker container", 'ip' => "coolify-testing-host", 'team_id' => $root_team->id, @@ -28,12 +27,20 @@ public function run(): void ]); Server::create([ 'id' => 2, - 'name' => "testing-host2", + 'name' => "testing-local-docker-container-2", 'description' => "This is a test docker container", 'ip' => "coolify-testing-host-2", 'team_id' => $root_team->id, 'private_key_id' => $private_key_1->id, ]); - + Server::create([ + 'id' => 3, + 'name' => "localhost", + 'description' => "This is the local machine", + 'user' => 'ab', + 'ip' => "172.17.0.1", + 'team_id' => $root_team->id, + 'private_key_id' => $private_key_1->id, + ]); } } diff --git a/database/seeders/StandaloneDockerSeeder.php b/database/seeders/StandaloneDockerSeeder.php index 17b764ba7..082e2647c 100644 --- a/database/seeders/StandaloneDockerSeeder.php +++ b/database/seeders/StandaloneDockerSeeder.php @@ -15,10 +15,10 @@ class StandaloneDockerSeeder extends Seeder */ public function run(): void { - $server_1 = Server::find(1); + $server_3 = Server::find(3); StandaloneDocker::create([ 'id' => 1, - 'server_id' => $server_1->id, + 'server_id' => $server_3->id, ]); } } diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index 031c6a8ce..030b2379b 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -13,9 +13,10 @@

Applications

@forelse ($environment->applications as $application)

{{ $application->name }}

-

Application: {{ $application }}

+

Application: {{ $application->settings }}

Destination Class: {{ $application->destination->getMorphClass() }}

Source Class: {{ $application->source->getMorphClass() }}

+ @empty
  • No application found
  • @endforelse diff --git a/resources/views/livewire/demo-deploy-application.blade.php b/resources/views/livewire/demo-deploy-application.blade.php new file mode 100644 index 000000000..18f781620 --- /dev/null +++ b/resources/views/livewire/demo-deploy-application.blade.php @@ -0,0 +1,13 @@ +
    + @isset($activity?->id) +
    + Activity: {{ $activity?->id ?? 'waiting' }} +
    +
    {{ data_get($activity, 'description') }}
    + {{--
    +
    Details:
    +
    {{ json_encode(data_get($activity, 'properties'), JSON_PRETTY_PRINT) }}
    +
    --}} + @endisset + +