Merge pull request #1250 from coollabsio/next

v4.0.0-beta.45
This commit is contained in:
Andras Bacsai 2023-09-24 21:41:58 +02:00 committed by GitHub
commit cfdab13d77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 57 additions and 30 deletions

View File

@ -97,7 +97,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
if ($this->pull_request_id !== 0) { if ($this->pull_request_id !== 0) {
$this->preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->application->id, $this->pull_request_id); $this->preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->application->id, $this->pull_request_id);
if ($this->application->fqdn) { if ($this->application->fqdn) {
$preview_fqdn = getOnlyFqdn(data_get($this->preview, 'fqdn')); $preview_fqdn = getFqdnWithoutPort(data_get($this->preview, 'fqdn'));
$template = $this->application->preview_url_template; $template = $this->application->preview_url_template;
$url = Url::fromString($this->application->fqdn); $url = Url::fromString($this->application->fqdn);
$host = $url->getHost(); $host = $url->getHost();
@ -284,9 +284,20 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
private function rolling_update() private function rolling_update()
{ {
$this->start_by_compose_file(); if (count($this->application->ports_mappings_array) > 0){
$this->health_check(); $this->execute_remote_command(
$this->stop_running_container(); ["echo -n 'Application has ports mapped to the host system, rolling update is not supported. Stopping current container.'"],
);
$this->stop_running_container(force: true);
$this->start_by_compose_file();
} else {
$this->execute_remote_command(
["echo -n 'Rolling update started.'"],
);
$this->start_by_compose_file();
$this->health_check();
$this->stop_running_container();
}
} }
private function health_check() private function health_check()
{ {
@ -529,7 +540,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
'restart' => RESTART_MODE, 'restart' => RESTART_MODE,
'environment' => $environment_variables, 'environment' => $environment_variables,
'labels' => generateLabelsApplication($this->application, $this->preview), 'labels' => generateLabelsApplication($this->application, $this->preview),
// 'expose' => $ports, 'expose' => $ports,
'networks' => [ 'networks' => [
$this->destination->network, $this->destination->network,
], ],
@ -704,10 +715,10 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
} }
} }
private function stop_running_container() private function stop_running_container(bool $force = false)
{ {
if ($this->currently_running_container_name) { if ($this->currently_running_container_name) {
if ($this->newVersionIsHealthy) { if ($this->newVersionIsHealthy || $force) {
$this->execute_remote_command( $this->execute_remote_command(
["echo -n 'Removing old version of your application.'"], ["echo -n 'Removing old version of your application.'"],
[executeInDocker($this->deployment_uuid, "docker rm -f $this->currently_running_container_name >/dev/null 2>&1"), "hidden" => true], [executeInDocker($this->deployment_uuid, "docker rm -f $this->currently_running_container_name >/dev/null 2>&1"), "hidden" => true],
@ -724,7 +735,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
private function start_by_compose_file() private function start_by_compose_file()
{ {
$this->execute_remote_command( $this->execute_remote_command(
["echo -n 'Rolling update started.'"], ["echo -n 'Starting application (could take a while).'"],
[executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} up -d >/dev/null"), "hidden" => true], [executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} up -d >/dev/null"), "hidden" => true],
); );
} }

View File

@ -377,7 +377,7 @@ class Service extends BaseModel
} else { } else {
$number = 0; $number = 0;
} }
$fqdn = getOnlyFqdn(data_get($fqdns, $number, $fqdns->first())); $fqdn = getFqdnWithoutPort(data_get($fqdns, $number, $fqdns->first()));
$environments = collect(data_get($service, 'environment')); $environments = collect(data_get($service, 'environment'));
$environments = $environments->map(function ($envValue) use ($value, $fqdn) { $environments = $environments->map(function ($envValue) use ($value, $fqdn) {
$envValue = Str::of($envValue)->replace($value, $fqdn); $envValue = Str::of($envValue)->replace($value, $fqdn);
@ -393,7 +393,7 @@ class Service extends BaseModel
} else { } else {
$number = 0; $number = 0;
} }
$fqdn = getOnlyFqdn(data_get($fqdns, $number, $fqdns->first())); $fqdn = getFqdnWithoutPort(data_get($fqdns, $number, $fqdns->first()));
$url = Url::fromString($fqdn)->getHost(); $url = Url::fromString($fqdn)->getHost();
$environments = collect(data_get($service, 'environment')); $environments = collect(data_get($service, 'environment'));
$environments = $environments->map(function ($envValue) use ($value, $url) { $environments = $environments->map(function ($envValue) use ($value, $url) {

View File

@ -19,7 +19,7 @@ class Links extends Component
if ($application->fqdn) { if ($application->fqdn) {
$fqdns = collect(Str::of($application->fqdn)->explode(',')); $fqdns = collect(Str::of($application->fqdn)->explode(','));
$fqdns->map(function ($fqdn) { $fqdns->map(function ($fqdn) {
$this->links->push(getOnlyFqdn($fqdn)); $this->links->push(getFqdnWithoutPort($fqdn));
}); });
} }
if ($application->ports) { if ($application->ports) {

View File

@ -147,7 +147,7 @@ function fqdnLabelsForTraefik(Collection $domains, $container_name, $is_force_ht
{ {
$labels = collect([]); $labels = collect([]);
$labels->push('traefik.enable=true'); $labels->push('traefik.enable=true');
foreach($domains as $domain) { foreach ($domains as $domain) {
$url = Url::fromString($domain); $url = Url::fromString($domain);
$host = $url->getHost(); $host = $url->getHost();
$path = $url->getPath(); $path = $url->getPath();
@ -216,9 +216,8 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview
} else { } else {
$domains = Str::of(data_get($application, 'fqdn'))->explode(','); $domains = Str::of(data_get($application, 'fqdn'))->explode(',');
} }
if ($application->destination->server->proxy->type === ProxyTypes::TRAEFIK_V2->value) { // Add Traefik labels no matter which proxy is selected
$labels = $labels->merge(fqdnLabelsForTraefik($domains, $container_name, $application->settings->is_force_https_enabled)); $labels = $labels->merge(fqdnLabelsForTraefik($domains, $container_name, $application->settings->is_force_https_enabled));
}
} }
return $labels->all(); return $labels->all();
} }

View File

@ -189,7 +189,7 @@ function validateServer(Server $server, bool $throwError = false)
]; ];
} }
$server->settings->is_reachable = true; $server->settings->is_reachable = true;
instant_remote_process(["docker ps"], $server, $throwError);
$dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $server, $throwError); $dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $server, $throwError);
if (!$dockerVersion) { if (!$dockerVersion) {
$dockerVersion = null; $dockerVersion = null;

View File

@ -100,7 +100,8 @@ function handleError(?Throwable $error = null, ?Livewire\Component $livewire = n
return "Too many requests. Please try again in {$error->secondsUntilAvailable} seconds."; return "Too many requests. Please try again in {$error->secondsUntilAvailable} seconds.";
} }
if (isset($livewire)) { if (isset($livewire)) {
return $livewire->emit('error', $message); $livewire->emit('error', $message);
throw new RuntimeException($message);
} }
throw new RuntimeException($message); throw new RuntimeException($message);
@ -240,11 +241,13 @@ function base_ip(): string
} }
return "localhost"; return "localhost";
} }
function getOnlyFqdn(String $fqdn) { function getFqdnWithoutPort(String $fqdn)
{
$url = Url::fromString($fqdn); $url = Url::fromString($fqdn);
$host = $url->getHost(); $host = $url->getHost();
$scheme = $url->getScheme(); $scheme = $url->getScheme();
return "$scheme://$host"; $path = $url->getPath();
return "$scheme://$host$path";
} }
/** /**
* If fqdn is set, return it, otherwise return public ip. * If fqdn is set, return it, otherwise return public ip.

View File

@ -7,7 +7,7 @@ return [
// The release version of your application // The release version of your application
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
'release' => '4.0.0-beta.44', 'release' => '4.0.0-beta.45',
// When left empty or `null` the Laravel environment will be used // When left empty or `null` the Laravel environment will be used
'environment' => config('app.env'), 'environment' => config('app.env'),

View File

@ -1,3 +1,3 @@
<?php <?php
return '4.0.0-beta.44'; return '4.0.0-beta.45';

View File

@ -19,7 +19,7 @@
@foreach (Str::of(data_get($application, 'fqdn'))->explode(',') as $fqdn) @foreach (Str::of(data_get($application, 'fqdn'))->explode(',') as $fqdn)
<li> <li>
<a class="text-xs text-white rounded-none hover:no-underline hover:bg-coollabs hover:text-white" <a class="text-xs text-white rounded-none hover:no-underline hover:bg-coollabs hover:text-white"
target="_blank" href="{{ getOnlyFqdn($fqdn) }}"> target="_blank" href="{{ getFqdnWithoutPort($fqdn) }}">
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24" <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round"> stroke-linejoin="round">
@ -28,7 +28,7 @@
<path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" /> <path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" />
<path <path
d="M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463" /> d="M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463" />
</svg>{{ getOnlyFqdn($fqdn) }} </svg>{{ getFqdnWithoutPort($fqdn) }}
</a> </a>
</li> </li>
@endforeach @endforeach
@ -38,7 +38,7 @@
@if (data_get($preview, 'fqdn')) @if (data_get($preview, 'fqdn'))
<li> <li>
<a class="text-xs text-white rounded-none hover:no-underline hover:bg-coollabs hover:text-white" <a class="text-xs text-white rounded-none hover:no-underline hover:bg-coollabs hover:text-white"
target="_blank" href="{{ getOnlyFqdn(data_get($preview, 'fqdn')) }}"> target="_blank" href="{{ getFqdnWithoutPort(data_get($preview, 'fqdn')) }}">
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24" <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round"> stroke-linejoin="round">

View File

@ -1,2 +1,2 @@
<a {{ $attributes->merge(['class' => 'text-xs cursor-pointer opacity-20 hover:opacity-100 hover:text-white']) }} <a {{ $attributes->merge(['class' => 'text-xs cursor-pointer opacity-20 hover:opacity-100 hover:text-white z-50']) }}
href="https://github.com/coollabsio/coolify/releases/tag/v{{ config('version') }}">v{{ config('version') }}</a> href="https://github.com/coollabsio/coolify/releases/tag/v{{ config('version') }}">v{{ config('version') }}</a>

View File

@ -2,7 +2,7 @@
@section('body') @section('body')
@parent @parent
<x-navbar /> <x-navbar />
<div class="fixed top-3 left-4" id="vue"> <div class="fixed top-3 left-4 z-50" id="vue">
<magic-bar></magic-bar> <magic-bar></magic-bar>
</div> </div>
<main class="main max-w-screen-2xl"> <main class="main max-w-screen-2xl">

View File

@ -2,7 +2,7 @@
@section('body') @section('body')
@parent @parent
@if (isSubscriptionOnGracePeriod()) @if (isSubscriptionOnGracePeriod())
<div class="fixed top-3 left-4" id="vue"> <div class="fixed top-3 left-4 z-50" id="vue">
<magic-bar></magic-bar> <magic-bar></magic-bar>
</div> </div>
<x-navbar /> <x-navbar />

View File

@ -26,6 +26,14 @@
@endif @endif
@endif @endif
</div> </div>
@if (!$application->dockerfile)
<div class="flex items-end gap-2">
<x-forms.select id="application.build_pack" label="Build Pack" required>
<option value="nixpacks">Nixpacks</option>
<option value="dockerfile">Dockerfile</option>
</x-forms.select>
</div>
@endif
@if ($application->settings->is_static) @if ($application->settings->is_static)
<x-forms.select id="application.static_image" label="Static Image" required> <x-forms.select id="application.static_image" label="Static Image" required>
<option value="nginx:alpine">nginx:alpine</option> <option value="nginx:alpine">nginx:alpine</option>
@ -54,6 +62,7 @@
@if ($application->dockerfile) @if ($application->dockerfile)
<x-forms.textarea label="Dockerfile" id="application.dockerfile" rows="6"> </x-forms.textarea> <x-forms.textarea label="Dockerfile" id="application.dockerfile" rows="6"> </x-forms.textarea>
@endif @endif
<h3>Network</h3> <h3>Network</h3>
<div class="flex flex-col gap-2 xl:flex-row"> <div class="flex flex-col gap-2 xl:flex-row">
@if ($application->settings->is_static) @if ($application->settings->is_static)
@ -63,7 +72,7 @@
helper="A comma separated list of ports your application uses. The first port will be used as default healthcheck port if nothing defined in the Healthcheck menu. Be sure to set this correctly." /> helper="A comma separated list of ports your application uses. The first port will be used as default healthcheck port if nothing defined in the Healthcheck menu. Be sure to set this correctly." />
@endif @endif
<x-forms.input placeholder="3000:3000" id="application.ports_mappings" label="Ports Mappings" <x-forms.input placeholder="3000:3000" id="application.ports_mappings" label="Ports Mappings"
helper="A comma separated list of ports you would like to map to the host system. Useful when you do not want to use domains.<br><span class='inline-block font-bold text-warning'>Example</span>3000:3000,3002:3002" /> helper="A comma separated list of ports you would like to map to the host system. Useful when you do not want to use domains.<br><br><span class='inline-block font-bold text-warning'>Example:</span><br>3000:3000,3002:3002<br><br>Rolling update is not supported if you have a port mapped to the host." />
</div> </div>
</div> </div>
<h3>Advanced</h3> <h3>Advanced</h3>

View File

@ -1,5 +1,10 @@
<x-layout> <x-layout>
<h1>Sources</h1> <div class="flex items-start gap-2">
<h1>Sources</h1>
<a class="text-white hover:no-underline" href="{{ route('source.new') }}">
<x-forms.button class="btn">+ Add</x-forms.button>
</a>
</div>
<div class="subtitle ">All Sources</div> <div class="subtitle ">All Sources</div>
<div class="grid gap-2 lg:grid-cols-2"> <div class="grid gap-2 lg:grid-cols-2">
@forelse ($sources as $source) @forelse ($sources as $source)

View File

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