catch-all traefik

This commit is contained in:
Andras Bacsai 2023-05-31 09:22:08 +02:00
parent 3d4e985aa6
commit 40bab90946
11 changed files with 164 additions and 46 deletions

View File

@ -14,12 +14,15 @@ class Form extends Component
public $do_not_track; public $do_not_track;
public $is_auto_update_enabled; public $is_auto_update_enabled;
public $is_registration_enabled; public $is_registration_enabled;
protected string $dynamic_config_path;
protected Server $server;
protected $rules = [ protected $rules = [
'settings.fqdn' => 'nullable', 'settings.fqdn' => 'nullable',
'settings.wildcard_domain' => 'nullable', 'settings.wildcard_domain' => 'nullable',
'settings.public_port_min' => 'required', 'settings.public_port_min' => 'required',
'settings.public_port_max' => 'required', 'settings.public_port_max' => 'required',
'settings.default_redirect_404' => 'nullable',
]; ];
public function mount() public function mount()
{ {
@ -35,27 +38,13 @@ public function instantSave()
$this->settings->save(); $this->settings->save();
$this->emit('saved', 'Settings updated!'); $this->emit('saved', 'Settings updated!');
} }
public function submit() private function setup_instance_fqdn()
{ {
$this->resetErrorBag(); $file = "$this->dynamic_config_path/coolify.yaml";
if ($this->settings->public_port_min > $this->settings->public_port_max) {
$this->addError('settings.public_port_min', 'The minimum port must be lower than the maximum port.');
return;
}
$this->validate();
$this->settings->save();
$dynamic_config_path = '/data/coolify/proxy/dynamic';
if (config('app.env') == 'local') {
$server = Server::findOrFail(1);
} else {
$server = Server::findOrFail(0);
}
if (empty($this->settings->fqdn)) { if (empty($this->settings->fqdn)) {
remote_process([ remote_process([
"rm -f $dynamic_config_path/coolify.yaml", "rm -f $file",
], $server); ], $this->server);
} else { } else {
$url = Url::fromString($this->settings->fqdn); $url = Url::fromString($this->settings->fqdn);
$host = $url->getHost(); $host = $url->getHost();
@ -108,19 +97,108 @@ public function submit()
], ],
]; ];
} }
$yaml = Yaml::dump($traefik_dynamic_conf, 12, 2); $this->save_configuration_to_disk($traefik_dynamic_conf, $file);
$yaml =
"# This file is automatically generated by Coolify.\n" .
"# Do not edit it manually (only if you know what are you doing).\n\n" .
$yaml;
if (config('app.env') == 'local') {
dump($yaml);
}
$base64 = base64_encode($yaml);
remote_process([
"mkdir -p $dynamic_config_path",
"echo '$base64' | base64 -d > $dynamic_config_path/coolify.yaml",
], $server);
} }
} }
private function setup_default_redirect_404()
{
$file = "$this->dynamic_config_path/default_redirect_404.yaml";
if (empty($this->settings->default_redirect_404)) {
remote_process([
"rm -f $file",
], $this->server);
} else {
$url = Url::fromString($this->settings->default_redirect_404);
$host = $url->getHost();
$schema = $url->getScheme();
$traefik_dynamic_conf = [
'http' =>
[
'routers' =>
[
'catchall' =>
[
'entryPoints' => [
0 => 'http',
1 => 'https',
],
'service' => 'noop',
'rule' => "HostRegexp(`{catchall:.*}`)",
'priority' => 1,
'middlewares' => [
0 => 'redirect-regexp@file',
],
],
],
'services' =>
[
'noop' =>
[
'loadBalancer' =>
[
'servers' =>
[
0 =>
[
'url' => '',
],
],
],
],
],
'middlewares' =>
[
'redirect-regexp' =>
[
'redirectRegex' =>
[
'regex' => '(.*)',
'replacement' => $this->settings->default_redirect_404,
'permanent' => false,
],
],
],
],
];
$this->save_configuration_to_disk($traefik_dynamic_conf, $file);
}
}
private function save_configuration_to_disk(array $traefik_dynamic_conf, string $file)
{
$yaml = Yaml::dump($traefik_dynamic_conf, 12, 2);
$yaml =
"# This file is automatically generated by Coolify.\n" .
"# Do not edit it manually (only if you know what are you doing).\n\n" .
$yaml;
$base64 = base64_encode($yaml);
remote_process([
"mkdir -p $this->dynamic_config_path",
"echo '$base64' | base64 -d > $file",
], $this->server);
if (config('app.env') == 'local') {
ray($yaml);
}
}
public function submit()
{
$this->resetErrorBag();
if ($this->settings->public_port_min > $this->settings->public_port_max) {
$this->addError('settings.public_port_min', 'The minimum port must be lower than the maximum port.');
return;
}
$this->validate();
$this->settings->save();
$this->dynamic_config_path = '/data/coolify/proxy/dynamic';
if (config('app.env') == 'local') {
$this->server = Server::findOrFail(1);
} else {
$this->server = Server::findOrFail(0);
}
$this->setup_instance_fqdn();
$this->setup_default_redirect_404();
}
} }

View File

@ -15,17 +15,15 @@ public function up(): void
$table->id(); $table->id();
$table->string('fqdn')->nullable(); $table->string('fqdn')->nullable();
$table->string('wildcard_domain')->nullable(); $table->string('wildcard_domain')->nullable();
$table->string('redirect_url')->nullable(); $table->string('default_redirect_404')->nullable();
// $table->string('preview_domain_separator')->default('.');
$table->integer('public_port_min')->default(9000); $table->integer('public_port_min')->default(9000);
$table->integer('public_port_max')->default(9100); $table->integer('public_port_max')->default(9100);
// $table->string('custom_dns_servers')->default('1.1.1.1,8.8.8.8');
$table->boolean('do_not_track')->default(false); $table->boolean('do_not_track')->default(false);
$table->boolean('is_auto_update_enabled')->default(true); $table->boolean('is_auto_update_enabled')->default(true);
// $table->boolean('is_dns_check_enabled')->default(true);
$table->boolean('is_registration_enabled')->default(true); $table->boolean('is_registration_enabled')->default(true);
// $table->string('preview_domain_separator')->default('.');
// $table->string('custom_dns_servers')->default('1.1.1.1,8.8.8.8');
// $table->boolean('is_dns_check_enabled')->default(true);
$table->timestamps(); $table->timestamps();
}); });
} }

View File

@ -66,6 +66,6 @@ services:
image: ghcr.io/buggregator/server:latest image: ghcr.io/buggregator/server:latest
container_name: coolify-debug container_name: coolify-debug
ports: ports:
- 8001:8000 - 23517:8000
networks: networks:
- coolify - coolify

View File

@ -0,0 +1,23 @@
# This is an example dynamic configuration.
http:
routers:
catchall:
entryPoints:
- http
- https
service: noop
rule: HostRegexp(`{catchall:.*}`)
priority: 1
middlewares:
- redirect-regexp
services:
noop:
loadBalancer:
servers:
- url: ''
middlewares:
redirect-regexp:
redirectRegex:
regex: '(.*)'
replacement: 'https://coolify.io'
permanent: false

View File

@ -0,0 +1,14 @@
# This is an example dynamic configuration.
http:
routers:
coolify-http:
entryPoints:
- http
service: coolify
rule: Host(`coolify.io`)
services:
coolify:
loadBalancer:
servers:
-
url: 'http://coolify:80'

View File

@ -127,6 +127,6 @@ @keyframes lds-heart {
.bg-coollabs-gradient { .bg-coollabs-gradient {
@apply text-transparent bg-clip-text bg-gradient-to-r from-purple-500 via-pink-500 to-red-500; @apply text-transparent bg-clip-text bg-gradient-to-r from-purple-500 via-pink-500 to-red-500;
} }
.bold-helper { .text-helper {
@apply inline-block font-bold text-warning @apply inline-block font-bold text-warning
} }

View File

@ -1,6 +1,7 @@
<div class="flex gap-10 text-xs text-white" x-data="{ visible: @entangle('visible') }"> <div class="flex gap-10 text-xs text-white" x-data="{ visible: @entangle('visible') }">
<button x-cloak x-show="!visible" <button x-cloak x-show="!visible"
class="gap-2 text-white normal-case btn btn-ghost hover:no-underline hover:bg-coollabs" wire:click='upgrade'> class="gap-2 text-white normal-case btn btn-ghost hover:no-underline bg-coollabs hover:bg-coollabs-100"
wire:click='upgrade'>
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" <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"> fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path stroke="none" d="M0 0h24v24H0z" fill="none" />

View File

@ -11,7 +11,7 @@
<div class="flex flex-col items-end gap-2 xl:flex-row"> <div class="flex flex-col items-end gap-2 xl:flex-row">
<x-forms.input class="w-full" id="application.name" label="Name" required /> <x-forms.input class="w-full" id="application.name" label="Name" required />
<x-forms.input placeholder="https://coolify.io" class="w-full" id="application.fqdn" label="Domains" <x-forms.input placeholder="https://coolify.io" class="w-full" id="application.fqdn" label="Domains"
helper="You can specify one domain with path or more with comma.<br><span class='bold-helper'>Example</span>- http://app.coolify.io, https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3" /> helper="You can specify one domain with path or more with comma.<br><span class='text-helper'>Example</span>- http://app.coolify.io, https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3" />
</div> </div>
@if ($wildcard_domain) @if ($wildcard_domain)

View File

@ -6,7 +6,7 @@
</div> </div>
<div class="flex flex-col gap-2 pb-4"> <div class="flex flex-col gap-2 pb-4">
<x-forms.input id="application.preview_url_template" label="Preview URL Template" <x-forms.input id="application.preview_url_template" label="Preview URL Template"
helper="Templates:<span class='bold-helper'>@@{{ random }}</span> to generate random sub-domain each time a PR is deployed, <span class='bold-helper'>@@{{ pr_id }}</span> to use pull request ID as sub-domain or <span class='bold-helper'>@@{{ domain }}</span> to replace the domain name with the application's domain name." /> helper="Templates:<span class='text-helper'>@@{{ random }}</span> to generate random sub-domain each time a PR is deployed, <span class='text-helper'>@@{{ pr_id }}</span> to use pull request ID as sub-domain or <span class='text-helper'>@@{{ domain }}</span> to replace the domain name with the application's domain name." />
<div class="text-sm">Domain Preview: {{ $preview_url_template }}</div> <div class="text-sm">Domain Preview: {{ $preview_url_template }}</div>
</div> </div>
</form> </form>

View File

@ -4,7 +4,7 @@
<x-forms.checkbox instantSave id="is_static" label="Is it a static site?" /> <x-forms.checkbox instantSave id="is_static" label="Is it a static site?" />
<div class="flex gap-2"> <div class="flex gap-2">
<x-forms.input id="repository_url" label="Repository URL" <x-forms.input id="repository_url" label="Repository URL"
helper="<span class='bold-helper'>Example</span>https://github.com/coollabsio/coolify-examples => main branch will be selected<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify => nodejs-fastify branch will be selected" /> helper="<span class='text-helper'>Example</span>https://github.com/coollabsio/coolify-examples => main branch will be selected<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify => nodejs-fastify branch will be selected" />
@if ($is_static) @if ($is_static)
<x-forms.input id="publish_directory" label="Publish Directory" <x-forms.input id="publish_directory" label="Publish Directory"
helper="If there is a build process involved (like Svelte, React, Next, etc..), please specify the output directory for the build assets." /> helper="If there is a build process involved (like Svelte, React, Next, etc..), please specify the output directory for the build assets." />

View File

@ -7,15 +7,18 @@
</x-forms.button> </x-forms.button>
</div> </div>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<div class="flex flex-col gap-2 xl:flex-row"> <div class="flex gap-2">
<x-forms.input id="settings.fqdn" label="Coolify's Domain" /> <x-forms.input id="settings.fqdn" label="Coolify's Domain" />
<x-forms.input id="settings.wildcard_domain" label="Wildcard Domain" <x-forms.input id="settings.wildcard_domain" label="Wildcard Domain"
helper="Wildcard domain for your applications. If you set this, you will get a random generated domain for your new applications.<br><br><span class='inline-block font-bold text-warning'>Example</span>https://example.com<br>Your applications will get https://randomthing.example.com" /> helper="Wildcard domain for your applications. If you set this, you will get a random generated domain for your new applications.<br><span class='font-bold text-white'>Example</span>In case you set:<span class='text-helper'>https://example.com</span>your applications will get: <span class='text-helper'>https://randomId.example.com</span>" />
<x-forms.input id="settings.default_redirect_404" label="Default Redirect 404"
helper="All urls that has no service available will be redirected to this domain.<span class='text-helper'>You can set to your main marketing page or your social media link.</span>" />
</div> </div>
<div class="flex flex-col gap-2 xl:flex-row"> <div class="flex gap-2 ">
<x-forms.input type="number" id="settings.public_port_min" label="Public Port Min" /> <x-forms.input type="number" id="settings.public_port_min" label="Public Port Min" />
<x-forms.input type="number" id="settings.public_port_max" label="Public Port Max" /> <x-forms.input type="number" id="settings.public_port_max" label="Public Port Max" />
</div> </div>
</div> </div>
</form> </form>
@ -26,6 +29,7 @@
{{-- <x-forms.checkbox instantSave id="is_https_forced" label="Force https?" /> --}} {{-- <x-forms.checkbox instantSave id="is_https_forced" label="Force https?" /> --}}
<x-forms.checkbox instantSave id="do_not_track" label="Do Not Track" /> <x-forms.checkbox instantSave id="do_not_track" label="Do Not Track" />
</div> </div>
<h3>Upgrade</h3>
@if (auth()->user()->isPartOfRootTeam()) @if (auth()->user()->isPartOfRootTeam())
<livewire:force-upgrade /> <livewire:force-upgrade />
@endif @endif