mirror of
https://github.com/coollabsio/coolify.git
synced 2026-03-11 08:55:47 +00:00
Merge remote-tracking branch 'upstream/next' into docker-image-login
This commit is contained in:
commit
b7e00ce054
32 changed files with 1001 additions and 953 deletions
|
|
@ -13,7 +13,6 @@ class CleanupRedis extends Command
|
|||
|
||||
public function handle()
|
||||
{
|
||||
echo "Cleanup Redis keys.\n";
|
||||
$prefix = config('database.redis.options.prefix');
|
||||
|
||||
$keys = Redis::connection()->keys('*:laravel*');
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ class CleanupStuckedResources extends Command
|
|||
|
||||
public function handle()
|
||||
{
|
||||
echo "Running cleanup stucked resources.\n";
|
||||
$this->cleanup_stucked_resources();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class Horizon extends Command
|
|||
public function handle()
|
||||
{
|
||||
if (config('constants.horizon.is_horizon_enabled')) {
|
||||
$this->info('Horizon is enabled. Starting.');
|
||||
$this->info('[x]: Horizon is enabled. Starting.');
|
||||
$this->call('horizon');
|
||||
exit(0);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Actions\Server\StopSentinel;
|
||||
use App\Enums\ActivityTypes;
|
||||
use App\Enums\ApplicationDeploymentStatus;
|
||||
use App\Jobs\CheckHelperImageJob;
|
||||
use App\Models\ApplicationDeploymentQueue;
|
||||
use App\Models\Environment;
|
||||
use App\Models\ScheduledDatabaseBackup;
|
||||
|
|
@ -12,6 +12,7 @@ use App\Models\Server;
|
|||
use App\Models\StandalonePostgresql;
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
|
|
@ -25,6 +26,8 @@ class Init extends Command
|
|||
|
||||
public function handle()
|
||||
{
|
||||
$this->optimize();
|
||||
|
||||
if (isCloud() && ! $this->option('force-cloud')) {
|
||||
echo "Skipping init as we are on cloud and --force-cloud option is not set\n";
|
||||
|
||||
|
|
@ -39,7 +42,6 @@ class Init extends Command
|
|||
}
|
||||
|
||||
// Backward compatibility
|
||||
// $this->disable_metrics();
|
||||
$this->replace_slash_in_environment_name();
|
||||
$this->restore_coolify_db_backup();
|
||||
$this->update_user_emails();
|
||||
|
|
@ -53,9 +55,18 @@ class Init extends Command
|
|||
} else {
|
||||
$this->cleanup_in_progress_application_deployments();
|
||||
}
|
||||
echo "[3]: Cleanup Redis keys.\n";
|
||||
$this->call('cleanup:redis');
|
||||
|
||||
echo "[4]: Cleanup stucked resources.\n";
|
||||
$this->call('cleanup:stucked-resources');
|
||||
|
||||
try {
|
||||
$this->pullHelperImage();
|
||||
} catch (\Throwable $e) {
|
||||
//
|
||||
}
|
||||
|
||||
if (isCloud()) {
|
||||
try {
|
||||
$this->pullTemplatesFromCDN();
|
||||
|
|
@ -87,6 +98,11 @@ class Init extends Command
|
|||
}
|
||||
}
|
||||
|
||||
private function pullHelperImage()
|
||||
{
|
||||
CheckHelperImageJob::dispatch();
|
||||
}
|
||||
|
||||
private function pullTemplatesFromCDN()
|
||||
{
|
||||
$response = Http::retry(3, 1000)->get(config('constants.services.official'));
|
||||
|
|
@ -95,19 +111,13 @@ class Init extends Command
|
|||
File::put(base_path('templates/service-templates.json'), json_encode($services));
|
||||
}
|
||||
}
|
||||
// private function disable_metrics()
|
||||
// {
|
||||
// if (version_compare('4.0.0-beta.312', config('version'), '<=')) {
|
||||
// foreach ($this->servers as $server) {
|
||||
// if ($server->settings->is_metrics_enabled === true) {
|
||||
// $server->settings->update(['is_metrics_enabled' => false]);
|
||||
// }
|
||||
// if ($server->isFunctional()) {
|
||||
// StopSentinel::dispatch($server)->onQueue('high');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private function optimize()
|
||||
{
|
||||
echo "[1]: Optimizing Laravel (caching config, routes, views).\n";
|
||||
Artisan::call('optimize:clear');
|
||||
Artisan::call('optimize');
|
||||
}
|
||||
|
||||
private function update_user_emails()
|
||||
{
|
||||
|
|
@ -222,15 +232,15 @@ class Init extends Command
|
|||
$settings = instanceSettings();
|
||||
$do_not_track = data_get($settings, 'do_not_track');
|
||||
if ($do_not_track == true) {
|
||||
echo "Skipping alive as do_not_track is enabled\n";
|
||||
echo "[2]: Skipping sending live signal as do_not_track is enabled\n";
|
||||
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Http::get("https://undead.coolify.io/v4/alive?appId=$id&version=$version");
|
||||
echo "I am alive!\n";
|
||||
echo "[2]: Sending live signal!\n";
|
||||
} catch (\Throwable $e) {
|
||||
echo "Error in alive: {$e->getMessage()}\n";
|
||||
echo "[2]: Error in sending live signal: {$e->getMessage()}\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class Scheduler extends Command
|
|||
public function handle()
|
||||
{
|
||||
if (config('constants.horizon.is_scheduler_enabled')) {
|
||||
$this->info('Scheduler is enabled. Starting.');
|
||||
$this->info('[x]: Scheduler is enabled. Starting.');
|
||||
$this->call('schedule:work');
|
||||
exit(0);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class ServerStorageCheckJob implements ShouldBeEncrypted, ShouldQueue
|
|||
return isDev() ? 1 : 3;
|
||||
}
|
||||
|
||||
public function __construct(public Server $server, public ?int $percentage = null) {}
|
||||
public function __construct(public Server $server, public int|string|null $percentage = null) {}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ class CreateScheduledBackup extends Component
|
|||
|
||||
public bool $enabled = true;
|
||||
|
||||
#[Validate(['required', 'integer'])]
|
||||
public int $s3StorageId;
|
||||
#[Validate(['nullable', 'integer'])]
|
||||
public ?int $s3StorageId = null;
|
||||
|
||||
public Collection $definedS3s;
|
||||
|
||||
|
|
@ -49,6 +49,7 @@ class CreateScheduledBackup extends Component
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'enabled' => true,
|
||||
'frequency' => $this->frequency,
|
||||
|
|
@ -58,6 +59,7 @@ class CreateScheduledBackup extends Component
|
|||
'database_type' => $this->database->getMorphClass(),
|
||||
'team_id' => currentTeam()->id,
|
||||
];
|
||||
|
||||
if ($this->database->type() === 'standalone-postgresql') {
|
||||
$payload['databases_to_backup'] = $this->database->postgres_db;
|
||||
} elseif ($this->database->type() === 'standalone-mysql') {
|
||||
|
|
@ -72,11 +74,11 @@ class CreateScheduledBackup extends Component
|
|||
} else {
|
||||
$this->dispatch('refreshScheduledBackups');
|
||||
}
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
} finally {
|
||||
$this->frequency = '';
|
||||
$this->saveToS3 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class Tags extends Component
|
|||
$this->validate();
|
||||
$tags = str($this->newTags)->trim()->explode(' ');
|
||||
foreach ($tags as $tag) {
|
||||
$tag = strip_tags($tag);
|
||||
if (strlen($tag) < 2) {
|
||||
$this->dispatch('error', 'Invalid tag.', "Tag <span class='dark:text-warning'>$tag</span> is invalid. Min length is 2.");
|
||||
|
||||
|
|
@ -65,6 +66,7 @@ class Tags extends Component
|
|||
public function addTag(string $id, string $name)
|
||||
{
|
||||
try {
|
||||
$name = strip_tags($name);
|
||||
if ($this->resource->tags()->where('id', $id)->exists()) {
|
||||
$this->dispatch('error', 'Duplicate tags.', "Tag <span class='dark:text-warning'>$name</span> already added.");
|
||||
|
||||
|
|
|
|||
|
|
@ -6,64 +6,60 @@ use App\Enums\ProxyTypes;
|
|||
use App\Models\Server;
|
||||
use App\Models\Team;
|
||||
use Illuminate\Support\Collection;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class ByIp extends Component
|
||||
{
|
||||
#[Locked]
|
||||
public $private_keys;
|
||||
|
||||
#[Locked]
|
||||
public $limit_reached;
|
||||
|
||||
#[Validate('nullable|integer', as: 'Private Key')]
|
||||
public ?int $private_key_id = null;
|
||||
|
||||
#[Validate('nullable|string', as: 'Private Key Name')]
|
||||
public $new_private_key_name;
|
||||
|
||||
#[Validate('nullable|string', as: 'Private Key Description')]
|
||||
public $new_private_key_description;
|
||||
|
||||
#[Validate('nullable|string', as: 'Private Key Value')]
|
||||
public $new_private_key_value;
|
||||
|
||||
#[Validate('required|string', as: 'Name')]
|
||||
public string $name;
|
||||
|
||||
#[Validate('nullable|string', as: 'Description')]
|
||||
public ?string $description = null;
|
||||
|
||||
#[Validate('required|string', as: 'IP Address/Domain')]
|
||||
public string $ip;
|
||||
|
||||
#[Validate('required|string', as: 'User')]
|
||||
public string $user = 'root';
|
||||
|
||||
#[Validate('required|integer|between:1,65535', as: 'Port')]
|
||||
public int $port = 22;
|
||||
|
||||
#[Validate('required|boolean', as: 'Swarm Manager')]
|
||||
public bool $is_swarm_manager = false;
|
||||
|
||||
#[Validate('required|boolean', as: 'Swarm Worker')]
|
||||
public bool $is_swarm_worker = false;
|
||||
|
||||
#[Validate('nullable|integer', as: 'Swarm Cluster')]
|
||||
public $selected_swarm_cluster = null;
|
||||
|
||||
#[Validate('required|boolean', as: 'Build Server')]
|
||||
public bool $is_build_server = false;
|
||||
|
||||
#[Locked]
|
||||
public Collection $swarm_managers;
|
||||
|
||||
protected $rules = [
|
||||
'name' => 'required|string',
|
||||
'description' => 'nullable|string',
|
||||
'ip' => 'required',
|
||||
'user' => 'required|string',
|
||||
'port' => 'required|integer',
|
||||
'is_swarm_manager' => 'required|boolean',
|
||||
'is_swarm_worker' => 'required|boolean',
|
||||
'is_build_server' => 'required|boolean',
|
||||
];
|
||||
|
||||
protected $validationAttributes = [
|
||||
'name' => 'Name',
|
||||
'description' => 'Description',
|
||||
'ip' => 'IP Address/Domain',
|
||||
'user' => 'User',
|
||||
'port' => 'Port',
|
||||
'is_swarm_manager' => 'Swarm Manager',
|
||||
'is_swarm_worker' => 'Swarm Worker',
|
||||
'is_build_server' => 'Build Server',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->name = generate_random_name();
|
||||
|
|
@ -88,6 +84,12 @@ class ByIp extends Component
|
|||
{
|
||||
$this->validate();
|
||||
try {
|
||||
if (Server::where('team_id', currentTeam()->id)
|
||||
->where('ip', $this->ip)
|
||||
->exists()) {
|
||||
return $this->dispatch('error', 'This IP/Domain is already in use by another server in your team.');
|
||||
}
|
||||
|
||||
if (is_null($this->private_key_id)) {
|
||||
return $this->dispatch('error', 'You must select a private key');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,6 +107,15 @@ class Show extends Component
|
|||
{
|
||||
if ($toModel) {
|
||||
$this->validate();
|
||||
|
||||
if (Server::where('team_id', currentTeam()->id)
|
||||
->where('ip', $this->ip)
|
||||
->where('id', '!=', $this->server->id)
|
||||
->exists()) {
|
||||
$this->ip = $this->server->ip;
|
||||
throw new \Exception('This IP/Domain is already in use by another server in your team.');
|
||||
}
|
||||
|
||||
$this->server->name = $this->name;
|
||||
$this->server->description = $this->description;
|
||||
$this->server->ip = $this->ip;
|
||||
|
|
|
|||
|
|
@ -218,10 +218,12 @@ class PrivateKey extends BaseModel
|
|||
|
||||
private static function fingerprintExists($fingerprint, $excludeId = null)
|
||||
{
|
||||
$query = self::where('fingerprint', $fingerprint);
|
||||
$query = self::query()
|
||||
->where('fingerprint', $fingerprint)
|
||||
->where('id', '!=', $excludeId);
|
||||
|
||||
if (! is_null($excludeId)) {
|
||||
$query->where('id', '!=', $excludeId);
|
||||
if (currentTeam()) {
|
||||
$query->where('team_id', currentTeam()->id);
|
||||
}
|
||||
|
||||
return $query->exists();
|
||||
|
|
|
|||
|
|
@ -17,11 +17,14 @@ class Checkbox extends Component
|
|||
public ?string $value = null,
|
||||
public ?string $label = null,
|
||||
public ?string $helper = null,
|
||||
public string|bool|null $checked = false,
|
||||
public string|bool $instantSave = false,
|
||||
public bool $disabled = false,
|
||||
public string $defaultClass = 'dark:border-neutral-700 text-coolgray-400 focus:ring-warning dark:bg-coolgray-100 rounded cursor-pointer dark:disabled:bg-base dark:disabled:cursor-not-allowed',
|
||||
) {
|
||||
//
|
||||
if ($this->disabled) {
|
||||
$this->defaultClass .= ' opacity-40';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -227,13 +227,17 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
|||
$MINIO_BROWSER_REDIRECT_URL = $variables->where('key', 'MINIO_BROWSER_REDIRECT_URL')->first();
|
||||
$MINIO_SERVER_URL = $variables->where('key', 'MINIO_SERVER_URL')->first();
|
||||
|
||||
if (str($MINIO_BROWSER_REDIRECT_URL->value)->isEmpty()) {
|
||||
$MINIO_BROWSER_REDIRECT_URL?->update([
|
||||
if (is_null($MINIO_BROWSER_REDIRECT_URL) || is_null($MINIO_SERVER_URL)) {
|
||||
return collect([]);
|
||||
}
|
||||
|
||||
if (str($MINIO_BROWSER_REDIRECT_URL->value ?? '')->isEmpty()) {
|
||||
$MINIO_BROWSER_REDIRECT_URL->update([
|
||||
'value' => generateFqdn($server, 'console-'.$uuid, true),
|
||||
]);
|
||||
}
|
||||
if (str($MINIO_SERVER_URL->value)->isEmpty()) {
|
||||
$MINIO_SERVER_URL?->update([
|
||||
if (str($MINIO_SERVER_URL->value ?? '')->isEmpty()) {
|
||||
$MINIO_SERVER_URL->update([
|
||||
'value' => generateFqdn($server, 'minio-'.$uuid, true),
|
||||
]);
|
||||
}
|
||||
|
|
@ -246,13 +250,17 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
|||
$LOGTO_ENDPOINT = $variables->where('key', 'LOGTO_ENDPOINT')->first();
|
||||
$LOGTO_ADMIN_ENDPOINT = $variables->where('key', 'LOGTO_ADMIN_ENDPOINT')->first();
|
||||
|
||||
if (str($LOGTO_ENDPOINT?->value)->isEmpty()) {
|
||||
$LOGTO_ENDPOINT?->update([
|
||||
if (is_null($LOGTO_ENDPOINT) || is_null($LOGTO_ADMIN_ENDPOINT)) {
|
||||
return collect([]);
|
||||
}
|
||||
|
||||
if (str($LOGTO_ENDPOINT->value ?? '')->isEmpty()) {
|
||||
$LOGTO_ENDPOINT->update([
|
||||
'value' => generateFqdn($server, 'logto-'.$uuid),
|
||||
]);
|
||||
}
|
||||
if (str($LOGTO_ADMIN_ENDPOINT?->value)->isEmpty()) {
|
||||
$LOGTO_ADMIN_ENDPOINT?->update([
|
||||
if (str($LOGTO_ADMIN_ENDPOINT->value ?? '')->isEmpty()) {
|
||||
$LOGTO_ADMIN_ENDPOINT->update([
|
||||
'value' => generateFqdn($server, 'logto-admin-'.$uuid),
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4075,7 +4075,7 @@ function defaultNginxConfiguration(): string
|
|||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
try_files $uri $uri/index.html =404;
|
||||
try_files $uri $uri.html $uri/index.html $uri/index.htm $uri/ /index.html /index.htm =404;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
"socialiteproviders/microsoft-azure": "^5.1",
|
||||
"spatie/laravel-activitylog": "^4.7.3",
|
||||
"spatie/laravel-data": "^4.11",
|
||||
"spatie/laravel-ray": "^1.37",
|
||||
"spatie/laravel-schemaless-attributes": "^2.4",
|
||||
"spatie/url": "^2.2",
|
||||
"stripe/stripe-php": "^16.2.0",
|
||||
|
|
@ -63,7 +64,6 @@
|
|||
"phpunit/phpunit": "^11.4",
|
||||
"serversideup/spin": "^2.3",
|
||||
"spatie/laravel-ignition": "^2.1.0",
|
||||
"spatie/laravel-ray": "^1.37",
|
||||
"symfony/http-client": "^7.1"
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
|
|
|
|||
1686
composer.lock
generated
1686
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
return [
|
||||
'coolify' => [
|
||||
'version' => '4.0.0-beta.368',
|
||||
'version' => '4.0.0-beta.370',
|
||||
'self_hosted' => env('SELF_HOSTED', true),
|
||||
'autoupdate' => env('AUTOUPDATE', false),
|
||||
'autoupdate' => env('AUTOUPDATE'),
|
||||
'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'),
|
||||
'helper_image' => env('HELPER_IMAGE', 'ghcr.io/coollabsio/coolify-helper'),
|
||||
'is_windows_docker_desktop' => env('IS_WINDOWS_DOCKER_DESKTOP', false),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
|
||||
return '4.0.0-beta.368';
|
||||
return '4.0.0-beta.370';
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ class ProductionSeeder extends Seeder
|
|||
public function run(): void
|
||||
{
|
||||
if (isCloud()) {
|
||||
echo "Running in cloud mode.\n";
|
||||
echo "[x]: Running in cloud mode.\n";
|
||||
} else {
|
||||
echo "Running in self-hosted mode.\n";
|
||||
echo "[x]: Running in self-hosted mode.\n";
|
||||
}
|
||||
|
||||
// Fix for 4.0.0-beta.37
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
# Versions
|
||||
|
||||
# https://hub.docker.com/_/alpine
|
||||
ARG BASE_IMAGE=alpine:3.20
|
||||
# https://download.docker.com/linux/static/stable/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
FROM quay.io/soketi/soketi:1.6-16-alpine
|
||||
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
# https://github.com/cloudflare/cloudflared/releases
|
||||
ARG CLOUDFLARED_VERSION=2024.4.1
|
||||
|
|
|
|||
|
|
@ -57,13 +57,6 @@ RUN composer dump-autoload
|
|||
COPY --from=static-assets --chown=9999:9999 /app/public/build ./public/build
|
||||
COPY --chmod=755 docker/prod/etc/s6-overlay/ /etc/s6-overlay/
|
||||
|
||||
RUN php artisan route:clear
|
||||
RUN php artisan view:clear
|
||||
RUN php artisan config:clear
|
||||
RUN php artisan route:cache
|
||||
RUN php artisan view:cache
|
||||
RUN php artisan config:cache
|
||||
|
||||
RUN echo "alias ll='ls -al'" >>/etc/bash.bashrc
|
||||
RUN echo "alias a='php artisan'" >>/etc/bash.bashrc
|
||||
RUN echo "alias logs='tail -f storage/logs/laravel.log'" >>/etc/bash.bashrc
|
||||
|
|
@ -86,4 +79,4 @@ RUN { \
|
|||
} > /etc/php/current_version/cli/conf.d/upload-limits.ini
|
||||
|
||||
COPY --from=minio-client /usr/bin/mc /usr/bin/mc
|
||||
RUN chmod +x /usr/bin/mc
|
||||
RUN chmod +x /usr/bin/mc
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ CDN="https://cdn.coollabs.io/coolify-nightly"
|
|||
DATE=$(date +"%Y%m%d-%H%M%S")
|
||||
|
||||
VERSION="1.6"
|
||||
DOCKER_VERSION="27.3"
|
||||
DOCKER_VERSION="27.0"
|
||||
# TODO: Ask for a user
|
||||
CURRENT_USER=$USER
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
'disabled' => false,
|
||||
'instantSave' => false,
|
||||
'value' => null,
|
||||
'checked' => false,
|
||||
'hideLabel' => false,
|
||||
'fullWidth' => false,
|
||||
])
|
||||
|
|
@ -14,7 +15,9 @@
|
|||
'w-full' => $fullWidth,
|
||||
])>
|
||||
@if (!$hideLabel)
|
||||
<label @class(['flex gap-4 items-center px-0 min-w-fit label w-full cursor-pointer', 'opacity-40' => $disabled])>
|
||||
<label @class([
|
||||
'flex gap-4 items-center px-0 min-w-fit label w-full cursor-pointer',
|
||||
])>
|
||||
<span class="flex flex-grow gap-2">
|
||||
@if ($label)
|
||||
{!! $label !!}
|
||||
|
|
@ -26,9 +29,10 @@
|
|||
@endif
|
||||
</span>
|
||||
@endif
|
||||
<input @disabled($disabled) type="checkbox" {{ $attributes->merge(['class' => $defaultClass]) }}
|
||||
@if ($instantSave) wire:loading.attr="disabled" wire:click='{{ $instantSave === 'instantSave' || $instantSave == '1' ? 'instantSave' : $instantSave }}'
|
||||
wire:model={{ $id }} @else wire:model={{ $value ?? $id }} @endif />
|
||||
<input @disabled($disabled) type="checkbox" {{ $attributes->merge(['class' => $defaultClass]) }}
|
||||
@if ($instantSave) wire:loading.attr="disabled" wire:click='{{ $instantSave === 'instantSave' || $instantSave == '1' ? 'instantSave' : $instantSave }}'
|
||||
@if ($checked) checked @endif
|
||||
wire:model={{ $id }} @else wire:model={{ $value ?? $id }} @endif />
|
||||
@if (!$hideLabel)
|
||||
</label>
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
'closeOutside' => true,
|
||||
])
|
||||
<div x-data="{ modalOpen: false }" :class="{ 'z-40': modalOpen }" @keydown.window.escape="modalOpen=false"
|
||||
class="relative w-auto h-auto">
|
||||
class="relative w-auto h-auto" wire:ignore>
|
||||
@if ($content)
|
||||
<div @click="modalOpen=true">
|
||||
{{ $content }}
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
@endif
|
||||
<template x-teleport="body">
|
||||
<div x-show="modalOpen"
|
||||
class="fixed top-0 left-0 lg:px-0 px-4 z-[99] flex items-center justify-center w-screen h-screen" x-cloak>
|
||||
class="fixed top-0 left-0 lg:px-0 px-4 z-[99] flex items-center justify-center w-screen h-screen">
|
||||
<div x-show="modalOpen" x-transition:enter="ease-out duration-100" x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-100"
|
||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
@forelse ($private_keys as $key)
|
||||
@if ($private_key_id == $key->id)
|
||||
<div class="gap-2 py-4 cursor-pointer group hover:bg-coollabs bg-coolgray-200 box"
|
||||
wire:click.defer="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}">
|
||||
wire:click="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="box-title">
|
||||
{{ $key->name }}
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
</div>
|
||||
@else
|
||||
<div class="gap-2 py-4 cursor-pointer group hover:bg-coollabs bg-coolgray-200 box"
|
||||
wire:click.defer="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}">
|
||||
wire:click="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="box-title">
|
||||
{{ $key->name }}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@
|
|||
@if (!is_null(config('constants.coolify.autoupdate', null)))
|
||||
<div class="text-right md:w-96">
|
||||
<x-forms.checkbox instantSave helper="AUTOUPDATE is set in .env file, you need to modify it there."
|
||||
disabled id="is_auto_update_enabled" label="Enabled" />
|
||||
disabled checked="{{ config('constants.coolify.autoupdate') }}" label="Auto Update Enabled" />
|
||||
</div>
|
||||
@else
|
||||
<x-forms.checkbox instantSave id="is_auto_update_enabled" label="Auto Update Enabled" />
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ CDN="https://cdn.coollabs.io/coolify"
|
|||
DATE=$(date +"%Y%m%d-%H%M%S")
|
||||
|
||||
VERSION="1.6"
|
||||
DOCKER_VERSION="27.3"
|
||||
DOCKER_VERSION="27.0"
|
||||
# TODO: Ask for a user
|
||||
CURRENT_USER=$USER
|
||||
|
||||
|
|
@ -151,24 +151,24 @@ echo "| Coolify | $LATEST_VERSION"
|
|||
echo "| Helper | $LATEST_HELPER_VERSION"
|
||||
echo "| Realtime | $LATEST_REALTIME_VERSION"
|
||||
echo -e "---------------------------------------------\n"
|
||||
echo -e "1. Installing required packages (curl, wget, git, jq). "
|
||||
echo -e "1. Installing required packages (curl, wget, git, jq, openssl). "
|
||||
|
||||
case "$OS_TYPE" in
|
||||
arch)
|
||||
pacman -Sy --noconfirm --needed curl wget git jq >/dev/null || true
|
||||
pacman -Sy --noconfirm --needed curl wget git jq openssl >/dev/null || true
|
||||
;;
|
||||
alpine)
|
||||
sed -i '/^#.*\/community/s/^#//' /etc/apk/repositories
|
||||
apk update >/dev/null
|
||||
apk add curl wget git jq >/dev/null
|
||||
apk add curl wget git jq openssl >/dev/null
|
||||
;;
|
||||
ubuntu | debian | raspbian)
|
||||
apt-get update -y >/dev/null
|
||||
apt-get install -y curl wget git jq >/dev/null
|
||||
apt-get install -y curl wget git jq openssl >/dev/null
|
||||
;;
|
||||
centos | fedora | rhel | ol | rocky | almalinux | amzn)
|
||||
if [ "$OS_TYPE" = "amzn" ]; then
|
||||
dnf install -y wget git jq >/dev/null
|
||||
dnf install -y wget git jq openssl >/dev/null
|
||||
else
|
||||
if ! command -v dnf >/dev/null; then
|
||||
yum install -y dnf >/dev/null
|
||||
|
|
@ -176,12 +176,12 @@ centos | fedora | rhel | ol | rocky | almalinux | amzn)
|
|||
if ! command -v curl >/dev/null; then
|
||||
dnf install -y curl >/dev/null
|
||||
fi
|
||||
dnf install -y wget git jq >/dev/null
|
||||
dnf install -y wget git jq openssl >/dev/null
|
||||
fi
|
||||
;;
|
||||
sles | opensuse-leap | opensuse-tumbleweed)
|
||||
zypper refresh >/dev/null
|
||||
zypper install -y curl wget git jq >/dev/null
|
||||
zypper install -y curl wget git jq openssl >/dev/null
|
||||
;;
|
||||
*)
|
||||
echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now."
|
||||
|
|
@ -326,6 +326,22 @@ if ! [ -x "$(command -v docker)" ]; then
|
|||
exit 1
|
||||
fi
|
||||
;;
|
||||
"fedora")
|
||||
if [ -x "$(command -v dnf5)" ]; then
|
||||
# dnf5 is available
|
||||
dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/fedora/docker-ce.repo --overwrite >/dev/null 2>&1
|
||||
else
|
||||
# dnf5 is not available, use dnf
|
||||
dnf config-manager --add-repo=https://download.docker.com/linux/fedora/docker-ce.repo >/dev/null 2>&1
|
||||
fi
|
||||
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin >/dev/null 2>&1
|
||||
if ! [ -x "$(command -v docker)" ]; then
|
||||
echo " - Docker could not be installed automatically. Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
|
||||
exit 1
|
||||
fi
|
||||
systemctl start docker >/dev/null 2>&1
|
||||
systemctl enable docker >/dev/null 2>&1
|
||||
;;
|
||||
*)
|
||||
if [ "$OS_TYPE" = "ubuntu" ] && [ "$OS_VERSION" = "24.10" ]; then
|
||||
echo "Docker automated installation is not supported on Ubuntu 24.10 (non-LTS release)."
|
||||
|
|
@ -516,9 +532,8 @@ echo -e "\033[0;35m
|
|||
\____\___/|_| |_|\__, |_| \__,_|\__|\__,_|_|\__,_|\__|_|\___/|_| |_|___(_)
|
||||
|___/
|
||||
\033[0m"
|
||||
echo -e "\nYour instance is ready to use."
|
||||
echo -e "You can access Coolify through:"
|
||||
echo -e "- Public IP: http://$(curl -4s https://ifconfig.io):8000"
|
||||
echo -e "\nYour instance is ready to use!\n"
|
||||
echo -e "You can access Coolify through your Public IP: http://$(curl -4s https://ifconfig.io):8000"
|
||||
|
||||
set +e
|
||||
DEFAULT_PRIVATE_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
|
||||
|
|
@ -526,15 +541,12 @@ PRIVATE_IPS=$(hostname -I)
|
|||
set -e
|
||||
|
||||
if [ -n "$PRIVATE_IPS" ]; then
|
||||
echo -e "If your Public IP is not accessible, you can use the following Private IPs:\n"
|
||||
echo -e "\nIf your Public IP is not accessible, you can use the following Private IPs:\n"
|
||||
for IP in $PRIVATE_IPS; do
|
||||
if [ "$IP" == "$DEFAULT_PRIVATE_IP" ]; then
|
||||
echo -e "http://$DEFAULT_PRIVATE_IP:8000 (default)"
|
||||
else
|
||||
if [ "$IP" != "$DEFAULT_PRIVATE_IP" ]; then
|
||||
echo -e "http://$IP:8000"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo -e "\n"
|
||||
echo -e "WARNING: It is highly recommended to backup your Environment variables file (/data/coolify/source/.env) to a safe location, outside of this server (e.g. into a Password Manager).\n"
|
||||
echo -e "\nWARNING: It is highly recommended to backup your Environment variables file (/data/coolify/source/.env) to a safe location, outside of this server (e.g. into a Password Manager).\n"
|
||||
cp /data/coolify/source/.env /data/coolify/source/.env.backup
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ services:
|
|||
image: ghcr.io/browserless/chromium
|
||||
environment:
|
||||
- SERVICE_FQDN_BROWSERLESS_3000
|
||||
- TOKEN=$SERVICE_BASE64_BROWSERLESS_TOKEN
|
||||
- TOKEN=$SERVICE_PASSWORD_BROWSERLESS
|
||||
expose:
|
||||
- 3000
|
||||
healthcheck:
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ services:
|
|||
- MONGO_URI=mongodb://mongo:27017/heyform
|
||||
- REDIS_HOST=keydb
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${SERVICE_PASSWORD_KEYDB}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8000 || exit 1"]
|
||||
interval: 5s
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@
|
|||
"browserless": {
|
||||
"documentation": "https://docs.browserless.io/?utm_source=coolify.io",
|
||||
"slogan": "A headless Chrome browser as a service .",
|
||||
"compose": "c2VydmljZXM6CiAgYnJvd3Nlcmxlc3M6CiAgICBpbWFnZTogZ2hjci5pby9icm93c2VybGVzcy9jaHJvbWl1bQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0JST1dTRVJMRVNTXzMwMDAKICAgICAgLSBUT0tFTj0kU0VSVklDRV9CQVNFNjRfQlJPV1NFUkxFU1NfVE9LRU4KICAgIGV4cG9zZToKICAgICAgLSAzMDAwCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMC9kb2NzJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1Cg==",
|
||||
"compose": "c2VydmljZXM6CiAgYnJvd3Nlcmxlc3M6CiAgICBpbWFnZTogZ2hjci5pby9icm93c2VybGVzcy9jaHJvbWl1bQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0JST1dTRVJMRVNTXzMwMDAKICAgICAgLSBUT0tFTj0kU0VSVklDRV9QQVNTV09SRF9CUk9XU0VSTEVTUwogICAgZXhwb3NlOgogICAgICAtIDMwMDAKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTozMDAwL2RvY3MnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUK",
|
||||
"tags": [
|
||||
"chrome",
|
||||
"headless",
|
||||
|
|
@ -1131,7 +1131,7 @@
|
|||
"heyform": {
|
||||
"documentation": "https://docs.heyform.net/open-source/self-hosting?utm_source=coolify.io",
|
||||
"slogan": "Allows anyone to create engaging conversational forms for surveys, questionnaires, quizzes, and polls. No coding skills required.",
|
||||
"compose": "c2VydmljZXM6CiAgaGV5Zm9ybToKICAgIGltYWdlOiAnaGV5Zm9ybS9jb21tdW5pdHktZWRpdGlvbjpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdoZXlmb3JtLWFzc2V0czovYXBwL3N0YXRpYy91cGxvYWQnCiAgICBkZXBlbmRzX29uOgogICAgICBtb25nbzoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBrZXlkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0hFWUZPUk1fODAwMAogICAgICAtICdBUFBfSE9NRVBBR0VfVVJMPSR7U0VSVklDRV9GUUROX0hFWUZPUk19JwogICAgICAtICdTRVNTSU9OX0tFWT0ke1NFUlZJQ0VfQkFTRTY0XzY0X1NFU1NJT059JwogICAgICAtICdGT1JNX0VOQ1JZUFRJT05fS0VZPSR7U0VSVklDRV9CQVNFNjRfNjRfRk9STX0nCiAgICAgIC0gJ01PTkdPX1VSST1tb25nb2RiOi8vbW9uZ286MjcwMTcvaGV5Zm9ybScKICAgICAgLSBSRURJU19IT1NUPWtleWRiCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3dnZXQgLXFPLSBodHRwOi8vMTI3LjAuMC4xOjgwMDAgfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMwogIG1vbmdvOgogICAgaW1hZ2U6ICdwZXJjb25hL3BlcmNvbmEtc2VydmVyLW1vbmdvZGI6bGF0ZXN0JwogICAgdm9sdW1lczoKICAgICAgLSAnaGV5Zm9ybS1tb25nby1kYXRhOi9kYXRhL2RiJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICJlY2hvICdvaycgPiAvZGV2L251bGwgMj4mMSIKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMKICBrZXlkYjoKICAgIGltYWdlOiAnZXFhbHBoYS9rZXlkYjpsYXRlc3QnCiAgICBjb21tYW5kOiAna2V5ZGItc2VydmVyIC0tYXBwZW5kb25seSB5ZXMnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnS0VZREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX0tFWURCfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2hleWZvcm0ta2V5ZGItZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBrZXlkYi1jbGkKICAgICAgICAtICctLXBhc3MnCiAgICAgICAgLSAnJHtTRVJWSUNFX1BBU1NXT1JEX0tFWURCfScKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMK",
|
||||
"compose": "c2VydmljZXM6CiAgaGV5Zm9ybToKICAgIGltYWdlOiAnaGV5Zm9ybS9jb21tdW5pdHktZWRpdGlvbjpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdoZXlmb3JtLWFzc2V0czovYXBwL3N0YXRpYy91cGxvYWQnCiAgICBkZXBlbmRzX29uOgogICAgICBtb25nbzoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBrZXlkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0hFWUZPUk1fODAwMAogICAgICAtICdBUFBfSE9NRVBBR0VfVVJMPSR7U0VSVklDRV9GUUROX0hFWUZPUk19JwogICAgICAtICdTRVNTSU9OX0tFWT0ke1NFUlZJQ0VfQkFTRTY0XzY0X1NFU1NJT059JwogICAgICAtICdGT1JNX0VOQ1JZUFRJT05fS0VZPSR7U0VSVklDRV9CQVNFNjRfNjRfRk9STX0nCiAgICAgIC0gJ01PTkdPX1VSST1tb25nb2RiOi8vbW9uZ286MjcwMTcvaGV5Zm9ybScKICAgICAgLSBSRURJU19IT1NUPWtleWRiCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICAgIC0gJ1JFRElTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9LRVlEQn0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3dnZXQgLXFPLSBodHRwOi8vMTI3LjAuMC4xOjgwMDAgfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMwogIG1vbmdvOgogICAgaW1hZ2U6ICdwZXJjb25hL3BlcmNvbmEtc2VydmVyLW1vbmdvZGI6bGF0ZXN0JwogICAgdm9sdW1lczoKICAgICAgLSAnaGV5Zm9ybS1tb25nby1kYXRhOi9kYXRhL2RiJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICJlY2hvICdvaycgPiAvZGV2L251bGwgMj4mMSIKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMKICBrZXlkYjoKICAgIGltYWdlOiAnZXFhbHBoYS9rZXlkYjpsYXRlc3QnCiAgICBjb21tYW5kOiAna2V5ZGItc2VydmVyIC0tYXBwZW5kb25seSB5ZXMnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnS0VZREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX0tFWURCfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2hleWZvcm0ta2V5ZGItZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBrZXlkYi1jbGkKICAgICAgICAtICctLXBhc3MnCiAgICAgICAgLSAnJHtTRVJWSUNFX1BBU1NXT1JEX0tFWURCfScKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMK",
|
||||
"tags": [
|
||||
"form",
|
||||
"builder",
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
{
|
||||
"coolify": {
|
||||
"v4": {
|
||||
"version": "4.0.0-beta.368"
|
||||
"version": "4.0.0-beta.370"
|
||||
},
|
||||
"nightly": {
|
||||
"version": "4.0.0-beta.369"
|
||||
"version": "4.0.0-beta.371"
|
||||
},
|
||||
"helper": {
|
||||
"version": "1.0.3"
|
||||
"version": "1.0.4"
|
||||
},
|
||||
"realtime": {
|
||||
"version": "1.0.4"
|
||||
"version": "1.0.5"
|
||||
},
|
||||
"sentinel": {
|
||||
"version": "0.0.15"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue