diff --git a/app/Console/Commands/Init.php b/app/Console/Commands/Init.php index 0efd9b025..f2c9371f4 100644 --- a/app/Console/Commands/Init.php +++ b/app/Console/Commands/Init.php @@ -6,6 +6,9 @@ use App\Enums\ApplicationDeploymentStatus; use App\Models\Application; use App\Models\ApplicationDeploymentQueue; use App\Models\Service; +use App\Models\ServiceApplication; +use App\Models\ServiceDatabase; +use App\Models\StandaloneMariadb; use App\Models\StandaloneMongodb; use App\Models\StandaloneMysql; use App\Models\StandalonePostgresql; @@ -15,15 +18,18 @@ use Illuminate\Support\Facades\Storage; class Init extends Command { - protected $signature = 'app:init'; + protected $signature = 'app:init {--cleanup}'; protected $description = 'Cleanup instance related stuffs'; public function handle() { ray()->clearAll(); + $cleanup = $this->option('cleanup'); + if ($cleanup) { + $this->cleanup_stucked_resources(); + $this->cleanup_ssh(); + } $this->cleanup_in_progress_application_deployments(); - $this->cleanup_stucked_resources(); - // $this->cleanup_ssh(); } private function cleanup_ssh() @@ -38,7 +44,7 @@ class Init extends Command Storage::delete($file); } } catch (\Throwable $e) { - echo "Error: {$e->getMessage()}\n"; + echo "Error in cleaning ssh: {$e->getMessage()}\n"; } } private function cleanup_in_progress_application_deployments() @@ -61,77 +67,129 @@ class Init extends Command try { $applications = Application::all(); foreach ($applications as $application) { - if (!$application->environment) { + if (!data_get($application, 'environment')) { ray('Application without environment', $application->name); $application->delete(); } + if (!data_get($application, 'destination.server')) { + ray('Application without server', $application->name); + $application->delete(); + } if (!$application->destination()) { ray('Application without destination', $application->name); $application->delete(); } } + } catch (\Throwable $e) { + echo "Error in application: {$e->getMessage()}\n"; + } + try { $postgresqls = StandalonePostgresql::all(); foreach ($postgresqls as $postgresql) { - if (!$postgresql->environment) { + if (!data_get($postgresql, 'environment')) { ray('Postgresql without environment', $postgresql->name); $postgresql->delete(); } + if (!data_get($postgresql, 'destination.server')) { + ray('Postgresql without server', $postgresql->name); + $postgresql->delete(); + } if (!$postgresql->destination()) { ray('Postgresql without destination', $postgresql->name); $postgresql->delete(); } } + } catch (\Throwable $e) { + echo "Error in postgresql: {$e->getMessage()}\n"; + } + try { $redis = StandaloneRedis::all(); foreach ($redis as $redis) { - if (!$redis->environment) { + if (!data_get($redis, 'environment')) { ray('Redis without environment', $redis->name); $redis->delete(); } + if (!data_get($redis, 'destination.server')) { + ray('Redis without server', $redis->name); + $redis->delete(); + } if (!$redis->destination()) { ray('Redis without destination', $redis->name); $redis->delete(); } } + } catch (\Throwable $e) { + echo "Error in redis: {$e->getMessage()}\n"; + } + + try { $mongodbs = StandaloneMongodb::all(); foreach ($mongodbs as $mongodb) { - if (!$mongodb->environment) { + if (!data_get($mongodb, 'environment')) { ray('Mongodb without environment', $mongodb->name); $mongodb->delete(); } + if (!data_get($mongodb, 'destination.server')) { + ray('Mongodb without server', $mongodb->name); + $mongodb->delete(); + } if (!$mongodb->destination()) { ray('Mongodb without destination', $mongodb->name); $mongodb->delete(); } } + } catch (\Throwable $e) { + echo "Error in mongodb: {$e->getMessage()}\n"; + } + + try { $mysqls = StandaloneMysql::all(); foreach ($mysqls as $mysql) { - if (!$mysql->environment) { + if (!data_get($mysql, 'environment')) { ray('Mysql without environment', $mysql->name); $mysql->delete(); } + if (!data_get($mysql, 'destination.server')) { + ray('Mysql without server', $mysql->name); + $mysql->delete(); + } if (!$mysql->destination()) { ray('Mysql without destination', $mysql->name); $mysql->delete(); } } - $mariadbs = StandaloneMysql::all(); + } catch (\Throwable $e) { + echo "Error in mysql: {$e->getMessage()}\n"; + } + + try { + $mariadbs = StandaloneMariadb::all(); foreach ($mariadbs as $mariadb) { - if (!$mariadb->environment) { + if (!data_get($mariadb, 'environment')) { ray('Mariadb without environment', $mariadb->name); $mariadb->delete(); } + if (!data_get($mariadb, 'destination.server')) { + ray('Mariadb without server', $mariadb->name); + $mariadb->delete(); + } if (!$mariadb->destination()) { ray('Mariadb without destination', $mariadb->name); $mariadb->delete(); } } + } catch (\Throwable $e) { + echo "Error in mariadb: {$e->getMessage()}\n"; + } + + try { $services = Service::all(); foreach ($services as $service) { - if (!$service->environment) { + if (!data_get($service, 'environment')) { ray('Service without environment', $service->name); $service->delete(); } - if (!$service->server) { + if (!data_get($service, 'server')) { ray('Service without server', $service->name); $service->delete(); } @@ -141,7 +199,29 @@ class Init extends Command } } } catch (\Throwable $e) { - echo "Error: {$e->getMessage()}\n"; + echo "Error in service: {$e->getMessage()}\n"; + } + try { + $serviceApplications = ServiceApplication::all(); + foreach ($serviceApplications as $service) { + if (!data_get($service, 'service')) { + ray('ServiceApplication without service', $service->name); + $service->delete(); + } + } + } catch (\Throwable $e) { + echo "Error in serviceApplications: {$e->getMessage()}\n"; + } + try { + $serviceDatabases = ServiceDatabase::all(); + foreach ($serviceDatabases as $service) { + if (!data_get($service, 'service')) { + ray('ServiceDatabase without service', $service->name); + $service->delete(); + } + } + } catch (\Throwable $e) { + echo "Error in ServiceDatabases: {$e->getMessage()}\n"; } } } diff --git a/app/Http/Livewire/Server/Delete.php b/app/Http/Livewire/Server/Delete.php index 966de4f19..8680d4cf0 100644 --- a/app/Http/Livewire/Server/Delete.php +++ b/app/Http/Livewire/Server/Delete.php @@ -14,7 +14,7 @@ class Delete extends Component { try { $this->authorize('delete', $this->server); - if (!$this->server->isEmpty()) { + if ($this->server->hasDefinedResources()) { $this->emit('error', 'Server has defined resources. Please delete them first.'); return; } diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index e399fb68f..4ffc1f6b6 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -293,7 +293,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted $this->build_image_name = Str::lower("{$this->application->git_repository}:{$tag}-build"); $this->production_image_name = Str::lower("{$this->application->uuid}:{$tag}"); } - ray('Build Image Name: ' . $this->build_image_name . ' & Production Image Name: ' . $this->production_image_name)->green(); } private function just_restart() { diff --git a/app/Models/Application.php b/app/Models/Application.php index 2e6c2814d..ca7334b7e 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -34,8 +34,11 @@ class Application extends BaseModel static::deleting(function ($application) { $application->settings()->delete(); $storages = $application->persistentStorages()->get(); - foreach ($storages as $storage) { - instant_remote_process(["docker volume rm -f $storage->name"], $application->destination->server, false); + $server = data_get($application, 'destination.server'); + if ($server) { + foreach ($storages as $storage) { + instant_remote_process(["docker volume rm -f $storage->name"], $server, false); + } } $application->persistentStorages()->delete(); $application->environment_variables()->delete(); diff --git a/app/Models/Server.php b/app/Models/Server.php index 11be55764..eca98889e 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -109,11 +109,12 @@ class Server extends BaseModel return $this->proxy->modelScope(); } - public function isEmpty() + public function hasDefinedResources() { $applications = $this->applications()->count() === 0; $databases = $this->databases()->count() === 0; - if ($applications && $databases) { + $services = $this->services()->count() === 0; + if ($applications || $databases || $services) { return true; } return false; diff --git a/app/Models/Service.php b/app/Models/Service.php index da3e81cbe..6aaa126e7 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -5,7 +5,6 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Collection; -use Illuminate\Support\Facades\Cache; use Symfony\Component\Yaml\Yaml; use Illuminate\Support\Str; @@ -23,21 +22,21 @@ class Service extends BaseModel foreach ($storages as $storage) { $storagesToDelete->push($storage); } - $application->persistentStorages()->delete(); } foreach ($service->databases()->get() as $database) { $storages = $database->persistentStorages()->get(); foreach ($storages as $storage) { $storagesToDelete->push($storage); } - $database->persistentStorages()->delete(); } $service->environment_variables()->delete(); $service->applications()->delete(); $service->databases()->delete(); - if ($storagesToDelete->count() > 0) { - $storagesToDelete->each(function ($storage) use ($service) { - instant_remote_process(["docker volume rm -f $storage->name"], $service->server, false); + + $server = data_get($service, 'server'); + if ($server && $storagesToDelete->count() > 0) { + $storagesToDelete->each(function ($storage) use ($server) { + instant_remote_process(["docker volume rm -f $storage->name"], $server, false); }); } }); @@ -257,13 +256,25 @@ class Service extends BaseModel ]); } } - $networks = $serviceNetworks->toArray(); - foreach ($definedNetwork as $key => $network) { - $networks = array_merge($networks, [ - $network - ]); + $networks = collect(); + foreach ($serviceNetworks as $key =>$serviceNetwork) { + if (gettype($serviceNetwork) === 'string') { + // networks: + // - appwrite + $networks->put($serviceNetwork, null); + } else if (gettype($serviceNetwork) === 'array') { + // networks: + // default: + // ipv4_address: 192.168.203.254 + // $networks->put($serviceNetwork, null); + ray($key); + $networks->put($key,$serviceNetwork); + } } - data_set($service, 'networks', $networks); + foreach ($definedNetwork as $key => $network) { + $networks->put($network, null); + } + data_set($service, 'networks', $networks->toArray()); // Collect/create/update volumes if ($serviceVolumes->count() > 0) { diff --git a/app/Models/ServiceApplication.php b/app/Models/ServiceApplication.php index 284453c42..c70ceeccf 100644 --- a/app/Models/ServiceApplication.php +++ b/app/Models/ServiceApplication.php @@ -11,6 +11,13 @@ class ServiceApplication extends BaseModel use HasFactory; protected $guarded = []; + protected static function booted() + { + static::deleting(function ($service) { + $service->persistentStorages()->delete(); + $service->fileStorages()->delete(); + }); + } public function type() { return 'service'; diff --git a/app/Models/ServiceDatabase.php b/app/Models/ServiceDatabase.php index b4a130904..900cdc3b4 100644 --- a/app/Models/ServiceDatabase.php +++ b/app/Models/ServiceDatabase.php @@ -9,6 +9,13 @@ class ServiceDatabase extends BaseModel use HasFactory; protected $guarded = []; + protected static function booted() + { + static::deleting(function ($service) { + $service->persistentStorages()->delete(); + $service->fileStorages()->delete(); + }); + } public function type() { return 'service'; diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php index 5e721857b..f9f3ad1ae 100644 --- a/app/Models/StandaloneMariadb.php +++ b/app/Models/StandaloneMariadb.php @@ -30,8 +30,11 @@ class StandaloneMariadb extends BaseModel }); static::deleting(function ($database) { $storages = $database->persistentStorages()->get(); - foreach ($storages as $storage) { - instant_remote_process(["docker volume rm -f $storage->name"], $database->destination->server, false); + $server = data_get($database, 'destination.server'); + if ($server) { + foreach ($storages as $storage) { + instant_remote_process(["docker volume rm -f $storage->name"], $server, false); + } } $database->scheduledBackups()->delete(); $database->persistentStorages()->delete(); diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php index 6e3b9e583..628cb6942 100644 --- a/app/Models/StandaloneMongodb.php +++ b/app/Models/StandaloneMongodb.php @@ -33,8 +33,11 @@ class StandaloneMongodb extends BaseModel }); static::deleting(function ($database) { $storages = $database->persistentStorages()->get(); - foreach ($storages as $storage) { - instant_remote_process(["docker volume rm -f $storage->name"], $database->destination->server, false); + $server = data_get($database, 'destination.server'); + if ($server) { + foreach ($storages as $storage) { + instant_remote_process(["docker volume rm -f $storage->name"], $server, false); + } } $database->scheduledBackups()->delete(); $database->persistentStorages()->delete(); diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php index 53a797d49..d7314f59b 100644 --- a/app/Models/StandaloneMysql.php +++ b/app/Models/StandaloneMysql.php @@ -30,8 +30,11 @@ class StandaloneMysql extends BaseModel }); static::deleting(function ($database) { $storages = $database->persistentStorages()->get(); - foreach ($storages as $storage) { - instant_remote_process(["docker volume rm -f $storage->name"], $database->destination->server, false); + $server = data_get($database, 'destination.server'); + if ($server) { + foreach ($storages as $storage) { + instant_remote_process(["docker volume rm -f $storage->name"], $server, false); + } } $database->scheduledBackups()->delete(); $database->persistentStorages()->delete(); diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index bbfabbf67..ca19e7a87 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -30,8 +30,11 @@ class StandalonePostgresql extends BaseModel }); static::deleting(function ($database) { $storages = $database->persistentStorages()->get(); - foreach ($storages as $storage) { - instant_remote_process(["docker volume rm -f $storage->name"], $database->destination->server, false); + $server = data_get($database, 'destination.server'); + if ($server) { + foreach ($storages as $storage) { + instant_remote_process(["docker volume rm -f $storage->name"], $server, false); + } } $database->scheduledBackups()->delete(); $database->persistentStorages()->delete(); diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index 9dff7ae84..9d12df040 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -26,8 +26,11 @@ class StandaloneRedis extends BaseModel static::deleting(function ($database) { $database->scheduledBackups()->delete(); $storages = $database->persistentStorages()->get(); - foreach ($storages as $storage) { - instant_remote_process(["docker volume rm -f $storage->name"], $database->destination->server, false); + $server = data_get($database, 'destination.server'); + if ($server) { + foreach ($storages as $storage) { + instant_remote_process(["docker volume rm -f $storage->name"], $server, false); + } } $database->persistentStorages()->delete(); $database->environment_variables()->delete(); diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index 8a01ec549..874b01ebd 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -6,6 +6,7 @@ use App\Models\Server; use Illuminate\Support\Collection; use Illuminate\Support\Str; use Spatie\Url\Url; +use Visus\Cuid2\Cuid2; function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null): Collection { @@ -141,6 +142,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ $labels = collect([]); $labels->push('traefik.enable=true'); foreach ($domains as $loop => $domain) { + $uuid = new Cuid2(7); $url = Url::fromString($domain); $host = $url->getHost(); $path = $url->getPath(); diff --git a/config/sentry.php b/config/sentry.php index b2b99a365..8899bddd2 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -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.110', + 'release' => '4.0.0-beta.111', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 4bcb4ce5b..f02cc33b3 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Build @if ($application->could_set_build_commands()) @if ($application->build_pack === 'nixpacks') -
Nixpacks will detect your package manager/configurations: Nixpacks documentation
+
Nixpacks will detect your package manager/configurations: Nixpacks documentation
You probably do not need to modify the commands below.
- - - + + +
@endif @endif @@ -103,11 +104,7 @@ - @if ($labelsChanged) - - @else - - @endif + Reset to Coolify Generated Labels

Advanced

diff --git a/resources/views/livewire/project/service/index.blade.php b/resources/views/livewire/project/service/index.blade.php index ea2ab7ff5..ba2bd8877 100644 --- a/resources/views/livewire/project/service/index.blade.php +++ b/resources/views/livewire/project/service/index.blade.php @@ -1,6 +1,6 @@
- +
Documentation diff --git a/resources/views/livewire/server/delete.blade.php b/resources/views/livewire/server/delete.blade.php index b4a9a030f..1cf2e1d74 100644 --- a/resources/views/livewire/server/delete.blade.php +++ b/resources/views/livewire/server/delete.blade.php @@ -11,8 +11,12 @@
This will remove this server from Coolify. Beware! There is no coming back!
- - Delete - + @if ($server->hasDefinedResources()) +
Please delete all resources before deleting this server.
+ @else + + Delete + + @endif @endif
diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index 047bf1882..c9ed332de 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -62,7 +62,6 @@ helper="Disk cleanup job will be executed if disk usage is more than this number." /> @endif -