From 0924070a13447e105a7b068c513811d1032599fd Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 13 Sep 2023 12:42:59 +0200 Subject: [PATCH 01/13] version++ --- config/sentry.php | 2 +- config/version.php | 2 +- versions.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/sentry.php b/config/sentry.php index 3e42e7029..b0db797f1 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.35', + 'release' => '4.0.0-beta.36', 'server_name' => env('APP_ID', 'coolify'), // 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 c31bdf903..c3cb2484c 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Wed, 13 Sep 2023 13:00:16 +0200 Subject: [PATCH 02/13] fix: add timeout for ssh commands --- app/Actions/CoolifyTask/RunRemoteProcess.php | 6 +----- app/Http/Livewire/Server/Form.php | 2 +- bootstrap/helpers/remoteProcess.php | 12 ++++++++---- config/constants.php | 5 +++++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/Actions/CoolifyTask/RunRemoteProcess.php b/app/Actions/CoolifyTask/RunRemoteProcess.php index 1444684a0..cc4bca873 100644 --- a/app/Actions/CoolifyTask/RunRemoteProcess.php +++ b/app/Actions/CoolifyTask/RunRemoteProcess.php @@ -10,9 +10,6 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Process; use Spatie\Activitylog\Models\Activity; -const TIMEOUT = 3600; -const IDLE_TIMEOUT = 3600; - class RunRemoteProcess { public Activity $activity; @@ -76,8 +73,7 @@ class RunRemoteProcess $this->time_start = hrtime(true); $status = ProcessStatus::IN_PROGRESS; - - $processResult = Process::timeout(TIMEOUT)->idleTimeout(IDLE_TIMEOUT)->run($this->getCommand(), $this->handleOutput(...)); + $processResult = Process::forever()->run($this->getCommand(), $this->handleOutput(...)); if ($this->activity->properties->get('status') === ProcessStatus::ERROR->value) { $status = ProcessStatus::ERROR; diff --git a/app/Http/Livewire/Server/Form.php b/app/Http/Livewire/Server/Form.php index 53cf8234d..9d5c892b3 100644 --- a/app/Http/Livewire/Server/Form.php +++ b/app/Http/Livewire/Server/Form.php @@ -56,7 +56,7 @@ class Form extends Component $this->uptime = $uptime; $this->emit('success', 'Server is reachable!'); } else { - $this->emit('error', 'Server is not rachable'); + $this->emit('error', 'Server is not reachable'); return; } if ($dockerVersion) { diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index 40ff2f958..d713e0c19 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -71,8 +71,12 @@ function save_private_key_for_server(Server $server) function generate_ssh_command(string $private_key_location, string $server_ip, string $user, string $port, string $command, bool $isMux = true) { + $timeout = config('constants.ssh.command_timeout'); + $connectionTimeout = config('constants.ssh.connection_timeout'); + $serverInterval = config('constants.ssh.server_interval'); + $delimiter = 'EOF-COOLIFY-SSH'; - $ssh_command = "ssh "; + $ssh_command = "timeout $timeout ssh "; if ($isMux && config('coolify.mux_enabled')) { $ssh_command .= '-o ControlMaster=auto -o ControlPersist=1m -o ControlPath=/var/www/html/storage/app/ssh/mux/%h_%p_%r '; @@ -81,8 +85,8 @@ function generate_ssh_command(string $private_key_location, string $server_ip, s $ssh_command .= "-i {$private_key_location} " . '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ' . '-o PasswordAuthentication=no ' - . '-o ConnectTimeout=3600 ' - . '-o ServerAliveInterval=20 ' + . "-o ConnectTimeout=$connectionTimeout " + . "-o ServerAliveInterval=$serverInterval " . '-o RequestTTY=no ' . '-o LogLevel=ERROR ' . "-p {$port} " @@ -90,7 +94,7 @@ function generate_ssh_command(string $private_key_location, string $server_ip, s . " 'bash -se' << \\$delimiter" . PHP_EOL . $command . PHP_EOL . $delimiter; - + ray($ssh_command); return $ssh_command; } function instantCommand(string $command, $throwError = true) { diff --git a/config/constants.php b/config/constants.php index 4cb112855..4630adcda 100644 --- a/config/constants.php +++ b/config/constants.php @@ -1,5 +1,10 @@ [ + 'connection_timeout' => 10, + 'server_interval' => 20, + 'command_timeout' => 7200, + ], 'waitlist' => [ 'expiration' => 10, ], From 23b7fc3c54258384fda828f42bbc9e5126669f12 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 13 Sep 2023 13:00:43 +0200 Subject: [PATCH 03/13] fix: prevent weird ui bug for validateServer --- resources/views/livewire/server/form.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index 9af0440a0..9b297b70c 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -52,7 +52,7 @@ @endif @if ($server->settings->is_reachable && !$server->settings->is_usable && $server->id !== 0) - Install Docker Engine 24.0 From b22fecb615af8c4bdfe420fbd61801ff2bfc9f12 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 13 Sep 2023 20:27:58 +0200 Subject: [PATCH 04/13] fix: lowercase email in forgot password --- resources/views/auth/forgot-password.blade.php | 2 +- routes/web.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/views/auth/forgot-password.blade.php b/resources/views/auth/forgot-password.blade.php index 3f815646b..04a9a5695 100644 --- a/resources/views/auth/forgot-password.blade.php +++ b/resources/views/auth/forgot-password.blade.php @@ -15,7 +15,7 @@ @if (is_transactional_emails_active())
@csrf - {{ __('auth.forgot_password_send_email') }} diff --git a/routes/web.php b/routes/web.php index a18af5df0..a8ae08aa4 100644 --- a/routes/web.php +++ b/routes/web.php @@ -30,6 +30,10 @@ use Laravel\Fortify\Fortify; Route::post('/forgot-password', function (Request $request) { if (is_transactional_emails_active()) { + $arrayOfRequest = $request->only(Fortify::email()); + $request->merge([ + 'email' => Str::lower($arrayOfRequest['email']), + ]); $type = set_transanctional_email_settings(); if (!$type) { return response()->json(['message' => 'Transactional emails are not active'], 400); From 52c84f8d22efe6d5322b6b562fe85f4ffa66e1fe Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 13 Sep 2023 20:48:13 +0200 Subject: [PATCH 05/13] fix: lower case email on waitlist --- app/Http/Livewire/Waitlist/Index.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Livewire/Waitlist/Index.php b/app/Http/Livewire/Waitlist/Index.php index fb040c6d5..d2ce6fe19 100644 --- a/app/Http/Livewire/Waitlist/Index.php +++ b/app/Http/Livewire/Waitlist/Index.php @@ -6,6 +6,7 @@ use App\Jobs\SendConfirmationForWaitlistJob; use App\Models\User; use App\Models\Waitlist; use Livewire\Component; +use Str; class Index extends Component { @@ -46,7 +47,7 @@ class Index extends Component return; } $waitlist = Waitlist::create([ - 'email' => $this->email, + 'email' => Str::lower($this->email), 'type' => 'registration', ]); From fe4a0ae166177db909f75eb415c3ee909333c13f Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 14 Sep 2023 10:12:44 +0200 Subject: [PATCH 06/13] fix: encrypt jobs --- app/Jobs/ApplicationContainerStatusJob.php | 3 ++- app/Jobs/ApplicationDeploymentJob.php | 9 +++------ app/Jobs/ApplicationPullRequestUpdateJob.php | 3 ++- app/Jobs/CheckResaleLicenseJob.php | 3 ++- app/Jobs/CleanupInstanceStuffsJob.php | 3 ++- app/Jobs/CoolifyTask.php | 3 ++- app/Jobs/DatabaseBackupJob.php | 3 ++- app/Jobs/DatabaseContainerStatusJob.php | 3 ++- app/Jobs/DockerCleanupJob.php | 3 ++- app/Jobs/InstanceAutoUpdateJob.php | 3 ++- app/Jobs/ProxyContainerStatusJob.php | 3 ++- app/Jobs/SendConfirmationForWaitlistJob.php | 3 ++- app/Jobs/SendMessageToDiscordJob.php | 3 ++- app/Jobs/SendMessageToTelegramJob.php | 3 ++- app/Jobs/ServerDetailsCheckJob.php | 3 ++- app/Jobs/SubscriptionInvoiceFailedJob.php | 3 ++- app/Jobs/SubscriptionTrialEndedJob.php | 3 ++- app/Jobs/SubscriptionTrialEndsSoonJob.php | 3 ++- 18 files changed, 37 insertions(+), 23 deletions(-) diff --git a/app/Jobs/ApplicationContainerStatusJob.php b/app/Jobs/ApplicationContainerStatusJob.php index 67e629425..f1d2ed7c9 100644 --- a/app/Jobs/ApplicationContainerStatusJob.php +++ b/app/Jobs/ApplicationContainerStatusJob.php @@ -6,13 +6,14 @@ use App\Models\Application; use App\Models\ApplicationPreview; use App\Notifications\Application\StatusChanged; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -class ApplicationContainerStatusJob implements ShouldQueue, ShouldBeUnique +class ApplicationContainerStatusJob implements ShouldQueue, ShouldBeUnique, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 81778203d..d224afd10 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -17,10 +17,10 @@ use App\Notifications\Application\DeploymentSuccess; use App\Traits\ExecuteRemoteCommand; use Exception; 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\Collection; use Illuminate\Support\Str; @@ -28,10 +28,8 @@ use Spatie\Url\Url; use Symfony\Component\Yaml\Yaml; use Throwable; use Visus\Cuid2\Cuid2; -use Yosymfony\Toml\Toml; -use Yosymfony\Toml\TomlArray; -class ApplicationDeploymentJob implements ShouldQueue +class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, ExecuteRemoteCommand; @@ -49,7 +47,6 @@ class ApplicationDeploymentJob implements ShouldQueue private GithubApp|GitlabApp $source; private StandaloneDocker|SwarmDocker $destination; private Server $server; - private string $private_key_location; private ApplicationPreview|null $preview = null; private string $container_name; @@ -92,7 +89,7 @@ class ApplicationDeploymentJob implements ShouldQueue $this->is_debug_enabled = $this->application->settings->is_debug_enabled; $this->container_name = generateApplicationContainerName($this->application->uuid, $this->pull_request_id); - $this->private_key_location = save_private_key_for_server($this->server); + addPrivateKeyToSshAgent($this->server); $this->saved_outputs = collect(); // Set preview fqdn diff --git a/app/Jobs/ApplicationPullRequestUpdateJob.php b/app/Jobs/ApplicationPullRequestUpdateJob.php index 19fbcd7e7..851c04169 100755 --- a/app/Jobs/ApplicationPullRequestUpdateJob.php +++ b/app/Jobs/ApplicationPullRequestUpdateJob.php @@ -6,12 +6,13 @@ use App\Enums\ProcessStatus; use App\Models\Application; use App\Models\ApplicationPreview; 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\SerializesModels; -class ApplicationPullRequestUpdateJob implements ShouldQueue +class ApplicationPullRequestUpdateJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/CheckResaleLicenseJob.php b/app/Jobs/CheckResaleLicenseJob.php index fe4eed27f..08530aeae 100644 --- a/app/Jobs/CheckResaleLicenseJob.php +++ b/app/Jobs/CheckResaleLicenseJob.php @@ -4,12 +4,13 @@ namespace App\Jobs; use App\Actions\License\CheckResaleLicense; 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\SerializesModels; -class CheckResaleLicenseJob implements ShouldQueue +class CheckResaleLicenseJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/CleanupInstanceStuffsJob.php b/app/Jobs/CleanupInstanceStuffsJob.php index 3d08203e3..f9d88cd4d 100644 --- a/app/Jobs/CleanupInstanceStuffsJob.php +++ b/app/Jobs/CleanupInstanceStuffsJob.php @@ -4,13 +4,14 @@ namespace App\Jobs; use App\Models\Waitlist; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -class CleanupInstanceStuffsJob implements ShouldQueue, ShouldBeUnique +class CleanupInstanceStuffsJob implements ShouldQueue, ShouldBeUnique, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/CoolifyTask.php b/app/Jobs/CoolifyTask.php index 176841b20..3ea32c27a 100755 --- a/app/Jobs/CoolifyTask.php +++ b/app/Jobs/CoolifyTask.php @@ -4,13 +4,14 @@ namespace App\Jobs; use App\Actions\CoolifyTask\RunRemoteProcess; 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\SerializesModels; use Spatie\Activitylog\Models\Activity; -class CoolifyTask implements ShouldQueue +class CoolifyTask implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/DatabaseBackupJob.php b/app/Jobs/DatabaseBackupJob.php index 778272705..578a5ec43 100644 --- a/app/Jobs/DatabaseBackupJob.php +++ b/app/Jobs/DatabaseBackupJob.php @@ -12,6 +12,7 @@ use App\Notifications\Database\BackupFailed; use App\Notifications\Database\BackupSuccess; use Carbon\Carbon; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; @@ -20,7 +21,7 @@ use Illuminate\Queue\SerializesModels; use Throwable; use Illuminate\Support\Str; -class DatabaseBackupJob implements ShouldQueue +class DatabaseBackupJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/DatabaseContainerStatusJob.php b/app/Jobs/DatabaseContainerStatusJob.php index d7b4d0085..f1d0de301 100644 --- a/app/Jobs/DatabaseContainerStatusJob.php +++ b/app/Jobs/DatabaseContainerStatusJob.php @@ -6,13 +6,14 @@ use App\Models\ApplicationPreview; use App\Models\StandalonePostgresql; use App\Notifications\Application\StatusChanged; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -class DatabaseContainerStatusJob implements ShouldQueue, ShouldBeUnique +class DatabaseContainerStatusJob implements ShouldQueue, ShouldBeUnique, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/DockerCleanupJob.php b/app/Jobs/DockerCleanupJob.php index b1fccbe4b..80c76e067 100644 --- a/app/Jobs/DockerCleanupJob.php +++ b/app/Jobs/DockerCleanupJob.php @@ -5,13 +5,14 @@ namespace App\Jobs; use App\Models\ApplicationDeploymentQueue; use App\Models\Server; 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; -class DockerCleanupJob implements ShouldQueue +class DockerCleanupJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/InstanceAutoUpdateJob.php b/app/Jobs/InstanceAutoUpdateJob.php index 957b8fe23..814ae9cc9 100644 --- a/app/Jobs/InstanceAutoUpdateJob.php +++ b/app/Jobs/InstanceAutoUpdateJob.php @@ -4,13 +4,14 @@ namespace App\Jobs; use App\Actions\Server\UpdateCoolify; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -class InstanceAutoUpdateJob implements ShouldQueue, ShouldBeUnique +class InstanceAutoUpdateJob implements ShouldQueue, ShouldBeUnique, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/ProxyContainerStatusJob.php b/app/Jobs/ProxyContainerStatusJob.php index 1e7eac6a3..6cfd2692f 100644 --- a/app/Jobs/ProxyContainerStatusJob.php +++ b/app/Jobs/ProxyContainerStatusJob.php @@ -7,6 +7,7 @@ use App\Enums\ProxyStatus; use App\Enums\ProxyTypes; use App\Models\Server; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; @@ -14,7 +15,7 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Middleware\WithoutOverlapping; use Illuminate\Queue\SerializesModels; -class ProxyContainerStatusJob implements ShouldQueue, ShouldBeUnique +class ProxyContainerStatusJob implements ShouldQueue, ShouldBeUnique, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/SendConfirmationForWaitlistJob.php b/app/Jobs/SendConfirmationForWaitlistJob.php index 470b1bafe..bee15975c 100755 --- a/app/Jobs/SendConfirmationForWaitlistJob.php +++ b/app/Jobs/SendConfirmationForWaitlistJob.php @@ -5,6 +5,7 @@ namespace App\Jobs; use App\Models\InstanceSettings; use App\Models\Waitlist; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Mail\Message; @@ -13,7 +14,7 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Mail; -class SendConfirmationForWaitlistJob implements ShouldQueue +class SendConfirmationForWaitlistJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/SendMessageToDiscordJob.php b/app/Jobs/SendMessageToDiscordJob.php index 66e3c1c1a..b9255baaa 100644 --- a/app/Jobs/SendMessageToDiscordJob.php +++ b/app/Jobs/SendMessageToDiscordJob.php @@ -3,13 +3,14 @@ namespace App\Jobs; 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\SerializesModels; use Illuminate\Support\Facades\Http; -class SendMessageToDiscordJob implements ShouldQueue +class SendMessageToDiscordJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/SendMessageToTelegramJob.php b/app/Jobs/SendMessageToTelegramJob.php index 1fa1347c4..37f1cf381 100644 --- a/app/Jobs/SendMessageToTelegramJob.php +++ b/app/Jobs/SendMessageToTelegramJob.php @@ -3,6 +3,7 @@ namespace App\Jobs; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; @@ -10,7 +11,7 @@ use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Http; use Str; -class SendMessageToTelegramJob implements ShouldQueue +class SendMessageToTelegramJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/ServerDetailsCheckJob.php b/app/Jobs/ServerDetailsCheckJob.php index 606931c42..8a68c66ae 100644 --- a/app/Jobs/ServerDetailsCheckJob.php +++ b/app/Jobs/ServerDetailsCheckJob.php @@ -4,6 +4,7 @@ namespace App\Jobs; use App\Models\Server; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; @@ -12,7 +13,7 @@ use Illuminate\Queue\Middleware\WithoutOverlapping; use Illuminate\Queue\SerializesModels; use Str; -class ServerDetailsCheckJob implements ShouldQueue, ShouldBeUnique +class ServerDetailsCheckJob implements ShouldQueue, ShouldBeUnique, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/SubscriptionInvoiceFailedJob.php b/app/Jobs/SubscriptionInvoiceFailedJob.php index 5e8654673..9b8534060 100755 --- a/app/Jobs/SubscriptionInvoiceFailedJob.php +++ b/app/Jobs/SubscriptionInvoiceFailedJob.php @@ -4,13 +4,14 @@ namespace App\Jobs; use App\Models\Team; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -class SubscriptionInvoiceFailedJob implements ShouldQueue +class SubscriptionInvoiceFailedJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/SubscriptionTrialEndedJob.php b/app/Jobs/SubscriptionTrialEndedJob.php index 39acd19a2..3f4ef187e 100755 --- a/app/Jobs/SubscriptionTrialEndedJob.php +++ b/app/Jobs/SubscriptionTrialEndedJob.php @@ -4,13 +4,14 @@ namespace App\Jobs; use App\Models\Team; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -class SubscriptionTrialEndedJob implements ShouldQueue +class SubscriptionTrialEndedJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/SubscriptionTrialEndsSoonJob.php b/app/Jobs/SubscriptionTrialEndsSoonJob.php index 84bd8ee66..5e8b35aa8 100755 --- a/app/Jobs/SubscriptionTrialEndsSoonJob.php +++ b/app/Jobs/SubscriptionTrialEndsSoonJob.php @@ -4,13 +4,14 @@ namespace App\Jobs; use App\Models\Team; use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -class SubscriptionTrialEndsSoonJob implements ShouldQueue +class SubscriptionTrialEndsSoonJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; From 17c0e91a0d60abd84e2ee4c6a352dc1457024be3 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 14 Sep 2023 10:12:58 +0200 Subject: [PATCH 07/13] feat: ssh-agent instead of filesystem based ssh keys --- app/Actions/CoolifyTask/RunRemoteProcess.php | 5 +- app/Data/CoolifyTaskArgs.php | 1 - app/Http/Livewire/Server/ShowPrivateKey.php | 3 +- app/Traits/ExecuteRemoteCommand.php | 7 ++- bootstrap/helpers/remoteProcess.php | 53 ++++++++++--------- config/coolify.php | 1 + docker-compose.dev.yml | 1 + docker-compose.prod.yml | 1 + docker/dev-ssu/Dockerfile | 2 +- .../etc/s6-overlay/s6-rc.d/horizon/run | 5 ++ .../s6-rc.d/{queue-worker => horizon}/type | 0 .../etc/s6-overlay/s6-rc.d/queue-worker/run | 2 - .../s6-overlay/s6-rc.d/scheduler-worker/run | 5 +- .../etc/s6-overlay/s6-rc.d/ssh-agent/type | 1 + .../etc/s6-overlay/s6-rc.d/ssh-agent/up | 5 ++ .../user/contents.d/{queue-worker => horizon} | 0 .../s6-rc.d/user/contents.d/ssh-agent | 0 .../etc/s6-overlay/s6-rc.d/ssh-agent/type | 1 + .../etc/s6-overlay/s6-rc.d/ssh-agent/up | 5 ++ .../s6-rc.d/user/contents.d/ssh-agent | 0 20 files changed, 61 insertions(+), 37 deletions(-) create mode 100644 docker/dev-ssu/etc/s6-overlay/s6-rc.d/horizon/run rename docker/dev-ssu/etc/s6-overlay/s6-rc.d/{queue-worker => horizon}/type (100%) delete mode 100644 docker/dev-ssu/etc/s6-overlay/s6-rc.d/queue-worker/run create mode 100644 docker/dev-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/type create mode 100644 docker/dev-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/up rename docker/dev-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/{queue-worker => horizon} (100%) create mode 100644 docker/dev-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/ssh-agent create mode 100644 docker/prod-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/type create mode 100644 docker/prod-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/up create mode 100644 docker/prod-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/ssh-agent diff --git a/app/Actions/CoolifyTask/RunRemoteProcess.php b/app/Actions/CoolifyTask/RunRemoteProcess.php index cc4bca873..e213f57f1 100644 --- a/app/Actions/CoolifyTask/RunRemoteProcess.php +++ b/app/Actions/CoolifyTask/RunRemoteProcess.php @@ -73,7 +73,7 @@ class RunRemoteProcess $this->time_start = hrtime(true); $status = ProcessStatus::IN_PROGRESS; - $processResult = Process::forever()->run($this->getCommand(), $this->handleOutput(...)); + $processResult = processWithEnv()->forever()->run($this->getCommand(), $this->handleOutput(...)); if ($this->activity->properties->get('status') === ProcessStatus::ERROR->value) { $status = ProcessStatus::ERROR; @@ -104,11 +104,10 @@ class RunRemoteProcess { $user = $this->activity->getExtraProperty('user'); $server_ip = $this->activity->getExtraProperty('server_ip'); - $private_key_location = $this->activity->getExtraProperty('private_key_location'); $port = $this->activity->getExtraProperty('port'); $command = $this->activity->getExtraProperty('command'); - return generate_ssh_command($private_key_location, $server_ip, $user, $port, $command); + return generateSshCommand($server_ip, $user, $port, $command); } protected function handleOutput(string $type, string $output) diff --git a/app/Data/CoolifyTaskArgs.php b/app/Data/CoolifyTaskArgs.php index 1b30126f0..44e62147c 100644 --- a/app/Data/CoolifyTaskArgs.php +++ b/app/Data/CoolifyTaskArgs.php @@ -13,7 +13,6 @@ class CoolifyTaskArgs extends Data { public function __construct( public string $server_ip, - public string $private_key_location, public string $command, public int $port, public string $user, diff --git a/app/Http/Livewire/Server/ShowPrivateKey.php b/app/Http/Livewire/Server/ShowPrivateKey.php index cfb1cdd67..1ec98b8b2 100644 --- a/app/Http/Livewire/Server/ShowPrivateKey.php +++ b/app/Http/Livewire/Server/ShowPrivateKey.php @@ -14,6 +14,7 @@ class ShowPrivateKey extends Component public function setPrivateKey($newPrivateKeyId) { try { + refresh_server_connection($this->server->privateKey); $oldPrivateKeyId = $this->server->private_key_id; $this->server->update([ 'private_key_id' => $newPrivateKeyId @@ -26,7 +27,7 @@ class ShowPrivateKey extends Component 'private_key_id' => $oldPrivateKeyId ]); $this->server->refresh(); - refresh_server_connection($this->server->privateKey); + refresh_server_connection($this->server->privateKey); return general_error_handler($e, that: $this); } } diff --git a/app/Traits/ExecuteRemoteCommand.php b/app/Traits/ExecuteRemoteCommand.php index fd20c3764..e03c414b8 100644 --- a/app/Traits/ExecuteRemoteCommand.php +++ b/app/Traits/ExecuteRemoteCommand.php @@ -28,9 +28,8 @@ trait ExecuteRemoteCommand $ip = data_get($this->server, 'ip'); $user = data_get($this->server, 'user'); $port = data_get($this->server, 'port'); - $private_key_location = get_private_key_for_server($this->server); - $commandsText->each(function ($single_command) use ($private_key_location, $ip, $user, $port) { + $commandsText->each(function ($single_command) use ($ip, $user, $port) { $command = data_get($single_command, 'command') ?? $single_command[0] ?? null; if ($command === null) { throw new \RuntimeException('Command is not set'); @@ -39,8 +38,8 @@ trait ExecuteRemoteCommand $ignore_errors = data_get($single_command, 'ignore_errors', false); $this->save = data_get($single_command, 'save'); - $remote_command = generate_ssh_command($private_key_location, $ip, $user, $port, $command); - $process = Process::timeout(3600)->idleTimeout(3600)->start($remote_command, function (string $type, string $output) use ($command, $hidden) { + $remote_command = generateSshCommand( $ip, $user, $port, $command); + $process = processWithEnv()->timeout(3600)->idleTimeout(3600)->start($remote_command, function (string $type, string $output) use ($command, $hidden) { $output = Str::of($output)->trim(); $new_log_entry = [ 'command' => $command, diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index d713e0c19..ab1551ed8 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -33,12 +33,9 @@ function remote_process( } } - $private_key_location = save_private_key_for_server($server); - return resolve(PrepareCoolifyTask::class, [ 'remoteProcessArgs' => new CoolifyTaskArgs( server_ip: $server->ip, - private_key_location: $private_key_location, command: <<name} does not have a private key"); } - $temp_file = "id.root@{$server->ip}"; - Storage::disk('ssh-keys')->put($temp_file, $server->privateKey->private_key); - Storage::disk('ssh-mux')->makeDirectory('.'); - return '/var/www/html/storage/app/ssh/keys/' . $temp_file; + Process::run("echo '{$server->privateKey->private_key}' | ssh-add -d -"); +} +function addPrivateKeyToSshAgent(Server $server, bool $onlyRemove = false) +{ + if (data_get($server, 'privateKey.private_key') === null) { + throw new \Exception("Server {$server->name} does not have a private key"); + } + // ray('adding key', $server->privateKey->private_key); + Process::run("echo '{$server->privateKey->private_key}' | ssh-add -q -"); } -function generate_ssh_command(string $private_key_location, string $server_ip, string $user, string $port, string $command, bool $isMux = true) +function generateSshCommand(string $server_ip, string $user, string $port, string $command, bool $isMux = true) { + $server = Server::where('ip', $server_ip)->first(); + if (!$server) { + throw new \Exception("Server with ip {$server_ip} not found"); + } + addPrivateKeyToSshAgent($server); $timeout = config('constants.ssh.command_timeout'); $connectionTimeout = config('constants.ssh.connection_timeout'); $serverInterval = config('constants.ssh.server_interval'); @@ -82,8 +83,7 @@ function generate_ssh_command(string $private_key_location, string $server_ip, s $ssh_command .= '-o ControlMaster=auto -o ControlPersist=1m -o ControlPath=/var/www/html/storage/app/ssh/mux/%h_%p_%r '; } $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"; - $ssh_command .= "-i {$private_key_location} " - . '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ' + $ssh_command .= '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ' . '-o PasswordAuthentication=no ' . "-o ConnectTimeout=$connectionTimeout " . "-o ServerAliveInterval=$serverInterval " @@ -94,11 +94,16 @@ function generate_ssh_command(string $private_key_location, string $server_ip, s . " 'bash -se' << \\$delimiter" . PHP_EOL . $command . PHP_EOL . $delimiter; - ray($ssh_command); + // ray($ssh_command); return $ssh_command; } -function instantCommand(string $command, $throwError = true) { - $process = Process::run($command); +function processWithEnv() +{ + return Process::env(['SSH_AUTH_SOCK' => config('coolify.ssh_auth_sock')]); +} +function instantCommand(string $command, $throwError = true) +{ + $process = processWithEnv()->run($command); $output = trim($process->output()); $exitCode = $process->exitCode(); if ($exitCode !== 0) { @@ -112,9 +117,8 @@ function instantCommand(string $command, $throwError = true) { function instant_remote_process(array $command, Server $server, $throwError = true, $repeat = 1) { $command_string = implode("\n", $command); - $private_key_location = save_private_key_for_server($server); - $ssh_command = generate_ssh_command($private_key_location, $server->ip, $server->user, $server->port, $command_string); - $process = Process::run($ssh_command); + $ssh_command = generateSshCommand($server->ip, $server->user, $server->port, $command_string); + $process = processWithEnv()->run($ssh_command); $output = trim($process->output()); $exitCode = $process->exitCode(); if ($exitCode !== 0) { @@ -172,6 +176,7 @@ function refresh_server_connection(PrivateKey $private_key) // currentTeam()->privateKeys = PrivateKey::where('team_id', currentTeam()->id)->get(); // } } + removePrivateKeyFromSshAgent($server); } function validateServer(Server $server) @@ -212,7 +217,7 @@ function validateServer(Server $server) $server->settings->is_usable = false; throw $e; } finally { - if(data_get($server,'settings')) $server->settings->save(); + if (data_get($server, 'settings')) $server->settings->save(); } } diff --git a/config/coolify.php b/config/coolify.php index cd16d6b6f..68960015b 100644 --- a/config/coolify.php +++ b/config/coolify.php @@ -8,4 +8,5 @@ return [ 'dev_webhook' => env('SERVEO_URL'), 'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'), 'helper_image' => env('HELPER_IMAGE', 'ghcr.io/coollabsio/coolify-helper:latest'), + 'ssh_auth_sock' => env('SSH_AUTH_SOCK', '/tmp/coolify-ssh-agent.sock'), ]; diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index cefdec07f..9af78058f 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -21,6 +21,7 @@ services: SSL_MODE: "off" AUTORUN_LARAVEL_STORAGE_LINK: "false" AUTORUN_LARAVEL_MIGRATION: "false" + SSH_AUTH_SOCK: "/tmp/coolify-ssh-agent.sock" volumes: - .:/var/www/html/:cached postgres: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 6268f9963..473513115 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -64,6 +64,7 @@ services: - LEMON_SQUEEZY_BASIC_PLAN_IDS - LEMON_SQUEEZY_PRO_PLAN_IDS - LEMON_SQUEEZY_ULTIMATE_PLAN_IDS + - SSH_AUTH_SOCK="/tmp/coolify-ssh-agent.sock" ports: - "${APP_PORT:-8000}:80" expose: diff --git a/docker/dev-ssu/Dockerfile b/docker/dev-ssu/Dockerfile index dc999f785..afc606d67 100644 --- a/docker/dev-ssu/Dockerfile +++ b/docker/dev-ssu/Dockerfile @@ -24,4 +24,4 @@ RUN echo "alias mfs='php artisan migrate:fresh --seed'" >>/etc/bash.bashrc RUN echo "alias cda='composer dump-autoload'" >>/etc/bash.bashrc RUN echo "alias run='./scripts/run'" >>/etc/bash.bashrc -# COPY --chmod=755 docker/dev-ssu/etc/s6-overlay/ /etc/s6-overlay/ +COPY --chmod=755 docker/dev-ssu/etc/s6-overlay/ /etc/s6-overlay/ diff --git a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/horizon/run b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/horizon/run new file mode 100644 index 000000000..cec4f1dda --- /dev/null +++ b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/horizon/run @@ -0,0 +1,5 @@ +#!/command/execlineb -P +foreground { + s6-sleep 5 + su - webuser -c "php /var/www/html/artisan horizon" +} diff --git a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/queue-worker/type b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/horizon/type similarity index 100% rename from docker/dev-ssu/etc/s6-overlay/s6-rc.d/queue-worker/type rename to docker/dev-ssu/etc/s6-overlay/s6-rc.d/horizon/type diff --git a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/queue-worker/run b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/queue-worker/run deleted file mode 100644 index 0029f9615..000000000 --- a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/queue-worker/run +++ /dev/null @@ -1,2 +0,0 @@ -#!/command/execlineb -P -su - webuser -c "php /var/www/html/artisan queue:listen" diff --git a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/scheduler-worker/run b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/scheduler-worker/run index 8021572af..0f205c897 100644 --- a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/scheduler-worker/run +++ b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/scheduler-worker/run @@ -1,2 +1,5 @@ #!/command/execlineb -P -su - webuser -c "php /var/www/html/artisan schedule:work" +foreground { + s6-sleep 5 + su - webuser -c "php /var/www/html/artisan schedule:work" +} diff --git a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/type b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/type new file mode 100644 index 000000000..bdd22a185 --- /dev/null +++ b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/type @@ -0,0 +1 @@ +oneshot diff --git a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/up b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/up new file mode 100644 index 000000000..0490fb31f --- /dev/null +++ b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/up @@ -0,0 +1,5 @@ +#!/usr/bin/execlineb -P +foreground { + s6-sleep 5 + su - webuser -c "ssh-agent -a /tmp/coolify-ssh-agent.sock" +} diff --git a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/queue-worker b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/horizon similarity index 100% rename from docker/dev-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/queue-worker rename to docker/dev-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/horizon diff --git a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/ssh-agent b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/ssh-agent new file mode 100644 index 000000000..e69de29bb diff --git a/docker/prod-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/type b/docker/prod-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/type new file mode 100644 index 000000000..bdd22a185 --- /dev/null +++ b/docker/prod-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/type @@ -0,0 +1 @@ +oneshot diff --git a/docker/prod-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/up b/docker/prod-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/up new file mode 100644 index 000000000..0490fb31f --- /dev/null +++ b/docker/prod-ssu/etc/s6-overlay/s6-rc.d/ssh-agent/up @@ -0,0 +1,5 @@ +#!/usr/bin/execlineb -P +foreground { + s6-sleep 5 + su - webuser -c "ssh-agent -a /tmp/coolify-ssh-agent.sock" +} diff --git a/docker/prod-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/ssh-agent b/docker/prod-ssu/etc/s6-overlay/s6-rc.d/user/contents.d/ssh-agent new file mode 100644 index 000000000..e69de29bb From 046eab37764854bd29565faac7442ce10cdf826a Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 14 Sep 2023 10:26:48 +0200 Subject: [PATCH 08/13] fix: processWithEnv()->run --- bootstrap/helpers/remoteProcess.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index ab1551ed8..e0d2f68db 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -54,7 +54,7 @@ function removePrivateKeyFromSshAgent(Server $server) if (data_get($server, 'privateKey.private_key') === null) { throw new \Exception("Server {$server->name} does not have a private key"); } - Process::run("echo '{$server->privateKey->private_key}' | ssh-add -d -"); + processWithEnv()->run("echo '{$server->privateKey->private_key}' | ssh-add -d -"); } function addPrivateKeyToSshAgent(Server $server, bool $onlyRemove = false) { @@ -62,7 +62,7 @@ function addPrivateKeyToSshAgent(Server $server, bool $onlyRemove = false) throw new \Exception("Server {$server->name} does not have a private key"); } // ray('adding key', $server->privateKey->private_key); - Process::run("echo '{$server->privateKey->private_key}' | ssh-add -q -"); + processWithEnv()->run("echo '{$server->privateKey->private_key}' | ssh-add -q -"); } function generateSshCommand(string $server_ip, string $user, string $port, string $command, bool $isMux = true) From 4a4d73b87b94776be651de391d61535b6e1c78a1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 14 Sep 2023 10:39:05 +0200 Subject: [PATCH 09/13] fix: plus boarding step about Coolify --- app/Http/Livewire/Boarding/Index.php | 3 +- .../views/components/boarding-step.blade.php | 4 +- .../views/livewire/boarding/index.blade.php | 52 +++++++++++++++---- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/app/Http/Livewire/Boarding/Index.php b/app/Http/Livewire/Boarding/Index.php index 2cb3b1049..77675441d 100644 --- a/app/Http/Livewire/Boarding/Index.php +++ b/app/Http/Livewire/Boarding/Index.php @@ -53,12 +53,13 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== $this->remoteServerHost = 'coolify-testing-host'; } } - public function welcome() { + public function explanation() { if (isCloud()) { return $this->setServerType('remote'); } $this->currentState = 'select-server-type'; } + public function restartBoarding() { if ($this->createdServer) { diff --git a/resources/views/components/boarding-step.blade.php b/resources/views/components/boarding-step.blade.php index e9341cbd9..9314727bd 100644 --- a/resources/views/components/boarding-step.blade.php +++ b/resources/views/components/boarding-step.blade.php @@ -14,12 +14,12 @@ @endif - @if($explanation) + @isset($explanation)

Explanation

{{$explanation}}
- @endif + @endisset diff --git a/resources/views/livewire/boarding/index.blade.php b/resources/views/livewire/boarding/index.blade.php index bee5f04b7..8c1e7125c 100644 --- a/resources/views/livewire/boarding/index.blade.php +++ b/resources/views/livewire/boarding/index.blade.php @@ -5,12 +5,34 @@

Welcome to Coolify

Let me help you to set the basics.

- Get Started + Get Started
@endif
+ @if ($currentState === 'explanation') + + + Coolify is an all-in-one application to automate tasks on your servers, deploy application with Git + integrations, deploy databases and services, monitor these resources with notifications and alerts + without vendor lock-in + and much much more. +

+ + +
+ +

You do not to manage your servers too much. Coolify do it for you.

+

All configurations are stored on your server, so everything works without Coolify (except integrations and automations).

+

You will get notified on your favourite platform (Discord, Telegram, Email, etc.) when something goes wrong, or an action needed from your side.

+
+ + Next + + +
+ @endif @if ($currentState === 'select-server-type') @@ -18,9 +40,11 @@ or on a ? - Localhost + Localhost - Remote Server + Remote Server @@ -42,9 +66,11 @@ Do you have your own SSH Private Key? - Yes + Yes - No (create one for me) + No (create one for me) @if (count($privateKeys) > 0)
@@ -115,9 +141,10 @@ @if ($privateKeyType === 'create') - - ACTION REQUIRED: Copy the 'Public Key' to your server's ~/.ssh/authorized_keys - file. + + ACTION REQUIRED: Copy the 'Public Key' to your server's + ~/.ssh/authorized_keys + file. @endif Save @@ -182,7 +209,8 @@ Could not find Docker Engine on your server. Do you want me to install it for you? - + Let's do it! @@ -233,12 +261,14 @@ @endif - Let's create a new one! + Let's create a new + one!
@if (count($projects) > 0)
- + @foreach ($projects as $project) From 49f8abcd79d9f174052975731ba9d7180f108788 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 14 Sep 2023 10:56:25 +0200 Subject: [PATCH 10/13] remove unnecessary things --- bootstrap/helpers/remoteProcess.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index e0d2f68db..84f2dc9d3 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -56,7 +56,7 @@ function removePrivateKeyFromSshAgent(Server $server) } processWithEnv()->run("echo '{$server->privateKey->private_key}' | ssh-add -d -"); } -function addPrivateKeyToSshAgent(Server $server, bool $onlyRemove = false) +function addPrivateKeyToSshAgent(Server $server) { if (data_get($server, 'privateKey.private_key') === null) { throw new \Exception("Server {$server->name} does not have a private key"); From 3c8c8e20b1435d33897a9cf9c736936fadae1a6f Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 14 Sep 2023 11:37:20 +0200 Subject: [PATCH 11/13] fix: editable ip fix: traefik dashboard --- resources/views/livewire/server/form.blade.php | 14 +++++--------- .../views/livewire/server/proxy/deploy.blade.php | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index 9b297b70c..ebb40f78f 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -35,11 +35,7 @@ label="Is it part of a Swarm cluster?" /> --}}
- @if ($server->id === 0) - - @else - - @endif +
@@ -52,15 +48,15 @@ @endif @if ($server->settings->is_reachable && !$server->settings->is_usable && $server->id !== 0) - + Install Docker Engine 24.0 @endif @if ($server->isFunctional())

Settings

- + @endif

Danger Zone

diff --git a/resources/views/livewire/server/proxy/deploy.blade.php b/resources/views/livewire/server/proxy/deploy.blade.php index 66cf4301b..9f133d33a 100644 --- a/resources/views/livewire/server/proxy/deploy.blade.php +++ b/resources/views/livewire/server/proxy/deploy.blade.php @@ -11,7 +11,7 @@ @if (data_get($server, 'proxy.status') === 'running')
@if ($application->previews->count() > 0) -

Deployed Previews

+

Deployed Previews

@foreach ($application->previews as $preview) -
+
PR #{{ data_get($preview, 'pull_request_id') }} | @if (data_get($preview, 'status') === 'running') diff --git a/routes/webhooks.php b/routes/webhooks.php index c3c80dba3..aebcfaf14 100644 --- a/routes/webhooks.php +++ b/routes/webhooks.php @@ -116,7 +116,7 @@ Route::post('/source/github/events', function () { $applications = $applications->where('git_branch', $base_branch)->get(); } if ($applications->isEmpty()) { - return response('Nothing to do. No applications found.'); + return response("Nothing to do. No applications found with branch '$base_branch'."); } foreach ($applications as $application) { $isFunctional = $application->destination->server->isFunctional(); @@ -178,6 +178,7 @@ Route::post('/source/github/events', function () { } } } catch (Exception $e) { + ray($e->getMessage()); return general_error_handler(err: $e); } });