Merge pull request #4941 from coollabsio/next

v4.0.0-beta.390
This commit is contained in:
Andras Bacsai
2025-01-28 13:48:29 +01:00
committed by GitHub
33 changed files with 370 additions and 250 deletions

View File

@@ -28,13 +28,13 @@ class StartProxy
$docker_compose_yml_base64 = base64_encode($configuration);
$server->proxy->last_applied_settings = str($docker_compose_yml_base64)->pipe('md5')->value();
$server->save();
if ($server->isSwarm()) {
if ($server->isSwarmManager()) {
$commands = $commands->merge([
"mkdir -p $proxy_path/dynamic",
"cd $proxy_path",
"echo 'Creating required Docker Compose file.'",
"echo 'Starting coolify-proxy.'",
'docker stack deploy -c docker-compose.yml coolify-proxy',
'docker stack deploy --detach=true -c docker-compose.yml coolify-proxy',
"echo 'Successfully started coolify-proxy.'",
]);
} else {

View File

@@ -57,6 +57,14 @@ class CleanupDatabase extends Command
$application_deployment_queues->delete();
}
// Cleanup scheduled_task_executions table
$scheduled_task_executions = DB::table('scheduled_task_executions')->where('created_at', '<', now()->subDays($keep_days))->orderBy('created_at', 'desc');
$count = $scheduled_task_executions->count();
echo "Delete $count entries from scheduled_task_executions.\n";
if ($this->option('yes')) {
$scheduled_task_executions->delete();
}
// Cleanup webhooks table
$webhooks = DB::table('webhooks')->where('created_at', '<', now()->subDays($keep_days));
$count = $webhooks->count();

View File

@@ -923,8 +923,11 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
$envs->push("COOLIFY_BRANCH=\"{$local_branch}\"");
}
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_RESOURCE_UUID')->isEmpty()) {
$envs->push("COOLIFY_RESOURCE_UUID={$this->application->uuid}");
}
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
$envs->push("COOLIFY_CONTAINER_NAME=\"{$this->container_name}\"");
$envs->push("COOLIFY_CONTAINER_NAME={$this->container_name}");
}
}
@@ -982,8 +985,11 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
if ($this->application->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
$envs->push("COOLIFY_BRANCH=\"{$local_branch}\"");
}
if ($this->application->environment_variables->where('key', 'COOLIFY_RESOURCE_UUID')->isEmpty()) {
$envs->push("COOLIFY_RESOURCE_UUID={$this->application->uuid}");
}
if ($this->application->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
$envs->push("COOLIFY_CONTAINER_NAME=\"{$this->container_name}\"");
$envs->push("COOLIFY_CONTAINER_NAME={$this->container_name}");
}
}
@@ -1145,7 +1151,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$this->application_deployment_queue->addLogEntry('Rolling update started.');
$this->execute_remote_command(
[
executeInDocker($this->deployment_uuid, "docker stack deploy --with-registry-auth -c {$this->workdir}{$this->docker_compose_location} {$this->application->uuid}"),
executeInDocker($this->deployment_uuid, "docker stack deploy --detach=true --with-registry-auth -c {$this->workdir}{$this->docker_compose_location} {$this->application->uuid}"),
],
);
$this->application_deployment_queue->addLogEntry('Rolling update completed.');

View File

@@ -495,12 +495,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
} else {
$commands[] = "docker run -d --network {$network} --name backup-of-{$this->backup->uuid} --rm -v $this->backup_location:$this->backup_location:ro {$fullImageName}";
}
if ($this->s3->isHetzner()) {
$endpointWithoutBucket = 'https://'.str($endpoint)->after('https://')->after('.')->value();
$commands[] = "docker exec backup-of-{$this->backup->uuid} mc alias set --path=off --api=S3v4 temporary {$endpointWithoutBucket} $key $secret";
} else {
$commands[] = "docker exec backup-of-{$this->backup->uuid} mc config host add temporary {$endpoint} $key $secret";
}
$commands[] = "docker exec backup-of-{$this->backup->uuid} mc cp $this->backup_location temporary/$bucket{$this->backup_dir}/";
instant_remote_process($commands, $this->server);

View File

@@ -124,9 +124,20 @@ class Advanced extends Component
}
}
private function resetDefaultLabels()
{
if ($this->application->settings->is_container_label_readonly_enabled === false) {
return;
}
$customLabels = str(implode('|coolify|', generateLabelsApplication($this->application)))->replace('|coolify|', "\n");
$this->application->custom_labels = base64_encode($customLabels);
$this->application->save();
}
public function instantSave()
{
try {
$reset = false;
if ($this->isLogDrainEnabled) {
if (! $this->application->destination->server->isLogDrainEnabled()) {
$this->isLogDrainEnabled = false;
@@ -140,7 +151,7 @@ class Advanced extends Component
$this->application->isGzipEnabled() !== $this->isGzipEnabled ||
$this->application->isStripprefixEnabled() !== $this->isStripprefixEnabled
) {
$this->dispatch('resetDefaultLabels', false);
$reset = true;
}
if ($this->application->settings->is_raw_compose_deployment_enabled) {
@@ -149,6 +160,11 @@ class Advanced extends Component
$this->application->parse();
}
$this->syncData(true);
if ($reset) {
$this->resetDefaultLabels();
}
$this->dispatch('success', 'Settings saved.');
$this->dispatch('configurationChanged');
} catch (\Throwable $e) {

View File

@@ -187,6 +187,9 @@ class General extends Component
});
}
}
if ($this->application->settings->is_container_label_readonly_enabled) {
$this->resetDefaultLabels(false);
}
}
public function loadComposeFile($isInit = false)

View File

@@ -221,7 +221,7 @@ EOD;
case \App\Models\StandaloneMongodb::class:
$restoreCommand = $this->mongodbRestoreCommand;
if ($this->dumpAll === false) {
$restoreCommand .= " {$tmpPath}";
$restoreCommand .= "{$tmpPath}";
}
break;
}

View File

@@ -77,6 +77,11 @@ class Show extends Component
{
if ($toModel) {
$this->validate();
$isValid = validate_cron_expression($this->frequency);
if (! $isValid) {
$this->frequency = $this->task->frequency;
throw new \Exception('Invalid Cron / Human expression.');
}
$this->task->enabled = $this->isEnabled;
$this->task->name = str($this->name)->trim()->value();
$this->task->command = str($this->command)->trim()->value();
@@ -109,7 +114,7 @@ class Show extends Component
$this->syncData(true);
$this->dispatch('success', 'Scheduled task updated.');
} catch (\Exception $e) {
return handleError($e);
return handleError($e, $this);
}
}

View File

@@ -41,7 +41,7 @@ class ConfigureCloudflareTunnels extends Component
$server->ip = $this->ssh_domain;
$server->save();
$server->settings->save();
$this->dispatch('warning', 'Cloudflare Tunnels configuration started.');
$this->dispatch('info', 'Cloudflare Tunnels configuration started.');
} catch (\Throwable $e) {
return handleError($e, $this);
}

View File

@@ -3,6 +3,7 @@
namespace App\Livewire\Storage;
use App\Models\S3Storage;
use Illuminate\Support\Uri;
use Livewire\Component;
class Create extends Component
@@ -45,15 +46,24 @@ class Create extends Component
public function updatedEndpoint($value)
{
if (! str($value)->startsWith('https://') && ! str($value)->startsWith('http://')) {
$this->endpoint = 'https://'.$value;
$value = $this->endpoint;
try {
if (empty($value)) {
return;
}
if (str($value)->contains('digitaloceanspaces.com')) {
$uri = Uri::of($value);
$host = $uri->host();
if (str($value)->contains('your-objectstorage.com') && ! isset($this->bucket)) {
$this->bucket = str($value)->after('//')->before('.');
} elseif (str($value)->contains('your-objectstorage.com')) {
$this->bucket = $this->bucket ?: str($value)->after('//')->before('.');
if (preg_match('/^(.+)\.([^.]+\.digitaloceanspaces\.com)$/', $host, $matches)) {
$host = $matches[2];
$value = "https://{$host}";
}
}
} finally {
if (! str($value)->startsWith('https://') && ! str($value)->startsWith('http://')) {
$value = 'https://'.$value;
}
$this->endpoint = $value;
}
}

View File

@@ -40,16 +40,6 @@ class S3Storage extends BaseModel
return "{$this->endpoint}/{$this->bucket}";
}
public function isHetzner()
{
return str($this->endpoint)->contains('your-objectstorage.com');
}
public function isDigitalOcean()
{
return str($this->endpoint)->contains('digitaloceanspaces.com');
}
public function testConnection(bool $shouldSave = false)
{
try {

View File

@@ -78,7 +78,7 @@ class ServiceDatabase extends BaseModel
public function databaseType()
{
$image = str($this->image)->before(':');
if ($image->value() === 'postgres') {
if ($image->contains('postgres') || $image->contains('postgis')) {
$image = 'postgresql';
}

View File

@@ -208,7 +208,6 @@ function deleteBackupsS3(string|array|null $filenames, S3Storage $s3): void
'bucket' => $s3->bucket,
'endpoint' => $s3->endpoint,
'use_path_style_endpoint' => true,
'bucket_endpoint' => $s3->isHetzner() || $s3->isDigitalOcean(),
'aws_url' => $s3->awsUrl(),
]);

View File

@@ -187,7 +187,6 @@ function generate_default_proxy_configuration(Server $server)
'--entryPoints.https.http2.maxConcurrentStreams=50',
'--entrypoints.https.http3',
'--providers.file.directory=/traefik/dynamic/',
'--providers.docker.exposedbydefault=false',
'--providers.file.watch=true',
'--certificatesresolvers.letsencrypt.acme.httpchallenge=true',
'--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http',
@@ -212,7 +211,8 @@ function generate_default_proxy_configuration(Server $server)
data_forget($config, 'services.traefik.restart');
data_forget($config, 'services.traefik.labels');
$config['services']['traefik']['command'][] = '--providers.docker.swarmMode=true';
$config['services']['traefik']['command'][] = '--providers.swarm.endpoint=unix:///var/run/docker.sock';
$config['services']['traefik']['command'][] = '--providers.swarm.exposedbydefault=false';
$config['services']['traefik']['deploy'] = [
'labels' => $labels,
'placement' => [
@@ -223,6 +223,7 @@ function generate_default_proxy_configuration(Server $server)
];
} else {
$config['services']['traefik']['command'][] = '--providers.docker=true';
$config['services']['traefik']['command'][] = '--providers.docker.exposedbydefault=false';
}
} elseif ($proxy_type === 'CADDY') {
$config = [

View File

@@ -4,8 +4,6 @@ use App\Models\S3Storage;
function set_s3_target(S3Storage $s3)
{
$is_digital_ocean = false;
config()->set('filesystems.disks.custom-s3', [
'driver' => 's3',
'region' => $s3['region'],
@@ -14,7 +12,6 @@ function set_s3_target(S3Storage $s3)
'bucket' => $s3['bucket'],
'endpoint' => $s3['endpoint'],
'use_path_style_endpoint' => true,
'bucket_endpoint' => $s3->isHetzner() || $s3->isDigitalOcean(),
'aws_url' => $s3->awsUrl(),
]);
}

View File

@@ -2115,6 +2115,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$parsedServiceVariables->put($key, $value);
}
}
$parsedServiceVariables->put('COOLIFY_RESOURCE_UUID', "{$resource->uuid}");
$parsedServiceVariables->put('COOLIFY_CONTAINER_NAME', "$serviceName-{$resource->uuid}");
// TODO: move this in a shared function
@@ -3606,9 +3607,14 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
}
}
// Add COOLIFY_RESOURCE_UUID to environment
if ($resource->environment_variables->where('key', 'COOLIFY_RESOURCE_UUID')->isEmpty()) {
$coolifyEnvironments->put('COOLIFY_RESOURCE_UUID', "{$resource->uuid}");
}
// Add COOLIFY_CONTAINER_NAME to environment
if ($resource->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
$coolifyEnvironments->put('COOLIFY_CONTAINER_NAME', "\"{$containerName}\"");
$coolifyEnvironments->put('COOLIFY_CONTAINER_NAME', "{$containerName}");
}
if ($isApplication) {

View File

@@ -2,7 +2,7 @@
return [
'coolify' => [
'version' => '4.0.0-beta.389',
'version' => '4.0.0-beta.390',
'helper_version' => '1.0.6',
'realtime_version' => '1.0.5',
'self_hosted' => env('SELF_HOSTED', true),

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -15,6 +15,8 @@
@endif
<x-forms.checkbox helper="Disable Docker build cache on every deployment." instantSave id="disableBuildCache"
label="Disable Build Cache" />
@if ($application->settings->is_container_label_readonly_enabled)
<x-forms.checkbox
helper="Your application will be available only on https if your domain starts with https://..."
instantSave id="isForceHttpsEnabled" label="Force Https" />
@@ -23,6 +25,17 @@
instantSave id="isGzipEnabled" />
<x-forms.checkbox helper="Strip Prefix is used to remove prefixes from paths. Like /api/ to /api."
instantSave id="isStripprefixEnabled" label="Strip Prefixes" />
@else
<x-forms.checkbox disabled
helper="Readonly labels are disabled. You need to set the labels in the labels section." instantSave
id="isForceHttpsEnabled" label="Force Https" />
<x-forms.checkbox label="Enable Gzip Compression" disabled
helper="Readonly labels are disabled. You need to set the labels in the labels section." instantSave
id="isGzipEnabled" />
<x-forms.checkbox
helper="Readonly labels are disabled. You need to set the labels in the labels section." disabled
instantSave id="isStripprefixEnabled" label="Strip Prefixes" />
@endif
@if ($application->build_pack === 'dockercompose')
<h3>Docker Compose</h3>
<x-forms.checkbox instantSave id="isRawComposeDeploymentEnabled" label="Raw Compose Deployment"

View File

@@ -107,12 +107,14 @@
class="text-gray-600 dark:text-gray-400 truncate max-w-md underline">
{{ Str::before($deployment->commitMessage(), "\n") }}
</a>
@if ($deployment->commitMessage() !== Str::before($deployment->commitMessage(), "\n"))
<button @click="expanded = !expanded"
class="text-gray-600 dark:text-gray-400 flex items-center gap-1">
<svg x-bind:class="{'rotate-180': expanded}" class="w-4 h-4 transition-transform" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m6 9l6 6l6-6"/>
</svg>
</button>
@endif
<span class="bg-gray-200/70 dark:bg-gray-600/20 px-2 py-0.5 rounded-md text-xs text-gray-800 dark:text-gray-100 border border-gray-400/30">
@if (data_get($deployment, 'is_webhook'))
Webhook

View File

@@ -71,27 +71,50 @@
@endif
@if ($application->build_pack !== 'dockercompose')
<div class="flex items-end gap-2">
<x-forms.input placeholder="https://coolify.io" wire:model.blur="application.fqdn" label="Domains"
@if ($application->settings->is_container_label_readonly_enabled == false)
<x-forms.input placeholder="https://coolify.io" wire:model.blur="application.fqdn"
label="Domains" readonly
helper="Readonly labels are disabled. You can set the domains in the labels section." />
@else
<x-forms.input placeholder="https://coolify.io" wire:model.blur="application.fqdn"
label="Domains"
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io,https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. " />
<x-forms.button wire:click="getWildcardDomain">Generate Domain
</x-forms.button>
@endif
</div>
<div class="flex items-end gap-2">
@if ($application->settings->is_container_label_readonly_enabled == false)
@if ($application->redirect === 'both')
<x-forms.input label="Direction" value="Allow www & non-www." readonly
helper="Readonly labels are disabled. You can set the direction in the labels section." />
@elseif ($application->redirect === 'www')
<x-forms.input label="Direction" value="Redirect to www." readonly
helper="Readonly labels are disabled. You can set the direction in the labels section." />
@elseif ($application->redirect === 'non-www')
<x-forms.input label="Direction" value="Redirect to non-www." readonly
helper="Readonly labels are disabled. You can set the direction in the labels section." />
@endif
@else
<x-forms.select label="Direction" id="application.redirect" required
helper="You must need to add www and non-www as an A DNS record. Make sure the www domain is added under Domains.">
<option value="both">Allow www & non-www.</option>
<option value="www">Redirect to www.</option>
<option value="non-www">Redirect to non-www.</option>
</x-forms.select>
@if ($application->settings->is_container_label_readonly_enabled)
<x-modal-confirmation title="Confirm Redirection Setting?" buttonTitle="Set Direction"
submitAction="setRedirect" :actions="['All traffic will be redirected to the selected direction.']" confirmationText="{{ $application->fqdn . '/' }}"
submitAction="setRedirect" :actions="['All traffic will be redirected to the selected direction.']"
confirmationText="{{ $application->fqdn . '/' }}"
confirmationLabel="Please confirm the execution of the action by entering the Application URL below"
shortConfirmationLabel="Application URL" :confirmWithPassword="false" step2ButtonText="Set Direction">
shortConfirmationLabel="Application URL" :confirmWithPassword="false"
step2ButtonText="Set Direction">
<x-slot:customButton>
<div class="w-[7.2rem]">Set Direction</div>
</x-slot:customButton>
</x-modal-confirmation>
@endif
@endif
</div>
@endif
@@ -285,7 +308,7 @@
helper="By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$.<br><br>If you want to use env variables inside the labels, turn this off."
id="application.settings.is_container_label_escape_enabled" instantSave></x-forms.checkbox>
{{-- <x-forms.checkbox label="Readonly labels"
helper="Labels are readonly by default. Readonly means that edits you do to the labels could be lost and Coolify will autogenrate the labels for you. If you want to edit the labels directly, disable this option. <br><br>Be careful, it could break the proxy configuration after you restart the container as Coolify will now NOT autogenrate the labels for you (ofc you can alway reset the labels to the coolify defaults manually)."
helper="Labels are readonly by default. Readonly means that edits you do to the labels could be lost and Coolify will autogenrate the labels for you. If you want to edit the labels directly, disable this option. <br><br>Be careful, it could break the proxy configuration after you restart the container as Coolify will now NOT autogenrate the labels for you (ofc you can always reset the labels to the coolify defaults manually)."
id="application.settings.is_container_label_readonly_enabled" instantSave></x-forms.checkbox> --}}
</div>
@endif
@@ -299,10 +322,16 @@
@if ($application->settings->is_static || $application->build_pack === 'static')
<x-forms.input id="application.ports_exposes" label="Ports Exposes" readonly />
@else
<x-forms.input placeholder="3000,3001" id="application.ports_exposes" label="Ports Exposes"
required
@if ($application->settings->is_container_label_readonly_enabled === false)
<x-forms.input placeholder="3000,3001" id="application.ports_exposes"
label="Ports Exposes" readonly
helper="Readonly labels are disabled. You can set the ports manually in the labels section." />
@else
<x-forms.input placeholder="3000,3001" id="application.ports_exposes"
label="Ports Exposes" required
helper="A comma separated list of ports your application uses. The first port will be used as default healthcheck port if nothing defined in the Healthcheck menu. Be sure to set this correctly." />
@endif
@endif
@if (!$application->destination->server->isSwarm())
<x-forms.input placeholder="3000:3000" id="application.ports_mappings" label="Ports Mappings"
helper="A comma separated list of ports you would like to map to the host system. Useful when you do not want to use domains.<br><br><span class='inline-block font-bold dark:text-warning'>Example:</span><br>3000:3000,3002:3002<br><br>Rolling update is not supported if you have a port mapped to the host." />
@@ -318,7 +347,7 @@
@endif
<div class="w-96">
<x-forms.checkbox label="Readonly labels"
helper="Labels are readonly by default. Readonly means that edits you do to the labels could be lost and Coolify will autogenrate the labels for you. If you want to edit the labels directly, disable this option. <br><br>Be careful, it could break the proxy configuration after you restart the container as Coolify will now NOT autogenrate the labels for you (ofc you can alway reset the labels to the coolify defaults manually)."
helper="Labels are readonly by default. Readonly means that edits you do to the labels could be lost and Coolify will autogenrate the labels for you. If you want to edit the labels directly, disable this option. <br><br>Be careful, it could break the proxy configuration after you restart the container as Coolify will now NOT autogenrate the labels for you (ofc you can always reset the labels to the coolify defaults manually)."
id="application.settings.is_container_label_readonly_enabled" instantSave></x-forms.checkbox>
<x-forms.checkbox label="Escape special characters in labels?"
helper="By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$.<br><br>If you want to use env variables inside the labels, turn this off."

View File

@@ -34,6 +34,7 @@
</a>
@endif
</nav>
@if ($database->destination->server->isFunctional())
<div class="flex flex-wrap gap-2 items-center">
@if (!str($database->status)->startsWith('exited'))
<x-modal-confirmation title="Confirm Database Restart?" buttonTitle="Restart" submitAction="restart"
@@ -43,7 +44,8 @@
]" :confirmWithText="false" :confirmWithPassword="false" step2ButtonText="Restart Database"
:dispatchEvent="true" dispatchEventType="restartEvent">
<x-slot:button-title>
<svg class="w-5 h-5 dark:text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<svg class="w-5 h-5 dark:text-warning" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path d="M19.933 13.041a8 8 0 1 1-9.925-8.788c3.899-1 7.935 1.007 9.425 4.747" />
@@ -58,8 +60,9 @@
'This database will be stopped.',
'If the database is currently in use data could be lost.',
'All non-persistent data of this database (containers, networks, unused images) will be deleted (don\'t worry, no data is lost and you can start the database again).',
]" :confirmWithText="false" :confirmWithPassword="false" step1ButtonText="Continue"
step2ButtonText="Stop Database" :dispatchEvent="true" dispatchEventType="stopEvent">
]" :confirmWithText="false" :confirmWithPassword="false"
step1ButtonText="Continue" step2ButtonText="Stop Database" :dispatchEvent="true"
dispatchEventType="stopEvent">
<x-slot:button-title>
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-error" viewBox="0 0 24 24"
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
@@ -67,7 +70,8 @@
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M6 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z">
</path>
<path d="M14 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z">
<path
d="M14 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z">
</path>
</svg>
Stop
@@ -101,5 +105,8 @@
</script>
@endscript
</div>
@else
<div class="text-error">Underlying server is not functional.</div>
@endif
</div>
</nav>

View File

@@ -40,7 +40,7 @@
@if ($unsupported)
<div>Database restore is not supported.</div>
@else
<div class="mt-2 mb-4 rounded alert-error">
<div class="pt-2 rounded alert-error">
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"

View File

@@ -14,31 +14,18 @@
</a>
@endif
@if ($applications->count() > 0)
<x-modal-confirmation
title="Confirm GitHub App Deletion?"
isErrorButton
buttonTitle="Delete"
submitAction="delete"
:actions="['The selected GitHub App will be permanently deleted.']"
confirmationText="{{ data_get($github_app, 'name') }}"
<x-modal-confirmation title="Confirm GitHub App Deletion?" isErrorButton buttonTitle="Delete"
submitAction="delete" :actions="['The selected GitHub App will be permanently deleted.']" confirmationText="{{ data_get($github_app, 'name') }}"
confirmationLabel="Please confirm the execution of the actions by entering the GitHub App Name below"
shortConfirmationLabel="GitHub App Name"
:confirmWithPassword="false"
step2ButtonText="Permanently Delete"
/>
shortConfirmationLabel="GitHub App Name" :confirmWithPassword="false"
step2ButtonText="Permanently Delete" />
@else
<x-modal-confirmation
title="Confirm GitHub App Deletion?"
isErrorButton
buttonTitle="Delete"
submitAction="delete"
:actions="['The selected GitHub App will be permanently deleted.']"
<x-modal-confirmation title="Confirm GitHub App Deletion?" isErrorButton buttonTitle="Delete"
submitAction="delete" :actions="['The selected GitHub App will be permanently deleted.']"
confirmationLabel="Please confirm the execution of the actions by entering the GitHub App Name below"
shortConfirmationLabel="GitHub App Name"
confirmationText="{{ data_get($github_app, 'name') }}"
:confirmWithPassword="false"
step2ButtonText="Permanently Delete"
/>
confirmationText="{{ data_get($github_app, 'name') }}" :confirmWithPassword="false"
step2ButtonText="Permanently Delete" />
@endif
</div>
</div>
@@ -135,7 +122,7 @@
<div class="flex gap-2">
<h2>Resources</h2>
</div>
<div class="pb-4 title">Here you can find all resources that are used by this source.</div>
<div class="pb-4 title">Here you can find all resources that are using this source.</div>
</div>
<div class="flex flex-col">
<div class="flex flex-col">
@@ -166,8 +153,7 @@
{{ data_get($resource, 'environment.name') }}
</td>
<td class="px-5 py-4 text-sm whitespace-nowrap"><a
class=""
wire:navigate
class="" wire:navigate
href="{{ $resource->link() }}">{{ $resource->name }}
<x-internal-link /></a>
</td>
@@ -190,21 +176,13 @@
<div class="flex items-center gap-2 pb-4">
<h1>GitHub App</h1>
<div class="flex gap-2">
<x-modal-confirmation
title="Confirm GitHub App Deletion?"
isErrorButton
buttonTitle="Delete"
submitAction="delete"
:actions="['The selected GitHub App will be permanently deleted.']"
confirmationText="{{ data_get($github_app, 'name') }}"
<x-modal-confirmation title="Confirm GitHub App Deletion?" isErrorButton buttonTitle="Delete"
submitAction="delete" :actions="['The selected GitHub App will be permanently deleted.']" confirmationText="{{ data_get($github_app, 'name') }}"
confirmationLabel="Please confirm the execution of the actions by entering the GitHub App Name below"
shortConfirmationLabel="GitHub App Name"
:confirmWithPassword="false"
step2ButtonText="Permanently Delete"
/>
shortConfirmationLabel="GitHub App Name" :confirmWithPassword="false" step2ButtonText="Permanently Delete" />
</div>
</div>
<div class="mb-10 rounded alert-error">
<div class=" pb-5 rounded alert-error">
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
@@ -213,15 +191,7 @@
<span>You must complete this step before you can use this source!</span>
</div>
<div class="flex flex-col">
<div class="flex gap-2">
<h2>Register a GitHub App</h2>
<x-forms.button class="bg-coollabs hover:bg-coollabs-100"
x-on:click.prevent="createGithubApp('{{ $webhook_endpoint }}','{{ $preview_deployment_permissions }}',{{ $administration }})">
Register Now
</x-forms.button>
</div>
<div>You need to register a GitHub App before using this source.</div>
<div class="py-10">
<div class="pb-10">
@if (!isCloud() || isDev())
<div class="flex items-end gap-2">
<x-forms.select wire:model.live='webhook_endpoint' label="Webhook Endpoint"
@@ -239,8 +209,22 @@
<option value="{{ config('app.url') }}">Use {{ config('app.url') }}</option>
@endif
</x-forms.select>
<x-forms.button isHighlighted
x-on:click.prevent="createGithubApp('{{ $webhook_endpoint }}','{{ $preview_deployment_permissions }}',{{ $administration }})">
Register Now
</x-forms.button>
</div>
@else
<div class="flex gap-2">
<h2>Register a GitHub App</h2>
<x-forms.button isHighlighted
x-on:click.prevent="createGithubApp('{{ $webhook_endpoint }}','{{ $preview_deployment_permissions }}',{{ $administration }})">
Register Now
</x-forms.button>
</div>
<div>You need to register a GitHub App before using this source.</div>
@endif
<div class="flex flex-col gap-2 pt-4 w-96">
<x-forms.checkbox disabled instantSave id="default_permissions" label="Mandatory"
helper="Contents: read<br>Metadata: read<br>Email: read" />

View File

@@ -23,7 +23,7 @@
<button @click="setActiveAccordion(id)"
class="flex items-center justify-between w-full px-1 py-2 text-left select-none hover:dark:text-white hover:bg-white/5"
type="button">
<h4>Advanced</h4>
<h4>Self-hosted / Enterprise GitHub</h4>
<svg class="w-4 h-4 duration-200 ease-out" :class="{ 'rotate-180': activeAccordion == id }"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
@@ -31,7 +31,6 @@
</svg>
</button>
<div x-show="activeAccordion==id" x-collapse x-cloak class="px-2">
<div class="py-2">Self-hosted / Enterprise GitHub details.</div>
<div class="flex flex-col gap-2 pt-0 opacity-70">
<div class="flex gap-2">
<x-forms.input id="html_url" label="HTML Url" required />

View File

@@ -116,7 +116,7 @@
}, 5000)
} else {
this.currentStatus =
"Waiting for Coolify to come back from dead..."
"Waiting for Coolify to come back from the dead..."
}
})
}, 2000);

View File

@@ -6,7 +6,7 @@
services:
authentik-server:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2024.8.0}
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2024.12.2}
restart: unless-stopped
command: server
environment:
@@ -35,7 +35,7 @@ services:
redis:
condition: service_healthy
authentik-worker:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2024.8.0}
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2024.12.2}
restart: unless-stopped
command: worker
environment:

View File

@@ -0,0 +1,24 @@
# documentation: https://docs.openwebui.com
# slogan: User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
# tags: ai,models,deployment,open-web-ui,integration
# logo: svgs/openwebui.svg
# port: 8080
services:
open-webui:
image: "ghcr.io/open-webui/open-webui:main"
volumes:
- "open-webui:/app/backend/data"
environment:
- SERVICE_FQDN_OPENWEBUI_8080
healthcheck:
test:
- CMD
- curl
- "-f"
- "http://127.0.0.1:8080"
interval: 5s
timeout: 30s
retries: 10
volumes:
open-webui: null

View File

@@ -11,9 +11,9 @@ services:
- SERVICE_FQDN_TRIGGER_3000
- LOGIN_ORIGIN=$SERVICE_FQDN_TRIGGER
- APP_ORIGIN=$SERVICE_FQDN_TRIGGER
- MAGIC_LINK_SECRET=$SERVICE_PASSWORD_64_MAGIC
- ENCRYPTION_KEY=$SERVICE_PASSWORD_64_ENCRYPTION
- SESSION_SECRET=$SERVICE_PASSWORD_64_SESSION
- MAGIC_LINK_SECRET=$SERVICE_PASSWORD_32_MAGIC
- ENCRYPTION_KEY=$SERVICE_PASSWORD_32_ENCRYPTION
- SESSION_SECRET=$SERVICE_PASSWORD_32_SESSION
- DATABASE_URL=${DATABASE_URL:?}
- DIRECT_URL=${DATABASE_URL:?}
- RUNTIME_PLATFORM=docker-compose

View File

@@ -14,9 +14,9 @@ x-common-env: &common-env
POSTGRES_USER: $SERVICE_USER_POSTGRES
POSTGRES_PASSWORD: $SERVICE_PASSWORD_POSTGRES
POSTGRES_DB: ${POSTGRES_DB:-trigger}
MAGIC_LINK_SECRET: $SERVICE_PASSWORD_64_MAGIC
SESSION_SECRET: $SERVICE_PASSWORD_64_SESSION
ENCRYPTION_KEY: $SERVICE_PASSWORD_64_ENCRYPTION
MAGIC_LINK_SECRET: $SERVICE_PASSWORD_32_MAGIC
SESSION_SECRET: $SERVICE_PASSWORD_32_SESSION
ENCRYPTION_KEY: $SERVICE_PASSWORD_32_ENCRYPTION
PROVIDER_SECRET: $SERVICE_PASSWORD_64_PROVIDER
COORDINATOR_SECRET: $SERVICE_PASSWORD_64_COORDINATOR
DATABASE_HOST: postgresql:5432
@@ -43,7 +43,7 @@ x-common-env: &common-env
LOGIN_ORIGIN: $SERVICE_FQDN_TRIGGER_3000
APP_ORIGIN: $SERVICE_FQDN_TRIGGER_3000
DEV_OTEL_EXPORTER_OTLP_ENDPOINT: $SERVICE_FQDN_TRIGGER_3000/otel
OTEL_EXPORTER_OTLP_ENDPOINT: "http://trigger:3040/otel"
OTEL_EXPORTER_OTLP_ENDPOINT: $SERVICE_FQDN_TRIGGER_3000/otel
ELECTRIC_ORIGIN: http://electric:3000
services:
@@ -119,13 +119,16 @@ services:
PLATFORM_HOST: trigger
PLATFORM_WS_PORT: 3000
SECURE_CONNECTION: "false"
PLATFORM_SECRET: $PROVIDER_SECRET
PLATFORM_SECRET: $SERVICE_PASSWORD_64_PROVIDER
HTTP_SERVER_PORT: 9020
coordinator:
image: ghcr.io/triggerdotdev/coordinator:v3
platform: linux/amd64
volumes:
- /var/run/docker.sock:/var/run/docker.sock
user: root
ports:
- '127.0.0.1:9020:9020'
depends_on:
trigger:
condition: service_healthy
@@ -134,7 +137,8 @@ services:
PLATFORM_HOST: trigger
PLATFORM_WS_PORT: 3000
SECURE_CONNECTION: "false"
PLATFORM_SECRET: $COORDINATOR_SECRET
PLATFORM_SECRET: $SERVICE_PASSWORD_64_COORDINATOR
HTTP_SERVER_PORT: 9020
healthcheck:
test:
- CMD-SHELL

File diff suppressed because one or more lines are too long

View File

@@ -1,10 +1,10 @@
{
"coolify": {
"v4": {
"version": "4.0.0-beta.389"
"version": "4.0.0-beta.390"
},
"nightly": {
"version": "4.0.0-beta.390"
"version": "4.0.0-beta.391"
},
"helper": {
"version": "1.0.6"

View File

@@ -1,8 +1,11 @@
import { defineConfig } from "vite";
import { defineConfig, loadEnv } from "vite";
import laravel from "laravel-vite-plugin";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '')
return {
server: {
watch: {
ignored: [
@@ -12,7 +15,7 @@ export default defineConfig({
},
host: "0.0.0.0",
hmr: {
host: process.env.VITE_HOST,
host: env.VITE_HOST || '0.0.0.0'
},
},
plugins: [
@@ -34,4 +37,5 @@ export default defineConfig({
vue: "vue/dist/vue.esm-bundler.js",
},
},
}
});