Merge pull request #1238 from coollabsio/next

Fixes
This commit is contained in:
Andras Bacsai 2023-09-18 15:31:54 +02:00 committed by GitHub
commit b7acf99cde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 301 additions and 405 deletions

View File

@ -16,9 +16,12 @@ class CheckConfiguration
"cat $proxy_path/docker-compose.yml",
], $server, false);
if ($reset || is_null($proxy_configuration)) {
if ($reset || !$proxy_configuration || is_null($proxy_configuration)) {
$proxy_configuration = Str::of(generate_default_proxy_configuration($server))->trim()->value;
}
if (!$proxy_configuration || is_null($proxy_configuration)) {
throw new \Exception("Could not generate proxy configuration");
}
return $proxy_configuration;
}
}

View File

@ -51,9 +51,9 @@ class StartProxy
"cd $proxy_path",
"echo '####### Creating Docker Compose file...'",
"echo '####### Pulling docker image...'",
'docker compose pull',
'docker compose pull || docker-compose pull',
"echo '####### Stopping existing coolify-proxy...'",
"docker compose down -v --remove-orphans > /dev/null 2>&1 || true",
"docker compose down -v --remove-orphans > /dev/null 2>&1 || docker-compose down -v --remove-orphans > /dev/null 2>&1 || true",
"command -v fuser >/dev/null || command -v lsof >/dev/null || echo '####### Could not kill existing processes listening on port 80 & 443. Please stop the process holding these ports...'",
"command -v lsof >/dev/null && lsof -nt -i:80 | xargs -r kill -9 || true",
"command -v lsof >/dev/null && lsof -nt -i:443 | xargs -r kill -9 || true",
@ -63,7 +63,7 @@ class StartProxy
"systemctl disable apache2 > /dev/null 2>&1 || true",
"systemctl disable apache > /dev/null 2>&1 || true",
"echo '####### Starting coolify-proxy...'",
'docker compose up -d --remove-orphans',
'docker compose up -d --remove-orphans || docker-compose up -d --remove-orphans',
"echo '####### Proxy installed successfully...'"
];
if (!$async) {

View File

@ -7,7 +7,7 @@ use App\Models\StandaloneDocker;
class InstallDocker
{
public function __invoke(Server $server, bool $instant = false)
public function __invoke(Server $server)
{
$dockerVersion = '24.0';
$config = base64_encode('{
@ -55,9 +55,6 @@ class InstallDocker
"echo '####### Done!'"
];
}
if ($instant) {
return instant_remote_process($command, $server);
}
return remote_process($command, $server);
}
}

View File

@ -17,8 +17,11 @@ class CoolifyTaskArgs extends Data
public string $type,
public ?string $type_uuid = null,
public ?Model $model = null,
public string $status = ProcessStatus::QUEUED->value,
public ?string $status = null ,
public bool $ignore_errors = false,
) {
if(is_null($status)){
$this->status = ProcessStatus::QUEUED->value;
}
}
}

View File

@ -9,7 +9,6 @@ use App\Models\Server;
use App\Models\Team;
use Illuminate\Support\Collection;
use Livewire\Component;
use Visus\Cuid2\Cuid2;
class Index extends Component
{
@ -40,8 +39,8 @@ class Index extends Component
public bool $dockerInstallationStarted = false;
public string $localhostPublicKey;
public bool $localhostReachable = true;
public string $serverPublicKey;
public bool $serverReachable = true;
public function mount()
{
@ -70,14 +69,6 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
public function restartBoarding()
{
// if ($this->selectedServerType !== 'localhost') {
// if ($this->createdServer) {
// $this->createdServer->delete();
// }
// if ($this->createdPrivateKey) {
// $this->createdPrivateKey->delete();
// }
// }
return redirect()->route('boarding');
}
public function skipBoarding()
@ -98,7 +89,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
if (!$this->createdServer) {
return $this->emit('error', 'Localhost server is not found. Something went wrong during installation. Please try to reinstall or contact support.');
}
$this->localhostPublicKey = $this->createdServer->privateKey->publicKey();
$this->serverPublicKey = $this->createdServer->privateKey->publicKey();
return $this->validateServer('localhost');
} elseif ($this->selectedServerType === 'remote') {
$this->privateKeys = PrivateKey::ownedByCurrentTeam(['name'])->where('id', '!=', 0)->get();
@ -123,6 +114,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
return;
}
$this->selectedExistingPrivateKey = $this->createdServer->privateKey->id;
$this->serverPublicKey = $this->createdServer->privateKey->publicKey();
$this->validateServer();
}
public function getProxyType()
@ -201,11 +193,11 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
instant_remote_process(['uptime'], $this->createdServer, true);
$this->createdServer->settings->update([
$this->createdServer->settings()->update([
'is_reachable' => true,
]);
} catch (\Throwable $e) {
$this->localhostReachable = false;
$this->serverReachable = false;
return handleError(error: $e, customErrorMessage: $customErrorMessage, livewire: $this);
}
@ -216,8 +208,12 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
$this->currentState = 'install-docker';
throw new \Exception('Docker version is not supported or not installed.');
}
$this->dockerInstalledOrSkipped();
$this->createdServer->settings()->update([
'is_usable' => true,
]);
$this->getProxyType();
} catch (\Throwable $e) {
$this->dockerInstallationStarted = false;
return handleError(error: $e, customErrorMessage: $customErrorMessage, livewire: $this);
}
}
@ -229,10 +225,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
}
public function dockerInstalledOrSkipped()
{
$this->createdServer->settings->update([
'is_usable' => true,
]);
$this->getProxyType();
$this->validateServer();
}
public function selectProxy(string|null $proxyType = null)
{

View File

@ -86,7 +86,6 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
$this->server->team->notify(new ContainerRestarted('coolify-proxy', $this->server));
}
} else {
ray($foundProxyContainer);
$this->server->proxy->status = data_get($foundProxyContainer, 'State.Status');
$this->server->save();
}
@ -198,94 +197,6 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
$url = base_url() . '/project/' . $project->uuid . "/" . $environment->name . "/database/" . $database->uuid;
$this->server->team->notify(new ContainerStopped($containerName, $this->server, $url));
}
return;
foreach ($applications as $application) {
$uuid = data_get($application, 'uuid');
$id = data_get($application, 'id');
$foundContainer = $containers->filter(function ($value, $key) use ($id, $uuid) {
$labels = data_get($value, 'Config.Labels');
$labels = Arr::undot(format_docker_labels_to_json($labels));
$labelId = data_get($labels, 'coolify.applicationId');
if ($labelId == $id) {
return $value;
}
$isPR = Str::startsWith(data_get($value, 'Name'), "/$uuid");
$isPR = Str::contains(data_get($value, 'Name'), "-pr-");
if ($isPR) {
return false;
}
return $value;
})->first();
if ($foundContainer) {
$containerStatus = data_get($foundContainer, 'State.Status');
$databaseStatus = data_get($application, 'status');
if ($containerStatus !== $databaseStatus) {
$application->update(['status' => $containerStatus]);
}
} else {
$databaseStatus = data_get($application, 'status');
if ($databaseStatus !== 'exited') {
$application->update(['status' => 'exited']);
$name = data_get($application, 'name');
$fqdn = data_get($application, 'fqdn');
$containerName = $name ? "$name ($fqdn)" : $fqdn;
$project = data_get($application, 'environment.project');
$environment = data_get($application, 'environment');
$url = base_url() . '/project/' . $project->uuid . "/" . $environment->name . "/application/" . $application->uuid;
$this->server->team->notify(new ContainerStopped($containerName, $this->server, $url));
}
}
$previews = $application->previews;
foreach ($previews as $preview) {
$foundContainer = $containers->filter(function ($value, $key) use ($id, $uuid, $preview) {
$labels = data_get($value, 'Config.Labels');
$labels = Arr::undot(format_docker_labels_to_json($labels));
$labelId = data_get($labels, 'coolify.applicationId');
if ($labelId == "$id-pr-{$preview->id}") {
return $value;
}
return Str::startsWith(data_get($value, 'Name'), "/$uuid-pr-{$preview->id}");
})->first();
}
}
foreach ($databases as $database) {
$uuid = data_get($database, 'uuid');
$foundContainer = $containers->filter(function ($value, $key) use ($uuid) {
return Str::startsWith(data_get($value, 'Name'), "/$uuid");
})->first();
if ($foundContainer) {
$containerStatus = data_get($foundContainer, 'State.Status');
$databaseStatus = data_get($database, 'status');
if ($containerStatus !== $databaseStatus) {
$database->update(['status' => $containerStatus]);
}
} else {
$databaseStatus = data_get($database, 'status');
if ($databaseStatus !== 'exited') {
$database->update(['status' => 'exited']);
$name = data_get($database, 'name');
$containerName = $name;
$project = data_get($database, 'environment.project');
$environment = data_get($database, 'environment');
$url = base_url() . '/project/' . $project->uuid . "/" . $environment->name . "/database/" . $database->uuid;
$this->server->team->notify(new ContainerStopped($containerName, $this->server, $url));
}
}
}
// TODO Monitor other containers not managed by Coolify
} catch (\Throwable $e) {
send_internal_notification('ContainerStatusJob failed with: ' . $e->getMessage());
ray($e->getMessage());

View File

@ -14,7 +14,7 @@ class DeploymentFailed extends Notification implements ShouldQueue
{
use Queueable;
public $tries = 5;
public $tries = 1;
public Application $application;
public ?ApplicationPreview $preview = null;

View File

@ -14,7 +14,7 @@ class DeploymentSuccess extends Notification implements ShouldQueue
{
use Queueable;
public $tries = 5;
public $tries = 1;
public Application $application;
public ApplicationPreview|null $preview = null;

View File

@ -13,7 +13,7 @@ class StatusChanged extends Notification implements ShouldQueue
{
use Queueable;
public $tries = 5;
public $tries = 1;
public Application $application;
public string $application_name;

View File

@ -6,27 +6,34 @@ use Exception;
use Illuminate\Mail\Message;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Mail;
use Log;
class EmailChannel
{
public function send(SendsEmail $notifiable, Notification $notification): void
{
$this->bootConfigs($notifiable);
$recepients = $notifiable->getRecepients($notification);
try {
$this->bootConfigs($notifiable);
$recepients = $notifiable->getRecepients($notification);
ray($recepients);
if (count($recepients) === 0) {
throw new Exception('No email recipients found');
}
if (count($recepients) === 0) {
throw new Exception('No email recipients found');
$mailMessage = $notification->toMail($notifiable);
Mail::send(
[],
[],
fn (Message $message) => $message
->to($recepients)
->subject($mailMessage->subject)
->html((string)$mailMessage->render())
);
} catch (Exception $e) {
ray($e->getMessage());
send_internal_notification("EmailChannel error: {$e->getMessage()}. Failed to send email to: " . implode(', ', $recepients) . " with subject: {$mailMessage->subject}");
throw $e;
}
$mailMessage = $notification->toMail($notifiable);
Mail::send(
[],
[],
fn (Message $message) => $message
->to($recepients)
->subject($mailMessage->subject)
->html((string)$mailMessage->render())
);
}
private function bootConfigs($notifiable): void

View File

@ -12,7 +12,7 @@ class ContainerRestarted extends Notification implements ShouldQueue
{
use Queueable;
public $tries = 5;
public $tries = 1;
public function __construct(public string $name, public Server $server, public ?string $url = null)

View File

@ -3,8 +3,6 @@
namespace App\Notifications\Database;
use App\Models\ScheduledDatabaseBackup;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@ -14,7 +12,7 @@ class BackupFailed extends Notification implements ShouldQueue
{
use Queueable;
public $tries = 5;
public $tries = 1;
public string $name;
public string $frequency;

View File

@ -3,8 +3,6 @@
namespace App\Notifications\Database;
use App\Models\ScheduledDatabaseBackup;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@ -14,7 +12,7 @@ class BackupSuccess extends Notification implements ShouldQueue
{
use Queueable;
public $tries = 5;
public $tries = 1;
public string $name;
public string $frequency;

View File

@ -18,12 +18,14 @@ use Spatie\Activitylog\Contracts\Activity;
function remote_process(
array $command,
Server $server,
string $type = ActivityTypes::INLINE->value,
?string $type = null,
?string $type_uuid = null,
?Model $model = null,
bool $ignore_errors = false,
): Activity {
if (is_null($type)) {
$type = ActivityTypes::INLINE->value;
}
$command_string = implode("\n", $command);
if (auth()->user()) {
$teams = auth()->user()->teams->pluck('id');

View File

@ -138,5 +138,6 @@ function allowedPathsForBoardingAccounts()
...allowedPathsForUnsubscribedAccounts(),
'boarding',
'livewire/message/boarding.index',
'livewire/message/activity-monitor'
];
}

View File

@ -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.42',
'release' => '4.0.0-beta.43',
// When left empty or `null` the Laravel environment will be used
'environment' => config('app.env'),

View File

@ -1,3 +1,3 @@
<?php
return '4.0.0-beta.42';
return '4.0.0-beta.43';

View File

@ -1,7 +1,7 @@
@props([
'showSubscribeButtons' => true,
])
<div x-data="{ selected: 'yearly' }" class="w-full pb-20">
<div x-data="{ selected: 'monthly' }" class="w-full pb-20">
<div class="px-6 mx-auto lg:px-8">
<div class="flex justify-center">
<fieldset
@ -24,80 +24,36 @@
<div class="py-2 text-center"><span class="font-bold text-warning">{{ config('constants.limits.trial_period') }}
days trial</span> included on all plans, without credit card details.</div>
<div x-show="selected === 'monthly'" class="flex justify-center h-10 mt-3 text-sm leading-6 ">
<div>Save <span class="font-bold text-warning">1 month</span> annually with the yearly plans.
<div>Save <span class="font-bold text-warning">10%</span> annually with the yearly plans.
</div>
</div>
<div x-show="selected === 'yearly'" class="flex justify-center h-10 mt-3 text-sm leading-6 ">
<div>
</div>
</div>
<div class="p-4 rounded bg-coolgray-400">
<h2 id="tier-hobby" class="flex items-start gap-4 text-4xl font-bold tracking-tight">Unlimited Trial
<x-forms.button><a class="font-bold text-white hover:no-underline"
href="https://github.com/coollabsio/coolify">Get Started</a></x-forms.button>
</h2>
<p class="mt-4 text-sm leading-6">Start self-hosting <span class="text-warning">without limits</span> with
our
OSS version. Same features as the paid version, but you have to manage by yourself.</p>
</div>
<div class="flow-root mt-12">
<div
class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-coolgray-500 isolate gap-y-16 sm:mx-auto lg:-mx-8 lg:mt-0 lg:max-w-none lg:grid-cols-4 lg:divide-x lg:divide-y-0 xl:-mx-4">
<div class="px-8 pt-16 lg:pt-0">
<h3 id="tier-trial" class="text-base font-semibold leading-7 text-white">Unlimited Trial</h3>
<p class="flex items-baseline mt-6 gap-x-1">
<span x-show="selected === 'monthly'" x-cloak>
<span class="text-4xl font-bold tracking-tight text-white">Free</span>
</span>
<span x-show="selected === 'yearly'" x-cloak>
<span class="text-4xl font-bold tracking-tight text-white">Still Free </span>
</span>
</p>
<span x-show="selected === 'monthly'" x-cloak>
<span>billed monthly</span>
</span>
<span x-show="selected === 'yearly'" x-cloak>
<span>billed annually</span>
</span>
<a href="https://github.com/coollabsio/coolify" aria-describedby="tier-trial" class="buyme">Get
Started</a>
<p class="mt-10 text-sm leading-6 text-white h-[6.5rem]">Start self-hosting without limits with our
OSS
version.</p>
<ul role="list" class="space-y-3 text-sm leading-6 ">
<li class="flex gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
</svg>
You manage everything
</li>
<li class="flex gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
</svg>
Community Support
</li>
<li class="flex font-bold text-white gap-x-3">
<svg width="512" height="512" class="flex-none w-5 h-6 text-green-600"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path
d="M4 13a8 8 0 0 1 7 7a6 6 0 0 0 3-5a9 9 0 0 0 6-8a3 3 0 0 0-3-3a9 9 0 0 0-8 6a6 6 0 0 0-5 3" />
<path d="M7 14a6 6 0 0 0-3 6a6 6 0 0 0 6-3m4-8a1 1 0 1 0 2 0a1 1 0 1 0-2 0" />
</g>
</svg>
+ All upcoming features
</li>
</ul>
</div>
class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-coolgray-500 isolate gap-y-16 sm:mx-auto lg:-mx-8 lg:mt-0 lg:max-w-none lg:grid-cols-3 lg:divide-x lg:divide-y-0 xl:-mx-4">
<div class="pt-16 lg:px-8 lg:pt-0 xl:px-14">
<h3 id="tier-basic" class="text-base font-semibold leading-7 text-white">Basic</h3>
<p class="flex items-baseline mt-6 gap-x-1">
<span x-show="selected === 'monthly'" x-cloak>
<span class="text-4xl font-bold tracking-tight text-white">$5</span>
<span class="text-sm font-semibold leading-6 ">/month</span>
<span class="text-sm font-semibold leading-6 ">/month + VAT</span>
</span>
<span x-show="selected === 'yearly'" x-cloak>
<span class="text-4xl font-bold tracking-tight text-white">$4</span>
<span class="text-sm font-semibold leading-6 ">/month</span>
<span class="text-sm font-semibold leading-6 ">/month + VAT</span>
</span>
</p>
<span x-show="selected === 'monthly'" x-cloak>
@ -139,8 +95,8 @@
<li class="flex font-bold text-white gap-x-3">
<svg width="512" height="512" class="flex-none w-5 h-6 text-green-600"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path
d="M4 13a8 8 0 0 1 7 7a6 6 0 0 0 3-5a9 9 0 0 0 6-8a3 3 0 0 0-3-3a9 9 0 0 0-8 6a6 6 0 0 0-5 3" />
<path d="M7 14a6 6 0 0 0-3 6a6 6 0 0 0 6-3m4-8a1 1 0 1 0 2 0a1 1 0 1 0-2 0" />
@ -154,12 +110,12 @@
<h3 id="tier-pro" class="text-base font-semibold leading-7 text-white">Pro</h3>
<p class="flex items-baseline mt-6 gap-x-1">
<span x-show="selected === 'monthly'" x-cloak>
<span class="text-4xl font-bold tracking-tight text-white">$29</span>
<span class="text-sm font-semibold leading-6 ">/month</span>
<span class="text-4xl font-bold tracking-tight text-white">$30</span>
<span class="text-sm font-semibold leading-6 ">/month + VAT</span>
</span>
<span x-show="selected === 'yearly'" x-cloak>
<span class="text-4xl font-bold tracking-tight text-white">$26</span>
<span class="text-sm font-semibold leading-6 ">/month</span>
<span class="text-4xl font-bold tracking-tight text-white">$27</span>
<span class="text-sm font-semibold leading-6 ">/month + VAT</span>
</span>
</p>
<span x-show="selected === 'monthly'" x-cloak>
@ -192,7 +148,7 @@
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
</svg>
Basic Support
Included Email System
</li>
<li class="flex gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
@ -201,7 +157,7 @@
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
</svg>
Included Email System
Email Support
</li>
<li class="flex font-bold text-white gap-x-3">
<svg width="512" height="512" class="flex-none w-5 h-6 text-green-600"
@ -221,12 +177,12 @@
<h3 id="tier-ultimate" class="text-base font-semibold leading-7 text-white">Ultimate</h3>
<p class="flex items-baseline mt-6 gap-x-1">
<span x-show="selected === 'monthly'" x-cloak>
<span class="text-4xl font-bold tracking-tight text-white">$69</span>
<span class="text-sm font-semibold leading-6 ">/month</span>
<span class="text-4xl font-bold tracking-tight text-white">$?</span>
<span class="text-sm font-semibold leading-6 ">/month + VAT</span>
</span>
<span x-show="selected === 'yearly'" x-cloak>
<span class="text-4xl font-bold tracking-tight text-white">$63</span>
<span class="text-sm font-semibold leading-6 ">/month</span>
<span class="text-4xl font-bold tracking-tight text-white">$?</span>
<span class="text-sm font-semibold leading-6 ">/month + VAT</span>
</span>
</p>
<span x-show="selected === 'monthly'" x-cloak>
@ -250,17 +206,9 @@
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
</svg>
25 servers <x-helper helper="Bring Your Own Server. All you need is n SSH connection." />
</li>
<li class="flex font-bold text-white gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
</svg>
Priority Support
? servers <x-helper helper="Bring Your Own Server. All you need is n SSH connection." />
</li>
<li class="flex gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
@ -270,6 +218,15 @@
</svg>
Included Email System
</li>
<li class="flex font-bold text-white gap-x-3">
<svg class="flex-none w-5 h-6 text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
</svg>
Priority (Email/Chat) Support
</li>
<li class="flex font-bold text-white gap-x-3">
<svg width="512" height="512" class="flex-none w-5 h-6 text-green-600"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
@ -285,176 +242,186 @@
</ul>
</div>
</div>
<div class="pt-10">Need unlimited servers or official support for your Coolify instance? <a
href="https://docs.coollabs.io/contact" class='text-warning'>Contact us.</a>
</div>
</div>
</div>
<div class="pt-8 pb-12 text-4xl font-bold text-center text-white">Included in all plans</div>
<div class="grid grid-cols-1 gap-10 md:grid-cols-2 gap-y-28">
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" class="icon" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2"
d="M3 7a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v2a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3zm12 13H6a3 3 0 0 1-3-3v-2a3 3 0 0 1 3-3h12M7 8v.01M7 16v.01M20 15l-2 3h3l-2 3" />
</svg>
<div class="p-4 mt-10 rounded">
<div class="flex items-start gap-4 text-xl tracking-tight">Need official support for
your self-hosted instance?
<x-forms.button>
<a class="font-bold text-white hover:no-underline"
href="https://docs.coollabs.io/contact">Contact Us</a>
</x-forms.button>
</div>
<div class="text-2xl font-semibold text-white">Bring Your Own Servers</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Bring your own server from any cloud providers, or even your own server at home! All you need is SSH
access. You will have full control over your server, and you can even use it for other purposes.
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" class="icon" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path
d="M7 7h10a2 2 0 0 1 2 2v1l1 1v3l-1 1v3a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-3l-1-1v-3l1-1V9a2 2 0 0 1 2-2zm3 9h4" />
<circle cx="8.5" cy="11.5" r=".5" fill="#000000" />
<circle cx="15.5" cy="11.5" r=".5" fill="#000000" />
<path d="M9 7L8 3m7 4l1-4" />
</g>
</svg>
<div class="pt-8 pb-12 text-4xl font-bold text-center text-white">Included in all plans</div>
<div class="grid grid-cols-1 gap-10 md:grid-cols-2 gap-y-28">
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" class="icon" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path fill="none" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="M3 7a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v2a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3zm12 13H6a3 3 0 0 1-3-3v-2a3 3 0 0 1 3-3h12M7 8v.01M7 16v.01M20 15l-2 3h3l-2 3" />
</svg>
</div>
<div class="text-2xl font-semibold text-white">Bring Your Own Servers</div>
</div>
<div class="text-2xl font-semibold text-white">Server Automations</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Once you connected your server, Coolify will start managing it and do a
lot of adminstrative tasks for you. You can also write your own scripts to
automate your server<span class="text-warning">*</span>.
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" viewBox="0 0 24 24" class="icon"
xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path d="M15 11h2a2 2 0 0 1 2 2v2m0 4a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-6a2 2 0 0 1 2-2h4" />
<path d="M11 16a1 1 0 1 0 2 0a1 1 0 1 0-2 0m-3-5V8m.347-3.631A4 4 0 0 1 16 6M3 3l18 18" />
</g>
</svg>
<div class="mt-1 text-base leading-7 text-gray-300">
Bring your own server from any cloud providers, or even your own server at home! All you need is SSH
access. You will have full control over your server, and you can even use it for other purposes.
</div>
<div class="text-2xl font-semibold text-white">No Vendor Lock-in</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
You own your own data. All configurations saved on your own servers, so if
you decide to stop using Coolify, you can still continue to manage your
deployed resources.
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" class="icon" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path
d="M7 7h10a2 2 0 0 1 2 2v1l1 1v3l-1 1v3a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-3l-1-1v-3l1-1V9a2 2 0 0 1 2-2zm3 9h4" />
<circle cx="8.5" cy="11.5" r=".5" fill="#000000" />
<circle cx="15.5" cy="11.5" r=".5" fill="#000000" />
<path d="M9 7L8 3m7 4l1-4" />
</g>
</svg>
</div>
<div class="text-2xl font-semibold text-white">Server Automations</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Once you connected your server, Coolify will start managing it and do a
lot of adminstrative tasks for you. You can also write your own scripts to
automate your server<span class="text-warning">*</span>.
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" viewBox="0 0 24 24" class="icon"
xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path
d="M15 11h2a2 2 0 0 1 2 2v2m0 4a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-6a2 2 0 0 1 2-2h4" />
<path
d="M11 16a1 1 0 1 0 2 0a1 1 0 1 0-2 0m-3-5V8m.347-3.631A4 4 0 0 1 16 6M3 3l18 18" />
</g>
</svg>
</div>
<div class="text-2xl font-semibold text-white">No Vendor Lock-in</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
You own your own data. All configurations saved on your own servers, so if
you decide to stop using Coolify, you can still continue to manage your
deployed resources.
</div>
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<rect x="3" y="4" width="18" height="12" rx="1" />
<path d="M7 20h10" />
<path d="M9 16v4" />
<path d="M15 16v4" />
<path d="M7 10h2l2 3l2 -6l1 3h3" />
</svg>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<rect x="3" y="4" width="18" height="12" rx="1" />
<path d="M7 20h10" />
<path d="M9 16v4" />
<path d="M15 16v4" />
<path d="M7 10h2l2 3l2 -6l1 3h3" />
</svg>
</div>
<div class="text-2xl font-semibold text-white">Monitoring</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Coolify will automatically monitor your configured servers and deployed
resources. Notifies you if something goes wrong on your favourite
channels, like Discord, Telegram, via Email and more...
</div>
<div class="text-2xl font-semibold text-white">Monitoring</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Coolify will automatically monitor your configured servers and deployed
resources. Notifies you if something goes wrong on your favourite
channels, like Discord, Telegram, via Email and more...
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" class="icon" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path d="M6 4h10l4 4v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2" />
<path d="M10 14a2 2 0 1 0 4 0a2 2 0 1 0-4 0m4-10v4H8V4" />
</g>
</svg>
</div>
<div class="text-2xl font-semibold text-white">Automatic Backups</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
We automatically backup your databases to any S3 compatible solution. If
something goes wrong, you can easily restore your data with a few clicks.
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<polyline points="5 7 10 12 5 17" />
<line x1="13" y1="17" x2="19" y2="17" />
</svg>
</div>
<div class="text-2xl font-semibold text-white">Powerful API</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Programatically deploy, query, and manage your servers & resources.
Integrate to your CI/CD pipelines, or build your own custom integrations. <span
class="text-warning">*</span>
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" class="icon" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path
d="M4 18a2 2 0 1 0 4 0a2 2 0 1 0-4 0M4 6a2 2 0 1 0 4 0a2 2 0 1 0-4 0m12 12a2 2 0 1 0 4 0a2 2 0 1 0-4 0M6 8v8" />
<path d="M11 6h5a2 2 0 0 1 2 2v8" />
<path d="m14 9l-3-3l3-3" />
</g>
</svg>
</div>
<div class="text-2xl font-semibold text-white">Push to Deploy</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Git integration is default today. We support hosted (github.com,
gitlab.com<span class="inline-block text-warning">*</span>) or self-hosted<span
class="text-warning">*</span>
(Github Enterprise, Gitlab) Git repositories.
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" class="icon" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path fill="none" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="M10 13a2 2 0 1 0 4 0a2 2 0 0 0-4 0m-2 8v-1a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1M15 5a2 2 0 1 0 4 0a2 2 0 0 0-4 0m2 5h2a2 2 0 0 1 2 2v1M5 5a2 2 0 1 0 4 0a2 2 0 0 0-4 0m-2 8v-1a2 2 0 0 1 2-2h2" />
</svg>
</div>
<div class="text-2xl font-semibold text-white">Pull Request Deployments</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Automagically deploy new commits and pull requests separately to quickly
review contributions and speed up your teamwork!
</div>
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" class="icon" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path d="M6 4h10l4 4v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2" />
<path d="M10 14a2 2 0 1 0 4 0a2 2 0 1 0-4 0m4-10v4H8V4" />
</g>
</svg>
</div>
<div class="text-2xl font-semibold text-white">Automatic Backups</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
We automatically backup your databases to any S3 compatible solution. If
something goes wrong, you can easily restore your data with a few clicks.
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<polyline points="5 7 10 12 5 17" />
<line x1="13" y1="17" x2="19" y2="17" />
</svg>
</div>
<div class="text-2xl font-semibold text-white">Powerful API</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Programatically deploy, query, and manage your servers & resources.
Integrate to your CI/CD pipelines, or build your own custom integrations. <span
class="text-warning">*</span>
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" class="icon" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path
d="M4 18a2 2 0 1 0 4 0a2 2 0 1 0-4 0M4 6a2 2 0 1 0 4 0a2 2 0 1 0-4 0m12 12a2 2 0 1 0 4 0a2 2 0 1 0-4 0M6 8v8" />
<path d="M11 6h5a2 2 0 0 1 2 2v8" />
<path d="m14 9l-3-3l3-3" />
</g>
</svg>
</div>
<div class="text-2xl font-semibold text-white">Push to Deploy</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Git integration is default today. We support hosted (github.com,
gitlab.com<span class="inline-block text-warning">*</span>) or self-hosted<span class="text-warning">*</span>
(Github Enterprise, Gitlab) Git repositories.
</div>
</div>
<div>
<div class="flex items-center gap-4 mb-4">
<div class="flex items-center justify-center w-10 h-10 text-white rounded-lg bg-coolgray-500">
<svg width="512" height="512" class="icon" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2"
d="M10 13a2 2 0 1 0 4 0a2 2 0 0 0-4 0m-2 8v-1a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1M15 5a2 2 0 1 0 4 0a2 2 0 0 0-4 0m2 5h2a2 2 0 0 1 2 2v1M5 5a2 2 0 1 0 4 0a2 2 0 0 0-4 0m-2 8v-1a2 2 0 0 1 2-2h2" />
</svg>
</div>
<div class="text-2xl font-semibold text-white">Pull Request Deployments</div>
</div>
<div class="mt-1 text-base leading-7 text-gray-300">
Automagically deploy new commits and pull requests separately to quickly
review contributions and speed up your teamwork!
</div>
<div class="pt-20 text-xs">
<span class="text-warning">*</span> Some features are work in progress and will be available soon.
</div>
</div>
<div class="pt-20 text-xs">
<span class="text-warning">*</span> Some features are work in progress and will be available soon.
</div>
</div>
@isset($other)
{{ $other }}
@endisset
@isset($other)
{{ $other }}
@endisset

View File

@ -1,17 +1,17 @@
@extends('layouts.base')
@section('body')
<x-modal noSubmit modalId="installDocker">
<x-slot:modalBody>
<livewire:activity-monitor header="Docker Installation Logs" />
</x-slot:modalBody>
<x-slot:modalSubmit>
<x-forms.button onclick="installDocker.close()" type="submit">
Close
</x-forms.button>
</x-slot:modalSubmit>
</x-modal>
<main class="min-h-screen hero">
<div class="hero-content">
<x-modal modalId="installDocker">
<x-slot:modalBody>
<livewire:activity-monitor header="Docker Installation Logs" />
</x-slot:modalBody>
<x-slot:modalSubmit>
<x-forms.button onclick="installDocker.close()" type="submit">
Close
</x-forms.button>
</x-slot:modalSubmit>
</x-modal>
{{ $slot }}
</div>
</main>

View File

@ -50,13 +50,13 @@
<x-forms.button class="justify-center box" wire:target="setServerType('remote')"
wire:click="setServerType('remote')">Remote Server
</x-forms.button>
@if (!$localhostReachable)
@if (!$serverReachable)
Localhost is not reachable with the following public key.
<br /> <br />
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for user
'root' or skip the boarding process and add a new private key manually to Coolify and to the
server.
<x-forms.input readonly id="localhostPublicKey"></x-forms.input>
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
<x-forms.button class="box" wire:target="setServerType('localhost')"
wire:click="setServerType('localhost')">Check again
</x-forms.button>
@ -130,6 +130,17 @@
<x-forms.button type="submit">Use this Server</x-forms.button>
</form>
</div>
@if (!$serverReachable)
This server is not reachable with the following public key.
<br /> <br />
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for user
'root' or skip the boarding process and add a new private key manually to Coolify and to the
server.
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
<x-forms.button class="box" wire:target="validateServer"
wire:click="validateServer">Check again
</x-forms.button>
@endif
</x-slot:actions>
<x-slot:explanation>
<p>Private Keys are used to connect to a remote server through a secure shell, called SSH.</p>
@ -214,10 +225,10 @@
Could not find Docker Engine on your server. Do you want me to install it for you?
</x-slot:question>
<x-slot:actions>
@if ($dockerInstallationStarted)
<x-forms.button class="justify-center box" wire:click="installDocker"
onclick="installDocker.showModal()">
Let's do it!</x-forms.button>
@if ($dockerInstallationStarted)
<x-forms.button class="justify-center box" wire:click="dockerInstalledOrSkipped">
Next</x-forms.button>
@endif

View File

@ -2,29 +2,34 @@
@if (config('subscription.provider') === 'stripe')
<x-slot:basic>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-basic"
class="w-full h-10 buyme" wire:click="subscribeStripe('basic-monthly')"> {{$isTrial ? 'Start Trial' : 'Subscribe' }}
class="w-full h-10 buyme" wire:click="subscribeStripe('basic-monthly')">
{{ $isTrial ? 'Start Trial' : 'Subscribe' }}
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-basic"
class="w-full h-10 buyme" wire:click="subscribeStripe('basic-yearly')"> {{$isTrial ? 'Start Trial' : 'Subscribe' }}
class="w-full h-10 buyme" wire:click="subscribeStripe('basic-yearly')">
{{ $isTrial ? 'Start Trial' : 'Subscribe' }}
</x-forms.button>
</x-slot:basic>
<x-slot:pro>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-pro"
class="w-full h-10 buyme" wire:click="subscribeStripe('pro-monthly')"> {{$isTrial ? 'Start Trial' : 'Subscribe' }}
class="w-full h-10 buyme" wire:click="subscribeStripe('pro-monthly')">
{{ $isTrial ? 'Start Trial' : 'Subscribe' }}
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-pro" class="w-full h-10 buyme"
wire:click="subscribeStripe('pro-yearly')"> {{$isTrial ? 'Start Trial' : 'Subscribe' }}
wire:click="subscribeStripe('pro-yearly')"> {{ $isTrial ? 'Start Trial' : 'Subscribe' }}
</x-forms.button>
</x-slot:pro>
<x-slot:ultimate>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-ultimate"
class="w-full h-10 buyme" wire:click="subscribeStripe('ultimate-monthly')"> {{$isTrial ? 'Start Trial' : 'Subscribe' }}
class="w-full h-10 buyme"><a class="text-white hover:no-underline" href="https://docs.coollabs.io/contact" target="_blank">
Contact Us</a>
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-ultimate"
class="w-full h-10 buyme" wire:click="subscribeStripe('ultimate-yearly')"> {{$isTrial ? 'Start Trial' : 'Subscribe' }}
class="w-full h-10 buyme"><a class="text-white hover:no-underline" href="https://docs.coollabs.io/contact" target="_blank">
Contact Us</a>
</x-forms.button>
</x-slot:ultimate>
@endif

View File

@ -4,7 +4,7 @@
"version": "3.12.36"
},
"v4": {
"version": "4.0.0-beta.42"
"version": "4.0.0-beta.43"
}
}
}