mirror of
https://github.com/ershisan99/coolify.git
synced 2025-12-27 12:33:54 +00:00
Compare commits
100 Commits
v4.0.0-bet
...
v4.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc8f09f05e | ||
|
|
2beda08717 | ||
|
|
b455d153ae | ||
|
|
5fddf01820 | ||
|
|
c80434141d | ||
|
|
d1128c7a1e | ||
|
|
aae81313a6 | ||
|
|
4667f96b40 | ||
|
|
28c320ae97 | ||
|
|
45017efe00 | ||
|
|
a20290cac8 | ||
|
|
31e02a154c | ||
|
|
023ee5db99 | ||
|
|
05d2e15ab5 | ||
|
|
7d6590c60a | ||
|
|
3152ce183b | ||
|
|
d9f1a7c4d0 | ||
|
|
952aed3c49 | ||
|
|
ab3c433450 | ||
|
|
2b5e4a34d4 | ||
|
|
35cea852ca | ||
|
|
88581c8983 | ||
|
|
a7a9aab189 | ||
|
|
370c9b63cf | ||
|
|
7cb08849de | ||
|
|
7f052163e3 | ||
|
|
277d939033 | ||
|
|
26fbdcfab0 | ||
|
|
6d63ba9d4d | ||
|
|
8963f4fd62 | ||
|
|
463021a9f3 | ||
|
|
f71a8e9fef | ||
|
|
2dd5be1b4e | ||
|
|
608838045f | ||
|
|
899d506faa | ||
|
|
21b3e3ea05 | ||
|
|
a68951541c | ||
|
|
7fd0deedb1 | ||
|
|
e9e12ad843 | ||
|
|
4fd3185d12 | ||
|
|
f5ccebfd41 | ||
|
|
294721eef9 | ||
|
|
8af509992d | ||
|
|
11fccb8e89 | ||
|
|
1e126dd2c3 | ||
|
|
cfe2f889a4 | ||
|
|
1bd76b0e07 | ||
|
|
6d8c935cc7 | ||
|
|
7144cee0f6 | ||
|
|
f75a8d56f2 | ||
|
|
2f321bcfd9 | ||
|
|
a157f4f17b | ||
|
|
7723c623d5 | ||
|
|
bc3bb78916 | ||
|
|
0ebf5e49fb | ||
|
|
c340921fbb | ||
|
|
30e26b101c | ||
|
|
1b17cab663 | ||
|
|
ab039adf97 | ||
|
|
62fe10df31 | ||
|
|
2004a751dd | ||
|
|
ace127acf4 | ||
|
|
82c5497a06 | ||
|
|
dbb7989027 | ||
|
|
103f677a93 | ||
|
|
cb6bf78595 | ||
|
|
62334ddef7 | ||
|
|
778f67f2e4 | ||
|
|
48737f8e60 | ||
|
|
94de62e503 | ||
|
|
0445052898 | ||
|
|
ccde90ea91 | ||
|
|
ed94355019 | ||
|
|
02fcd1b5fc | ||
|
|
ca934e7cdf | ||
|
|
0ddd5f0a79 | ||
|
|
099d6801b7 | ||
|
|
62293926ec | ||
|
|
c96daad12c | ||
|
|
9cc3be152f | ||
|
|
f841c0d4ba | ||
|
|
3cd1d8135e | ||
|
|
86474d9f90 | ||
|
|
9bf87a3033 | ||
|
|
71e32520cf | ||
|
|
e3e938c8eb | ||
|
|
03aa440424 | ||
|
|
e16bd194a3 | ||
|
|
a3765c19e3 | ||
|
|
ba4be02e75 | ||
|
|
d4f6a86a57 | ||
|
|
7c0c1e6cf8 | ||
|
|
39f787b7db | ||
|
|
424437446d | ||
|
|
908c74eb27 | ||
|
|
97da13c3c4 | ||
|
|
7134b46cdc | ||
|
|
de3b8a10a0 | ||
|
|
8feece702c | ||
|
|
f3fe4433ae |
19
.github/ISSUE_TEMPLATE/BUG_REPORT.yml
vendored
19
.github/ISSUE_TEMPLATE/BUG_REPORT.yml
vendored
@@ -1,17 +1,28 @@
|
||||
name: Bug report
|
||||
description: Create a new bug report
|
||||
description: 'Create a new bug report.'
|
||||
title: '[Bug]: '
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >-
|
||||
# 💎 Bounty program (with
|
||||
[algora.io](https://console.algora.io/org/coollabsio/bounties/new))
|
||||
|
||||
|
||||
If you would like to prioritize the issue resolution, you can add bounty
|
||||
to this issue.
|
||||
|
||||
|
||||
Click [here](https://console.algora.io/org/coollabsio/bounties/new) to
|
||||
get started.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: A clear and concise description of the problem
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Minimal Reproduction (if possible, example repository)
|
||||
description: Please provide a step by step guide to reproduce the issue
|
||||
description: Please provide a step by step guide to reproduce the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
||||
@@ -42,6 +42,7 @@ Special thanks to our biggest sponsor, [CCCareers](https://cccareers.org/)!
|
||||
<a href="https://www.quantcdn.io/?utm_source=coolify.io"><img src="https://github.com/quantcdn.png" width="60px" alt="QuantCDN"/></a>
|
||||
<a href="https://www.runpod.io/?utm_source=coolify.io">
|
||||
<svg style="width:60px;height:60px;background:#fff;" xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 200 200"><g><path d="M74.5 51.1c-25.4 14.9-27 16-29.6 20.2-1.8 3-1.9 5.3-1.9 32.3 0 21.7.3 29.4 1.3 30.6 1.9 2.5 46.7 27.9 48.5 27.6 1.5-.3 1.7-3.1 2-27.7.2-21.9 0-27.8-1.1-29.5-.8-1.2-9.9-6.8-20.2-12.6-10.3-5.8-19.4-11.5-20.2-12.7-1.8-2.6-.9-5.9 1.8-7.4 1.6-.8 6.3 0 21.8 4C87.8 78.7 98 81 99.6 81c4.4 0 49.9-25.9 49.9-28.4 0-1.6-3.4-2.8-24-8.2-13.2-3.5-25.1-6.3-26.5-6.3-1.4.1-12.4 5.9-24.5 13z"></path><path d="m137.2 68.1-3.3 2.1 6.3 3.7c3.5 2 6.3 4.3 6.3 5.1 0 .9-8 6.1-19.4 12.6-10.6 6-20 11.9-20.7 12.9-1.2 1.6-1.4 7.2-1.2 29.4.3 24.8.5 27.6 2 27.9 1.8.3 46.6-25.1 48.6-27.6.9-1.2 1.2-8.8 1.2-30.2s-.3-29-1.2-30.2c-1.6-1.9-12.1-7.8-13.9-7.8-.8 0-2.9 1-4.7 2.1z"></path></g></svg></a>
|
||||
<a href="https://lightspeed.run/?utm_source=coolify.io"><img src="https://github.com/lightspeedrun.png" width="60px" alt="Lightspeed.run"/></a>
|
||||
<a href="https://www.flint.sh/en/home?utm_source=coolify.io"> <img src="https://github.com/Flint-company.png" width="60px" alt="FlintCompany"/></a>
|
||||
<a href="https://americancloud.com/?utm_source=coolify.io"><img src="https://github.com/American-Cloud.png" width="60px" alt="American Cloud"/></a>
|
||||
<a href="https://cryptojobslist.com/?utm_source=coolify.io"><img src="https://github.com/cryptojobslist.png" width="60px" alt="CryptoJobsList" /></a>
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace App\Actions\Server;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UpdateCoolify
|
||||
{
|
||||
@@ -28,24 +27,17 @@ class UpdateCoolify
|
||||
$this->currentVersion = config('version');
|
||||
if (!$manual_update) {
|
||||
if (!$settings->is_auto_update_enabled) {
|
||||
Log::debug('Auto update is disabled');
|
||||
return;
|
||||
}
|
||||
if ($this->latestVersion === $this->currentVersion) {
|
||||
Log::debug('Already on latest version');
|
||||
return;
|
||||
}
|
||||
if (version_compare($this->latestVersion, $this->currentVersion, '<')) {
|
||||
Log::debug('Latest version is lower than current version?!');
|
||||
return;
|
||||
}
|
||||
}
|
||||
Log::info("Updating from {$this->currentVersion} -> {$this->latestVersion}");
|
||||
$this->update();
|
||||
} catch (\Throwable $e) {
|
||||
ray('InstanceAutoUpdateJob failed');
|
||||
ray($e->getMessage());
|
||||
send_internal_notification('InstanceAutoUpdateJob failed: ' . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +54,6 @@ class UpdateCoolify
|
||||
"curl -fsSL https://cdn.coollabs.io/coolify/upgrade.sh -o /data/coolify/source/upgrade.sh",
|
||||
"bash /data/coolify/source/upgrade.sh $this->latestVersion"
|
||||
], $this->server);
|
||||
send_internal_notification("Instance updated from {$this->currentVersion} -> {$this->latestVersion}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ class ServicesGenerate extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// ray()->clearAll();
|
||||
$files = array_diff(scandir(base_path('templates/compose')), ['.', '..']);
|
||||
$files = array_filter($files, function ($file) {
|
||||
return strpos($file, '.yaml') !== false;
|
||||
@@ -63,6 +62,7 @@ class ServicesGenerate extends Command
|
||||
$documentation = collect(preg_grep('/^# documentation:/', explode("\n", $content)))->values();
|
||||
if ($documentation->count() > 0) {
|
||||
$documentation = str($documentation[0])->after('# documentation:')->trim()->value();
|
||||
$documentation = str($documentation)->append('?utm_source=coolify.io');
|
||||
} else {
|
||||
$documentation = 'https://coolify.io/docs';
|
||||
}
|
||||
|
||||
@@ -6,15 +6,12 @@ use App\Jobs\CheckLogDrainContainerJob;
|
||||
use App\Jobs\CleanupInstanceStuffsJob;
|
||||
use App\Jobs\DatabaseBackupJob;
|
||||
use App\Jobs\ScheduledTaskJob;
|
||||
use App\Jobs\InstanceAutoUpdateJob;
|
||||
use App\Jobs\ContainerStatusJob;
|
||||
use App\Jobs\PullCoolifyImageJob;
|
||||
use App\Jobs\PullHelperImageJob;
|
||||
use App\Jobs\PullSentinelImageJob;
|
||||
use App\Jobs\PullTemplatesAndVersions;
|
||||
use App\Jobs\PullTemplatesFromCDN;
|
||||
use App\Jobs\PullVersionsFromCDN;
|
||||
use App\Jobs\ServerStatusJob;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\ScheduledDatabaseBackup;
|
||||
use App\Models\ScheduledTask;
|
||||
use App\Models\Server;
|
||||
@@ -32,37 +29,33 @@ class Kernel extends ConsoleKernel
|
||||
// Instance Jobs
|
||||
$schedule->command('horizon:snapshot')->everyMinute();
|
||||
$schedule->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer();
|
||||
$schedule->job(new PullVersionsFromCDN)->everyTenMinutes()->onOneServer();
|
||||
$schedule->job(new PullTemplatesFromCDN)->everyTwoHours()->onOneServer();
|
||||
// $schedule->job(new CheckResaleLicenseJob)->hourly()->onOneServer();
|
||||
// Server Jobs
|
||||
$this->check_scheduled_backups($schedule);
|
||||
$this->check_resources($schedule);
|
||||
$this->check_scheduled_backups($schedule);
|
||||
// $this->pull_helper_image($schedule);
|
||||
$this->check_scheduled_tasks($schedule);
|
||||
$schedule->command('uploads:clear')->everyTwoMinutes();
|
||||
} else {
|
||||
// Instance Jobs
|
||||
$schedule->command('horizon:snapshot')->everyFiveMinutes();
|
||||
$schedule->command('cleanup:unreachable-servers')->daily();
|
||||
$schedule->job(new PullVersionsFromCDN)->everyTenMinutes()->onOneServer();
|
||||
$schedule->job(new PullTemplatesFromCDN)->everyTwoHours()->onOneServer();
|
||||
$schedule->job(new PullCoolifyImageJob)->everyTenMinutes()->onOneServer();
|
||||
$schedule->job(new PullTemplatesFromCDN)->everyThirtyMinutes()->onOneServer();
|
||||
$schedule->job(new CleanupInstanceStuffsJob)->everyTwoMinutes()->onOneServer();
|
||||
// $schedule->job(new CheckResaleLicenseJob)->hourly()->onOneServer();
|
||||
|
||||
// Server Jobs
|
||||
$this->instance_auto_update($schedule);
|
||||
$this->check_scheduled_backups($schedule);
|
||||
$this->check_resources($schedule);
|
||||
$this->pull_helper_image($schedule);
|
||||
$this->pull_images($schedule);
|
||||
$this->check_scheduled_tasks($schedule);
|
||||
|
||||
$schedule->command('cleanup:database --yes')->daily();
|
||||
$schedule->command('uploads:clear')->everyTwoMinutes();
|
||||
}
|
||||
}
|
||||
private function pull_helper_image($schedule)
|
||||
private function pull_images($schedule)
|
||||
{
|
||||
$servers = $this->all_servers->where('settings.is_usable', true)->where('settings.is_reachable', true)->where('ip', '!=', '1.2.3.4');
|
||||
foreach ($servers as $server) {
|
||||
@@ -93,16 +86,6 @@ class Kernel extends ConsoleKernel
|
||||
$schedule->job(new ServerStatusJob($server))->everyMinute()->onOneServer();
|
||||
}
|
||||
}
|
||||
private function instance_auto_update($schedule)
|
||||
{
|
||||
if (isDev() || isCloud()) {
|
||||
return;
|
||||
}
|
||||
$settings = InstanceSettings::get();
|
||||
if ($settings->is_auto_update_enabled) {
|
||||
$schedule->job(new InstanceAutoUpdateJob)->everyTenMinutes()->onOneServer();
|
||||
}
|
||||
}
|
||||
private function check_scheduled_backups($schedule)
|
||||
{
|
||||
$scheduled_backups = ScheduledDatabaseBackup::all();
|
||||
|
||||
@@ -410,11 +410,12 @@ class Github extends Controller
|
||||
if ($action === 'closed' || $action === 'close') {
|
||||
$found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
|
||||
if ($found) {
|
||||
$container_name = generateApplicationContainerName($application, $pull_request_id);
|
||||
instant_remote_process(["docker rm -f $container_name"], $application->destination->server);
|
||||
|
||||
ApplicationPullRequestUpdateJob::dispatchSync(application: $application, preview: $found, status: ProcessStatus::CLOSED);
|
||||
$found->delete();
|
||||
$container_name = generateApplicationContainerName($application, $pull_request_id);
|
||||
// ray('Stopping container: ' . $container_name);
|
||||
instant_remote_process(["docker rm -f $container_name"], $application->destination->server);
|
||||
|
||||
$return_payloads->push([
|
||||
'application' => $application->name,
|
||||
'status' => 'success',
|
||||
@@ -430,7 +431,6 @@ class Github extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
ray($return_payloads);
|
||||
return response($return_payloads);
|
||||
} catch (Exception $e) {
|
||||
ray($e->getMessage());
|
||||
|
||||
@@ -202,7 +202,7 @@ class Gitlab extends Controller
|
||||
]);
|
||||
ray('Preview deployments disabled for ' . $application->name);
|
||||
}
|
||||
} else if ($action === 'closed' || $action === 'close') {
|
||||
} else if ($action === 'closed' || $action === 'close' || $action === 'merge') {
|
||||
$found = ApplicationPreview::where('application_id', $application->id)->where('pull_request_id', $pull_request_id)->first();
|
||||
if ($found) {
|
||||
$found->delete();
|
||||
|
||||
@@ -113,7 +113,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
||||
public $tries = 1;
|
||||
public function __construct(int $application_deployment_queue_id)
|
||||
{
|
||||
ray()->clearAll();
|
||||
$this->application_deployment_queue = ApplicationDeploymentQueue::find($application_deployment_queue_id);
|
||||
$this->application = Application::find($this->application_deployment_queue->application_id);
|
||||
$this->build_pack = data_get($this->application, 'build_pack');
|
||||
@@ -290,7 +289,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
||||
}
|
||||
private function post_deployment()
|
||||
{
|
||||
|
||||
if ($this->server->isProxyShouldRun()) {
|
||||
GetContainersStatus::dispatch($this->server);
|
||||
// dispatch(new ContainerStatusJob($this->server));
|
||||
@@ -347,9 +345,15 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
||||
}
|
||||
if (data_get($this->application, 'docker_compose_custom_start_command')) {
|
||||
$this->docker_compose_custom_start_command = $this->application->docker_compose_custom_start_command;
|
||||
if (!str($this->docker_compose_custom_start_command)->contains('--project-directory')) {
|
||||
$this->docker_compose_custom_start_command = str($this->docker_compose_custom_start_command)->replaceFirst('compose', 'compose --project-directory ' . $this->workdir)->value();
|
||||
}
|
||||
}
|
||||
if (data_get($this->application, 'docker_compose_custom_build_command')) {
|
||||
$this->docker_compose_custom_build_command = $this->application->docker_compose_custom_build_command;
|
||||
if (!str($this->docker_compose_custom_build_command)->contains('--project-directory')) {
|
||||
$this->docker_compose_custom_build_command = str($this->docker_compose_custom_build_command)->replaceFirst('compose', 'compose --project-directory ' . $this->workdir)->value();
|
||||
}
|
||||
}
|
||||
if ($this->pull_request_id === 0) {
|
||||
$this->application_deployment_queue->addLogEntry("Starting deployment of {$this->application->name} to {$this->server->name}.");
|
||||
@@ -367,7 +371,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
||||
$yaml = $composeFile = $this->application->docker_compose_raw;
|
||||
$this->save_environment_variables();
|
||||
} else {
|
||||
$composeFile = $this->application->parseCompose(pull_request_id: $this->pull_request_id);
|
||||
$composeFile = $this->application->parseCompose(pull_request_id: $this->pull_request_id, preview_id: data_get($this, 'preview.id'));
|
||||
$this->save_environment_variables();
|
||||
if (!is_null($this->env_filename)) {
|
||||
$services = collect($composeFile['services']);
|
||||
@@ -407,7 +411,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
||||
}
|
||||
|
||||
$this->stop_running_container(force: true);
|
||||
|
||||
$this->application_deployment_queue->addLogEntry("Starting new application.");
|
||||
$networkId = $this->application->uuid;
|
||||
if ($this->pull_request_id !== 0) {
|
||||
$networkId = "{$this->application->uuid}-{$this->pull_request_id}";
|
||||
@@ -759,7 +763,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
||||
if ($env->version === '4.0.0-beta.239') {
|
||||
$real_value = $env->real_value;
|
||||
} else {
|
||||
if ($env->is_literal) {
|
||||
if ($env->is_literal || $env->is_multiline) {
|
||||
$real_value = '\'' . $real_value . '\'';
|
||||
} else {
|
||||
$real_value = escapeEnvVariables($env->real_value);
|
||||
@@ -792,7 +796,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
||||
$url = str($this->application->fqdn)->replace('http://', '')->replace('https://', '');
|
||||
$envs->push("COOLIFY_URL={$url}");
|
||||
}
|
||||
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
|
||||
if ($this->application->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
|
||||
$envs->push("COOLIFY_BRANCH={$local_branch}");
|
||||
}
|
||||
foreach ($sorted_environment_variables as $env) {
|
||||
@@ -800,10 +804,11 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
||||
if ($env->version === '4.0.0-beta.239') {
|
||||
$real_value = $env->real_value;
|
||||
} else {
|
||||
if ($env->is_literal) {
|
||||
if ($env->is_literal || $env->is_multiline) {
|
||||
$real_value = '\'' . $real_value . '\'';
|
||||
} else {
|
||||
$real_value = escapeEnvVariables($env->real_value);
|
||||
ray($real_value);
|
||||
}
|
||||
}
|
||||
$envs->push($env->key . '=' . $real_value);
|
||||
@@ -1944,11 +1949,17 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
||||
if ($this->pull_request_id === 0) {
|
||||
foreach ($this->application->build_environment_variables as $env) {
|
||||
$value = escapeshellarg($env->real_value);
|
||||
if (str($value)->contains("\n") && data_get($env, 'is_multiline') === true) {
|
||||
$value = str_replace("\n", "\\\n", $value);
|
||||
}
|
||||
$this->build_args->push("--build-arg {$env->key}={$value}");
|
||||
}
|
||||
} else {
|
||||
foreach ($this->application->build_environment_variables_preview as $env) {
|
||||
$value = escapeshellarg($env->real_value);
|
||||
if (str($value)->contains("\n") && data_get($env, 'is_multiline') === true) {
|
||||
$value = str_replace("\n", "\\\n", $value);
|
||||
}
|
||||
$this->build_args->push("--build-arg {$env->key}={$value}");
|
||||
}
|
||||
}
|
||||
@@ -1964,10 +1975,20 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
||||
$dockerfile = collect(Str::of($this->saved_outputs->get('dockerfile'))->trim()->explode("\n"));
|
||||
if ($this->pull_request_id === 0) {
|
||||
foreach ($this->application->build_environment_variables as $env) {
|
||||
$dockerfile->splice(1, 0, "ARG {$env->key}={$env->real_value}");
|
||||
if (str($env->real_value)->contains("\n") && data_get($env, 'is_multiline') === true) {
|
||||
$value = str_replace("\n", "\\\n", $env->real_value);
|
||||
} else {
|
||||
$value = $env->real_value;
|
||||
}
|
||||
$dockerfile->splice(1, 0, "ARG {$env->key}={$value}");
|
||||
}
|
||||
} else {
|
||||
foreach ($this->application->build_environment_variables_preview as $env) {
|
||||
if (str($env->real_value)->contains("\n") && data_get($env, 'is_multiline') === true) {
|
||||
$value = str_replace("\n", "\\\n", $env->real_value);
|
||||
} else {
|
||||
$value = $env->real_value;
|
||||
}
|
||||
$dockerfile->splice(1, 0, "ARG {$env->key}={$env->real_value}");
|
||||
}
|
||||
}
|
||||
@@ -1987,7 +2008,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
||||
if ($containers->count() == 0) {
|
||||
return;
|
||||
}
|
||||
$this->application_deployment_queue->addLogEntry("Executing pre-deployment command (see debug log for output).");
|
||||
$this->application_deployment_queue->addLogEntry("Executing pre-deployment command (see debug log for output/errors).");
|
||||
|
||||
foreach ($containers as $container) {
|
||||
$containerName = data_get($container, 'Names');
|
||||
@@ -2010,6 +2031,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
||||
if (empty($this->application->post_deployment_command)) {
|
||||
return;
|
||||
}
|
||||
$this->application_deployment_queue->addLogEntry("----------------------------------------");
|
||||
$this->application_deployment_queue->addLogEntry("Executing post-deployment command (see debug log for output).");
|
||||
|
||||
$containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);
|
||||
@@ -2018,11 +2040,20 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
||||
if ($containers->count() == 1 || str_starts_with($containerName, $this->application->post_deployment_command_container . '-' . $this->application->uuid)) {
|
||||
$cmd = "sh -c '" . str_replace("'", "'\''", $this->application->post_deployment_command) . "'";
|
||||
$exec = "docker exec {$containerName} {$cmd}";
|
||||
$this->execute_remote_command(
|
||||
[
|
||||
'command' => $exec, 'hidden' => true
|
||||
],
|
||||
);
|
||||
try {
|
||||
$this->execute_remote_command(
|
||||
[
|
||||
'command' => $exec, 'hidden' => true, 'save' => 'post-deployment-command-output'
|
||||
],
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$post_deployment_command_output = $this->saved_outputs->get('post-deployment-command-output');
|
||||
if ($post_deployment_command_output) {
|
||||
$this->application_deployment_queue->addLogEntry("Post-deployment command failed.");
|
||||
$this->application_deployment_queue->addLogEntry($post_deployment_command_output, 'stderr');
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,7 @@ class ApplicationPullRequestUpdateJob implements ShouldQueue, ShouldBeEncrypted
|
||||
{
|
||||
try {
|
||||
if ($this->application->is_public_repository()) {
|
||||
ray('Public repository. Skipping comment update.');
|
||||
return;
|
||||
}
|
||||
if ($this->status === ProcessStatus::CLOSED) {
|
||||
@@ -59,7 +60,7 @@ class ApplicationPullRequestUpdateJob implements ShouldQueue, ShouldBeEncrypted
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
ray($e);
|
||||
throw $e;
|
||||
return $e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class CheckLogDrainContainerJob implements ShouldQueue, ShouldBeEncrypted
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public function handle(): void
|
||||
public function handle()
|
||||
{
|
||||
// ray("checking log drain statuses for {$this->server->id}");
|
||||
try {
|
||||
@@ -80,9 +80,9 @@ class CheckLogDrainContainerJob implements ShouldQueue, ShouldBeEncrypted
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
send_internal_notification("CheckLogDrainContainerJob failed on ({$this->server->id}) with: " . $e->getMessage());
|
||||
if (!isCloud()) send_internal_notification("CheckLogDrainContainerJob failed on ({$this->server->id}) with: " . $e->getMessage());
|
||||
ray($e->getMessage());
|
||||
handleError($e);
|
||||
return handleError($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
59
app/Jobs/PullCoolifyImageJob.php
Normal file
59
app/Jobs/PullCoolifyImageJob.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\InstanceSettings;
|
||||
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\SerializesModels;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class PullCoolifyImageJob implements ShouldQueue, ShouldBeEncrypted
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $timeout = 1000;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
public function handle(): void
|
||||
{
|
||||
try {
|
||||
if (isDev() || isCloud()) {
|
||||
return;
|
||||
}
|
||||
$server = Server::findOrFail(0);
|
||||
$response = Http::retry(3, 1000)->get('https://cdn.coollabs.io/coolify/versions.json');
|
||||
if ($response->successful()) {
|
||||
$versions = $response->json();
|
||||
File::put(base_path('versions.json'), json_encode($versions, JSON_PRETTY_PRINT));
|
||||
}
|
||||
$latest_version = get_latest_version_of_coolify();
|
||||
instant_remote_process(["docker pull -q ghcr.io/coollabsio/coolify:{$latest_version}"], $server, false);
|
||||
|
||||
$settings = InstanceSettings::get();
|
||||
$current_version = config('version');
|
||||
if (!$settings->is_auto_update_enabled) {
|
||||
return;
|
||||
}
|
||||
if ($latest_version === $current_version) {
|
||||
return;
|
||||
}
|
||||
if (version_compare($latest_version, $current_version, '<')) {
|
||||
return;
|
||||
}
|
||||
instant_remote_process([
|
||||
"curl -fsSL https://cdn.coollabs.io/coolify/upgrade.sh -o /data/coolify/source/upgrade.sh",
|
||||
"bash /data/coolify/source/upgrade.sh $latest_version"
|
||||
], $server);
|
||||
} catch (\Throwable $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,8 +34,7 @@ class PullVersionsFromCDN implements ShouldQueue, ShouldBeEncrypted
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
send_internal_notification('PullTemplatesAndVersions failed with: ' . $e->getMessage());
|
||||
ray($e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ class General extends Component
|
||||
$this->initialDockerComposeLocation = $this->application->docker_compose_location;
|
||||
if ($this->application->build_pack === 'dockercompose' && !$this->application->docker_compose_raw) {
|
||||
$this->initLoadingCompose = true;
|
||||
$this->dispatch('info', 'Loading docker compose file...');
|
||||
$this->dispatch('info', 'Loading docker compose file.');
|
||||
}
|
||||
|
||||
if (str($this->application->status)->startsWith('running') && is_null($this->application->config_hash)) {
|
||||
|
||||
@@ -25,6 +25,7 @@ class Heading extends Component
|
||||
return [
|
||||
"echo-private:team.{$teamId},ApplicationStatusChanged" => 'check_status',
|
||||
"compose_loaded" => '$refresh',
|
||||
"update_links" => '$refresh',
|
||||
];
|
||||
}
|
||||
public function mount()
|
||||
|
||||
@@ -43,7 +43,7 @@ class Previews extends Component
|
||||
try {
|
||||
$success = true;
|
||||
$preview = $this->application->previews->find($preview_id);
|
||||
if (isset($preview->fqdn)) {
|
||||
if (data_get_str($preview, 'fqdn')->isNotEmpty()) {
|
||||
$preview->fqdn = str($preview->fqdn)->replaceEnd(',', '')->trim();
|
||||
$preview->fqdn = str($preview->fqdn)->replaceStart(',', '')->trim();
|
||||
$preview->fqdn = str($preview->fqdn)->trim()->lower();
|
||||
@@ -79,7 +79,7 @@ class Previews extends Component
|
||||
$random = new Cuid2(7);
|
||||
$preview_fqdn = str_replace('{{random}}', $random, $template);
|
||||
$preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
|
||||
$preview_fqdn = str_replace('{{pr_id}}', $preview_id, $preview_fqdn);
|
||||
$preview_fqdn = str_replace('{{pr_id}}', $preview->pull_request_id, $preview_fqdn);
|
||||
$preview_fqdn = "$schema://$preview_fqdn";
|
||||
$preview->fqdn = $preview_fqdn;
|
||||
$preview->save();
|
||||
@@ -88,17 +88,34 @@ class Previews extends Component
|
||||
public function add(int $pull_request_id, string|null $pull_request_html_url = null)
|
||||
{
|
||||
try {
|
||||
$this->setDeploymentUuid();
|
||||
$found = ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first();
|
||||
if (!$found && !is_null($pull_request_html_url)) {
|
||||
ApplicationPreview::create([
|
||||
'application_id' => $this->application->id,
|
||||
'pull_request_id' => $pull_request_id,
|
||||
'pull_request_html_url' => $pull_request_html_url
|
||||
]);
|
||||
if ($this->application->build_pack === 'dockercompose') {
|
||||
$this->setDeploymentUuid();
|
||||
$found = ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first();
|
||||
if (!$found && !is_null($pull_request_html_url)) {
|
||||
$found = ApplicationPreview::create([
|
||||
'application_id' => $this->application->id,
|
||||
'pull_request_id' => $pull_request_id,
|
||||
'pull_request_html_url' => $pull_request_html_url,
|
||||
'docker_compose_domains' => $this->application->docker_compose_domains,
|
||||
]);
|
||||
}
|
||||
$found->generate_preview_fqdn_compose();
|
||||
$this->application->refresh();
|
||||
} else {
|
||||
$this->setDeploymentUuid();
|
||||
$found = ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first();
|
||||
if (!$found && !is_null($pull_request_html_url)) {
|
||||
$found = ApplicationPreview::create([
|
||||
'application_id' => $this->application->id,
|
||||
'pull_request_id' => $pull_request_id,
|
||||
'pull_request_html_url' => $pull_request_html_url,
|
||||
]);
|
||||
}
|
||||
$this->application->generate_preview_fqdn($pull_request_id);
|
||||
$this->application->refresh();
|
||||
$this->dispatch('update_links');
|
||||
$this->dispatch('success', 'Preview added.');
|
||||
}
|
||||
$this->application->generate_preview_fqdn($pull_request_id);
|
||||
$this->application->refresh();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
@@ -152,7 +169,7 @@ class Previews extends Component
|
||||
}
|
||||
}
|
||||
GetContainersStatus::dispatchSync($this->application->destination->server);
|
||||
$this->application->refresh();
|
||||
$this->dispatch('reloadWindow');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
@@ -172,15 +189,10 @@ class Previews extends Component
|
||||
}
|
||||
ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first()->delete();
|
||||
$this->application->refresh();
|
||||
$this->dispatch('update_links');
|
||||
$this->dispatch('success', 'Preview deleted.');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function previewRefresh()
|
||||
{
|
||||
$this->application->previews->each(function ($preview) {
|
||||
$preview->refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
56
app/Livewire/Project/Application/PreviewsCompose.php
Normal file
56
app/Livewire/Project/Application/PreviewsCompose.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Project\Application;
|
||||
|
||||
use App\Models\ApplicationPreview;
|
||||
use Livewire\Component;
|
||||
use Spatie\Url\Url;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
class PreviewsCompose extends Component
|
||||
{
|
||||
public $service;
|
||||
public $serviceName;
|
||||
public ApplicationPreview $preview;
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.project.application.previews-compose');
|
||||
}
|
||||
public function save()
|
||||
{
|
||||
$domain = data_get($this->service, 'domain');
|
||||
$docker_compose_domains = data_get($this->preview, 'docker_compose_domains');
|
||||
$docker_compose_domains = json_decode($docker_compose_domains, true);
|
||||
$docker_compose_domains[$this->serviceName]['domain'] = $domain;
|
||||
$this->preview->docker_compose_domains = json_encode($docker_compose_domains);
|
||||
$this->preview->save();
|
||||
$this->dispatch('update_links');
|
||||
$this->dispatch('success', 'Domain saved.');
|
||||
}
|
||||
public function generate()
|
||||
{
|
||||
$domains = collect(json_decode($this->preview->application->docker_compose_domains)) ?? collect();
|
||||
$domain = $domains->first(function ($_, $key) {
|
||||
return $key === $this->serviceName;
|
||||
});
|
||||
if ($domain) {
|
||||
$domain = data_get($domain, 'domain');
|
||||
$url = Url::fromString($domain);
|
||||
$template = $this->preview->application->preview_url_template;
|
||||
$host = $url->getHost();
|
||||
$schema = $url->getScheme();
|
||||
$random = new Cuid2(7);
|
||||
$preview_fqdn = str_replace('{{random}}', $random, $template);
|
||||
$preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
|
||||
$preview_fqdn = str_replace('{{pr_id}}', $this->preview->pull_request_id, $preview_fqdn);
|
||||
$preview_fqdn = "$schema://$preview_fqdn";
|
||||
$docker_compose_domains = data_get($this->preview, 'docker_compose_domains');
|
||||
$docker_compose_domains = json_decode($docker_compose_domains, true);
|
||||
$docker_compose_domains[$this->serviceName]['domain'] = $this->service->domain = $preview_fqdn;
|
||||
$this->preview->docker_compose_domains = json_encode($docker_compose_domains);
|
||||
$this->preview->save();
|
||||
}
|
||||
$this->dispatch('update_links');
|
||||
$this->dispatch('success', 'Domain generated.');
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ use Livewire\Component;
|
||||
class Index extends Component
|
||||
{
|
||||
public $database;
|
||||
public $s3s;
|
||||
public function mount()
|
||||
{
|
||||
$project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
|
||||
@@ -36,7 +35,6 @@ class Index extends Component
|
||||
]);
|
||||
}
|
||||
$this->database = $database;
|
||||
$this->s3s = currentTeam()->s3s;
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ class BackupExecutions extends Component
|
||||
public function refreshBackupExecutions(): void
|
||||
{
|
||||
if ($this->backup) {
|
||||
$this->executions = $this->backup->executions()->get()->sortByDesc('created_at');
|
||||
$this->executions = $this->backup->executions()->get()->sortBy('created_at');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@ namespace App\Livewire\Project\Database\Clickhouse;
|
||||
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Database\StopDatabaseProxy;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneClickhouse;
|
||||
use Exception;
|
||||
use Livewire\Component;
|
||||
|
||||
class General extends Component
|
||||
{
|
||||
public Server $server;
|
||||
public StandaloneClickhouse $database;
|
||||
public ?string $db_url = null;
|
||||
public ?string $db_url_public = null;
|
||||
@@ -43,10 +45,11 @@ class General extends Component
|
||||
if ($this->database->is_public) {
|
||||
$this->db_url_public = $this->database->get_db_url();
|
||||
}
|
||||
$this->server = data_get($this->database,'destination.server');
|
||||
}
|
||||
public function instantSaveAdvanced() {
|
||||
try {
|
||||
if (!$this->database->destination->server->isLogDrainEnabled()) {
|
||||
if (!$this->server->isLogDrainEnabled()) {
|
||||
$this->database->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
return;
|
||||
|
||||
@@ -25,6 +25,7 @@ class CreateScheduledBackup extends Component
|
||||
];
|
||||
public function mount()
|
||||
{
|
||||
$this->s3s = currentTeam()->s3s;
|
||||
if ($this->s3s->count() > 0) {
|
||||
$this->s3_storage_id = $this->s3s->first()->id;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Database\Dragonfly;
|
||||
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Database\StopDatabaseProxy;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneDragonfly;
|
||||
use Exception;
|
||||
use Livewire\Component;
|
||||
@@ -12,6 +13,7 @@ class General extends Component
|
||||
{
|
||||
protected $listeners = ['refresh'];
|
||||
|
||||
public Server $server;
|
||||
public StandaloneDragonfly $database;
|
||||
public ?string $db_url = null;
|
||||
public ?string $db_url_public = null;
|
||||
@@ -41,10 +43,11 @@ class General extends Component
|
||||
if ($this->database->is_public) {
|
||||
$this->db_url_public = $this->database->get_db_url();
|
||||
}
|
||||
$this->server = data_get($this->database,'destination.server');
|
||||
}
|
||||
public function instantSaveAdvanced() {
|
||||
try {
|
||||
if (!$this->database->destination->server->isLogDrainEnabled()) {
|
||||
if (!$this->server->isLogDrainEnabled()) {
|
||||
$this->database->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Database\Keydb;
|
||||
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Database\StopDatabaseProxy;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneKeydb;
|
||||
use Exception;
|
||||
use Livewire\Component;
|
||||
@@ -12,6 +13,7 @@ class General extends Component
|
||||
{
|
||||
protected $listeners = ['refresh'];
|
||||
|
||||
public Server $server;
|
||||
public StandaloneKeydb $database;
|
||||
public ?string $db_url = null;
|
||||
public ?string $db_url_public = null;
|
||||
@@ -43,10 +45,12 @@ class General extends Component
|
||||
if ($this->database->is_public) {
|
||||
$this->db_url_public = $this->database->get_db_url();
|
||||
}
|
||||
$this->server = data_get($this->database,'destination.server');
|
||||
|
||||
}
|
||||
public function instantSaveAdvanced() {
|
||||
try {
|
||||
if (!$this->database->destination->server->isLogDrainEnabled()) {
|
||||
if (!$this->server->isLogDrainEnabled()) {
|
||||
$this->database->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Database\Mariadb;
|
||||
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Database\StopDatabaseProxy;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneMariadb;
|
||||
use Exception;
|
||||
use Livewire\Component;
|
||||
@@ -12,6 +13,7 @@ class General extends Component
|
||||
{
|
||||
protected $listeners = ['refresh'];
|
||||
|
||||
public Server $server;
|
||||
public StandaloneMariadb $database;
|
||||
public ?string $db_url = null;
|
||||
public ?string $db_url_public = null;
|
||||
@@ -50,10 +52,12 @@ class General extends Component
|
||||
if ($this->database->is_public) {
|
||||
$this->db_url_public = $this->database->get_db_url();
|
||||
}
|
||||
$this->server = data_get($this->database,'destination.server');
|
||||
|
||||
}
|
||||
public function instantSaveAdvanced() {
|
||||
try {
|
||||
if (!$this->database->destination->server->isLogDrainEnabled()) {
|
||||
if (!$this->server->isLogDrainEnabled()) {
|
||||
$this->database->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Database\Mongodb;
|
||||
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Database\StopDatabaseProxy;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneMongodb;
|
||||
use Exception;
|
||||
use Livewire\Component;
|
||||
@@ -12,6 +13,7 @@ class General extends Component
|
||||
{
|
||||
protected $listeners = ['refresh'];
|
||||
|
||||
public Server $server;
|
||||
public StandaloneMongodb $database;
|
||||
public ?string $db_url = null;
|
||||
public ?string $db_url_public = null;
|
||||
@@ -48,11 +50,13 @@ class General extends Component
|
||||
if ($this->database->is_public) {
|
||||
$this->db_url_public = $this->database->get_db_url();
|
||||
}
|
||||
$this->server = data_get($this->database,'destination.server');
|
||||
|
||||
}
|
||||
public function instantSaveAdvanced()
|
||||
{
|
||||
try {
|
||||
if (!$this->database->destination->server->isLogDrainEnabled()) {
|
||||
if (!$this->server->isLogDrainEnabled()) {
|
||||
$this->database->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Database\Mysql;
|
||||
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Database\StopDatabaseProxy;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneMysql;
|
||||
use Exception;
|
||||
use Livewire\Component;
|
||||
@@ -13,6 +14,7 @@ class General extends Component
|
||||
protected $listeners = ['refresh'];
|
||||
|
||||
public StandaloneMysql $database;
|
||||
public Server $server;
|
||||
public ?string $db_url = null;
|
||||
public ?string $db_url_public = null;
|
||||
|
||||
@@ -50,11 +52,12 @@ class General extends Component
|
||||
if ($this->database->is_public) {
|
||||
$this->db_url_public = $this->database->get_db_url();
|
||||
}
|
||||
$this->server = data_get($this->database,'destination.server');
|
||||
}
|
||||
public function instantSaveAdvanced()
|
||||
{
|
||||
try {
|
||||
if (!$this->database->destination->server->isLogDrainEnabled()) {
|
||||
if (!$this->server->isLogDrainEnabled()) {
|
||||
$this->database->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Database\Postgresql;
|
||||
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Database\StopDatabaseProxy;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandalonePostgresql;
|
||||
use Exception;
|
||||
use Livewire\Component;
|
||||
@@ -13,6 +14,7 @@ use function Aws\filter;
|
||||
class General extends Component
|
||||
{
|
||||
public StandalonePostgresql $database;
|
||||
public Server $server;
|
||||
public string $new_filename;
|
||||
public string $new_content;
|
||||
public ?string $db_url = null;
|
||||
@@ -57,11 +59,12 @@ class General extends Component
|
||||
if ($this->database->is_public) {
|
||||
$this->db_url_public = $this->database->get_db_url();
|
||||
}
|
||||
$this->server = data_get($this->database,'destination.server');
|
||||
}
|
||||
public function instantSaveAdvanced()
|
||||
{
|
||||
try {
|
||||
if (!$this->database->destination->server->isLogDrainEnabled()) {
|
||||
if (!$this->server->isLogDrainEnabled()) {
|
||||
$this->database->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Database\Redis;
|
||||
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Database\StopDatabaseProxy;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneRedis;
|
||||
use Exception;
|
||||
use Livewire\Component;
|
||||
@@ -12,6 +13,7 @@ class General extends Component
|
||||
{
|
||||
protected $listeners = ['refresh'];
|
||||
|
||||
public Server $server;
|
||||
public StandaloneRedis $database;
|
||||
public ?string $db_url = null;
|
||||
public ?string $db_url_public = null;
|
||||
@@ -43,10 +45,12 @@ class General extends Component
|
||||
if ($this->database->is_public) {
|
||||
$this->db_url_public = $this->database->get_db_url();
|
||||
}
|
||||
$this->server = data_get($this->database,'destination.server');
|
||||
|
||||
}
|
||||
public function instantSaveAdvanced() {
|
||||
try {
|
||||
if (!$this->database->destination->server->isLogDrainEnabled()) {
|
||||
if (!$this->server->isLogDrainEnabled()) {
|
||||
$this->database->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
return;
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Models\Application;
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\GitlabApp;
|
||||
use App\Models\Project;
|
||||
use App\Models\Service;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\SwarmDocker;
|
||||
use Carbon\Carbon;
|
||||
@@ -33,6 +34,8 @@ class PublicGitRepository extends Component
|
||||
public $build_pack = 'nixpacks';
|
||||
public bool $show_is_static = true;
|
||||
|
||||
public bool $new_compose_services = false;
|
||||
|
||||
protected $rules = [
|
||||
'repository_url' => 'required|url',
|
||||
'port' => 'required|numeric',
|
||||
@@ -177,6 +180,31 @@ class PublicGitRepository extends Component
|
||||
$project = Project::where('uuid', $project_uuid)->first();
|
||||
$environment = $project->load(['environments'])->environments->where('name', $environment_name)->first();
|
||||
|
||||
if ($this->build_pack === 'dockercompose' && isDev() && $this->new_compose_services ) {
|
||||
$server = $destination->server;
|
||||
$new_service = [
|
||||
'name' => 'service' . str()->random(10),
|
||||
'docker_compose_raw' => 'coolify',
|
||||
'environment_id' => $environment->id,
|
||||
'server_id' => $server->id,
|
||||
];
|
||||
if ($this->git_source === 'other') {
|
||||
$new_service['git_repository'] = $this->git_repository;
|
||||
$new_service['git_branch'] = $this->git_branch;
|
||||
} else {
|
||||
$new_service['git_repository'] = $this->git_repository;
|
||||
$new_service['git_branch'] = $this->git_branch;
|
||||
$new_service['source_id'] = $this->git_source->id;
|
||||
$new_service['source_type'] = $this->git_source->getMorphClass();
|
||||
}
|
||||
$service = Service::create($new_service);
|
||||
return redirect()->route('project.service.configuration', [
|
||||
'service_uuid' => $service->uuid,
|
||||
'environment_name' => $environment->name,
|
||||
'project_uuid' => $project->uuid,
|
||||
]);
|
||||
return;
|
||||
}
|
||||
if ($this->git_source === 'other') {
|
||||
$application_init = [
|
||||
'name' => generate_random_name(),
|
||||
|
||||
@@ -10,6 +10,7 @@ use Livewire\Component;
|
||||
class Create extends Component
|
||||
{
|
||||
public $type;
|
||||
public $project;
|
||||
public function mount()
|
||||
{
|
||||
$type = str(request()->query('type'));
|
||||
@@ -20,6 +21,7 @@ class Create extends Component
|
||||
if (!$project) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
$this->project = $project;
|
||||
$environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first();
|
||||
if (!$environment) {
|
||||
return redirect()->route('dashboard');
|
||||
|
||||
@@ -42,7 +42,7 @@ class StackForm extends Component
|
||||
$this->validationAttributes["fields.$key.value"] = $fieldKey;
|
||||
}
|
||||
}
|
||||
$this->fields = $this->fields->sortDesc();
|
||||
$this->fields = $this->fields->sortBy('name');
|
||||
}
|
||||
public function saveCompose($raw)
|
||||
{
|
||||
@@ -52,7 +52,7 @@ class StackForm extends Component
|
||||
public function instantSave()
|
||||
{
|
||||
$this->service->save();
|
||||
$this->dispatch('success', 'Service settings saved.');
|
||||
$this->dispatch('success', 'Service settings saved.');
|
||||
}
|
||||
|
||||
public function submit()
|
||||
|
||||
@@ -11,16 +11,16 @@ use Livewire\Component;
|
||||
class Change extends Component
|
||||
{
|
||||
public string $webhook_endpoint;
|
||||
public ?string $ipv4;
|
||||
public ?string $ipv6;
|
||||
public ?string $fqdn;
|
||||
public ?string $ipv4 = null;
|
||||
public ?string $ipv6 = null;
|
||||
public ?string $fqdn = null;
|
||||
|
||||
public ?bool $default_permissions = true;
|
||||
public ?bool $preview_deployment_permissions = true;
|
||||
public ?bool $administration = false;
|
||||
|
||||
public $parameters;
|
||||
public ?GithubApp $github_app;
|
||||
public ?GithubApp $github_app = null;
|
||||
public string $name;
|
||||
public bool $is_system_wide;
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@ class InviteLink extends Component
|
||||
public string $email;
|
||||
public string $role = 'member';
|
||||
|
||||
protected $rules = [
|
||||
'email' => 'required|email',
|
||||
'role' => 'required|string',
|
||||
];
|
||||
public function mount()
|
||||
{
|
||||
$this->email = isDev() ? 'test3@example.com' : '';
|
||||
@@ -34,6 +38,7 @@ class InviteLink extends Component
|
||||
private function generate_invite_link(bool $sendEmail = false)
|
||||
{
|
||||
try {
|
||||
$this->validate();
|
||||
$member_emails = currentTeam()->members()->get()->pluck('email');
|
||||
if ($member_emails->contains($this->email)) {
|
||||
return handleError(livewire: $this, customErrorMessage: "$this->email is already a member of " . currentTeam()->name . ".");
|
||||
|
||||
@@ -861,14 +861,10 @@ class Application extends BaseModel
|
||||
|
||||
instant_remote_process($commands, $this->destination->server, false);
|
||||
}
|
||||
function parseCompose(int $pull_request_id = 0)
|
||||
function parseCompose(int $pull_request_id = 0, ?int $preview_id = null)
|
||||
{
|
||||
if ($this->docker_compose_raw) {
|
||||
$mainCompose = parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id);
|
||||
if ($this->getMorphClass() === 'App\Models\Application' && $this->docker_compose_pr_raw) {
|
||||
parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id, is_pr: true);
|
||||
}
|
||||
return $mainCompose;
|
||||
return parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id, preview_id: $preview_id);
|
||||
} else {
|
||||
return collect([]);
|
||||
}
|
||||
@@ -1052,7 +1048,8 @@ class Application extends BaseModel
|
||||
}
|
||||
}
|
||||
}
|
||||
function generate_preview_fqdn(int $pull_request_id) {
|
||||
function generate_preview_fqdn(int $pull_request_id)
|
||||
{
|
||||
$preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->id, $pull_request_id);
|
||||
if (is_null(data_get($preview, 'fqdn')) && $this->fqdn) {
|
||||
if (str($this->fqdn)->contains(',')) {
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Spatie\Url\Url;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
class ApplicationPreview extends BaseModel
|
||||
{
|
||||
protected $guarded = [];
|
||||
@@ -34,4 +37,26 @@ class ApplicationPreview extends BaseModel
|
||||
{
|
||||
return $this->belongsTo(Application::class);
|
||||
}
|
||||
function generate_preview_fqdn_compose()
|
||||
{
|
||||
$domains = collect(json_decode($this->application->docker_compose_domains)) ?? collect();
|
||||
foreach ($domains as $service_name => $domain) {
|
||||
$domain = data_get($domain, 'domain');
|
||||
$url = Url::fromString($domain);
|
||||
$template = $this->application->preview_url_template;
|
||||
$host = $url->getHost();
|
||||
$schema = $url->getScheme();
|
||||
$random = new Cuid2(7);
|
||||
$preview_fqdn = str_replace('{{random}}', $random, $template);
|
||||
$preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
|
||||
$preview_fqdn = str_replace('{{pr_id}}', $this->pull_request_id, $preview_fqdn);
|
||||
$preview_fqdn = "$schema://$preview_fqdn";
|
||||
$docker_compose_domains = data_get($this, 'docker_compose_domains');
|
||||
$docker_compose_domains = json_decode($docker_compose_domains, true);
|
||||
$docker_compose_domains[$service_name]['domain'] = $preview_fqdn;
|
||||
$docker_compose_domains = json_encode($docker_compose_domains);
|
||||
$this->docker_compose_domains = $docker_compose_domains;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ class EnvironmentVariable extends Model
|
||||
return true;
|
||||
}
|
||||
$found_in_compose = false;
|
||||
$found_in_args = false;
|
||||
$resource = $this->resource();
|
||||
$compose = data_get($resource, 'docker_compose_raw');
|
||||
if (!$compose) {
|
||||
@@ -102,21 +103,35 @@ class EnvironmentVariable extends Model
|
||||
}
|
||||
foreach ($services as $service) {
|
||||
$environments = collect(data_get($service, 'environment'));
|
||||
if ($environments->isEmpty()) {
|
||||
$args = collect(data_get($service, 'build.args'));
|
||||
if ($environments->isEmpty() && $args->isEmpty()) {
|
||||
$found_in_compose = false;
|
||||
break;
|
||||
}
|
||||
|
||||
$found_in_compose = $environments->contains(function ($item) {
|
||||
if (str($item)->contains('=')) {
|
||||
$item = str($item)->before('=');
|
||||
}
|
||||
return strpos($item, $this->key) !== false;
|
||||
});
|
||||
|
||||
if ($found_in_compose) {
|
||||
break;
|
||||
}
|
||||
|
||||
$found_in_args = $args->contains(function ($item) {
|
||||
if (str($item)->contains('=')) {
|
||||
$item = str($item)->before('=');
|
||||
}
|
||||
return strpos($item, $this->key) !== false;
|
||||
});
|
||||
|
||||
if ($found_in_args) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $found_in_compose;
|
||||
return $found_in_compose || $found_in_args;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -897,7 +897,9 @@ $schema://$host {
|
||||
}
|
||||
public function validateDockerEngineVersion()
|
||||
{
|
||||
$dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $this, false);
|
||||
$dockerVersionRaw = instant_remote_process(["docker version --format json"], $this, false);
|
||||
$dockerVersionJson = json_decode($dockerVersionRaw, true);
|
||||
$dockerVersion = data_get($dockerVersionJson, 'Server.Version', '0.0.0');
|
||||
$dockerVersion = checkMinimumDockerEngineVersion($dockerVersion);
|
||||
if (is_null($dockerVersion)) {
|
||||
$this->settings->is_usable = false;
|
||||
|
||||
@@ -472,6 +472,72 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('Admin', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('vaultwarden'):
|
||||
$data = collect([]);
|
||||
|
||||
$DATABASE_URL = $this->environment_variables()->where('key', 'DATABASE_URL')->first();
|
||||
$ADMIN_TOKEN = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_64_ADMIN')->first();
|
||||
$SIGNUP_ALLOWED = $this->environment_variables()->where('key', 'SIGNUP_ALLOWED')->first();
|
||||
$PUSH_ENABLED = $this->environment_variables()->where('key', 'PUSH_ENABLED')->first();
|
||||
$PUSH_INSTALLATION_ID = $this->environment_variables()->where('key', 'PUSH_SERVICE_ID')->first();
|
||||
$PUSH_INSTALLATION_KEY = $this->environment_variables()->where('key', 'PUSH_SERVICE_KEY')->first();
|
||||
|
||||
if ($DATABASE_URL) {
|
||||
$data = $data->merge([
|
||||
'Database URL' => [
|
||||
'key' => data_get($DATABASE_URL, 'key'),
|
||||
'value' => data_get($DATABASE_URL, 'value'),
|
||||
],
|
||||
]);
|
||||
}
|
||||
if ($ADMIN_TOKEN) {
|
||||
$data = $data->merge([
|
||||
'Admin Password' => [
|
||||
'key' => data_get($ADMIN_TOKEN, 'key'),
|
||||
'value' => data_get($ADMIN_TOKEN, 'value'),
|
||||
'isPassword' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
if ($SIGNUP_ALLOWED) {
|
||||
$data = $data->merge([
|
||||
'Signup Allowed' => [
|
||||
'key' => data_get($SIGNUP_ALLOWED, 'key'),
|
||||
'value' => data_get($SIGNUP_ALLOWED, 'value'),
|
||||
'rules' => 'required|string|in:true,false',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
if ($PUSH_ENABLED) {
|
||||
$data = $data->merge([
|
||||
'Push Enabled' => [
|
||||
'key' => data_get($PUSH_ENABLED, 'key'),
|
||||
'value' => data_get($PUSH_ENABLED, 'value'),
|
||||
'rules' => 'required|string|in:true,false',
|
||||
],
|
||||
]);
|
||||
}
|
||||
if ($PUSH_INSTALLATION_ID) {
|
||||
$data = $data->merge([
|
||||
'Push Installation ID' => [
|
||||
'key' => data_get($PUSH_INSTALLATION_ID, 'key'),
|
||||
'value' => data_get($PUSH_INSTALLATION_ID, 'value'),
|
||||
],
|
||||
]);
|
||||
}
|
||||
if ($PUSH_INSTALLATION_KEY) {
|
||||
$data = $data->merge([
|
||||
'Push Installation Key' => [
|
||||
'key' => data_get($PUSH_INSTALLATION_KEY, 'key'),
|
||||
'value' => data_get($PUSH_INSTALLATION_KEY, 'value'),
|
||||
'isPassword' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
$fields->put('Vaultwarden', $data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$databases = $this->databases()->get();
|
||||
|
||||
@@ -22,6 +22,8 @@ class TelegramChannel
|
||||
$topicId = data_get($notifiable, 'telegram_notifications_test_message_thread_id');
|
||||
break;
|
||||
case 'App\Notifications\Application\StatusChanged':
|
||||
case 'App\Notifications\Container\ContainerRestarted':
|
||||
case 'App\Notifications\Container\ContainerStopped':
|
||||
$topicId = data_get($notifiable, 'telegram_notifications_status_changes_message_thread_id');
|
||||
break;
|
||||
case 'App\Notifications\Application\DeploymentSuccess':
|
||||
|
||||
@@ -38,7 +38,7 @@ const SPECIFIC_SERVICES = [
|
||||
// Based on /etc/os-release
|
||||
const SUPPORTED_OS = [
|
||||
'ubuntu debian raspbian',
|
||||
'centos fedora rhel ol rocky amzn',
|
||||
'centos fedora rhel ol rocky amzn almalinux',
|
||||
'sles opensuse-leap opensuse-tumbleweed'
|
||||
];
|
||||
|
||||
|
||||
@@ -488,8 +488,10 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview
|
||||
));
|
||||
}
|
||||
} else {
|
||||
if ($preview->fqdn) {
|
||||
if (data_get($preview,'fqdn')) {
|
||||
$domains = Str::of(data_get($preview, 'fqdn'))->explode(',');
|
||||
} else {
|
||||
$domains = collect([]);
|
||||
}
|
||||
$labels = $labels->merge(fqdnLabelsForTraefik(
|
||||
uuid: $appUuid,
|
||||
|
||||
@@ -121,7 +121,7 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
// ray($generatedEnv);
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn . ':' . $port . $path;
|
||||
$generatedEnv->value = $fqdn . $path;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
}
|
||||
@@ -140,7 +140,7 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$variableName = $variableName . "_$port";
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $url . ':' . $port . $path;
|
||||
$generatedEnv->value = $url . $path;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
}
|
||||
@@ -160,7 +160,7 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$env->value = $host . $path;
|
||||
$env->save();
|
||||
}
|
||||
$port_env->value = $host . ':' . $port . $path;
|
||||
$port_env->value = $host . $path;
|
||||
$port_env->save();
|
||||
}
|
||||
$port_envs_url = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'like', "SERVICE_URL_%_$port")->get();
|
||||
@@ -171,7 +171,7 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$env->value = $url . $path;
|
||||
$env->save();
|
||||
}
|
||||
$port_env_url->value = $url . ':' . $port . $path;
|
||||
$port_env_url->value = $url . $path;
|
||||
$port_env_url->save();
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -576,6 +576,13 @@ function getTopLevelNetworks(Service|Application $resource)
|
||||
// Collect/create/update networks
|
||||
if ($serviceNetworks->count() > 0) {
|
||||
foreach ($serviceNetworks as $networkName => $networkDetails) {
|
||||
if ($networkName === 'default') {
|
||||
continue;
|
||||
}
|
||||
// ignore alias
|
||||
if ($networkDetails['aliases'] ?? false) {
|
||||
continue;
|
||||
}
|
||||
$networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) {
|
||||
return $value == $networkName || $key == $networkName;
|
||||
});
|
||||
@@ -618,6 +625,13 @@ function getTopLevelNetworks(Service|Application $resource)
|
||||
// Collect/create/update networks
|
||||
if ($serviceNetworks->count() > 0) {
|
||||
foreach ($serviceNetworks as $networkName => $networkDetails) {
|
||||
if ($networkName === 'default') {
|
||||
continue;
|
||||
}
|
||||
// ignore alias
|
||||
if ($networkDetails['aliases'] ?? false) {
|
||||
continue;
|
||||
}
|
||||
$networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) {
|
||||
return $value == $networkName || $key == $networkName;
|
||||
});
|
||||
@@ -642,9 +656,9 @@ function getTopLevelNetworks(Service|Application $resource)
|
||||
return $topLevelNetworks->keys();
|
||||
}
|
||||
}
|
||||
function parseDockerComposeFile(Service|Application $resource, bool $isNew = false, int $pull_request_id = 0, bool $is_pr = false)
|
||||
|
||||
function parseDockerComposeFile(Service|Application $resource, bool $isNew = false, int $pull_request_id = 0, ?int $preview_id = null)
|
||||
{
|
||||
// ray()->clearAll();
|
||||
if ($resource->getMorphClass() === 'App\Models\Service') {
|
||||
if ($resource->docker_compose_raw) {
|
||||
try {
|
||||
@@ -666,6 +680,16 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
}
|
||||
}
|
||||
$definedNetwork = collect([$resource->uuid]);
|
||||
if ($topLevelVolumes->count() > 0) {
|
||||
$tempTopLevelVolumes = collect([]);
|
||||
foreach ($topLevelVolumes as $volumeName => $volume) {
|
||||
if (is_null($volume)) {
|
||||
continue;
|
||||
}
|
||||
$tempTopLevelVolumes->put($volumeName, $volume);
|
||||
}
|
||||
$topLevelVolumes = collect($tempTopLevelVolumes);
|
||||
}
|
||||
$services = collect($services)->map(function ($service, $serviceName) use ($topLevelVolumes, $topLevelNetworks, $definedNetwork, $isNew, $generatedServiceFQDNS, $resource, $allServices) {
|
||||
// Workarounds for beta users.
|
||||
if ($serviceName === 'registry') {
|
||||
@@ -764,6 +788,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
// Collect/create/update networks
|
||||
if ($serviceNetworks->count() > 0) {
|
||||
foreach ($serviceNetworks as $networkName => $networkDetails) {
|
||||
if ($networkName === 'default') {
|
||||
continue;
|
||||
}
|
||||
// ignore alias
|
||||
if ($networkDetails['aliases'] ?? false) {
|
||||
continue;
|
||||
}
|
||||
$networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) {
|
||||
return $value == $networkName || $key == $networkName;
|
||||
});
|
||||
@@ -815,7 +846,6 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
// default:
|
||||
// ipv4_address: 192.168.203.254
|
||||
// $networks->put($serviceNetwork, null);
|
||||
ray($key);
|
||||
$networks->put($key, $serviceNetwork);
|
||||
}
|
||||
}
|
||||
@@ -879,6 +909,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
]
|
||||
);
|
||||
} else if ($type->value() === 'volume') {
|
||||
if ($topLevelVolumes->has($source->value())) {
|
||||
$v = $topLevelVolumes->get($source->value());
|
||||
if (data_get($v, 'driver_opts.type') === 'cifs') {
|
||||
return $volume;
|
||||
}
|
||||
}
|
||||
$slugWithoutUuid = Str::slug($source, '-');
|
||||
$name = "{$savedService->service->uuid}_{$slugWithoutUuid}";
|
||||
if (is_string($volume)) {
|
||||
@@ -1246,26 +1282,29 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
$isSameDockerComposeFile = false;
|
||||
if ($resource->dockerComposePrLocation() === $resource->dockerComposeLocation()) {
|
||||
$isSameDockerComposeFile = true;
|
||||
$is_pr = false;
|
||||
}
|
||||
if ($is_pr) {
|
||||
try {
|
||||
$yaml = Yaml::parse($resource->docker_compose_pr_raw);
|
||||
} catch (\Exception $e) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$yaml = Yaml::parse($resource->docker_compose_raw);
|
||||
} catch (\Exception $e) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$yaml = Yaml::parse($resource->docker_compose_raw);
|
||||
} catch (\Exception $e) {
|
||||
return;
|
||||
}
|
||||
$server = $resource->destination->server;
|
||||
$topLevelVolumes = collect(data_get($yaml, 'volumes', []));
|
||||
if ($pull_request_id !== 0) {
|
||||
$topLevelVolumes = collect([]);
|
||||
}
|
||||
|
||||
if ($topLevelVolumes->count() > 0) {
|
||||
$tempTopLevelVolumes = collect([]);
|
||||
foreach ($topLevelVolumes as $volumeName => $volume) {
|
||||
if (is_null($volume)) {
|
||||
continue;
|
||||
}
|
||||
$tempTopLevelVolumes->put($volumeName, $volume);
|
||||
}
|
||||
$topLevelVolumes = collect($tempTopLevelVolumes);
|
||||
}
|
||||
|
||||
$topLevelNetworks = collect(data_get($yaml, 'networks', []));
|
||||
$services = data_get($yaml, 'services');
|
||||
|
||||
@@ -1281,7 +1320,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
if ($pull_request_id !== 0) {
|
||||
$definedNetwork = collect(["{$resource->uuid}-$pull_request_id"]);
|
||||
}
|
||||
$services = collect($services)->map(function ($service, $serviceName) use ($topLevelVolumes, $topLevelNetworks, $definedNetwork, $isNew, $generatedServiceFQDNS, $resource, $server, $pull_request_id) {
|
||||
$services = collect($services)->map(function ($service, $serviceName) use ($topLevelVolumes, $topLevelNetworks, $definedNetwork, $isNew, $generatedServiceFQDNS, $resource, $server, $pull_request_id, $preview_id) {
|
||||
$serviceVolumes = collect(data_get($service, 'volumes', []));
|
||||
$servicePorts = collect(data_get($service, 'ports', []));
|
||||
$serviceNetworks = collect(data_get($service, 'networks', []));
|
||||
@@ -1329,13 +1368,36 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
if ($pull_request_id !== 0) {
|
||||
$name = $name . "-pr-$pull_request_id";
|
||||
$volume = str("$name:$mount");
|
||||
$topLevelVolumes->put($name, [
|
||||
'name' => $name,
|
||||
]);
|
||||
if ($topLevelVolumes->has($name)) {
|
||||
$v = $topLevelVolumes->get($name);
|
||||
if (data_get($v, 'driver_opts.type') === 'cifs') {
|
||||
// Do nothing
|
||||
} else {
|
||||
if (is_null(data_get($v, 'name'))) {
|
||||
data_set($v, 'name', $name);
|
||||
data_set($topLevelVolumes, $name, $v);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$topLevelVolumes->put($name, [
|
||||
'name' => $name,
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$topLevelVolumes->put($name->value(), [
|
||||
'name' => $name->value(),
|
||||
]);
|
||||
if ($topLevelVolumes->has($name->value())) {
|
||||
$v = $topLevelVolumes->get($name->value());
|
||||
if (data_get($v, 'driver_opts.type') === 'cifs') {
|
||||
// Do nothing
|
||||
} else {
|
||||
if (is_null(data_get($v, 'name'))) {
|
||||
data_set($topLevelVolumes, $name->value(), $v);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$topLevelVolumes->put($name->value(), [
|
||||
'name' => $name->value(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1379,9 +1441,21 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
data_set($volume, 'source', $source . ':' . $target);
|
||||
}
|
||||
if (!str($source)->startsWith('/')) {
|
||||
$topLevelVolumes->put($source, [
|
||||
'name' => $source,
|
||||
]);
|
||||
if ($topLevelVolumes->has($source)) {
|
||||
$v = $topLevelVolumes->get($source);
|
||||
if (data_get($v, 'driver_opts.type') === 'cifs') {
|
||||
// Do nothing
|
||||
} else {
|
||||
if (is_null(data_get($v, 'name'))) {
|
||||
data_set($v, 'name', $source);
|
||||
data_set($topLevelVolumes, $source, $v);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$topLevelVolumes->put($source, [
|
||||
'name' => $source,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1408,6 +1482,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
// Collect/create/update networks
|
||||
if ($serviceNetworks->count() > 0) {
|
||||
foreach ($serviceNetworks as $networkName => $networkDetails) {
|
||||
if ($networkName === 'default') {
|
||||
continue;
|
||||
}
|
||||
// ignore alias
|
||||
if ($networkDetails['aliases'] ?? false) {
|
||||
continue;
|
||||
}
|
||||
$networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) {
|
||||
return $value == $networkName || $key == $networkName;
|
||||
});
|
||||
@@ -1639,21 +1720,32 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
if ($fqdns) {
|
||||
$fqdns = str($fqdns)->explode(',');
|
||||
if ($pull_request_id !== 0) {
|
||||
$fqdns = $fqdns->map(function ($fqdn) use ($pull_request_id, $resource) {
|
||||
$preview = ApplicationPreview::findPreviewByApplicationAndPullId($resource->id, $pull_request_id);
|
||||
$url = Url::fromString($fqdn);
|
||||
$template = $resource->preview_url_template;
|
||||
$host = $url->getHost();
|
||||
$schema = $url->getScheme();
|
||||
$random = new Cuid2(7);
|
||||
$preview_fqdn = str_replace('{{random}}', $random, $template);
|
||||
$preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
|
||||
$preview_fqdn = str_replace('{{pr_id}}', $pull_request_id, $preview_fqdn);
|
||||
$preview_fqdn = "$schema://$preview_fqdn";
|
||||
$preview->fqdn = $preview_fqdn;
|
||||
$preview->save();
|
||||
return $preview_fqdn;
|
||||
});
|
||||
$preview = $resource->previews()->find($preview_id);
|
||||
$docker_compose_domains = collect(json_decode(data_get($preview, 'docker_compose_domains')));
|
||||
if ($docker_compose_domains->count() > 0) {
|
||||
$found_fqdn = data_get($docker_compose_domains, "$serviceName.domain");
|
||||
if ($found_fqdn) {
|
||||
$fqdns = collect($found_fqdn);
|
||||
} else {
|
||||
$fqdns = collect([]);
|
||||
}
|
||||
} else {
|
||||
$fqdns = $fqdns->map(function ($fqdn) use ($pull_request_id, $resource) {
|
||||
$preview = ApplicationPreview::findPreviewByApplicationAndPullId($resource->id, $pull_request_id);
|
||||
$url = Url::fromString($fqdn);
|
||||
$template = $resource->preview_url_template;
|
||||
$host = $url->getHost();
|
||||
$schema = $url->getScheme();
|
||||
$random = new Cuid2(7);
|
||||
$preview_fqdn = str_replace('{{random}}', $random, $template);
|
||||
$preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
|
||||
$preview_fqdn = str_replace('{{pr_id}}', $pull_request_id, $preview_fqdn);
|
||||
$preview_fqdn = "$schema://$preview_fqdn";
|
||||
$preview->fqdn = $preview_fqdn;
|
||||
$preview->save();
|
||||
return $preview_fqdn;
|
||||
});
|
||||
}
|
||||
}
|
||||
$serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik(
|
||||
uuid: $resource->uuid,
|
||||
@@ -1720,13 +1812,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
$resource->docker_compose_raw = Yaml::dump($yaml, 10, 2);
|
||||
$resource->docker_compose = Yaml::dump($finalServices, 10, 2);
|
||||
} else {
|
||||
if ($is_pr) {
|
||||
$resource->docker_compose_pr_raw = Yaml::dump($yaml, 10, 2);
|
||||
$resource->docker_compose_pr = Yaml::dump($finalServices, 10, 2);
|
||||
} else {
|
||||
$resource->docker_compose_raw = Yaml::dump($yaml, 10, 2);
|
||||
$resource->docker_compose = Yaml::dump($finalServices, 10, 2);
|
||||
}
|
||||
$resource->docker_compose_raw = Yaml::dump($yaml, 10, 2);
|
||||
$resource->docker_compose = Yaml::dump($finalServices, 10, 2);
|
||||
}
|
||||
$resource->save();
|
||||
return collect($finalServices);
|
||||
|
||||
@@ -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.293',
|
||||
'release' => '4.0.0-beta.296',
|
||||
// When left empty or `null` the Laravel environment will be used
|
||||
'environment' => config('app.env'),
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
return '4.0.0-beta.293';
|
||||
return '4.0.0-beta.296';
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('application_previews', function (Blueprint $table) {
|
||||
$table->text('docker_compose_domains')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('application_previews', function (Blueprint $table) {
|
||||
$table->dropColumn('docker_compose_domains');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('application_previews', function (Blueprint $table) {
|
||||
$table->string('pull_request_issue_comment_id')->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('application_previews', function (Blueprint $table) {
|
||||
$table->integer('pull_request_issue_comment_id')->nullable()->change();
|
||||
});
|
||||
}
|
||||
};
|
||||
32
database/seeders/new_services.php
Normal file
32
database/seeders/new_services.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('services', function (Blueprint $table) {
|
||||
$table->string('git_repository')->nullable();
|
||||
$table->string('git_branch')->nullable();
|
||||
$table->nullableMorphs('source');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('services', function (Blueprint $table) {
|
||||
$table->dropColumn('git_repository');
|
||||
$table->dropColumn('git_branch');
|
||||
$table->dropMorphs('source');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -2,15 +2,15 @@ FROM alpine:3.17
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
# https://download.docker.com/linux/static/stable/
|
||||
ARG DOCKER_VERSION=26.1.2
|
||||
ARG DOCKER_VERSION=26.1.3
|
||||
# https://github.com/docker/compose/releases
|
||||
ARG DOCKER_COMPOSE_VERSION=2.27.0
|
||||
ARG DOCKER_COMPOSE_VERSION=2.27.1
|
||||
# https://github.com/docker/buildx/releases
|
||||
ARG DOCKER_BUILDX_VERSION=0.14.0
|
||||
ARG DOCKER_BUILDX_VERSION=0.14.1
|
||||
# https://github.com/buildpacks/pack/releases
|
||||
ARG PACK_VERSION=0.33.2
|
||||
ARG PACK_VERSION=0.34.1
|
||||
# https://github.com/railwayapp/nixpacks/releases
|
||||
ARG NIXPACKS_VERSION=1.21.3
|
||||
ARG NIXPACKS_VERSION=1.24.1
|
||||
|
||||
USER root
|
||||
WORKDIR /artifacts
|
||||
|
||||
@@ -31,7 +31,7 @@ RUN apt-get update
|
||||
RUN apt-get install postgresql-client-$POSTGRES_VERSION -y
|
||||
|
||||
# Coolify requirements
|
||||
RUN apt-get install -y php8.2-pgsql openssh-client git git-lfs jq lsof
|
||||
RUN apt-get install -y php8.2-pgsql openssh-client git git-lfs jq lsof vim
|
||||
RUN apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
|
||||
|
||||
COPY docker/prod/nginx.conf /etc/nginx/conf.d/custom.conf
|
||||
|
||||
30
lang/fa.json
Normal file
30
lang/fa.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"auth.login": "ورود",
|
||||
"auth.login.azure": "ورود با مایکروسافت",
|
||||
"auth.login.bitbucket": "ورود با Bitbucket",
|
||||
"auth.login.github": "ورود با گیت هاب",
|
||||
"auth.login.gitlab": "ورود با گیت لب",
|
||||
"auth.login.google": "ورود با گوگل",
|
||||
"auth.already_registered": "قبلاً ثبت نام کردهاید؟",
|
||||
"auth.confirm_password": "تایید رمز عبور",
|
||||
"auth.forgot_password": "فراموشی رمز عبور",
|
||||
"auth.forgot_password_send_email": "ارسال ایمیل بازیابی رمز عبور",
|
||||
"auth.register_now": "ثبت نام",
|
||||
"auth.logout": "خروج",
|
||||
"auth.register": "ثبت نام",
|
||||
"auth.registration_disabled": "ثبت نام غیر فعال است. لطفا با ادمین تماس بگیرید.",
|
||||
"auth.reset_password": "بازیابی رمز عبور",
|
||||
"auth.failed": "این اطلاعات با سوابق ما مطابقت ندارد.",
|
||||
"auth.failed.callback": "پردازش بازگشت از ارائهدهنده ورود با شکست مواجه شد.",
|
||||
"auth.failed.password": "رمز عبور ارائه شده نادرست است.",
|
||||
"auth.failed.email": "ما نمی توانیم کاربر با آدرس ایمیل مورد نظر را پیدا کنیم.",
|
||||
"auth.throttle": "تعداد تلاشهای ورود بیش از حد است. لطفاً در :seconds ثانیه دوباره تلاش کنید.",
|
||||
"input.name": "نام",
|
||||
"input.email": "ایمیل",
|
||||
"input.password": "رمز عبور",
|
||||
"input.password.again": "تکرار رمز عبور",
|
||||
"input.code": "کد یک بار مصرف",
|
||||
"input.recovery_code": "کد بازیابی",
|
||||
"button.save": "ذخیره",
|
||||
"repository.url": "<span class='text-helper'>مثالها</span><br>برای مخازن عمومی، از <span class='text-helper'>https://...</span> استفاده کنید.<br>برای مخازن خصوصی، از <span class='text-helper'>git@...</span> استفاده کنید.<br><br>شاخه <span class='text-helper'>main</span> انتخاب خواهد شد.<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify شاخه <span class='text-helper'>nodejs-fastify</span> انتخاب خواهد شد.<br>https://gitea.com/sedlav/expressjs.git شاخه <span class='text-helper'>main</span> انتخاب خواهد شد.<br>https://gitlab.com/andrasbacsai/nodejs-example.git شاخه <span class='text-helper'>main</span> انتخاب خواهد شد."
|
||||
}
|
||||
6
public/svgs/rocketchat.svg
Normal file
6
public/svgs/rocketchat.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="520" height="520" viewBox="0 0 520 520" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M422.968 205.942C413.422 191.118 400.042 177.995 383.222 166.926C350.724 145.574 308.024 133.811 262.987 133.811C247.939 133.811 233.115 135.12 218.724 137.71C209.796 129.114 199.357 121.382 188.301 115.272C147.282 94.8216 111.134 102.436 92.8693 109.004C86.8687 111.163 85.0173 118.752 89.4554 123.331C102.336 136.624 123.647 162.896 118.408 186.787C98.0427 207.577 87 232.646 87 258.748C87 285.347 98.0427 310.416 118.408 331.206C123.647 355.097 102.336 381.382 89.4554 394.675C85.0304 399.241 86.8687 406.83 92.8693 408.989C111.134 415.557 147.282 423.185 188.314 402.735C199.37 396.625 209.809 388.892 218.737 380.296C233.128 382.887 247.953 384.195 263 384.195C308.05 384.195 350.751 372.446 383.235 351.093C400.055 340.024 413.435 326.914 422.981 312.077C433.617 295.566 439 277.785 439 259.258C438.987 240.234 433.603 222.467 422.968 205.942ZM261.149 353.383C241.676 353.383 223.11 350.871 206.185 346.331L193.816 358.224C187.093 364.687 179.215 370.536 170.995 375.141C160.11 380.466 149.356 383.384 138.721 384.26C139.325 383.175 139.876 382.076 140.467 380.976C152.862 358.211 156.21 337.748 150.499 319.601C130.225 303.678 118.067 283.293 118.067 261.09C118.067 210.129 182.13 168.81 261.149 168.81C340.167 168.81 404.244 210.129 404.244 261.09C404.244 312.064 340.181 353.383 261.149 353.383Z" fill="#F5455C"/>
|
||||
<path d="M192.7 239.868C181.053 239.868 171.612 249.236 171.612 260.789C171.612 272.342 181.053 281.71 192.7 281.71C204.346 281.71 213.787 272.342 213.787 260.789C213.787 249.236 204.346 239.868 192.7 239.868Z" fill="#F5455C"/>
|
||||
<path d="M260.571 239.868C248.925 239.868 239.484 249.236 239.484 260.789C239.484 272.342 248.925 281.71 260.571 281.71C272.218 281.71 281.659 272.342 281.659 260.789C281.659 249.236 272.218 239.868 260.571 239.868Z" fill="#F5455C"/>
|
||||
<path d="M328.455 239.868C316.808 239.868 307.367 249.236 307.367 260.789C307.367 272.342 316.808 281.71 328.455 281.71C340.101 281.71 349.542 272.342 349.542 260.789C349.542 249.236 340.101 239.868 328.455 239.868Z" fill="#F5455C"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -45,24 +45,48 @@
|
||||
</a>
|
||||
@endforeach
|
||||
@endif
|
||||
@if (data_get($application, 'previews', collect([]))->count() > 0)
|
||||
@foreach (data_get($application, 'previews') as $preview)
|
||||
@if (data_get($preview, 'fqdn'))
|
||||
<a class="dropdown-item" 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" stroke-width="1.5"
|
||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M9 15l6 -6" />
|
||||
<path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" />
|
||||
<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" />
|
||||
</svg>
|
||||
PR{{ data_get($preview, 'pull_request_id') }} |
|
||||
{{ data_get($preview, 'fqdn') }}
|
||||
</a>
|
||||
@endif
|
||||
@endforeach
|
||||
@if (data_get($application, 'previews', collect())->count() > 0)
|
||||
@if (data_get($application, 'build_pack') === 'dockercompose')
|
||||
@foreach ($application->previews as $preview)
|
||||
@foreach (collect(json_decode($preview->docker_compose_domains)) as $fqdn)
|
||||
@if (data_get($fqdn, 'domain'))
|
||||
@foreach (explode(',', data_get($fqdn, 'domain')) as $domain)
|
||||
<a class="dropdown-item" target="_blank" href="{{ getFqdnWithoutPort($domain) }}">
|
||||
<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-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M9 15l6 -6" />
|
||||
<path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" />
|
||||
<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" />
|
||||
</svg>PR{{ data_get($preview, 'pull_request_id') }} |
|
||||
{{ getFqdnWithoutPort($domain) }}
|
||||
</a>
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
@endforeach
|
||||
@else
|
||||
@foreach (data_get($application, 'previews') as $preview)
|
||||
@if (data_get($preview, 'fqdn'))
|
||||
<a class="dropdown-item" 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"
|
||||
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M9 15l6 -6" />
|
||||
<path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" />
|
||||
<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" />
|
||||
</svg>
|
||||
PR{{ data_get($preview, 'pull_request_id') }} |
|
||||
{{ data_get($preview, 'fqdn') }}
|
||||
</a>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endif
|
||||
@if (data_get($application, 'ports_mappings_array'))
|
||||
@foreach ($application->ports_mappings_array as $port)
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<x-layout>
|
||||
<x-slot:title>
|
||||
Destinations | Coolify
|
||||
</x-slot>
|
||||
<div class="flex items-start gap-2">
|
||||
<h1>Destinations</h1>
|
||||
@if ($servers->count() > 0)
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="preconnect" href="https://api.fonts.coollabs.io" crossorigin>
|
||||
<link rel="dns-prefetch" href="https://api.fonts.coollabs.io" />
|
||||
<link rel="preload" href="https://api.fonts.coollabs.io/css2?family=Inter:wght@400;500;600;700;800&display=swap" as="style" />
|
||||
<link rel="preload" href="https://api.fonts.coollabs.io/css2?family=Inter:wght@400;500;600;700;800&display=swap"
|
||||
as="style" />
|
||||
<link rel="preload" href="https://cdn.fonts.coollabs.io/inter/normal/400.woff2" as="style" />
|
||||
<link rel="preload" href="https://cdn.fonts.coollabs.io/inter/normal/500.woff2" as="style" />
|
||||
<link rel="preload" href="https://cdn.fonts.coollabs.io/inter/normal/600.woff2" as="style" />
|
||||
@@ -14,7 +15,7 @@
|
||||
<link rel="preload" href="https://cdn.fonts.coollabs.io/inter/normal/800.woff2" as="style" />
|
||||
<link href="https://api.fonts.coollabs.io/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<meta name="robots" content="noindex">
|
||||
<title>Coolify</title>
|
||||
<title>{{ $title ?? 'Coolify' }}</title>
|
||||
@env('local')
|
||||
<link rel="icon" href="{{ asset('favicon-dev.png') }}" type="image/x-icon" />
|
||||
@else
|
||||
@@ -44,7 +45,10 @@
|
||||
<body>
|
||||
<x-toast />
|
||||
<script data-navigate-once>
|
||||
if (localStorage.theme === 'dark') {
|
||||
if (!('theme' in localStorage)) {
|
||||
localStorage.theme = 'dark';
|
||||
document.documentElement.classList.add('dark')
|
||||
} else if (localStorage.theme === 'dark') {
|
||||
document.documentElement.classList.add('dark')
|
||||
} else if (localStorage.theme === 'light') {
|
||||
document.documentElement.classList.remove('dark')
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
@php use App\Enums\ProxyTypes; @endphp
|
||||
<x-slot:title>
|
||||
Onboarding | Coolify
|
||||
</x-slot>
|
||||
<section class="flex flex-col h-full lg:items-center lg:justify-center">
|
||||
<div
|
||||
class="flex flex-col items-center justify-center p-10 mx-2 mt-10 bg-white border rounded-lg shadow lg:p-20 dark:bg-transparent dark:border-none max-w-7xl ">
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
Command Center | Coolify
|
||||
</x-slot>
|
||||
<h1>Command Center</h1>
|
||||
<div class="subtitle">Execute commands on your servers without leaving the browser.</div>
|
||||
@if ($servers->count() > 0)
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
Dashboard | Coolify
|
||||
</x-slot>
|
||||
@if (session('error'))
|
||||
<span x-data x-init="$wire.emit('error', '{{ session('error') }}')" />
|
||||
@endif
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
Notifications | Coolify
|
||||
</x-slot>
|
||||
<x-notification.navbar />
|
||||
<form wire:submit='submit' class="flex flex-col gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -7,7 +10,7 @@
|
||||
Save
|
||||
</x-forms.button>
|
||||
@if ($team->discord_enabled)
|
||||
<x-forms.button class="dark:text-white normal-case btn btn-xs no-animation btn-primary"
|
||||
<x-forms.button class="normal-case dark:text-white btn btn-xs no-animation btn-primary"
|
||||
wire:click="sendTestNotification">
|
||||
Send Test Notifications
|
||||
</x-forms.button>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
Notifications | Coolify
|
||||
</x-slot>
|
||||
<x-notification.navbar />
|
||||
<form wire:submit='submit' class="flex flex-col gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
Notifications | Coolify
|
||||
</x-slot>
|
||||
<x-notification.navbar />
|
||||
<form wire:submit='submit' class="flex flex-col gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
Profile | Coolify
|
||||
</x-slot>
|
||||
<h1>Profile</h1>
|
||||
<div class="subtitle ">Your user profile settings.</div>
|
||||
<form wire:submit='submit' class="flex flex-col">
|
||||
@@ -11,7 +14,7 @@
|
||||
<x-forms.input id="email" label="Email" readonly />
|
||||
</div>
|
||||
</form>
|
||||
<form wire:submit='resetPassword' class="flex flex-col max-w-xl pt-4">
|
||||
<form wire:submit='resetPassword' class="flex flex-col pt-4">
|
||||
<div class="flex items-center gap-2 pb-2">
|
||||
<h2>Change Password</h2>
|
||||
<x-forms.button type="submit" label="Save">Save</x-forms.button>
|
||||
@@ -91,7 +94,7 @@
|
||||
@else
|
||||
<form action="/user/two-factor-authentication" method="POST">
|
||||
@csrf
|
||||
<x-forms.button type="submit">Configure 2FA</x-forms.button>
|
||||
<x-forms.button type="submit">Configure</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($application, 'name')->limit(10) }} > Configuration | Coolify
|
||||
</x-slot>
|
||||
<h1>Configuration</h1>
|
||||
<livewire:project.shared.configuration-checker :resource="$application" />
|
||||
<livewire:project.application.heading :application="$application" />
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($application, 'name')->limit(10) }} > Deployments | Coolify
|
||||
</x-slot>
|
||||
<h1>Deployments</h1>
|
||||
<livewire:project.shared.configuration-checker :resource="$application" />
|
||||
<livewire:project.application.heading :application="$application" />
|
||||
@@ -93,10 +96,11 @@
|
||||
<div>
|
||||
@if ($deployment->status !== 'in_progress')
|
||||
Finished <span x-text="measure_since_started()">0s</span> in
|
||||
<span class="font-bold" x-text="measure_finished_time()">0s</span>
|
||||
@else
|
||||
Running for
|
||||
Running for <span class="font-bold" x-text="measure_since_started()">0s</span>
|
||||
@endif
|
||||
<span class="font-bold" x-text="measure_finished_time()">0s</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -135,11 +139,15 @@
|
||||
}
|
||||
},
|
||||
measure_finished_time() {
|
||||
return this.finished_time;
|
||||
if (this.finished_time > 2000) {
|
||||
return 0;
|
||||
} else {
|
||||
return this.finished_time;
|
||||
}
|
||||
},
|
||||
measure_since_started() {
|
||||
return dayjs.utc(created_at).fromNow();
|
||||
}
|
||||
},
|
||||
}))
|
||||
</script>
|
||||
@endif
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($application, 'name')->limit(10) }} > Deployment | Coolify
|
||||
</x-slot>
|
||||
<h1 class="py-0">Deployment</h1>
|
||||
<livewire:project.shared.configuration-checker :resource="$application" />
|
||||
<livewire:project.application.heading :application="$application" />
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
</div>
|
||||
@endif
|
||||
@if ($application->build_pack === 'dockercompose')
|
||||
|
||||
@if (
|
||||
!is_null($parsedServices) &&
|
||||
count($parsedServices) > 0 &&
|
||||
@@ -266,20 +265,24 @@
|
||||
|
||||
<h3 class="pt-8">Pre/Post Deployment Commands</h3>
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
<x-forms.input x-bind:disabled="initLoadingCompose" id="application.pre_deployment_command"
|
||||
label="Pre-deployment Command"
|
||||
helper="An optional script or command to execute in the existing container before the deployment begins." />
|
||||
<x-forms.input x-bind:disabled="initLoadingCompose" id="application.pre_deployment_command_container"
|
||||
label="Container Name"
|
||||
helper="The name of the container to execute within. You can leave it blank if your application only has one container." />
|
||||
<x-forms.input x-bind:disabled="initLoadingCompose" placeholder="php artisan migrate"
|
||||
id="application.pre_deployment_command" label="Pre-deployment "
|
||||
helper="An optional script or command to execute in the existing container before the deployment begins.<br>It is always executed with 'sh -c', so you do not need add it manually." />
|
||||
@if ($application->build_pack === 'dockercompose')
|
||||
<x-forms.input x-bind:disabled="initLoadingCompose"
|
||||
id="application.pre_deployment_command_container" label="Container Name"
|
||||
helper="The name of the container to execute within. You can leave it blank if your application only has one container." />
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
<x-forms.input x-bind:disabled="initLoadingCompose" placeholder="php artisan migrate"
|
||||
id="application.post_deployment_command" label="Post-deployment Command"
|
||||
helper="An optional script or command to execute in the newly built container after the deployment completes." />
|
||||
<x-forms.input x-bind:disabled="initLoadingCompose" id="application.post_deployment_command_container"
|
||||
label="Container Name"
|
||||
helper="The name of the container to execute within. You can leave it blank if your application only has one container." />
|
||||
id="application.post_deployment_command" label="Post-deployment "
|
||||
helper="An optional script or command to execute in the newly built container after the deployment completes.<br>It is always executed with 'sh -c', so you do not need add it manually." />
|
||||
@if ($application->build_pack === 'dockercompose')
|
||||
<x-forms.input x-bind:disabled="initLoadingCompose"
|
||||
id="application.post_deployment_command_container" label="Container Name"
|
||||
helper="The name of the container to execute within. You can leave it blank if your application only has one container." />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<form wire:submit="save" class="flex items-end gap-2">
|
||||
<x-forms.input helper="One domain per preview." label="Domains for {{ str($serviceName)->headline() }}"
|
||||
id="service.domain"></x-forms.input>
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
<x-forms.button wire:click="generate">Generate
|
||||
Domain</x-forms.button>
|
||||
</form>
|
||||
@@ -42,11 +42,16 @@
|
||||
<td class="flex flex-col gap-1 md:flex-row">
|
||||
<x-forms.button
|
||||
wire:click="add('{{ data_get($pull_request, 'number') }}', '{{ data_get($pull_request, 'html_url') }}')">
|
||||
Add
|
||||
Configure
|
||||
</x-forms.button>
|
||||
<x-forms.button
|
||||
wire:click="deploy('{{ data_get($pull_request, 'number') }}', '{{ data_get($pull_request, 'html_url') }}')">
|
||||
Deploy
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 dark:text-warning"
|
||||
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" />
|
||||
<path d="M7 4v16l13 -8z" />
|
||||
</svg>Deploy
|
||||
</x-forms.button>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -58,7 +63,7 @@
|
||||
</div>
|
||||
</div>
|
||||
@if ($application->previews->count() > 0)
|
||||
<div class="pb-4">Previews</div>
|
||||
<h3 class="py-4">Deployments</h3>
|
||||
<div class="flex flex-wrap w-full gap-4">
|
||||
@foreach (data_get($application, 'previews') as $previewName => $preview)
|
||||
<div class="flex flex-col w-full p-4 border dark:border-coolgray-200">
|
||||
@@ -81,21 +86,35 @@
|
||||
<x-external-link />
|
||||
</a>
|
||||
</div>
|
||||
<form wire:submit="save_preview('{{ $preview->id }}')" class="flex items-end gap-2 pt-4">
|
||||
<x-forms.input label="Domain" helper="One domain per preview."
|
||||
id="application.previews.{{ $previewName }}.fqdn"></x-forms.input>
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
<x-forms.button wire:click="generate_preview('{{ $preview->id }}')">Generate
|
||||
Domain</x-forms.button>
|
||||
</form>
|
||||
<div class="flex items-center gap-2 pt-6">
|
||||
<x-forms.button wire:click="deploy({{ data_get($preview, 'pull_request_id') }})">
|
||||
@if (data_get($preview, 'status') === 'exited')
|
||||
Deploy
|
||||
|
||||
@if ($application->build_pack === 'dockercompose')
|
||||
<div class="flex flex-col gap-4 pt-4">
|
||||
@if (collect(json_decode($preview->docker_compose_domains))->count() === 0)
|
||||
<form wire:submit="save_preview('{{ $preview->id }}')"
|
||||
class="flex items-end gap-2 pt-4">
|
||||
<x-forms.input label="Domain" helper="One domain per preview."
|
||||
id="application.previews.{{ $previewName }}.fqdn"></x-forms.input>
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
<x-forms.button wire:click="generate_preview('{{ $preview->id }}')">Generate
|
||||
Domain</x-forms.button>
|
||||
</form>
|
||||
@else
|
||||
Redeploy
|
||||
@foreach (collect(json_decode($preview->docker_compose_domains)) as $serviceName => $service)
|
||||
<livewire:project.application.previews-compose wire:key="{{ $preview->id }}"
|
||||
:service="$service" :serviceName="$serviceName" :preview="$preview" />
|
||||
@endforeach
|
||||
@endif
|
||||
</x-forms.button>
|
||||
</div>
|
||||
@else
|
||||
<form wire:submit="save_preview('{{ $preview->id }}')" class="flex items-end gap-2 pt-4">
|
||||
<x-forms.input label="Domain" helper="One domain per preview."
|
||||
id="application.previews.{{ $previewName }}.fqdn"></x-forms.input>
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
<x-forms.button wire:click="generate_preview('{{ $preview->id }}')">Generate
|
||||
Domain</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
<div class="flex items-center gap-2 pt-6">
|
||||
@if (count($parameters) > 0)
|
||||
<a
|
||||
href="{{ route('project.application.deployment.index', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}">
|
||||
@@ -111,6 +130,27 @@
|
||||
</a>
|
||||
@endif
|
||||
<div class="flex-1"></div>
|
||||
<x-forms.button wire:click="deploy({{ data_get($preview, 'pull_request_id') }})">
|
||||
@if (data_get($preview, 'status') === 'exited')
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 dark:text-warning"
|
||||
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" />
|
||||
<path d="M7 4v16l13 -8z" />
|
||||
</svg>
|
||||
Deploy
|
||||
@else
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 dark:text-orange-400"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path
|
||||
d="M10.09 4.01l.496 -.495a2 2 0 0 1 2.828 0l7.071 7.07a2 2 0 0 1 0 2.83l-7.07 7.07a2 2 0 0 1 -2.83 0l-7.07 -7.07a2 2 0 0 1 0 -2.83l3.535 -3.535h-3.988">
|
||||
</path>
|
||||
<path d="M7.05 11.038v-3.988"></path>
|
||||
</svg> Redeploy
|
||||
@endif
|
||||
</x-forms.button>
|
||||
@if (data_get($preview, 'status') !== 'exited')
|
||||
<x-modal-confirmation isErrorButton
|
||||
action="stop({{ data_get($preview, 'pull_request_id') }})">
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<form>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($project, 'name')->limit(10) }} > Clone | Coolify
|
||||
</x-slot>
|
||||
<div class="flex flex-col">
|
||||
<h1>Clone</h1>
|
||||
<div class="subtitle ">Quickly clone all resources to a new project or environment.</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div>
|
||||
<div wire:init='refreshBackupExecutions'>
|
||||
@isset($backup)
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="py-4">Executions</h3>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($database, 'name')->limit(10) }} > Backup | Coolify
|
||||
</x-slot>
|
||||
<h1>Backups</h1>
|
||||
<livewire:project.shared.configuration-checker :resource="$database" />
|
||||
<livewire:project.database.heading :database="$database" />
|
||||
<div class="pt-6">
|
||||
<livewire:project.database.backup-edit :backup="$backup" :s3s="$s3s" :status="data_get($database, 'status')" />
|
||||
<livewire:project.database.backup-executions :backup="$backup" :executions="$executions" />
|
||||
<livewire:project.database.backup-executions :backup="$backup" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($database, 'name')->limit(10) }} > Backups | Coolify
|
||||
</x-slot>
|
||||
<h1>Backups</h1>
|
||||
<livewire:project.shared.configuration-checker :resource="$database" />
|
||||
<livewire:project.database.heading :database="$database" />
|
||||
<div class="pt-6">
|
||||
<div class="flex gap-2 ">
|
||||
<div class="flex gap-2">
|
||||
<h2 class="pb-4">Scheduled Backups</h2>
|
||||
<x-modal-input buttonTitle="+ Add" title="New Scheduled Backup">
|
||||
<livewire:project.database.create-scheduled-backup :database="$database" :s3s="$s3s" />
|
||||
<livewire:project.database.create-scheduled-backup :database="$database" />
|
||||
</x-modal-input>
|
||||
</div>
|
||||
<livewire:project.database.scheduled-backups :database="$database" />
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
@if ($database->started_at)
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input label="Initial Username" id="database.clickhouse_admin_user" placeholder="If empty: clickhouse"
|
||||
readonly helper="You can only change this in the database." />
|
||||
<x-forms.input label="Initial Username" id="database.clickhouse_admin_user"
|
||||
placeholder="If empty: clickhouse" readonly helper="You can only change this in the database." />
|
||||
<x-forms.input label="Initial Password" id="database.clickhouse_admin_password" type="password" required
|
||||
readonly helper="You can only change this in the database." />
|
||||
</div>
|
||||
@@ -34,9 +34,6 @@
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="3000:5432" id="database.ports_mappings" label="Ports Mappings"
|
||||
helper="A comma separated list of ports you would like to map to the host system.<br><span class='inline-block font-bold dark:text-warning'>Example</span>3000:5432,3002:5433" />
|
||||
<x-forms.input placeholder="5432" disabled="{{ $database->is_public }}" id="database.public_port"
|
||||
label="Public Port" />
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
<x-forms.input label="Clickhouse URL (internal)"
|
||||
helper="If you change the user/password/port, this could be different. This is with the default values."
|
||||
@@ -47,6 +44,23 @@
|
||||
type="password" readonly wire:model="db_url_public" />
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="py-2">Proxy</h3>
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="5432" disabled="{{ data_get($database, 'is_public') }}"
|
||||
id="database.public_port" label="Public Port" />
|
||||
<x-slide-over fullScreen>
|
||||
<x-slot:title>Proxy Logs</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:project.shared.get-logs :server="$server" :resource="$database"
|
||||
container="{{ data_get($database, 'uuid') }}-proxy" lazy />
|
||||
</x-slot:content>
|
||||
<x-forms.button disabled="{{ !data_get($database, 'is_public') }}" @click="slideOverOpen=true"
|
||||
class="w-28">Proxy Logs</x-forms.button>
|
||||
</x-slide-over>
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<h3 class="pt-4">Advanced</h3>
|
||||
<div class="flex flex-col">
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($database, 'name')->limit(10) }} > Configuration | Coolify
|
||||
</x-slot>
|
||||
<h1>Configuration</h1>
|
||||
<livewire:project.shared.configuration-checker :resource="$database" />
|
||||
<livewire:project.database.heading :database="$database" />
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="3000:5432" id="database.ports_mappings" label="Ports Mappings"
|
||||
helper="A comma separated list of ports you would like to map to the host system.<br><span class='inline-block font-bold dark:text-warning'>Example</span>3000:5432,3002:5433" />
|
||||
<x-forms.input placeholder="5432" disabled="{{ $database->is_public }}" id="database.public_port"
|
||||
label="Public Port" />
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
<x-forms.input label="Dragonfly URL (internal)"
|
||||
helper="If you change the user/password/port, this could be different. This is with the default values."
|
||||
@@ -29,6 +26,23 @@
|
||||
type="password" readonly wire:model="db_url_public" />
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="py-2">Proxy</h3>
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="5432" disabled="{{ data_get($database, 'is_public') }}"
|
||||
id="database.public_port" label="Public Port" />
|
||||
<x-slide-over fullScreen>
|
||||
<x-slot:title>Proxy Logs</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:project.shared.get-logs :server="$server" :resource="$database"
|
||||
container="{{ data_get($database, 'uuid') }}-proxy" lazy />
|
||||
</x-slot:content>
|
||||
<x-forms.button disabled="{{ !data_get($database, 'is_public') }}" @click="slideOverOpen=true"
|
||||
class="w-28">Proxy Logs</x-forms.button>
|
||||
</x-slide-over>
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
</div>
|
||||
{{-- <x-forms.textarea
|
||||
helper="<a target='_blank' class='underline dark:text-white' href='https://raw.githubusercontent.com/Snapchat/KeyDB/unstable/keydb.conf'>KeyDB Default Configuration</a>"
|
||||
label="Custom Dragonfly Configuration" rows="10" id="database.keydb_conf" /> --}}
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="3000:5432" id="database.ports_mappings" label="Ports Mappings"
|
||||
helper="A comma separated list of ports you would like to map to the host system.<br><span class='inline-block font-bold dark:text-warning'>Example</span>3000:5432,3002:5433" />
|
||||
<x-forms.input placeholder="5432" disabled="{{ $database->is_public }}" id="database.public_port"
|
||||
label="Public Port" />
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
<x-forms.input label="KeyDB URL (internal)"
|
||||
helper="If you change the user/password/port, this could be different. This is with the default values."
|
||||
@@ -30,6 +27,23 @@
|
||||
type="password" readonly wire:model="db_url_public" />
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="py-2">Proxy</h3>
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="5432" disabled="{{ data_get($database, 'is_public') }}"
|
||||
id="database.public_port" label="Public Port" />
|
||||
<x-slide-over fullScreen>
|
||||
<x-slot:title>Proxy Logs</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:project.shared.get-logs :server="$server" :resource="$database"
|
||||
container="{{ data_get($database, 'uuid') }}-proxy" lazy />
|
||||
</x-slot:content>
|
||||
<x-forms.button disabled="{{ !data_get($database, 'is_public') }}" @click="slideOverOpen=true"
|
||||
class="w-28">Proxy Logs</x-forms.button>
|
||||
</x-slide-over>
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
</div>
|
||||
<x-forms.textarea
|
||||
helper="<a target='_blank' class='underline dark:text-white' href='https://raw.githubusercontent.com/Snapchat/KeyDB/unstable/keydb.conf'>KeyDB Default Configuration</a>"
|
||||
label="Custom KeyDB Configuration" rows="10" id="database.keydb_conf" />
|
||||
|
||||
@@ -12,23 +12,23 @@
|
||||
<x-forms.input label="Image" id="database.image" required
|
||||
helper="For all available images, check here:<br><br><a target='_blank' href='https://hub.docker.com/_/mariadb'>https://hub.docker.com/_/mariadb</a>" />
|
||||
</div>
|
||||
<div class="pt-2 dark:text-warning">If you change the values in the database, please sync it here, otherwise
|
||||
automations (like backups) won't work.
|
||||
</div>
|
||||
@if ($database->started_at)
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input label="Root Password" id="database.mariadb_root_password" type="password" readonly
|
||||
helper="You can only change this in the database." />
|
||||
<x-forms.input label="Normal User" id="database.mariadb_user" required readonly
|
||||
helper="You can only change this in the database." />
|
||||
<div class="flex flex-col gap-2">
|
||||
<x-forms.input label="Root Password" id="database.mariadb_root_password" type="password" required
|
||||
helper="If you change this in the database, please sync it here, otherwise automations (like backups) won't work." />
|
||||
<x-forms.input label="Normal User" id="database.mariadb_user" required
|
||||
helper="If you change this in the database, please sync it here, otherwise automations (like backups) won't work." />
|
||||
<x-forms.input label="Normal User Password" id="database.mariadb_password" type="password" required
|
||||
readonly helper="You can only change this in the database." />
|
||||
helper="If you change this in the database, please sync it here, otherwise automations (like backups) won't work." />
|
||||
<x-forms.input label="Initial Database" id="database.mariadb_database"
|
||||
placeholder="If empty, it will be the same as Username." readonly
|
||||
helper="You can only change this in the database." />
|
||||
</div>
|
||||
@else
|
||||
<div class="pt-8 dark:text-warning">Please verify these values. You can only modify them before the initial
|
||||
start. After that, you need to modify it in the database.
|
||||
</div>
|
||||
<div class="flex gap-2 pb-8">
|
||||
<div class="flex flex-col gap-2 pb-2">
|
||||
<x-forms.input label="Root Password" id="database.mariadb_root_password" type="password"
|
||||
helper="You can only change this in the database." />
|
||||
<x-forms.input label="Normal User" id="database.mariadb_user" required
|
||||
@@ -45,9 +45,6 @@
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="3000:5432" id="database.ports_mappings" label="Ports Mappings"
|
||||
helper="A comma separated list of ports you would like to map to the host system.<br><span class='inline-block font-bold dark:text-warning'>Example</span>3000:5432,3002:5433" />
|
||||
<x-forms.input placeholder="5432" disabled="{{ $database->is_public }}" id="database.public_port"
|
||||
label="Public Port" />
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
<x-forms.input label="MariaDB URL (internal)"
|
||||
helper="If you change the user/password/port, this could be different. This is with the default values."
|
||||
@@ -58,6 +55,23 @@
|
||||
type="password" readonly wire:model="db_url_public" />
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="py-2">Proxy</h3>
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="5432" disabled="{{ data_get($database, 'is_public') }}"
|
||||
id="database.public_port" label="Public Port" />
|
||||
<x-slide-over fullScreen>
|
||||
<x-slot:title>Proxy Logs</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:project.shared.get-logs :server="$server" :resource="$database"
|
||||
container="{{ data_get($database, 'uuid') }}-proxy" lazy />
|
||||
</x-slot:content>
|
||||
<x-forms.button disabled="{{ !data_get($database, 'is_public') }}" @click="slideOverOpen=true"
|
||||
class="w-28">Proxy Logs</x-forms.button>
|
||||
</x-slide-over>
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
</div>
|
||||
<x-forms.textarea label="Custom MariaDB Configuration" rows="10" id="database.mariadb_conf" />
|
||||
<h3 class="pt-4">Advanced</h3>
|
||||
<div class="flex flex-col">
|
||||
|
||||
@@ -12,21 +12,23 @@
|
||||
<x-forms.input label="Image" id="database.image" required
|
||||
helper="For all available images, check here:<br><br><a target='_blank' href='https://hub.docker.com/_/mongo'>https://hub.docker.com/_/mongo</a>" />
|
||||
</div>
|
||||
<div class="pt-2 dark:text-warning">If you change the values in the database, please sync it here, otherwise
|
||||
automations (like backups) won't work.
|
||||
</div>
|
||||
@if ($database->started_at)
|
||||
<div class="flex gap-2">
|
||||
<div class="flex flex-col gap-2">
|
||||
<x-forms.input label="Initial Username" id="database.mongo_initdb_root_username"
|
||||
placeholder="If empty: postgres" readonly helper="You can only change this in the database." />
|
||||
placeholder="If empty: postgres"
|
||||
helper="If you change this in the database, please sync it here, otherwise automations (like backups) won't work." />
|
||||
<x-forms.input label="Initial Password" id="database.mongo_initdb_root_password" type="password"
|
||||
required readonly helper="You can only change this in the database." />
|
||||
required
|
||||
helper="If you change this in the database, please sync it here, otherwise automations (like backups) won't work." />
|
||||
<x-forms.input label="Initial Database" id="database.mongo_initdb_database"
|
||||
placeholder="If empty, it will be the same as Username." readonly
|
||||
helper="You can only change this in the database." />
|
||||
</div>
|
||||
@else
|
||||
<div class="pt-8 dark:text-warning">Please verify these values. You can only modify them before the initial
|
||||
start. After that, you need to modify it in the database.
|
||||
</div>
|
||||
<div class="flex gap-2 pb-8">
|
||||
<div class="flex flex-col gap-2 pb-2">
|
||||
<x-forms.input required label="Username" id="database.mongo_initdb_root_username"
|
||||
placeholder="If empty: postgres" />
|
||||
<x-forms.input label="Password" id="database.mongo_initdb_root_password" type="password" required />
|
||||
@@ -39,9 +41,6 @@
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="3000:5432" id="database.ports_mappings" label="Ports Mappings"
|
||||
helper="A comma separated list of ports you would like to map to the host system.<br><span class='inline-block font-bold dark:text-warning'>Example</span>3000:5432,3002:5433" />
|
||||
<x-forms.input placeholder="5432" disabled="{{ $database->is_public }}" id="database.public_port"
|
||||
label="Public Port" />
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
<x-forms.input label="Mongo URL (internal)"
|
||||
helper="If you change the user/password/port, this could be different. This is with the default values."
|
||||
@@ -52,6 +51,23 @@
|
||||
type="password" readonly wire:model="db_url_public" />
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="py-2">Proxy</h3>
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="5432" disabled="{{ data_get($database, 'is_public') }}"
|
||||
id="database.public_port" label="Public Port" />
|
||||
<x-slide-over fullScreen>
|
||||
<x-slot:title>Proxy Logs</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:project.shared.get-logs :server="$server" :resource="$database"
|
||||
container="{{ data_get($database, 'uuid') }}-proxy" lazy />
|
||||
</x-slot:content>
|
||||
<x-forms.button disabled="{{ !data_get($database, 'is_public') }}" @click="slideOverOpen=true"
|
||||
class="w-28">Proxy Logs</x-forms.button>
|
||||
</x-slide-over>
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
</div>
|
||||
<x-forms.textarea label="Custom MongoDB Configuration" rows="10" id="database.mongo_conf" />
|
||||
<h3 class="pt-4">Advanced</h3>
|
||||
<div class="flex flex-col">
|
||||
|
||||
@@ -12,23 +12,23 @@
|
||||
<x-forms.input label="Image" id="database.image" required
|
||||
helper="For all available images, check here:<br><br><a target='_blank' href='https://hub.docker.com/_/mysql'>https://hub.docker.com/_/mysql</a>" />
|
||||
</div>
|
||||
<div class="pt-2 dark:text-warning">If you change the values in the database, please sync it here, otherwise
|
||||
automations (like backups) won't work.
|
||||
</div>
|
||||
@if ($database->started_at)
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input label="Root Password" id="database.mysql_root_password" type="password" readonly
|
||||
helper="You can only change this in the database." />
|
||||
<x-forms.input label="Normal User" id="database.mysql_user" required readonly
|
||||
helper="You can only change this in the database." />
|
||||
<div class="flex flex-col gap-2">
|
||||
<x-forms.input label="Root Password" id="database.mysql_root_password" type="password" required
|
||||
helper="If you change this in the database, please sync it here, otherwise automations (like backups) won't work." />
|
||||
<x-forms.input label="Normal User" id="database.mysql_user" required
|
||||
helper="If you change this in the database, please sync it here, otherwise automations (like backups) won't work." />
|
||||
<x-forms.input label="Normal User Password" id="database.mysql_password" type="password" required
|
||||
readonly helper="You can only change this in the database." />
|
||||
helper="If you change this in the database, please sync it here, otherwise automations (like backups) won't work." />
|
||||
<x-forms.input label="Initial Database" id="database.mysql_database"
|
||||
placeholder="If empty, it will be the same as Username." readonly
|
||||
helper="You can only change this in the database." />
|
||||
</div>
|
||||
@else
|
||||
<div class="pt-8 dark:text-warning">Please verify these values. You can only modify them before the initial
|
||||
start. After that, you need to modify it in the database.
|
||||
</div>
|
||||
<div class="flex gap-2 pb-8">
|
||||
<div class="flex flex-col gap-4 pb-2">
|
||||
<x-forms.input label="Root Password" id="database.mysql_root_password" type="password"
|
||||
helper="You can only change this in the database." />
|
||||
<x-forms.input label="Normal User" id="database.mysql_user" required
|
||||
@@ -45,9 +45,6 @@
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="3000:5432" id="database.ports_mappings" label="Ports Mappings"
|
||||
helper="A comma separated list of ports you would like to map to the host system.<br><span class='inline-block font-bold dark:text-warning'>Example</span>3000:5432,3002:5433" />
|
||||
<x-forms.input placeholder="5432" disabled="{{ $database->is_public }}" id="database.public_port"
|
||||
label="Public Port" />
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
<x-forms.input label="MySQL URL (internal)"
|
||||
helper="If you change the user/password/port, this could be different. This is with the default values."
|
||||
@@ -58,6 +55,23 @@
|
||||
type="password" readonly wire:model="db_url_public" />
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="py-2">Proxy</h3>
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="5432" disabled="{{ data_get($database, 'is_public') }}"
|
||||
id="database.public_port" label="Public Port" />
|
||||
<x-slide-over fullScreen>
|
||||
<x-slot:title>Proxy Logs</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:project.shared.get-logs :server="$server" :resource="$database"
|
||||
container="{{ data_get($database, 'uuid') }}-proxy" lazy />
|
||||
</x-slot:content>
|
||||
<x-forms.button disabled="{{ !data_get($database, 'is_public') }}" @click="slideOverOpen=true"
|
||||
class="w-28">Proxy Logs</x-forms.button>
|
||||
</x-slide-over>
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
</div>
|
||||
<x-forms.textarea label="Custom Mysql Configuration" rows="10" id="database.mysql_conf" />
|
||||
<h3 class="pt-4">Advanced</h3>
|
||||
<div class="flex flex-col">
|
||||
|
||||
@@ -20,31 +20,30 @@
|
||||
Save
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div class="flex gap-2 flex-wrap sm:flex-nowrap">
|
||||
<div class="flex flex-wrap gap-2 sm:flex-nowrap">
|
||||
<x-forms.input label="Name" id="database.name" />
|
||||
<x-forms.input label="Description" id="database.description" />
|
||||
<x-forms.input label="Image" id="database.image" required
|
||||
helper="For all available images, check here:<br><br><a target='_blank' href='https://hub.docker.com/_/postgres'>https://hub.docker.com/_/postgres</a>" />
|
||||
</div>
|
||||
|
||||
<div class="pt-2 dark:text-warning">If you change the values in the database, please sync it here, otherwise
|
||||
automations (like backups) won't work.
|
||||
</div>
|
||||
@if ($database->started_at)
|
||||
<div class="flex gap-2 flex-wrap sm:flex-nowrap">
|
||||
<x-forms.input label="Initial Username" id="database.postgres_user" placeholder="If empty: postgres"
|
||||
readonly helper="You can only change this in the database." />
|
||||
<x-forms.input label="Initial Password" id="database.postgres_password" type="password" required
|
||||
readonly helper="You can only change this in the database." />
|
||||
<div class="flex flex-col gap-2">
|
||||
<x-forms.input label="Username" id="database.postgres_user" placeholder="If empty: postgres"
|
||||
helper="If you change this in the database, please sync it here, otherwise automations (like backups) won't work." />
|
||||
<x-forms.input label="Password" id="database.postgres_password" type="password" required
|
||||
helper="If you change this in the database, please sync it here, otherwise automations (like backups) won't work." />
|
||||
<x-forms.input label="Initial Database" id="database.postgres_db"
|
||||
placeholder="If empty, it will be the same as Username." readonly
|
||||
helper="You can only change this in the database." />
|
||||
</div>
|
||||
@else
|
||||
<div class="pt-8 dark:text-warning">Please verify these values. You can only modify them before the initial
|
||||
start. After that, you need to modify it in the database.
|
||||
</div>
|
||||
<div class="flex gap-2 pb-8">
|
||||
<div class="flex flex-col gap-2 pb-2">
|
||||
<x-forms.input label="Username" id="database.postgres_user" placeholder="If empty: postgres" />
|
||||
<x-forms.input label="Password" id="database.postgres_password" type="password" required />
|
||||
<x-forms.input label="Database" id="database.postgres_db"
|
||||
<x-forms.input label="Initial Database" id="database.postgres_db"
|
||||
placeholder="If empty, it will be the same as Username." />
|
||||
</div>
|
||||
@endif
|
||||
@@ -59,10 +58,8 @@
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="3000:5432" id="database.ports_mappings" label="Ports Mappings"
|
||||
helper="A comma separated list of ports you would like to map to the host system.<br><span class='inline-block font-bold dark:text-warning'>Example</span>3000:5432,3002:5433" />
|
||||
<x-forms.input placeholder="5432" disabled="{{ $database->is_public }}" id="database.public_port"
|
||||
label="Public Port" />
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
|
||||
<x-forms.input label="Postgres URL (internal)"
|
||||
helper="If you change the user/password/port, this could be different. This is with the default values."
|
||||
type="password" readonly wire:model="db_url" />
|
||||
@@ -72,6 +69,23 @@
|
||||
type="password" readonly wire:model="db_url_public" />
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="py-2">Proxy</h3>
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="5432" disabled="{{ data_get($database, 'is_public') }}"
|
||||
id="database.public_port" label="Public Port" />
|
||||
<x-slide-over fullScreen>
|
||||
<x-slot:title>Proxy Logs</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:project.shared.get-logs :server="$server" :resource="$database"
|
||||
container="{{ data_get($database, 'uuid') }}-proxy" lazy />
|
||||
</x-slot:content>
|
||||
<x-forms.button disabled="{{ !data_get($database, 'is_public') }}" @click="slideOverOpen=true"
|
||||
class="w-28">Proxy Logs</x-forms.button>
|
||||
</x-slide-over>
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
</div>
|
||||
<x-forms.textarea label="Custom PostgreSQL Configuration" rows="10" id="database.postgres_conf" />
|
||||
</form>
|
||||
<h3 class="pt-4">Advanced</h3>
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="3000:5432" id="database.ports_mappings" label="Ports Mappings"
|
||||
helper="A comma separated list of ports you would like to map to the host system.<br><span class='inline-block font-bold dark:text-warning'>Example</span>3000:5432,3002:5433" />
|
||||
<x-forms.input placeholder="5432" disabled="{{ $database->is_public }}" id="database.public_port"
|
||||
label="Public Port" />
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
<x-forms.input label="Redis URL (internal)"
|
||||
helper="If you change the user/password/port, this could be different. This is with the default values."
|
||||
@@ -30,8 +27,25 @@
|
||||
type="password" readonly wire:model="db_url_public" />
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="py-2">Proxy</h3>
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="5432" disabled="{{ data_get($database, 'is_public') }}"
|
||||
id="database.public_port" label="Public Port" />
|
||||
<x-slide-over fullScreen>
|
||||
<x-slot:title>Proxy Logs</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:project.shared.get-logs :server="$server" :resource="$database"
|
||||
container="{{ data_get($database, 'uuid') }}-proxy" lazy />
|
||||
</x-slot:content>
|
||||
<x-forms.button disabled="{{ !data_get($database, 'is_public') }}" @click="slideOverOpen=true"
|
||||
class="w-28">Proxy Logs</x-forms.button>
|
||||
</x-slide-over>
|
||||
<x-forms.checkbox instantSave id="database.is_public" label="Make it publicly available" />
|
||||
</div>
|
||||
</div>
|
||||
<x-forms.textarea
|
||||
helper="<a target='_blank' class='dark:text-white underline' href='https://raw.githubusercontent.com/redis/redis/7.2/redis.conf'>Redis Default Configuration</a>"
|
||||
helper="<a target='_blank' class='underline dark:text-white' href='https://raw.githubusercontent.com/redis/redis/7.2/redis.conf'>Redis Default Configuration</a>"
|
||||
label="Custom Redis Configuration" rows="10" id="database.redis_conf" />
|
||||
<h3 class="pt-4">Advanced</h3>
|
||||
<div class="flex flex-col">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<div class="flex flex-col gap-2">
|
||||
@forelse($database->scheduledBackups as $backup)
|
||||
@if ($type == 'database')
|
||||
<a class="box"
|
||||
@@ -32,8 +32,7 @@
|
||||
<livewire:project.database.backup-edit wire:key="{{ $selectedBackup->id }}" :backup="$selectedBackup"
|
||||
:s3s="$s3s" :status="data_get($database, 'status')" />
|
||||
<h3 class="py-4">Executions</h3>
|
||||
<livewire:project.database.backup-executions wire:keykey="{{ $selectedBackup->id }}" :backup="$selectedBackup"
|
||||
:executions="$selectedBackup->executions" />
|
||||
<livewire:project.database.backup-executions wire:key="{{ $selectedBackup->id }}" :backup="$selectedBackup" />
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($project, 'name')->limit(10) }} > Edit | Coolify
|
||||
</x-slot>
|
||||
<form wire:submit='submit' class="flex flex-col pb-10">
|
||||
<div class="flex gap-2">
|
||||
<h1>Project: {{ data_get($project, 'name') }}</h1>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($project, 'name')->limit(10) }} > Edit | Coolify
|
||||
</x-slot>
|
||||
<form wire:submit='submit' class="flex flex-col">
|
||||
<div class="flex items-end gap-2">
|
||||
<h1>Environment: {{ data_get($environment, 'name') }}</h1>
|
||||
@@ -6,7 +9,7 @@
|
||||
<livewire:project.delete-environment :disabled="!$environment->isEmpty()" :environment_id="$environment->id" />
|
||||
</div>
|
||||
<nav class="flex pt-2 pb-10">
|
||||
<ol class="flex items-center flex-wrap gap-y-1">
|
||||
<ol class="flex flex-wrap items-center gap-y-1">
|
||||
<li class="inline-flex items-center">
|
||||
<div class="flex items-center">
|
||||
<a class="text-xs truncate lg:text-sm"
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
Projects | Coolify
|
||||
</x-slot>
|
||||
<div class="flex gap-2">
|
||||
<h1>Projects</h1>
|
||||
<x-modal-input buttonTitle="+ Add" title="New Project">
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input required id="repository_url" label="Repository URL (https://)" helper="{!! __('repository.url') !!}" />
|
||||
<x-forms.input required id="repository_url" label="Repository URL (https://)"
|
||||
helper="{!! __('repository.url') !!}" />
|
||||
<x-forms.button type="submit">
|
||||
Check repository
|
||||
</x-forms.button>
|
||||
@@ -58,6 +59,10 @@
|
||||
helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
|
||||
</div>
|
||||
@endif
|
||||
@if ($build_pack === 'dockercompose' && isDev())
|
||||
<div class="dark:text-warning">If you choose Docker Compose based deployments, you cannot change it afterwards.</div>
|
||||
<x-forms.checkbox instantSave label="New Compose Services (only in dev mode)" id="new_compose_services"></x-forms.checkbox>
|
||||
@endif
|
||||
</div>
|
||||
<x-forms.button wire:click.prevent='submit'>
|
||||
Continue
|
||||
|
||||
@@ -32,19 +32,20 @@
|
||||
You can deploy public & private repositories through your GitHub Apps.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<svg class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<g fill="currentColor">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M64 1.512c-23.493 0-42.545 19.047-42.545 42.545 0 18.797 12.19 34.745 29.095 40.37 2.126.394 2.907-.923 2.907-2.047 0-1.014-.04-4.366-.058-7.92-11.837 2.573-14.334-5.02-14.334-5.02-1.935-4.918-4.724-6.226-4.724-6.226-3.86-2.64.29-2.586.29-2.586 4.273.3 6.523 4.385 6.523 4.385 3.794 6.504 9.953 4.623 12.38 3.536.383-2.75 1.485-4.628 2.702-5.69-9.45-1.075-19.384-4.724-19.384-21.026 0-4.645 1.662-8.44 4.384-11.42-.442-1.072-1.898-5.4.412-11.26 0 0 3.572-1.142 11.7 4.363 3.395-.943 7.035-1.416 10.65-1.432 3.616.017 7.258.49 10.658 1.432 8.12-5.504 11.688-4.362 11.688-4.362 2.316 5.86.86 10.187.418 11.26 2.728 2.978 4.378 6.774 4.378 11.42 0 16.34-9.953 19.938-19.427 20.99 1.526 1.32 2.886 3.91 2.886 7.88 0 5.692-.048 10.273-.048 11.674 0 1.13.766 2.458 2.922 2.04 16.896-5.632 29.07-21.574 29.07-40.365C106.545 20.56 87.497 1.512 64 1.512z" />
|
||||
<div>
|
||||
<svg class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<g fill="currentColor">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M64 1.512c-23.493 0-42.545 19.047-42.545 42.545 0 18.797 12.19 34.745 29.095 40.37 2.126.394 2.907-.923 2.907-2.047 0-1.014-.04-4.366-.058-7.92-11.837 2.573-14.334-5.02-14.334-5.02-1.935-4.918-4.724-6.226-4.724-6.226-3.86-2.64.29-2.586.29-2.586 4.273.3 6.523 4.385 6.523 4.385 3.794 6.504 9.953 4.623 12.38 3.536.383-2.75 1.485-4.628 2.702-5.69-9.45-1.075-19.384-4.724-19.384-21.026 0-4.645 1.662-8.44 4.384-11.42-.442-1.072-1.898-5.4.412-11.26 0 0 3.572-1.142 11.7 4.363 3.395-.943 7.035-1.416 10.65-1.432 3.616.017 7.258.49 10.658 1.432 8.12-5.504 11.688-4.362 11.688-4.362 2.316 5.86.86 10.187.418 11.26 2.728 2.978 4.378 6.774 4.378 11.42 0 16.34-9.953 19.938-19.427 20.99 1.526 1.32 2.886 3.91 2.886 7.88 0 5.692-.048 10.273-.048 11.674 0 1.13.766 2.458 2.922 2.04 16.896-5.632 29.07-21.574 29.07-40.365C106.545 20.56 87.497 1.512 64 1.512z" />
|
||||
<path
|
||||
d="M37.57 62.596c-.095.212-.428.275-.73.13-.31-.14-.482-.427-.382-.64.09-.216.424-.277.733-.132.31.14.486.43.38.642zM39.293 64.52c-.203.187-.6.1-.87-.198-.278-.297-.33-.694-.124-.884.208-.188.593-.1.87.197.28.3.335.693.123.884zm1.677 2.448c-.26.182-.687.012-.95-.367-.262-.377-.262-.83.005-1.013.264-.182.684-.018.95.357.262.385.262.84-.005 1.024zm2.298 2.368c-.233.257-.73.188-1.093-.163-.372-.343-.475-.83-.242-1.087.237-.257.736-.185 1.102.163.37.342.482.83.233 1.086zm3.172 1.374c-.104.334-.582.485-1.064.344-.482-.146-.796-.536-.7-.872.1-.336.582-.493 1.067-.342.48.144.795.53.696.87zm3.48.255c.013.35-.396.642-.902.648-.508.012-.92-.272-.926-.618 0-.354.4-.642.908-.65.506-.01.92.272.92.62zm3.24-.551c.06.342-.29.694-.793.787-.494.092-.95-.12-1.014-.46-.06-.35.297-.7.79-.792.503-.088.953.118 1.017.466zm0 0" />
|
||||
</g>
|
||||
<path
|
||||
d="M37.57 62.596c-.095.212-.428.275-.73.13-.31-.14-.482-.427-.382-.64.09-.216.424-.277.733-.132.31.14.486.43.38.642zM39.293 64.52c-.203.187-.6.1-.87-.198-.278-.297-.33-.694-.124-.884.208-.188.593-.1.87.197.28.3.335.693.123.884zm1.677 2.448c-.26.182-.687.012-.95-.367-.262-.377-.262-.83.005-1.013.264-.182.684-.018.95.357.262.385.262.84-.005 1.024zm2.298 2.368c-.233.257-.73.188-1.093-.163-.372-.343-.475-.83-.242-1.087.237-.257.736-.185 1.102.163.37.342.482.83.233 1.086zm3.172 1.374c-.104.334-.582.485-1.064.344-.482-.146-.796-.536-.7-.872.1-.336.582-.493 1.067-.342.48.144.795.53.696.87zm3.48.255c.013.35-.396.642-.902.648-.508.012-.92-.272-.926-.618 0-.354.4-.642.908-.65.506-.01.92.272.92.62zm3.24-.551c.06.342-.29.694-.793.787-.494.092-.95-.12-1.014-.46-.06-.35.297-.7.79-.792.503-.088.953.118 1.017.466zm0 0" />
|
||||
</g>
|
||||
<path
|
||||
d="M24.855 108.302h-10.7a.5.5 0 00-.5.5v5.232a.5.5 0 00.5.5h4.173v6.5s-.937.32-3.53.32c-3.056 0-7.327-1.116-7.327-10.508 0-9.393 4.448-10.63 8.624-10.63 3.614 0 5.17.636 6.162.943.31.094.6-.216.6-.492l1.193-5.055a.468.468 0 00-.192-.39c-.403-.288-2.857-1.66-9.058-1.66-7.144 0-14.472 3.038-14.472 17.65 0 14.61 8.39 16.787 15.46 16.787 5.854 0 9.405-2.502 9.405-2.502.146-.08.162-.285.162-.38v-16.316a.5.5 0 00-.5-.5zM79.506 94.81H73.48a.5.5 0 00-.498.503l.002 11.644h-9.392V95.313a.5.5 0 00-.497-.503H57.07a.5.5 0 00-.498.503v31.53c0 .277.224.503.498.503h6.025a.5.5 0 00.497-.504v-13.486h9.392l-.016 13.486c0 .278.224.504.5.504h6.038a.5.5 0 00.497-.504v-31.53a.497.497 0 00-.497-.502zm-47.166.717c-2.144 0-3.884 1.753-3.884 3.923 0 2.167 1.74 3.925 3.884 3.925 2.146 0 3.885-1.758 3.885-3.925 0-2.17-1.74-3.923-3.885-3.923zm2.956 9.608H29.29c-.276 0-.522.284-.522.56v20.852c0 .613.382.795.876.795h5.41c.595 0 .74-.292.74-.805v-20.899a.5.5 0 00-.498-.502zm67.606.047h-5.98a.5.5 0 00-.496.504v15.46s-1.52 1.11-3.675 1.11-2.727-.977-2.727-3.088v-13.482a.5.5 0 00-.497-.504h-6.068a.502.502 0 00-.498.504v14.502c0 6.27 3.495 7.804 8.302 7.804 3.944 0 7.124-2.18 7.124-2.18s.15 1.15.22 1.285c.07.136.247.273.44.273l3.86-.017a.502.502 0 00.5-.504l-.003-21.166a.504.504 0 00-.5-.502zm16.342-.708c-3.396 0-5.706 1.515-5.706 1.515V95.312a.5.5 0 00-.497-.503H107a.5.5 0 00-.5.503v31.53a.5.5 0 00.5.503h4.192c.19 0 .332-.097.437-.268.103-.17.254-1.454.254-1.454s2.47 2.34 7.148 2.34c5.49 0 8.64-2.784 8.64-12.502s-5.03-10.988-8.428-10.988zm-2.36 17.764c-2.073-.063-3.48-1.004-3.48-1.004v-9.985s1.388-.85 3.09-1.004c2.153-.193 4.228.458 4.228 5.594 0 5.417-.935 6.486-3.837 6.398zm-63.689-.118c-.263 0-.937.107-1.63.107-2.22 0-2.973-1.032-2.973-2.368v-8.866h4.52a.5.5 0 00.5-.504v-4.856a.5.5 0 00-.5-.502h-4.52l-.007-5.97c0-.227-.116-.34-.378-.34h-6.16c-.238 0-.367.106-.367.335v6.17s-3.087.745-3.295.805a.5.5 0 00-.36.48v3.877a.5.5 0 00.497.503h3.158v9.328c0 6.93 4.86 7.61 8.14 7.61 1.497 0 3.29-.48 3.586-.59.18-.067.283-.252.283-.453l.004-4.265a.51.51 0 00-.5-.502z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
d="M24.855 108.302h-10.7a.5.5 0 00-.5.5v5.232a.5.5 0 00.5.5h4.173v6.5s-.937.32-3.53.32c-3.056 0-7.327-1.116-7.327-10.508 0-9.393 4.448-10.63 8.624-10.63 3.614 0 5.17.636 6.162.943.31.094.6-.216.6-.492l1.193-5.055a.468.468 0 00-.192-.39c-.403-.288-2.857-1.66-9.058-1.66-7.144 0-14.472 3.038-14.472 17.65 0 14.61 8.39 16.787 15.46 16.787 5.854 0 9.405-2.502 9.405-2.502.146-.08.162-.285.162-.38v-16.316a.5.5 0 00-.5-.5zM79.506 94.81H73.48a.5.5 0 00-.498.503l.002 11.644h-9.392V95.313a.5.5 0 00-.497-.503H57.07a.5.5 0 00-.498.503v31.53c0 .277.224.503.498.503h6.025a.5.5 0 00.497-.504v-13.486h9.392l-.016 13.486c0 .278.224.504.5.504h6.038a.5.5 0 00.497-.504v-31.53a.497.497 0 00-.497-.502zm-47.166.717c-2.144 0-3.884 1.753-3.884 3.923 0 2.167 1.74 3.925 3.884 3.925 2.146 0 3.885-1.758 3.885-3.925 0-2.17-1.74-3.923-3.885-3.923zm2.956 9.608H29.29c-.276 0-.522.284-.522.56v20.852c0 .613.382.795.876.795h5.41c.595 0 .74-.292.74-.805v-20.899a.5.5 0 00-.498-.502zm67.606.047h-5.98a.5.5 0 00-.496.504v15.46s-1.52 1.11-3.675 1.11-2.727-.977-2.727-3.088v-13.482a.5.5 0 00-.497-.504h-6.068a.502.502 0 00-.498.504v14.502c0 6.27 3.495 7.804 8.302 7.804 3.944 0 7.124-2.18 7.124-2.18s.15 1.15.22 1.285c.07.136.247.273.44.273l3.86-.017a.502.502 0 00.5-.504l-.003-21.166a.504.504 0 00-.5-.502zm16.342-.708c-3.396 0-5.706 1.515-5.706 1.515V95.312a.5.5 0 00-.497-.503H107a.5.5 0 00-.5.503v31.53a.5.5 0 00.5.503h4.192c.19 0 .332-.097.437-.268.103-.17.254-1.454.254-1.454s2.47 2.34 7.148 2.34c5.49 0 8.64-2.784 8.64-12.502s-5.03-10.988-8.428-10.988zm-2.36 17.764c-2.073-.063-3.48-1.004-3.48-1.004v-9.985s1.388-.85 3.09-1.004c2.153-.193 4.228.458 4.228 5.594 0 5.417-.935 6.486-3.837 6.398zm-63.689-.118c-.263 0-.937.107-1.63.107-2.22 0-2.973-1.032-2.973-2.368v-8.866h4.52a.5.5 0 00.5-.504v-4.856a.5.5 0 00-.5-.502h-4.52l-.007-5.97c0-.227-.116-.34-.378-.34h-6.16c-.238 0-.367.106-.367.335v6.17s-3.087.745-3.295.805a.5.5 0 00-.36.48v3.877a.5.5 0 00.497.503h3.158v9.328c0 6.93 4.86 7.61 8.14 7.61 1.497 0 3.29-.48 3.586-.59.18-.067.283-.252.283-.453l.004-4.265a.51.51 0 00-.5-.502z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
</div>
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('private-deploy-key')">
|
||||
@@ -67,42 +68,43 @@
|
||||
You can deploy a simple Dockerfile, without Git.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<svg class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="currentColor"
|
||||
d="M20 96.9v-8.1c0-1.1.7-1.9 1.8-1.9h.3c1.1 0 1.8.9 1.8 1.9v17c0 4.1-2 7.4-5.6 9.5-1.7 1-3.5 1.5-5.4 1.5h-.8c-4.1 0-7.4-2-9.5-5.6-1-1.7-1.5-3.5-1.5-5.4v-.8c0-4.1 2-7.4 5.6-9.5 1.7-1 3.5-1.5 5.4-1.5h.8c2.7.1 5.1 1.1 7.1 2.9zm-15.1 8.5c0 3 1.5 5.2 4.1 6.7 1.1.6 2.2.9 3.4.9 2.9 0 5.1-1.4 6.6-3.9.7-1.2 1-2.4 1-3.8 0-2.6-1.2-4.6-3.3-6.1-1.3-.9-2.7-1.4-4.2-1.4-3.2 0-5.5 1.6-6.9 4.5-.5 1-.7 2.1-.7 3.1zm32.2-11.3h.5c4.4 0 7.8 2.1 9.9 6 .9 1.5 1.3 3.2 1.3 5v.8c0 4.1-2 7.4-5.6 9.5-1.7 1-3.5 1.5-5.4 1.5H37c-4.1 0-7.4-2-9.5-5.6-1-1.7-1.5-3.5-1.5-5.4v-.8c0-4.1 2.1-7.4 5.6-9.5 1.7-1.1 3.6-1.5 5.5-1.5zm-7.2 11.3c0 2.9 1.4 5 3.9 6.5 1.2.7 2.4 1 3.8 1 2.9 0 5-1.5 6.5-3.9.7-1.2 1-2.4 1-3.8 0-2.7-1.3-4.8-3.5-6.3-1.2-.8-2.6-1.2-4-1.2-3.2 0-5.5 1.6-6.9 4.5-.6 1.1-.8 2.2-.8 3.2zm34.8-7.2c-.6-.3-1.7-.4-2.3-.4-3.2-.1-5.5 1.7-6.9 4.5-.5 1-.7 2-.7 3.1 0 3.3 1.7 5.6 4.6 7 1.1.5 2.4.6 3.6.6 1 0 2.5-.6 3.4-1.1l.2-.1h.8c.9.2 1.5.7 1.5 1.7v.4c0 2.3-4.3 2.9-5.9 3-5.7.4-10-2.7-11.6-8.2-.3-.9-.4-1.9-.4-2.9v-.8c0-4.1 2.1-7.4 5.6-9.5 1.7-1 3.5-1.5 5.4-1.5h.8c2 0 3.9.6 5.6 1.7l.1.1.1.1c.2.3.3.6.3 1v.4c0 1-.7 1.5-1.6 1.7H67c-.5 0-1.8-.6-2.3-.8zm12.4 2.6c1.5-1.5 3-3 4.5-4.4.4-.4 2-2.1 2.6-2.1h.8c.9.2 1.5.7 1.5 1.7v.4c0 .6-.7 1.4-1.2 1.8l-2.7 2.7-4.6 4.7c2 2 4 4 5.9 6l1.6 1.7c.2.2.5.4.6.7.2.3.3.6.3.9v.5c-.2.9-.8 1.6-1.7 1.6h-.3c-.6 0-1.3-.7-1.8-1.1-.9-.8-1.8-1.7-2.6-2.6l-2.9-2.9v4.6c0 1.1-.7 1.9-1.8 1.9H75c-1.1 0-1.8-.9-1.8-1.9V88.9c0-1.1.7-1.9 1.8-1.9h.3c1.1 0 1.8.8 1.8 1.9v11.9zm47.6-6.6h.4c1.1 0 1.9.8 1.9 1.9 0 1.6-1.5 2-2.8 2-1.7 0-3.4 1-4.5 2.2-1.5 1.5-2.1 3.3-2.1 5.4v9.2c0 1.1-.7 1.9-1.8 1.9h-.3c-1.1 0-1.8-.9-1.8-1.9v-9.8c0-3.8 1.8-6.8 4.9-9 1.8-1.2 3.9-1.9 6.1-1.9zm-27.1 18.3c1.4.5 3 .4 4.4.2.7-.3 2.6-1.1 3.3-1h.2c.4.2.8.5 1 .9.5 1 .3 2-.7 2.6l-.3.2c-3.6 2.1-7.5 1.8-11.1-.2-1.7-.9-3-2.3-4-4l-.2-.4c-2.3-4-2-8.3.6-12.1.9-1.3 2.1-2.3 3.5-3.1l.5-.3c3.4-2 7.1-1.8 10.6-.1 1.9.9 3.4 2.3 4.5 4.1l.2.3c.8 1.3-.2 2.5-1.2 3.3-1.2.9-2.4 2-3.5 3-2.7 2.2-5.3 4.4-7.8 6.6zm-3.3-2.3l8.5-7.3c1-.8 2-1.7 3-2.6-.8-1-2.1-1.7-3.1-2.1-2.2-.8-4.4-.6-6.4.6-2.6 1.5-3.8 4-3.7 7 0 1.2.4 2.3 1 3.4.2.4.4.7.7 1M73.7 33.7H85v11.5h5.7c2.6 0 5.3-.5 7.8-1.3 1.2-.4 2.6-1 3.8-1.7-1.6-2.1-2.4-4.7-2.6-7.3-.3-3.5.4-8.1 2.8-10.8l1.2-1.4 1.4 1.1c3.6 2.9 6.5 6.8 7.1 11.4 4.3-1.3 9.3-1 13.1 1.2l1.5.9-.8 1.6c-3.2 6.2-9.9 8.2-16.4 7.8-9.8 24.3-31 35.8-56.8 35.8-13.3 0-25.5-5-32.5-16.8l-.1-.2-1-2.1c-2.4-5.2-3.1-10.9-2.6-16.6l.2-1.7h9.6V33.7h11.3V22.4h22.5V11.1h13.5v22.6z" />
|
||||
<path fill="#00AADA"
|
||||
d="M110.2 37.9c.8-5.9-3.6-10.5-6.4-12.7-3.1 3.6-3.6 13.2 1.3 17.2-2.8 2.4-8.5 4.7-14.5 4.7H18.4c-.6 6.2.5 11.9 3 16.8l.8 1.5c.5.9 1.1 1.7 1.7 2.6 3 .2 5.7.3 8.2.2 4.9-.1 8.9-.7 12-1.7.5-.2.9.1 1.1.5.2.5-.1.9-.5 1.1-.4.1-.8.3-1.3.4-2.4.7-5 1.1-8.3 1.3h-.6c-1.3.1-2.7.1-4.2.1-1.6 0-3.1 0-4.9-.1 6 6.8 15.4 10.8 27.2 10.8 25 0 46.2-11.1 55.5-35.9 6.7.7 13.1-1 16-6.7-4.5-2.6-10.5-1.8-13.9-.1z" />
|
||||
<path fill="#28B8EB"
|
||||
d="M110.2 37.9c.8-5.9-3.6-10.5-6.4-12.7-3.1 3.6-3.6 13.2 1.3 17.2-2.8 2.4-8.5 4.7-14.5 4.7h-68c-.3 9.5 3.2 16.7 9.5 21 4.9-.1 8.9-.7 12-1.7.5-.2.9.1 1.1.5.2.5-.1.9-.5 1.1-.4.1-.8.3-1.3.4-2.4.7-5.2 1.2-8.5 1.4l-.1-.1c8.5 4.4 20.8 4.3 35-1.1 15.8-6.1 30.6-17.7 40.9-30.9-.2.1-.3.2-.5.2z" />
|
||||
<path fill="#028BB8"
|
||||
d="M18.5 54.6c.4 3.3 1.4 6.4 2.9 9.3l.8 1.5c.5.9 1.1 1.7 1.7 2.6 3 .2 5.7.3 8.2.2 4.9-.1 8.9-.7 12-1.7.5-.2.9.1 1.1.5.2.5-.1.9-.5 1.1-.4.1-.8.3-1.3.4-2.4.7-5.2 1.2-8.5 1.4h-.4c-1.3.1-2.7.1-4.1.1-1.6 0-3.2 0-4.9-.1 6 6.8 15.5 10.8 27.3 10.8 21.4 0 40-8.1 50.8-26H18.5v-.1z" />
|
||||
<path fill="#019BC6"
|
||||
d="M23.3 54.6c1.3 5.8 4.3 10.4 8.8 13.5 4.9-.1 8.9-.7 12-1.7.5-.2.9.1 1.1.5.2.5-.1.9-.5 1.1-.4.1-.8.3-1.3.4-2.4.7-5.2 1.2-8.6 1.4 8.5 4.4 20.8 4.3 34.9-1.1 8.5-3.3 16.8-8.2 24.2-14.1H23.3z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#00ACD3"
|
||||
d="M28.2 35.5H38v9.8h-9.8v-9.8zm.8.9h.8v8.1H29v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1H32v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm3.1-12.1h9.8V34h-9.8v-9.7zm.8.8h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#23C2EE"
|
||||
d="M39.5 35.5h9.8v9.8h-9.8v-9.8zm.8.9h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#00ACD3"
|
||||
d="M50.8 35.5h9.8v9.8h-9.8v-9.8zm.8.9h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1H53v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1H56v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#23C2EE"
|
||||
d="M50.8 24.3h9.8V34h-9.8v-9.7zm.8.8h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1H53v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1H56v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zM62 35.5h9.8v9.8H62v-9.8zm.9.9h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#00ACD3"
|
||||
d="M62 24.3h9.8V34H62v-9.7zm.9.8h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#23C2EE"
|
||||
d="M62 13h9.8v9.8H62V13zm.9.8h.8V22h-.8v-8.2zm1.4 0h.8V22h-.8v-8.2zm1.5 0h.8V22h-.8v-8.2zm1.5 0h.8V22h-.8v-8.2zm1.4 0h.8V22h-.8v-8.2zm1.5 0h.8V22h-.8v-8.2z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#00ACD3"
|
||||
d="M73.3 35.5h9.8v9.8h-9.8v-9.8zm.8.9h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1H80v-8.1zm1.5 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#D4EEF1"
|
||||
d="M48.6 61.2c1.5 0 2.7 1.2 2.7 2.7 0 1.5-1.2 2.7-2.7 2.7-1.5 0-2.7-1.2-2.7-2.7.1-1.5 1.3-2.7 2.7-2.7" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#3A4D54"
|
||||
d="M48.6 61.9c.2 0 .5 0 .7.1-.2.1-.4.4-.4.7 0 .4.4.8.8.8.3 0 .6-.2.7-.4.1.2.1.5.1.7 0 1.1-.9 1.9-1.9 1.9-1.1 0-1.9-.9-1.9-1.9 0-1 .9-1.9 1.9-1.9M1 55.6h125.3c-2.7-.7-8.6-1.6-7.7-5.2-5 5.7-16.9 4-20 1.2-3.4 4.9-23 3-24.3-.8-4.2 5-17.3 5-21.5 0-1.4 3.8-21 5.7-24.3.8-3 2.8-15 4.5-20-1.2 1.1 3.5-4.8 4.5-7.5 5.2" />
|
||||
<path fill="#BFDBE0"
|
||||
d="M55.8 80.6c-6.7-3.2-10.3-7.5-12.4-12.2-2.5.7-5.5 1.2-8.9 1.4-1.3.1-2.7.1-4.1.1-1.7 0-3.4 0-5.2-.1 6.1 6.1 13.7 10.8 27.6 10.9 1-.1 2-.1 3-.1z" />
|
||||
<path fill="#D4EEF1"
|
||||
d="M45.9 72.7c-.9-1.3-1.8-2.8-2.5-4.3-2.5.7-5.5 1.2-8.9 1.4 2.4 1.3 5.8 2.5 11.4 2.9z" />
|
||||
</svg>
|
||||
<div>
|
||||
<svg class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="currentColor"
|
||||
d="M20 96.9v-8.1c0-1.1.7-1.9 1.8-1.9h.3c1.1 0 1.8.9 1.8 1.9v17c0 4.1-2 7.4-5.6 9.5-1.7 1-3.5 1.5-5.4 1.5h-.8c-4.1 0-7.4-2-9.5-5.6-1-1.7-1.5-3.5-1.5-5.4v-.8c0-4.1 2-7.4 5.6-9.5 1.7-1 3.5-1.5 5.4-1.5h.8c2.7.1 5.1 1.1 7.1 2.9zm-15.1 8.5c0 3 1.5 5.2 4.1 6.7 1.1.6 2.2.9 3.4.9 2.9 0 5.1-1.4 6.6-3.9.7-1.2 1-2.4 1-3.8 0-2.6-1.2-4.6-3.3-6.1-1.3-.9-2.7-1.4-4.2-1.4-3.2 0-5.5 1.6-6.9 4.5-.5 1-.7 2.1-.7 3.1zm32.2-11.3h.5c4.4 0 7.8 2.1 9.9 6 .9 1.5 1.3 3.2 1.3 5v.8c0 4.1-2 7.4-5.6 9.5-1.7 1-3.5 1.5-5.4 1.5H37c-4.1 0-7.4-2-9.5-5.6-1-1.7-1.5-3.5-1.5-5.4v-.8c0-4.1 2.1-7.4 5.6-9.5 1.7-1.1 3.6-1.5 5.5-1.5zm-7.2 11.3c0 2.9 1.4 5 3.9 6.5 1.2.7 2.4 1 3.8 1 2.9 0 5-1.5 6.5-3.9.7-1.2 1-2.4 1-3.8 0-2.7-1.3-4.8-3.5-6.3-1.2-.8-2.6-1.2-4-1.2-3.2 0-5.5 1.6-6.9 4.5-.6 1.1-.8 2.2-.8 3.2zm34.8-7.2c-.6-.3-1.7-.4-2.3-.4-3.2-.1-5.5 1.7-6.9 4.5-.5 1-.7 2-.7 3.1 0 3.3 1.7 5.6 4.6 7 1.1.5 2.4.6 3.6.6 1 0 2.5-.6 3.4-1.1l.2-.1h.8c.9.2 1.5.7 1.5 1.7v.4c0 2.3-4.3 2.9-5.9 3-5.7.4-10-2.7-11.6-8.2-.3-.9-.4-1.9-.4-2.9v-.8c0-4.1 2.1-7.4 5.6-9.5 1.7-1 3.5-1.5 5.4-1.5h.8c2 0 3.9.6 5.6 1.7l.1.1.1.1c.2.3.3.6.3 1v.4c0 1-.7 1.5-1.6 1.7H67c-.5 0-1.8-.6-2.3-.8zm12.4 2.6c1.5-1.5 3-3 4.5-4.4.4-.4 2-2.1 2.6-2.1h.8c.9.2 1.5.7 1.5 1.7v.4c0 .6-.7 1.4-1.2 1.8l-2.7 2.7-4.6 4.7c2 2 4 4 5.9 6l1.6 1.7c.2.2.5.4.6.7.2.3.3.6.3.9v.5c-.2.9-.8 1.6-1.7 1.6h-.3c-.6 0-1.3-.7-1.8-1.1-.9-.8-1.8-1.7-2.6-2.6l-2.9-2.9v4.6c0 1.1-.7 1.9-1.8 1.9H75c-1.1 0-1.8-.9-1.8-1.9V88.9c0-1.1.7-1.9 1.8-1.9h.3c1.1 0 1.8.8 1.8 1.9v11.9zm47.6-6.6h.4c1.1 0 1.9.8 1.9 1.9 0 1.6-1.5 2-2.8 2-1.7 0-3.4 1-4.5 2.2-1.5 1.5-2.1 3.3-2.1 5.4v9.2c0 1.1-.7 1.9-1.8 1.9h-.3c-1.1 0-1.8-.9-1.8-1.9v-9.8c0-3.8 1.8-6.8 4.9-9 1.8-1.2 3.9-1.9 6.1-1.9zm-27.1 18.3c1.4.5 3 .4 4.4.2.7-.3 2.6-1.1 3.3-1h.2c.4.2.8.5 1 .9.5 1 .3 2-.7 2.6l-.3.2c-3.6 2.1-7.5 1.8-11.1-.2-1.7-.9-3-2.3-4-4l-.2-.4c-2.3-4-2-8.3.6-12.1.9-1.3 2.1-2.3 3.5-3.1l.5-.3c3.4-2 7.1-1.8 10.6-.1 1.9.9 3.4 2.3 4.5 4.1l.2.3c.8 1.3-.2 2.5-1.2 3.3-1.2.9-2.4 2-3.5 3-2.7 2.2-5.3 4.4-7.8 6.6zm-3.3-2.3l8.5-7.3c1-.8 2-1.7 3-2.6-.8-1-2.1-1.7-3.1-2.1-2.2-.8-4.4-.6-6.4.6-2.6 1.5-3.8 4-3.7 7 0 1.2.4 2.3 1 3.4.2.4.4.7.7 1M73.7 33.7H85v11.5h5.7c2.6 0 5.3-.5 7.8-1.3 1.2-.4 2.6-1 3.8-1.7-1.6-2.1-2.4-4.7-2.6-7.3-.3-3.5.4-8.1 2.8-10.8l1.2-1.4 1.4 1.1c3.6 2.9 6.5 6.8 7.1 11.4 4.3-1.3 9.3-1 13.1 1.2l1.5.9-.8 1.6c-3.2 6.2-9.9 8.2-16.4 7.8-9.8 24.3-31 35.8-56.8 35.8-13.3 0-25.5-5-32.5-16.8l-.1-.2-1-2.1c-2.4-5.2-3.1-10.9-2.6-16.6l.2-1.7h9.6V33.7h11.3V22.4h22.5V11.1h13.5v22.6z" />
|
||||
<path fill="#00AADA"
|
||||
d="M110.2 37.9c.8-5.9-3.6-10.5-6.4-12.7-3.1 3.6-3.6 13.2 1.3 17.2-2.8 2.4-8.5 4.7-14.5 4.7H18.4c-.6 6.2.5 11.9 3 16.8l.8 1.5c.5.9 1.1 1.7 1.7 2.6 3 .2 5.7.3 8.2.2 4.9-.1 8.9-.7 12-1.7.5-.2.9.1 1.1.5.2.5-.1.9-.5 1.1-.4.1-.8.3-1.3.4-2.4.7-5 1.1-8.3 1.3h-.6c-1.3.1-2.7.1-4.2.1-1.6 0-3.1 0-4.9-.1 6 6.8 15.4 10.8 27.2 10.8 25 0 46.2-11.1 55.5-35.9 6.7.7 13.1-1 16-6.7-4.5-2.6-10.5-1.8-13.9-.1z" />
|
||||
<path fill="#28B8EB"
|
||||
d="M110.2 37.9c.8-5.9-3.6-10.5-6.4-12.7-3.1 3.6-3.6 13.2 1.3 17.2-2.8 2.4-8.5 4.7-14.5 4.7h-68c-.3 9.5 3.2 16.7 9.5 21 4.9-.1 8.9-.7 12-1.7.5-.2.9.1 1.1.5.2.5-.1.9-.5 1.1-.4.1-.8.3-1.3.4-2.4.7-5.2 1.2-8.5 1.4l-.1-.1c8.5 4.4 20.8 4.3 35-1.1 15.8-6.1 30.6-17.7 40.9-30.9-.2.1-.3.2-.5.2z" />
|
||||
<path fill="#028BB8"
|
||||
d="M18.5 54.6c.4 3.3 1.4 6.4 2.9 9.3l.8 1.5c.5.9 1.1 1.7 1.7 2.6 3 .2 5.7.3 8.2.2 4.9-.1 8.9-.7 12-1.7.5-.2.9.1 1.1.5.2.5-.1.9-.5 1.1-.4.1-.8.3-1.3.4-2.4.7-5.2 1.2-8.5 1.4h-.4c-1.3.1-2.7.1-4.1.1-1.6 0-3.2 0-4.9-.1 6 6.8 15.5 10.8 27.3 10.8 21.4 0 40-8.1 50.8-26H18.5v-.1z" />
|
||||
<path fill="#019BC6"
|
||||
d="M23.3 54.6c1.3 5.8 4.3 10.4 8.8 13.5 4.9-.1 8.9-.7 12-1.7.5-.2.9.1 1.1.5.2.5-.1.9-.5 1.1-.4.1-.8.3-1.3.4-2.4.7-5.2 1.2-8.6 1.4 8.5 4.4 20.8 4.3 34.9-1.1 8.5-3.3 16.8-8.2 24.2-14.1H23.3z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#00ACD3"
|
||||
d="M28.2 35.5H38v9.8h-9.8v-9.8zm.8.9h.8v8.1H29v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1H32v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm3.1-12.1h9.8V34h-9.8v-9.7zm.8.8h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#23C2EE"
|
||||
d="M39.5 35.5h9.8v9.8h-9.8v-9.8zm.8.9h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#00ACD3"
|
||||
d="M50.8 35.5h9.8v9.8h-9.8v-9.8zm.8.9h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1H53v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1H56v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#23C2EE"
|
||||
d="M50.8 24.3h9.8V34h-9.8v-9.7zm.8.8h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1H53v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1H56v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zM62 35.5h9.8v9.8H62v-9.8zm.9.9h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#00ACD3"
|
||||
d="M62 24.3h9.8V34H62v-9.7zm.9.8h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#23C2EE"
|
||||
d="M62 13h9.8v9.8H62V13zm.9.8h.8V22h-.8v-8.2zm1.4 0h.8V22h-.8v-8.2zm1.5 0h.8V22h-.8v-8.2zm1.5 0h.8V22h-.8v-8.2zm1.4 0h.8V22h-.8v-8.2zm1.5 0h.8V22h-.8v-8.2z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#00ACD3"
|
||||
d="M73.3 35.5h9.8v9.8h-9.8v-9.8zm.8.9h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1h-.8v-8.1zm1.4 0h.8v8.1h-.8v-8.1zm1.5 0h.8v8.1H80v-8.1zm1.5 0h.8v8.1h-.8v-8.1z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#D4EEF1"
|
||||
d="M48.6 61.2c1.5 0 2.7 1.2 2.7 2.7 0 1.5-1.2 2.7-2.7 2.7-1.5 0-2.7-1.2-2.7-2.7.1-1.5 1.3-2.7 2.7-2.7" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#3A4D54"
|
||||
d="M48.6 61.9c.2 0 .5 0 .7.1-.2.1-.4.4-.4.7 0 .4.4.8.8.8.3 0 .6-.2.7-.4.1.2.1.5.1.7 0 1.1-.9 1.9-1.9 1.9-1.1 0-1.9-.9-1.9-1.9 0-1 .9-1.9 1.9-1.9M1 55.6h125.3c-2.7-.7-8.6-1.6-7.7-5.2-5 5.7-16.9 4-20 1.2-3.4 4.9-23 3-24.3-.8-4.2 5-17.3 5-21.5 0-1.4 3.8-21 5.7-24.3.8-3 2.8-15 4.5-20-1.2 1.1 3.5-4.8 4.5-7.5 5.2" />
|
||||
<path fill="#BFDBE0"
|
||||
d="M55.8 80.6c-6.7-3.2-10.3-7.5-12.4-12.2-2.5.7-5.5 1.2-8.9 1.4-1.3.1-2.7.1-4.1.1-1.7 0-3.4 0-5.2-.1 6.1 6.1 13.7 10.8 27.6 10.9 1-.1 2-.1 3-.1z" />
|
||||
<path fill="#D4EEF1"
|
||||
d="M45.9 72.7c-.9-1.3-1.8-2.8-2.5-4.3-2.5.7-5.5 1.2-8.9 1.4 2.4 1.3 5.8 2.5 11.4 2.9z" />
|
||||
</svg>
|
||||
</div>
|
||||
</x-slot:logo>
|
||||
</x-resource-view>
|
||||
<x-resource-view wire="setType('docker-compose-empty')">
|
||||
@@ -111,10 +113,9 @@
|
||||
You can deploy complex application easily with Docker Compose, without Git.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-black">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<div>
|
||||
<svg class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="currentColor"
|
||||
d="M20 96.9v-8.1c0-1.1.7-1.9 1.8-1.9h.3c1.1 0 1.8.9 1.8 1.9v17c0 4.1-2 7.4-5.6 9.5-1.7 1-3.5 1.5-5.4 1.5h-.8c-4.1 0-7.4-2-9.5-5.6-1-1.7-1.5-3.5-1.5-5.4v-.8c0-4.1 2-7.4 5.6-9.5 1.7-1 3.5-1.5 5.4-1.5h.8c2.7.1 5.1 1.1 7.1 2.9zm-15.1 8.5c0 3 1.5 5.2 4.1 6.7 1.1.6 2.2.9 3.4.9 2.9 0 5.1-1.4 6.6-3.9.7-1.2 1-2.4 1-3.8 0-2.6-1.2-4.6-3.3-6.1-1.3-.9-2.7-1.4-4.2-1.4-3.2 0-5.5 1.6-6.9 4.5-.5 1-.7 2.1-.7 3.1zm32.2-11.3h.5c4.4 0 7.8 2.1 9.9 6 .9 1.5 1.3 3.2 1.3 5v.8c0 4.1-2 7.4-5.6 9.5-1.7 1-3.5 1.5-5.4 1.5H37c-4.1 0-7.4-2-9.5-5.6-1-1.7-1.5-3.5-1.5-5.4v-.8c0-4.1 2.1-7.4 5.6-9.5 1.7-1.1 3.6-1.5 5.5-1.5zm-7.2 11.3c0 2.9 1.4 5 3.9 6.5 1.2.7 2.4 1 3.8 1 2.9 0 5-1.5 6.5-3.9.7-1.2 1-2.4 1-3.8 0-2.7-1.3-4.8-3.5-6.3-1.2-.8-2.6-1.2-4-1.2-3.2 0-5.5 1.6-6.9 4.5-.6 1.1-.8 2.2-.8 3.2zm34.8-7.2c-.6-.3-1.7-.4-2.3-.4-3.2-.1-5.5 1.7-6.9 4.5-.5 1-.7 2-.7 3.1 0 3.3 1.7 5.6 4.6 7 1.1.5 2.4.6 3.6.6 1 0 2.5-.6 3.4-1.1l.2-.1h.8c.9.2 1.5.7 1.5 1.7v.4c0 2.3-4.3 2.9-5.9 3-5.7.4-10-2.7-11.6-8.2-.3-.9-.4-1.9-.4-2.9v-.8c0-4.1 2.1-7.4 5.6-9.5 1.7-1 3.5-1.5 5.4-1.5h.8c2 0 3.9.6 5.6 1.7l.1.1.1.1c.2.3.3.6.3 1v.4c0 1-.7 1.5-1.6 1.7H67c-.5 0-1.8-.6-2.3-.8zm12.4 2.6c1.5-1.5 3-3 4.5-4.4.4-.4 2-2.1 2.6-2.1h.8c.9.2 1.5.7 1.5 1.7v.4c0 .6-.7 1.4-1.2 1.8l-2.7 2.7-4.6 4.7c2 2 4 4 5.9 6l1.6 1.7c.2.2.5.4.6.7.2.3.3.6.3.9v.5c-.2.9-.8 1.6-1.7 1.6h-.3c-.6 0-1.3-.7-1.8-1.1-.9-.8-1.8-1.7-2.6-2.6l-2.9-2.9v4.6c0 1.1-.7 1.9-1.8 1.9H75c-1.1 0-1.8-.9-1.8-1.9V88.9c0-1.1.7-1.9 1.8-1.9h.3c1.1 0 1.8.8 1.8 1.9v11.9zm47.6-6.6h.4c1.1 0 1.9.8 1.9 1.9 0 1.6-1.5 2-2.8 2-1.7 0-3.4 1-4.5 2.2-1.5 1.5-2.1 3.3-2.1 5.4v9.2c0 1.1-.7 1.9-1.8 1.9h-.3c-1.1 0-1.8-.9-1.8-1.9v-9.8c0-3.8 1.8-6.8 4.9-9 1.8-1.2 3.9-1.9 6.1-1.9zm-27.1 18.3c1.4.5 3 .4 4.4.2.7-.3 2.6-1.1 3.3-1h.2c.4.2.8.5 1 .9.5 1 .3 2-.7 2.6l-.3.2c-3.6 2.1-7.5 1.8-11.1-.2-1.7-.9-3-2.3-4-4l-.2-.4c-2.3-4-2-8.3.6-12.1.9-1.3 2.1-2.3 3.5-3.1l.5-.3c3.4-2 7.1-1.8 10.6-.1 1.9.9 3.4 2.3 4.5 4.1l.2.3c.8 1.3-.2 2.5-1.2 3.3-1.2.9-2.4 2-3.5 3-2.7 2.2-5.3 4.4-7.8 6.6zm-3.3-2.3l8.5-7.3c1-.8 2-1.7 3-2.6-.8-1-2.1-1.7-3.1-2.1-2.2-.8-4.4-.6-6.4.6-2.6 1.5-3.8 4-3.7 7 0 1.2.4 2.3 1 3.4.2.4.4.7.7 1M73.7 33.7H85v11.5h5.7c2.6 0 5.3-.5 7.8-1.3 1.2-.4 2.6-1 3.8-1.7-1.6-2.1-2.4-4.7-2.6-7.3-.3-3.5.4-8.1 2.8-10.8l1.2-1.4 1.4 1.1c3.6 2.9 6.5 6.8 7.1 11.4 4.3-1.3 9.3-1 13.1 1.2l1.5.9-.8 1.6c-3.2 6.2-9.9 8.2-16.4 7.8-9.8 24.3-31 35.8-56.8 35.8-13.3 0-25.5-5-32.5-16.8l-.1-.2-1-2.1c-2.4-5.2-3.1-10.9-2.6-16.6l.2-1.7h9.6V33.7h11.3V22.4h22.5V11.1h13.5v22.6z" />
|
||||
<path fill="#00AADA"
|
||||
@@ -157,10 +158,9 @@
|
||||
You can deploy an existing Docker Image from any Registry, without Git.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-black">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<div>
|
||||
<svg class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="currentColor"
|
||||
d="M20 96.9v-8.1c0-1.1.7-1.9 1.8-1.9h.3c1.1 0 1.8.9 1.8 1.9v17c0 4.1-2 7.4-5.6 9.5-1.7 1-3.5 1.5-5.4 1.5h-.8c-4.1 0-7.4-2-9.5-5.6-1-1.7-1.5-3.5-1.5-5.4v-.8c0-4.1 2-7.4 5.6-9.5 1.7-1 3.5-1.5 5.4-1.5h.8c2.7.1 5.1 1.1 7.1 2.9zm-15.1 8.5c0 3 1.5 5.2 4.1 6.7 1.1.6 2.2.9 3.4.9 2.9 0 5.1-1.4 6.6-3.9.7-1.2 1-2.4 1-3.8 0-2.6-1.2-4.6-3.3-6.1-1.3-.9-2.7-1.4-4.2-1.4-3.2 0-5.5 1.6-6.9 4.5-.5 1-.7 2.1-.7 3.1zm32.2-11.3h.5c4.4 0 7.8 2.1 9.9 6 .9 1.5 1.3 3.2 1.3 5v.8c0 4.1-2 7.4-5.6 9.5-1.7 1-3.5 1.5-5.4 1.5H37c-4.1 0-7.4-2-9.5-5.6-1-1.7-1.5-3.5-1.5-5.4v-.8c0-4.1 2.1-7.4 5.6-9.5 1.7-1.1 3.6-1.5 5.5-1.5zm-7.2 11.3c0 2.9 1.4 5 3.9 6.5 1.2.7 2.4 1 3.8 1 2.9 0 5-1.5 6.5-3.9.7-1.2 1-2.4 1-3.8 0-2.7-1.3-4.8-3.5-6.3-1.2-.8-2.6-1.2-4-1.2-3.2 0-5.5 1.6-6.9 4.5-.6 1.1-.8 2.2-.8 3.2zm34.8-7.2c-.6-.3-1.7-.4-2.3-.4-3.2-.1-5.5 1.7-6.9 4.5-.5 1-.7 2-.7 3.1 0 3.3 1.7 5.6 4.6 7 1.1.5 2.4.6 3.6.6 1 0 2.5-.6 3.4-1.1l.2-.1h.8c.9.2 1.5.7 1.5 1.7v.4c0 2.3-4.3 2.9-5.9 3-5.7.4-10-2.7-11.6-8.2-.3-.9-.4-1.9-.4-2.9v-.8c0-4.1 2.1-7.4 5.6-9.5 1.7-1 3.5-1.5 5.4-1.5h.8c2 0 3.9.6 5.6 1.7l.1.1.1.1c.2.3.3.6.3 1v.4c0 1-.7 1.5-1.6 1.7H67c-.5 0-1.8-.6-2.3-.8zm12.4 2.6c1.5-1.5 3-3 4.5-4.4.4-.4 2-2.1 2.6-2.1h.8c.9.2 1.5.7 1.5 1.7v.4c0 .6-.7 1.4-1.2 1.8l-2.7 2.7-4.6 4.7c2 2 4 4 5.9 6l1.6 1.7c.2.2.5.4.6.7.2.3.3.6.3.9v.5c-.2.9-.8 1.6-1.7 1.6h-.3c-.6 0-1.3-.7-1.8-1.1-.9-.8-1.8-1.7-2.6-2.6l-2.9-2.9v4.6c0 1.1-.7 1.9-1.8 1.9H75c-1.1 0-1.8-.9-1.8-1.9V88.9c0-1.1.7-1.9 1.8-1.9h.3c1.1 0 1.8.8 1.8 1.9v11.9zm47.6-6.6h.4c1.1 0 1.9.8 1.9 1.9 0 1.6-1.5 2-2.8 2-1.7 0-3.4 1-4.5 2.2-1.5 1.5-2.1 3.3-2.1 5.4v9.2c0 1.1-.7 1.9-1.8 1.9h-.3c-1.1 0-1.8-.9-1.8-1.9v-9.8c0-3.8 1.8-6.8 4.9-9 1.8-1.2 3.9-1.9 6.1-1.9zm-27.1 18.3c1.4.5 3 .4 4.4.2.7-.3 2.6-1.1 3.3-1h.2c.4.2.8.5 1 .9.5 1 .3 2-.7 2.6l-.3.2c-3.6 2.1-7.5 1.8-11.1-.2-1.7-.9-3-2.3-4-4l-.2-.4c-2.3-4-2-8.3.6-12.1.9-1.3 2.1-2.3 3.5-3.1l.5-.3c3.4-2 7.1-1.8 10.6-.1 1.9.9 3.4 2.3 4.5 4.1l.2.3c.8 1.3-.2 2.5-1.2 3.3-1.2.9-2.4 2-3.5 3-2.7 2.2-5.3 4.4-7.8 6.6zm-3.3-2.3l8.5-7.3c1-.8 2-1.7 3-2.6-.8-1-2.1-1.7-3.1-2.1-2.2-.8-4.4-.6-6.4.6-2.6 1.5-3.8 4-3.7 7 0 1.2.4 2.3 1 3.4.2.4.4.7.7 1M73.7 33.7H85v11.5h5.7c2.6 0 5.3-.5 7.8-1.3 1.2-.4 2.6-1 3.8-1.7-1.6-2.1-2.4-4.7-2.6-7.3-.3-3.5.4-8.1 2.8-10.8l1.2-1.4 1.4 1.1c3.6 2.9 6.5 6.8 7.1 11.4 4.3-1.3 9.3-1 13.1 1.2l1.5.9-.8 1.6c-3.2 6.2-9.9 8.2-16.4 7.8-9.8 24.3-31 35.8-56.8 35.8-13.3 0-25.5-5-32.5-16.8l-.1-.2-1-2.1c-2.4-5.2-3.1-10.9-2.6-16.6l.2-1.7h9.6V33.7h11.3V22.4h22.5V11.1h13.5v22.6z" />
|
||||
<path fill="#00AADA"
|
||||
@@ -207,10 +207,9 @@
|
||||
robustness, advanced features, and strong standards compliance.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<div>
|
||||
<svg class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<path fill="#currentColor"
|
||||
d="M85.988 76.075c.632-5.262.443-6.034 4.362-5.182l.995.088c3.014.137 6.957-.485 9.272-1.561 4.986-2.313 7.942-6.177 3.026-5.162-11.215 2.313-11.986-1.483-11.986-1.483C103.5 45.204 108.451 22.9 104.178 17.44 92.524 2.548 72.35 9.59 72.012 9.773l-.108.021c-2.216-.461-4.695-.735-7.481-.78-5.075-.083-8.926 1.331-11.847 3.546 0 0-35.989-14.827-34.315 18.646.356 7.121 10.207 53.882 21.956 39.758 4.294-5.164 8.444-9.531 8.444-9.531 2.061 1.369 4.528 2.067 7.116 1.816l.2-.17c-.062.641-.035 1.268.081 2.01-3.027 3.383-2.137 3.977-8.189 5.222-6.122 1.262-2.525 3.508-.178 4.095 2.848.713 9.433 1.722 13.884-4.509l-.177.711c1.188.95 1.107 6.827 1.275 11.026.168 4.199.45 8.117 1.306 10.429.856 2.31 1.866 8.261 9.819 6.557 6.646-1.426 11.727-3.476 12.19-22.545" />
|
||||
<path fill="#currentColor"
|
||||
@@ -235,10 +234,9 @@
|
||||
broker.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<div>
|
||||
<svg class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<path
|
||||
d="M21.4 97.6c0 1.8-1.5 3.5-3.5 3.5-1.5 0-2.8.4-4 1.3-1.3.8-2.2 1.9-3 3.2-1.6 2.1-2.4 4.6-2.7 5.5v12.5c0 1.9-1.6 3.5-3.6 3.5-1.9 0-3.5-1.6-3.5-3.5v-26c0-1.9 1.6-3.4 3.5-3.4 2 0 3.6 1.5 3.6 3.4v.5c.4-.5.9-1 1.4-1.3 2.2-1.4 5-2.6 8.3-2.6 2 0 3.5 1.5 3.5 3.4zm-1.9 13c.1-9 7-16.5 16.1-16.5 8.6 0 15.3 6.4 15.9 15.3v.3c0 .1 0 .5-.1.6-.2 1.6-1.6 2.6-3.4 2.6H27c.3 1.5 1.1 3.2 2.2 4.3 1.4 1.6 4 2.8 6.3 3 2.4.2 5.2-.4 6.8-1.6 1.4-1.4 4.1-1.3 4.9-.2.9.9 1.5 2.9 0 4.3-3.2 3-7.1 4.3-11.8 4.3-8.9 0-15.9-7.5-15.9-16.4zm7.1-3.2h18.6c-.7-2.6-4-6.5-9.7-7-5.6.2-8.3 4.3-8.9 7zm58.3 16.1c0 1.9-1.6 3.6-3.6 3.6-1.8 0-3.2-1.3-3.5-2.8-2.5 1.7-5.7 2.8-9 2.8-8.9 0-16-7.5-16-16.4 0-9 7.1-16.5 16-16.5 3.2 0 6.4 1.1 8.8 2.8V84.5c0-1.9 1.6-3.6 3.6-3.6s3.6 1.6 3.6 3.6v26.2l.1 12.8zm-16-22.2c-2.4 0-4.5 1-6.2 2.7-1.6 1.6-2.6 4-2.6 6.6 0 2.5 1 4.9 2.6 6.5 1.6 1.7 3.8 2.7 6.2 2.7 2.4 0 4.5-1 6.2-2.7 1.6-1.6 2.6-4 2.6-6.5 0-2.6-1-5-2.6-6.6-1.6-1.7-3.7-2.7-6.2-2.7zm28.6-15.4c0 2-1.5 3.6-3.6 3.6-2 0-3.6-1.6-3.6-3.6v-1.4c0-2 1.6-3.6 3.6-3.6s3.6 1.6 3.6 3.6v1.4zm0 11.9v25.7c0 2-1.5 3.6-3.6 3.6-2 0-3.6-1.6-3.6-3.6V97.8c0-2.1 1.6-3.6 3.6-3.6 2.1 0 3.6 1.5 3.6 3.6zm4.5 19.8c1.2-1.6 3.5-1.8 4.9-.5 1.7 1.4 4.7 3 7.2 2.9 1.8 0 3.4-.6 4.5-1.3.9-.8 1.2-1.4 1.2-2 0-.3-.1-.5-.2-.7-.1-.2-.3-.5-.9-.8-.9-.7-2.9-1.4-5.3-1.8h-.1c-2-.4-4-.9-5.7-1.7-1.8-.9-3.4-2-4.5-3.8-.7-1.2-1.1-2.6-1.1-4.1 0-3 1.7-5.6 3.9-7.2 2.3-1.6 5.1-2.4 8.1-2.4 4.5 0 7.8 2.2 9.9 3.6 1.6 1.1 2 3.2 1.1 4.9-1.1 1.6-3.2 2-4.9.9-2.1-1.4-4-2.4-6.1-2.4-1.6 0-3.1.5-4 1.2-.9.6-1.1 1.2-1.1 1.5 0 .3 0 .3.1.5.1.1.3.4.7.7.9.6 2.6 1.2 4.8 1.6l.1.1h.1c2.2.4 4.2 1 6.1 1.9 1.8.8 3.6 2 4.7 3.9.8 1.3 1.3 2.8 1.3 4.3 0 3.2-1.8 5.9-4.1 7.6-2.4 1.6-5.3 2.6-8.6 2.6-5.1-.1-9.1-2.4-11.7-4.5-1.4-1.3-1.6-3.5-.4-5z"
|
||||
fill="#currentColor" />
|
||||
@@ -272,8 +270,7 @@
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
<svg class="block dark:hidden" width="245" height="60" viewBox="0 0 210 50"
|
||||
fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
@@ -300,8 +297,7 @@
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
<svg version="1.1" width="180" height="60" id="svg1326" viewBox="0 0 544 182"
|
||||
sodipodi:docname="keydb.svg" inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
@@ -363,9 +359,8 @@
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
<svg width="200" height="90" viewBox="0 0 100 43" fill="currentColor"
|
||||
class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
<svg width="215" height="90" viewBox="0 0 100 43" fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_378_10860)">
|
||||
<rect x="2.70837" y="2.875" width="2.24992" height="20.2493" rx="0.236664"
|
||||
@@ -390,10 +385,9 @@
|
||||
optional schemas.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<div>
|
||||
<svg class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="currentColor"
|
||||
d="M87.259 100.139c.169-.325.331-.612.469-.909.087-.19.221-.228.41-.223 1.133.032 2.266.067 3.4.078.963.01 1.928-.008 2.892-.019 1.086-.013 2.172-.07 3.257-.039 1.445.042 2.853.325 4.16.968 1.561.769 2.742 1.94 3.547 3.483a8.71 8.71 0 01.931 3.14c.172 1.608.059 3.179-.451 4.717-.632 1.906-1.832 3.365-3.499 4.458-1.283.841-2.69 1.338-4.198 1.622-1.596.301-3.197.204-4.798.209-1.756.007-3.511-.031-5.267-.051-.307-.003-.351-.061-.27-.354l.075-.27c.171-.538.263-.562.809-.652a2.83 2.83 0 001.087-.413c.184-.122.26-.44.332-.685.062-.214.065-.449.067-.675.025-3.425.051-6.849.065-10.272a44.077 44.077 0 00-.065-2.596c-.034-.605-.357-1.019-1.077-1.162-.56-.111-1.124-.197-1.687-.296l-.189-.059zm16.076 8.293c-.076-.682-.113-1.37-.235-2.042-.292-1.613-.998-3.018-2.238-4.119-2.005-1.779-4.419-2.053-6.949-1.841-.576.048-.7.245-.709.837-.014.84-.028 1.68-.029 2.52-.004 2.664-.004 5.328 0 7.992.001.758.009 1.516.031 2.272.024.774.305 1.429 1.063 1.729 1.195.473 2.452.529 3.706.336 2.003-.307 3.404-1.474 4.344-3.223.744-1.388.954-2.903 1.016-4.461zm4.869 9.071c-.024-.415.146-.758.356-1.073.057-.085.253-.081.388-.108l1.146-.227c.405-.086.618-.358.675-.755.038-.262.074-.527.077-.792a879.6 879.6 0 00.059-6.291c.01-2.1.002-4.2.002-6.3l-.009-.401c-.041-.675-.367-1.025-1.037-1.124l-1.453-.221c-.179-.024-.244-.11-.179-.269.112-.271.219-.552.377-.796.059-.09.258-.125.392-.122.694.01 1.388.062 2.082.061l6.041-.036c1.164-.001 2.288.202 3.332.759 1.149.612 1.792 1.559 1.976 2.849.192 1.355-.219 2.497-1.209 3.404-.407.374-.934.618-1.406.922l-.154.096c.438.161.855.3 1.261.466 1.188.487 2.133 1.248 2.633 2.463.395.959.395 1.959.161 2.953-.364 1.556-1.389 2.591-2.722 3.374-1.251.735-2.605 1.163-4.047 1.235-1.33.067-2.666.042-3.999.057l-.772.004a996.106 996.106 0 01-3.854-.096l-.117-.032zm5.537-6.089h.013c0 .658-.009 1.316.003 1.974.008.426-.007.864.085 1.274.138.613.418 1.166 1.106 1.342a6.671 6.671 0 002.818.124c1.177-.205 2.116-.795 2.631-1.916.382-.833.439-1.716.308-2.618-.174-1.188-.805-2.05-1.854-2.615-.688-.371-1.422-.598-2.204-.628-.876-.033-1.753-.035-2.629-.062-.246-.007-.28.118-.279.32.005.934.002 1.869.002 2.805zm1.865-4.475c.479-.024 1.021-.031 1.56-.085 1.032-.103 1.759-.622 2.138-1.609.193-.501.185-1.017.19-1.538.015-1.357-.777-2.469-2.066-2.929-.995-.355-2.021-.361-3.053-.333-.418.011-.605.194-.611.615l-.062 5.489c-.003.218.091.312.303.319l1.601.071z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="currentColor"
|
||||
@@ -450,10 +444,9 @@
|
||||
flexibility.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<div>
|
||||
<svg class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<path fill="currentColor"
|
||||
d="M0 91.313h4.242V74.566l6.566 14.598c.773 1.77 1.832 2.391 3.914 2.391s3.098-.621 3.871-2.391l6.566-14.598v16.746h4.242V74.594c0-1.633-.652-2.422-2-2.828-3.223-1.004-5.383-.137-6.363 2.039l-6.441 14.41-6.238-14.41c-.937-2.176-3.14-3.043-6.359-2.039-1.348.406-2 1.195-2 2.828zM32.93 77.68h4.238v9.227c-.039.5.16 1.676 2.484 1.715h9.223V77.633h4.25c.02 0-.008 14.984-.008 15.047.023 3.695-4.582 4.496-6.707 4.559H33.02v-2.852l13.414-.004c2.73-.285 2.406-1.645 2.406-2.098v-1.113h-9.012c-4.195-.039-6.863-1.871-6.898-3.977-.004-.191.09-9.422 0-9.516zm0 0" />
|
||||
<path fill="currentColor"
|
||||
@@ -471,10 +464,9 @@
|
||||
replacement for MySQL.
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<div>
|
||||
<svg class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:fill-white fill-black"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||
<path fill="currentColor"
|
||||
d="M127.434 12.182a1.727 1.727 0 0 0-1.174-.392c-1.168 0-2.68.793-3.495 1.218l-.322.165a11.095 11.095 0 0 1-4.365 1.1c-1.554.049-2.892.14-4.635.322-10.327 1.06-14.933 8.975-19.37 16.63-2.416 4.164-4.91 8.489-8.33 11.793a22.472 22.472 0 0 1-2.252 1.913c-3.54 2.631-7.985 4.51-11.443 5.84-3.329 1.273-6.964 2.417-10.474 3.524-3.219 1.012-6.255 1.97-9.048 3.008a96.902 96.902 0 0 1-3.275 1.14c-2.545.825-4.378 1.458-7.06 3.304a45.386 45.386 0 0 0-2.804 2.066 29.585 29.585 0 0 0-5.597 5.894 34.802 34.802 0 0 1-4.701 5.642c-.566.554-1.57.826-3.074.826-1.76 0-3.895-.363-6.154-.747-2.33-.413-4.738-.805-6.803-.805-1.677 0-2.962.273-3.92.826 0 0-1.617.942-2.298 2.16l.67.302a13.718 13.718 0 0 1 2.859 2.065 14.342 14.342 0 0 0 2.973 2.115 2.553 2.553 0 0 1 .918.582c-.281.413-.694.946-1.129 1.516-2.384 3.119-3.774 5.09-2.977 6.163a2.507 2.507 0 0 0 1.239.28c5.196 0 7.989-1.35 11.52-3.06 1.024-.495 2.066-1.004 3.305-1.528 2.065-.896 4.288-2.325 6.647-3.838 3.084-2.01 6.31-4.076 9.442-5.072a25.734 25.734 0 0 1 7.943-1.115c3.305 0 6.783.441 10.138.872 2.499.322 5.089.652 7.63.805.986.057 1.9.086 2.787.086a32.307 32.307 0 0 0 3.557-.185l.284-.1c1.781-1.094 2.617-3.444 3.425-5.717.52-1.462.96-2.775 1.652-3.61a1.054 1.054 0 0 1 .132-.11.166.166 0 0 1 .202.032v.066c-.412 8.885-3.99 14.527-7.608 19.543l-2.416 2.59s3.383 0 5.307-.744c7.024-2.099 12.324-6.725 16.181-14.103a60.185 60.185 0 0 0 2.549-5.82c.065-.165.673-.47.616.384-.021.252-.038.533-.059.827 0 .173 0 .35-.033.528-.1 1.24-.392 3.859-.392 3.859l2.169-1.162c5.229-3.304 9.26-9.97 12.318-20.343 1.272-4.321 2.205-8.613 3.027-12.392.983-4.545 1.83-8.44 2.801-9.952 1.524-2.37 3.85-3.973 6.101-5.53.306-.211.616-.414.917-.637 2.83-1.986 5.643-4.279 6.263-8.555v-.095c.45-3.189.07-4.002-.364-4.373zm-7.283 103.727h-10.327V97.92h9.315c3.56 0 6.952.67 6.902 4.66 0 2.813-1.747 3.59-3.589 3.886 2.615.224 4.188 1.892 4.188 4.586.017 4.035-3.523 4.858-6.489 4.858zm-.772-10.14c3.565 0 4.362-1.372 4.362-3.115 0-2.619-1.595-3.214-4.362-3.214h-7.402v6.328zm.099 1.52h-7.501v7.1h7.823c2.194 0 4.511-.723 4.511-3.486 0-3.19-2.665-3.615-4.833-3.615zm-31.497-9.37h8.125c6.828 0 10.24 3.764 10.19 8.994.05 5.436-3.716 8.997-9.591 8.997H87.98zm2.242 1.596v14.825h6.197c5.432 0 7.501-3.665 7.501-7.477 0-4.309-2.59-7.348-7.5-7.348zm-10.838 5.357v-2.095h3.404v13.132h-3.392v-2.114c-.896 1.52-2.739 2.391-4.982 2.391-4.684 0-7.303-3.305-7.303-7.105 0-3.664 2.479-6.609 6.804-6.609 2.454.029 4.498.855 5.469 2.4zm-8.675 4.387c0 2.416 1.52 4.485 4.462 4.485 2.841 0 4.386-2.02 4.386-4.411 0-2.392-1.599-4.436-4.544-4.436-2.828 0-4.3 2.04-4.3 4.362zm-10.013-9.947a1.722 1.722 0 0 1 1.818-1.768 1.788 1.788 0 0 1 1.847 1.821 1.714 1.714 0 0 1-1.847 1.744 1.743 1.743 0 0 1-1.818-1.797zm.15 3.465h3.39v9.596c0 .595.125 1.02.62 1.02a3.657 3.657 0 0 0 .648-.073l.525 2.478a5.931 5.931 0 0 1-2.242.414c-1.421 0-2.942-.414-2.942-3.64zM52.15 115.91h-3.386v-13.132h3.386v2.942a5.197 5.197 0 0 1 4.735-3.218 6.13 6.13 0 0 1 2.119.347l-.723 2.479a7.435 7.435 0 0 0-1.793-.249c-2.445 0-4.338 1.843-4.338 4.545zm-11.037-11.037v-2.095h3.392v13.132h-3.392v-2.114c-.896 1.52-2.738 2.391-4.982 2.391-4.688 0-7.303-3.305-7.303-7.105 0-3.664 2.479-6.609 6.804-6.609 2.466.029 4.51.855 5.481 2.4zm-8.675 4.387c0 2.416 1.52 4.485 4.462 4.485 2.838 0 4.383-2.02 4.383-4.411 0-2.391-1.595-4.436-4.544-4.436-2.826 0-4.296 2.04-4.296 4.362zm-9.24-11.34 4.651 17.99h-3.51L21.24 102.95 15.4 115.91h-2.965l-5.808-12.883-3.19 12.883H0l4.61-17.99h3.04l6.28 13.93 6.253-13.93z" />
|
||||
</svg>
|
||||
@@ -517,8 +509,7 @@
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
@if (data_get($service, 'logo'))
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
<img class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100"
|
||||
src="{{ asset(data_get($service, 'logo')) }}">
|
||||
@endif
|
||||
</x-slot:logo>
|
||||
@@ -540,19 +531,9 @@
|
||||
</x-slot>
|
||||
<x-slot:logo>
|
||||
@if (file_exists(public_path(data_get($service, 'logo'))))
|
||||
<img class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 bg-neutral-300 dark:bg-transparent hover:bg-neutral-800"
|
||||
<img class="w-[4.5rem] aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 bg-neutral-300 dark:bg-transparent hover:bg-neutral-800"
|
||||
src="{{ asset(data_get($service, 'logo')) }}">
|
||||
@else
|
||||
<div
|
||||
class="w-[4.5rem]
|
||||
aspect-square h-[4.5rem] p-2 transition-all duration-200 opacity-30 grayscale group-hover:grayscale-0 group-hover:opacity-100 dark:text-warning text-coollabs">
|
||||
<svg width="50" height="50" viewBox="0 0 17 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor"
|
||||
d="M11.403 18.751v4.499c-.01.41-.34.74-.748.75H6.159a.768.768 0 0 1-.749-.748v-4.5c.01-.41.34-.739.749-.749h4.5c.41.01.74.34.75.749v.001zm5.923-11.247a6.306 6.306 0 0 1-.962 3.354l.015-.026a5.462 5.462 0 0 1-1.021 1.108l-.01.008c-.321.282-.672.55-1.042.794l-.036.022q-.413.253-1.144.665a3.71 3.71 0 0 0-1.275 1.204l-.009.014a2.535 2.535 0 0 0-.515 1.243l-.001.012a.978.978 0 0 1-.226.611l.001-.002a.652.652 0 0 1-.524.29h-4.5a.563.563 0 0 1-.479-.343l-.001-.004a1.394 1.394 0 0 1-.197-.702v-.845a4.356 4.356 0 0 1 1.219-2.935l-.001.001A7.945 7.945 0 0 1 9.251 9.96l.048-.02a4.627 4.627 0 0 0 1.574-1.049l.001-.001a2.094 2.094 0 0 0 .469-1.429v.005a1.695 1.695 0 0 0-.863-1.382l-.009-.004a3.436 3.436 0 0 0-2.018-.599h.003a3.53 3.53 0 0 0-2.039.552l.014-.009A12.825 12.825 0 0 0 4.45 8.149l-.025.035a.73.73 0 0 1-.581.3a.897.897 0 0 1-.472-.152l.003.002L.301 5.991a.732.732 0 0 1-.29-.464L.01 5.523a.747.747 0 0 1 .105-.527l-.002.003C1.77 2 4.912.003 8.522.003c.103 0 .205.002.307.005h-.015a8.362 8.362 0 0 1 3.074.602l-.057-.02a10.2 10.2 0 0 1 2.757 1.571l-.02-.016a7.838 7.838 0 0 1 1.966 2.349l.02.041c.483.857.768 1.881.769 2.971z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@endif
|
||||
</x-slot:logo>
|
||||
<x-slot:documentation>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($project, 'name')->limit(10) }} > New | Coolify
|
||||
</x-slot>
|
||||
@if ($type === 'public')
|
||||
<livewire:project.new.public-git-repository :type="$type" />
|
||||
@elseif ($type === 'private-gh-app')
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($project, 'name')->limit(10) }} > Resources | Coolify
|
||||
</x-slot>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center gap-2">
|
||||
<h1>Resources</h1>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'service-stack' }" x-init="$wire.check_status" wire:poll.5000ms="check_status">
|
||||
<x-slot:title>
|
||||
{{ data_get_str($service, 'name')->limit(10) }} > Configuration | Coolify
|
||||
</x-slot>
|
||||
<livewire:project.service.navbar :service="$service" :parameters="$parameters" :query="$query" />
|
||||
<div class="flex flex-col h-full gap-8 pt-6 sm:flex-row">
|
||||
<div class="flex flex-col items-start gap-2 min-w-fit">
|
||||
|
||||
@@ -19,12 +19,18 @@
|
||||
</div>
|
||||
<div class="w-full">
|
||||
@isset($serviceApplication)
|
||||
<x-slot:title>
|
||||
{{ data_get_str($service, 'name')->limit(10) }} >
|
||||
{{ data_get_str($serviceApplication, 'name')->limit(10) }} | Coolify
|
||||
</x-slot>
|
||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||
<livewire:project.service.service-application-view :application="$serviceApplication" />
|
||||
</div>
|
||||
|
||||
@endisset
|
||||
@isset($serviceDatabase)
|
||||
<x-slot:title>
|
||||
{{ data_get_str($service, 'name')->limit(10) }} > {{ data_get_str($serviceDatabase, 'name')->limit(10) }} | Coolify
|
||||
</x-slot>
|
||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||
<livewire:project.service.database :database="$serviceDatabase" />
|
||||
</div>
|
||||
|
||||
@@ -63,9 +63,11 @@
|
||||
@else
|
||||
<x-forms.checkbox instantSave id="env.is_build_time" label="Build Variable?" />
|
||||
<x-forms.checkbox instantSave id="env.is_multiline" label="Is Multiline?" />
|
||||
<x-forms.checkbox instantSave id="env.is_literal"
|
||||
helper="This means that when you use $VARIABLES in a value, it should be interpreted as the actual characters '$VARIABLES' and not as the value of a variable named VARIABLE.<br><br>Useful if you have $ sign in your value and there are some characters after it, but you would not like to interpolate it form another value. In this case, you should set this to true."
|
||||
label="Is Literal?" />
|
||||
@if (!data_get($env, 'is_multiline'))
|
||||
<x-forms.checkbox instantSave id="env.is_literal"
|
||||
helper="This means that when you use $VARIABLES in a value, it should be interpreted as the actual characters '$VARIABLES' and not as the value of a variable named VARIABLE.<br><br>Useful if you have $ sign in your value and there are some characters after it, but you would not like to interpolate it form another value. In this case, you should set this to true."
|
||||
label="Is Literal?" />
|
||||
@endif
|
||||
@endif
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($resource, 'name')->limit(10) }} > Commands | Coolify
|
||||
</x-slot>
|
||||
<livewire:project.shared.configuration-checker :resource="$resource" />
|
||||
@if ($type === 'application')
|
||||
<h1>Execute Command</h1>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
}
|
||||
}">
|
||||
<div class="flex items-center gap-2 ">
|
||||
@if ($resource?->type() === 'application')
|
||||
@if ($resource?->type() === 'application' || str($resource?->type())->startsWith('standalone'))
|
||||
<h4>{{ $container }}</h4>
|
||||
@else
|
||||
<h3>{{ str($container)->beforeLast('-')->headline() }}</h3>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($resource, 'name')->limit(10) }} > Logs | Coolify
|
||||
</x-slot>
|
||||
<livewire:project.shared.configuration-checker :resource="$resource" />
|
||||
@if ($type === 'application')
|
||||
<h1>Logs</h1>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($resource, 'name')->limit(10) }} > Scheduled Tasks | Coolify
|
||||
</x-slot>
|
||||
@if ($type === 'application')
|
||||
<h1>Scheduled Task</h1>
|
||||
<livewire:project.application.heading :application="$resource" />
|
||||
|
||||
@@ -18,10 +18,9 @@
|
||||
Update
|
||||
</x-forms.button>
|
||||
@else
|
||||
<x-forms.input id="storage.name" required readonly
|
||||
helper="Warning: Changing the volume name after the initial start could cause problems. Only use it when you know what are you doing." />
|
||||
<x-forms.input id="storage.host_path" helper="Directory on the host system." readonly />
|
||||
<x-forms.input id="storage.mount_path" helper="Directory inside the container." required readonly />
|
||||
<x-forms.input id="storage.name" required readonly />
|
||||
<x-forms.input id="storage.host_path" readonly />
|
||||
<x-forms.input id="storage.mount_path" required readonly />
|
||||
@endif
|
||||
@else
|
||||
@if ($isFirst)
|
||||
@@ -31,8 +30,8 @@
|
||||
required />
|
||||
@else
|
||||
<x-forms.input id="storage.name" required />
|
||||
<x-forms.input id="storage.host_path" helper="Directory on the host system." />
|
||||
<x-forms.input id="storage.mount_path" helper="Directory inside the container." required />
|
||||
<x-forms.input id="storage.host_path" />
|
||||
<x-forms.input id="storage.mount_path" required />
|
||||
@endif
|
||||
<div class="flex gap-2">
|
||||
<x-forms.button type="submit">
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($project, 'name')->limit(10) }} > Environments | Coolify
|
||||
</x-slot>
|
||||
<div class="flex items-center gap-2">
|
||||
<h1>Environments</h1>
|
||||
<x-modal-input buttonTitle="+ Add" title="New Environment">
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
API Tokens | Coolify
|
||||
</x-slot>
|
||||
<x-security.navbar />
|
||||
<div class="flex gap-2">
|
||||
<h2 class="pb-4">API Tokens</h2>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<div x-init="$wire.loadPublicKey()">
|
||||
<x-slot:title>
|
||||
Private Key | Coolify
|
||||
</x-slot>
|
||||
<x-security.navbar />
|
||||
<div x-data="{ showPrivateKey: false }">
|
||||
<form class="flex flex-col gap-2" wire:submit='changePrivateKey'>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user