diff --git a/app/Actions/Server/CleanupDocker.php b/app/Actions/Server/CleanupDocker.php new file mode 100644 index 000000000..4faeccf1a --- /dev/null +++ b/app/Actions/Server/CleanupDocker.php @@ -0,0 +1,23 @@ +server) { return; } + CleanupDocker::run($this->server, false); $this->latestVersion = get_latest_version_of_coolify(); $this->currentVersion = config('version'); ray('latest version:' . $this->latestVersion . " current version: " . $this->currentVersion . ' force: ' . $force); diff --git a/app/Console/Commands/ServicesDelete.php b/app/Console/Commands/ServicesDelete.php index 31ccfa9a9..bc30bd842 100644 --- a/app/Console/Commands/ServicesDelete.php +++ b/app/Console/Commands/ServicesDelete.php @@ -2,6 +2,7 @@ namespace App\Console\Commands; +use App\Jobs\DeleteResourceJob; use App\Models\Application; use App\Models\Server; use App\Models\Service; @@ -91,7 +92,7 @@ class ServicesDelete extends Command if (!$confirmed) { break; } - $toDelete->delete(); + DeleteResourceJob::dispatch($toDelete); } } } @@ -115,7 +116,7 @@ class ServicesDelete extends Command if (!$confirmed) { return; } - $toDelete->delete(); + DeleteResourceJob::dispatch($toDelete); } } } @@ -139,7 +140,7 @@ class ServicesDelete extends Command if (!$confirmed) { return; } - $toDelete->delete(); + DeleteResourceJob::dispatch($toDelete); } } } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 267572b39..7dbead831 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -72,7 +72,7 @@ class Kernel extends ConsoleKernel } } foreach ($servers as $server) { - $schedule->job(new ServerStatusJob($server))->everyTenMinutes()->onOneServer(); + $schedule->job(new ServerStatusJob($server))->everyFiveMinutes()->onOneServer(); } } private function instance_auto_update($schedule) diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index b7534952c..e846f9f61 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -203,7 +203,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted dispatch(new ContainerStatusJob($this->server)); } $this->next(ApplicationDeploymentStatus::FINISHED->value); - $this->application->isConfigurationChanged(true); + $this->application->isConfigurationChanged(false); return; } else if ($this->application->dockerfile) { $this->deploy_simple_dockerfile(); @@ -738,13 +738,15 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted $this->generate_nixpacks_confs(); } $this->generate_compose_file(); + // Needs separate preview variables $this->generate_build_env_variables(); - $this->add_build_env_variables_to_dockerfile(); + if ($this->application->build_pack !== 'nixpacks') { + $this->add_build_env_variables_to_dockerfile(); + } $this->build_image(); $this->stop_running_container(); if ($this->application->destination->server->isSwarm()) { - ray("{$this->workdir}{$this->docker_compose_location}"); $this->push_to_docker_registry(); $this->execute_remote_command( [ @@ -911,10 +913,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted if ($this->nixpacks_plan) { $parsed = Toml::Parse($this->nixpacks_plan); // Do any modifications here - // $cmds = collect(data_get($parsed, 'phases.setup.cmds', [])); $this->generate_env_variables(); - // data_set($parsed, 'phases.setup.cmds', $cmds); - ray($this->env_args->toArray()); $merged_envs = $this->env_args->merge(collect(data_get($parsed, 'variables', []))); data_set($parsed, 'variables', $merged_envs->toArray()); $this->nixpacks_plan = json_encode($parsed, JSON_PRETTY_PRINT); diff --git a/app/Jobs/DockerCleanupJob.php b/app/Jobs/DockerCleanupJob.php index a48ddd248..69c445801 100644 --- a/app/Jobs/DockerCleanupJob.php +++ b/app/Jobs/DockerCleanupJob.php @@ -2,6 +2,7 @@ namespace App\Jobs; +use App\Actions\Server\CleanupDocker; use App\Models\Server; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeEncrypted; @@ -43,9 +44,7 @@ class DockerCleanupJob implements ShouldQueue, ShouldBeEncrypted ray('Usage before: ' . $this->usageBefore); if ($this->usageBefore >= $this->server->settings->cleanup_after_percentage) { ray('Cleaning up ' . $this->server->name); - instant_remote_process(['docker image prune -af'], $this->server, false); - instant_remote_process(['docker container prune -f --filter "label=coolify.managed=true"'], $this->server, false); - instant_remote_process(['docker builder prune -af'], $this->server, false); + CleanupDocker::run($this->server); $usageAfter = $this->server->getDiskUsage(); if ($usageAfter < $this->usageBefore) { ray('Saved ' . ($this->usageBefore - $usageAfter) . '% disk space on ' . $this->server->name); diff --git a/app/Jobs/ScheduledTaskJob.php b/app/Jobs/ScheduledTaskJob.php index 104b5f7e3..49511ad95 100644 --- a/app/Jobs/ScheduledTaskJob.php +++ b/app/Jobs/ScheduledTaskJob.php @@ -108,7 +108,7 @@ class ScheduledTaskJob implements ShouldQueue 'message' => $this->task_output ?? $e->getMessage(), ]); } - send_internal_notification('ScheduledTaskJob failed with: ' . $e->getMessage()); + // send_internal_notification('ScheduledTaskJob failed with: ' . $e->getMessage()); throw $e; } } diff --git a/app/Livewire/Project/Resource/Index.php b/app/Livewire/Project/Resource/Index.php index 2a7570c9d..718b5003c 100644 --- a/app/Livewire/Project/Resource/Index.php +++ b/app/Livewire/Project/Resource/Index.php @@ -10,7 +10,15 @@ class Index extends Component { public Project $project; public Environment $environment; - public function mount () { + public $applications = []; + public $postgresqls = []; + public $redis = []; + public $mongodbs = []; + public $mysqls = []; + public $mariadbs = []; + public $services = []; + public function mount() + { $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (!$project) { return redirect()->route('dashboard'); @@ -21,6 +29,84 @@ class Index extends Component } $this->project = $project; $this->environment = $environment; + $this->applications = $environment->applications->sortBy('name'); + $this->applications = $this->applications->map(function ($application) { + if (data_get($application, 'environment.project.uuid')) { + $application->hrefLink = route('project.application.configuration', [ + 'project_uuid' => data_get($application, 'environment.project.uuid'), + 'environment_name' => data_get($application, 'environment.name'), + 'application_uuid' => data_get($application, 'uuid') + ]); + } + return $application; + }); + $this->postgresqls = $environment->postgresqls->sortBy('name'); + $this->postgresqls = $this->postgresqls->map(function ($postgresql) { + if (data_get($postgresql, 'environment.project.uuid')) { + $postgresql->hrefLink = route('project.database.configuration', [ + 'project_uuid' => data_get($postgresql, 'environment.project.uuid'), + 'environment_name' => data_get($postgresql, 'environment.name'), + 'database_uuid' => data_get($postgresql, 'uuid') + ]); + } + return $postgresql; + }); + $this->redis = $environment->redis->sortBy('name'); + $this->redis = $this->redis->map(function ($redis) { + if (data_get($redis, 'environment.project.uuid')) { + $redis->hrefLink = route('project.database.configuration', [ + 'project_uuid' => data_get($redis, 'environment.project.uuid'), + 'environment_name' => data_get($redis, 'environment.name'), + 'database_uuid' => data_get($redis, 'uuid') + ]); + } + return $redis; + }); + $this->mongodbs = $environment->mongodbs->sortBy('name'); + $this->mongodbs = $this->mongodbs->map(function ($mongodb) { + if (data_get($mongodb, 'environment.project.uuid')) { + $mongodb->hrefLink = route('project.database.configuration', [ + 'project_uuid' => data_get($mongodb, 'environment.project.uuid'), + 'environment_name' => data_get($mongodb, 'environment.name'), + 'database_uuid' => data_get($mongodb, 'uuid') + ]); + } + return $mongodb; + }); + $this->mysqls = $environment->mysqls->sortBy('name'); + $this->mysqls = $this->mysqls->map(function ($mysql) { + if (data_get($mysql, 'environment.project.uuid')) { + $mysql->hrefLink = route('project.database.configuration', [ + 'project_uuid' => data_get($mysql, 'environment.project.uuid'), + 'environment_name' => data_get($mysql, 'environment.name'), + 'database_uuid' => data_get($mysql, 'uuid') + ]); + } + return $mysql; + }); + $this->mariadbs = $environment->mariadbs->sortBy('name'); + $this->mariadbs = $this->mariadbs->map(function ($mariadb) { + if (data_get($mariadb, 'environment.project.uuid')) { + $mariadb->hrefLink = route('project.database.configuration', [ + 'project_uuid' => data_get($mariadb, 'environment.project.uuid'), + 'environment_name' => data_get($mariadb, 'environment.name'), + 'database_uuid' => data_get($mariadb, 'uuid') + ]); + } + return $mariadb; + }); + $this->services = $environment->services->sortBy('name'); + $this->services = $this->services->map(function ($service) { + if (data_get($service, 'environment.project.uuid')) { + $service->hrefLink = route('project.service.configuration', [ + 'project_uuid' => data_get($service, 'environment.project.uuid'), + 'environment_name' => data_get($service, 'environment.name'), + 'service_uuid' => data_get($service, 'uuid') + ]); + $service->status = serviceStatus($service); + } + return $service; + }); } public function render() { diff --git a/app/Livewire/Project/Shared/ExecuteContainerCommand.php b/app/Livewire/Project/Shared/ExecuteContainerCommand.php index f06f7784d..1ffcd810b 100644 --- a/app/Livewire/Project/Shared/ExecuteContainerCommand.php +++ b/app/Livewire/Project/Shared/ExecuteContainerCommand.php @@ -108,8 +108,7 @@ class ExecuteContainerCommand extends Component $this->validate(); try { // Wrap command to prevent escaped execution in the host. - $cmd = 'sh -c "' . str_replace('"', '\"', $this->command) . '"'; - + $cmd = 'sh -c "if [ -f ~/.profile ]; then . ~/.profile; fi; ' . str_replace('"', '\"', $this->command) . '"'; if (!empty($this->workDir)) { $exec = "docker exec -w {$this->workDir} {$this->container} {$cmd}"; } else { diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index f49c7cafc..da6705e4c 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -126,7 +126,7 @@ function generateSshCommand(Server $server, string $command, bool $isMux = true) if (data_get($server, 'settings.is_cloudflare_tunnel')) { $ssh_command .= '-o ProxyCommand="/usr/local/bin/cloudflared access ssh --hostname %h" '; } - $command = "PATH=\$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/host/usr/local/sbin:/host/usr/local/bin:/host/usr/sbin:/host/usr/bin:/host/sbin:/host/bin && $command"; + $command = "test -f ~/.profile && . ~/.profile; PATH=\$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/host/usr/local/sbin:/host/usr/local/bin:/host/usr/sbin:/host/usr/bin:/host/sbin:/host/bin && $command"; $ssh_command .= "-i {$privateKeyLocation} " . '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ' . '-o PasswordAuthentication=no ' diff --git a/config/sentry.php b/config/sentry.php index e793c9f2b..2d526fb85 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.188', + 'release' => '4.0.0-beta.189', // 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 d91322b99..dec4e2c54 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ -