diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..3ded74ce3 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1 @@ +> Always use `next` branch as destination branch for PRs, not `main` diff --git a/app/Console/Commands/CleanupStuckedResources.php b/app/Console/Commands/CleanupStuckedResources.php index 32ba67a1e..afc00140c 100644 --- a/app/Console/Commands/CleanupStuckedResources.php +++ b/app/Console/Commands/CleanupStuckedResources.php @@ -62,7 +62,7 @@ private function cleanup_stucked_resources() $keydbs = StandaloneKeydb::withTrashed()->whereNotNull('deleted_at')->get(); foreach ($keydbs as $keydb) { echo "Deleting stuck keydb: {$keydb->name}\n"; - $redis->forceDelete(); + $keydb->forceDelete(); } } catch (\Throwable $e) { echo "Error in cleaning stuck keydb: {$e->getMessage()}\n"; @@ -71,7 +71,7 @@ private function cleanup_stucked_resources() $dragonflies = StandaloneDragonfly::withTrashed()->whereNotNull('deleted_at')->get(); foreach ($dragonflies as $dragonfly) { echo "Deleting stuck dragonfly: {$dragonfly->name}\n"; - $redis->forceDelete(); + $dragonfly->forceDelete(); } } catch (\Throwable $e) { echo "Error in cleaning stuck dragonfly: {$e->getMessage()}\n"; @@ -80,7 +80,7 @@ private function cleanup_stucked_resources() $clickhouses = StandaloneClickhouse::withTrashed()->whereNotNull('deleted_at')->get(); foreach ($clickhouses as $clickhouse) { echo "Deleting stuck clickhouse: {$clickhouse->name}\n"; - $redis->forceDelete(); + $clickhouse->forceDelete(); } } catch (\Throwable $e) { echo "Error in cleaning stuck clickhouse: {$e->getMessage()}\n"; diff --git a/app/Console/Commands/Init.php b/app/Console/Commands/Init.php index acdff5b35..06414f715 100644 --- a/app/Console/Commands/Init.php +++ b/app/Console/Commands/Init.php @@ -20,6 +20,7 @@ class Init extends Command public function handle() { $this->alive(); + get_public_ips(); $full_cleanup = $this->option('full-cleanup'); $cleanup_deployments = $this->option('cleanup-deployments'); if ($cleanup_deployments) { @@ -56,6 +57,7 @@ public function handle() $this->cleanup_stucked_helper_containers(); $this->call('cleanup:stucked-resources'); } + private function restore_coolify_db_backup() { try { diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 52afdd47e..3d04be7d3 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -718,10 +718,11 @@ private function save_environment_variables() if ($env->version === '4.0.0-beta.239') { $real_value = $env->real_value; } else { - $real_value = escapeEnvVariables($env->real_value); - } - if ($env->is_literal) { - $real_value = '\'' . $real_value . '\''; + if ($env->is_literal) { + $real_value = '\'' . $real_value . '\''; + } else { + $real_value = escapeEnvVariables($env->real_value); + } } $envs->push($env->key . '=' . $real_value); } @@ -750,10 +751,11 @@ private function save_environment_variables() if ($env->version === '4.0.0-beta.239') { $real_value = $env->real_value; } else { - $real_value = escapeEnvVariables($env->real_value); - } - if ($env->is_literal) { - $real_value = '\'' . $real_value . '\''; + if ($env->is_literal) { + $real_value = '\'' . $real_value . '\''; + } else { + $real_value = escapeEnvVariables($env->real_value); + } } $envs->push($env->key . '=' . $real_value); } @@ -1506,7 +1508,7 @@ private function generate_local_persistent_volumes_only_volume_names() return $local_persistent_volumes_names; } - private function generate_environment_variables($ports) + /*private function generate_environment_variables($ports) { $environment_variables = collect(); if ($this->pull_request_id === 0) { @@ -1524,8 +1526,10 @@ private function generate_environment_variables($ports) } if ($env->is_literal) { $real_value = escapeDollarSign($real_value); + $environment_variables->push("$env->key='$real_value'"); + } else { + $environment_variables->push("$env->key=$real_value"); } - $environment_variables->push("$env->key=$real_value"); } foreach ($this->application->nixpacks_environment_variables as $env) { if ($env->version === '4.0.0-beta.239') { @@ -1535,8 +1539,10 @@ private function generate_environment_variables($ports) } if ($env->is_literal) { $real_value = escapeDollarSign($real_value); + $environment_variables->push("$env->key='$real_value'"); + } else { + $environment_variables->push("$env->key=$real_value"); } - $environment_variables->push("$env->key=$real_value"); } } else { foreach ($this->application->runtime_environment_variables_preview as $env) { @@ -1547,8 +1553,10 @@ private function generate_environment_variables($ports) } if ($env->is_literal) { $real_value = escapeDollarSign($real_value); + $environment_variables->push("$env->key='$real_value'"); + } else { + $environment_variables->push("$env->key=$real_value"); } - $environment_variables->push("$env->key=$real_value"); } foreach ($this->application->nixpacks_environment_variables_preview as $env) { if ($env->version === '4.0.0-beta.239') { @@ -1558,8 +1566,10 @@ private function generate_environment_variables($ports) } if ($env->is_literal) { $real_value = escapeDollarSign($real_value); + $environment_variables->push("$env->key='$real_value'"); + } else { + $environment_variables->push("$env->key=$real_value"); } - $environment_variables->push("$env->key=$real_value"); } } // Add PORT if not exists, use the first port as default @@ -1577,8 +1587,9 @@ private function generate_environment_variables($ports) $environment_variables->push("SOURCE_COMMIT=unknown"); } } + ray($environment_variables->all()); return $environment_variables->all(); - } + }*/ private function generate_healthcheck_commands() { diff --git a/app/Livewire/Project/Application/Advanced.php b/app/Livewire/Project/Application/Advanced.php index 278cab5a1..d35867e8f 100644 --- a/app/Livewire/Project/Application/Advanced.php +++ b/app/Livewire/Project/Application/Advanced.php @@ -27,6 +27,8 @@ class Advanced extends Component 'application.settings.gpu_count' => 'string|required', 'application.settings.gpu_device_ids' => 'string|required', 'application.settings.gpu_options' => 'string|required', + 'application.settings.is_raw_compose_deployment_enabled' => 'boolean|required', + 'application.settings.connect_to_docker_network' => 'boolean|required', ]; public function mount() { $this->is_force_https_enabled = $this->application->isForceHttpsEnabled(); @@ -54,8 +56,14 @@ public function instantSave() $this->application->settings->is_stripprefix_enabled = $this->is_stripprefix_enabled; $this->dispatch('resetDefaultLabels', false); } + if ($this->application->settings->is_raw_compose_deployment_enabled) { + $this->application->parseRawCompose(); + } else { + $this->application->parseCompose(); + } $this->application->settings->save(); $this->dispatch('success', 'Settings saved.'); + $this->dispatch('configurationChanged'); } public function submit() { if ($this->application->settings->gpu_count && $this->application->settings->gpu_device_ids) { diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php index 022a7b710..6926e52cb 100644 --- a/app/Livewire/Project/Application/General.php +++ b/app/Livewire/Project/Application/General.php @@ -34,7 +34,8 @@ class General extends Component public $parsedServiceDomains = []; protected $listeners = [ - 'resetDefaultLabels' + 'resetDefaultLabels', + 'configurationChanged' => '$refresh' ]; protected $rules = [ 'application.name' => 'required', @@ -72,7 +73,6 @@ class General extends Component 'application.post_deployment_command' => 'nullable', 'application.post_deployment_command_container' => 'nullable', 'application.settings.is_static' => 'boolean|required', - 'application.settings.is_raw_compose_deployment_enabled' => 'boolean|required', 'application.settings.is_build_server_enabled' => 'boolean|required', 'application.watch_paths' => 'nullable', ]; @@ -108,7 +108,6 @@ class General extends Component 'application.docker_compose_custom_start_command' => 'Docker compose custom start command', 'application.docker_compose_custom_build_command' => 'Docker compose custom build command', 'application.settings.is_static' => 'Is static', - 'application.settings.is_raw_compose_deployment_enabled' => 'Is raw compose deployment enabled', 'application.settings.is_build_server_enabled' => 'Is build server enabled', 'application.watch_paths' => 'Watch paths', ]; @@ -337,11 +336,6 @@ public function submit($showToaster = true) check_domain_usage(resource: $this->application); } } - if ($this->application->settings->is_raw_compose_deployment_enabled) { - $this->application->parseRawCompose(); - } else { - $this->parsedServices = $this->application->parseCompose(); - } } $this->application->custom_labels = base64_encode($this->customLabels); $this->application->save(); diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/Show.php b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php index 9beb7cfab..65e91e60a 100644 --- a/app/Livewire/Project/Shared/EnvironmentVariable/Show.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php @@ -50,9 +50,9 @@ public function mount() public function checkEnvs() { $this->isDisabled = false; - // if (str($this->env->key)->startsWith('SERVICE_FQDN') || str($this->env->key)->startsWith('SERVICE_URL')) { - // $this->isDisabled = true; - // } + if (str($this->env->key)->startsWith('SERVICE_FQDN') || str($this->env->key)->startsWith('SERVICE_URL')) { + $this->isDisabled = true; + } if ($this->env->is_shown_once) { $this->isLocked = true; } diff --git a/app/Livewire/Tags/Deployments.php b/app/Livewire/Tags/Deployments.php new file mode 100644 index 000000000..5c43edfb1 --- /dev/null +++ b/app/Livewire/Tags/Deployments.php @@ -0,0 +1,33 @@ +deployments_per_tag_per_server = ApplicationDeploymentQueue::whereIn("status", ["in_progress", "queued"])->whereIn('application_id', $this->resource_ids)->get([ + "id", + "application_id", + "application_name", + "deployment_url", + "pull_request_id", + "server_name", + "server_id", + "status" + ])->sortBy('id')->groupBy('server_name')->toArray(); + } catch (\Exception $e) { + return handleError($e, $this); + } + } +} diff --git a/app/Livewire/Tags/Index.php b/app/Livewire/Tags/Index.php index 75ed06f7b..d04bb53f9 100644 --- a/app/Livewire/Tags/Index.php +++ b/app/Livewire/Tags/Index.php @@ -20,32 +20,22 @@ class Index extends Component public $webhook = null; public $deployments_per_tag_per_server = []; - public function updatedTag() + public function tag_updated() { + if ($this->tag == "") { + return; + } $tag = $this->tags->where('name', $this->tag)->first(); + if (!$tag) { + $this->dispatch('error', "Tag ({$this->tag}) not found."); + $this->tag = ""; + return; + } $this->webhook = generatTagDeployWebhook($tag->name); $this->applications = $tag->applications()->get(); $this->services = $tag->services()->get(); - $this->get_deployments(); - } - public function get_deployments() - { - try { - $resource_ids = $this->applications->pluck('id'); - $this->deployments_per_tag_per_server = ApplicationDeploymentQueue::whereIn("status", ["in_progress", "queued"])->whereIn('application_id', $resource_ids)->get([ - "id", - "application_id", - "application_name", - "deployment_url", - "pull_request_id", - "server_name", - "server_id", - "status" - ])->sortBy('id')->groupBy('server_name')->toArray(); - } catch (\Exception $e) { - return handleError($e, $this); - } } + public function redeploy_all() { try { @@ -67,7 +57,7 @@ public function mount() { $this->tags = Tag::ownedByCurrentTeam()->get()->unique('name')->sortBy('name'); if ($this->tag) { - $this->updatedTag(); + $this->tag_updated(); } } public function render() diff --git a/app/Models/Application.php b/app/Models/Application.php index 66e18565b..971f1e894 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -579,9 +579,9 @@ function generateGitImportCommands(string $deployment_uuid, int $pull_request_id ['repository' => $customRepository, 'port' => $customPort] = $this->customRepository(); $baseDir = $custom_base_dir ?? $this->generateBaseDir($deployment_uuid); $commands = collect([]); - $git_clone_command = "git clone -b {$this->git_branch}"; + $git_clone_command = "git clone -b \"{$this->git_branch}\""; if ($only_checkout) { - $git_clone_command = "git clone --no-checkout -b {$this->git_branch}"; + $git_clone_command = "git clone --no-checkout -b \"{$this->git_branch}\""; } if ($pull_request_id !== 0) { $pr_branch_name = "pr-{$pull_request_id}-coolify"; diff --git a/app/Models/StandaloneClickhouse.php b/app/Models/StandaloneClickhouse.php index 2197d51df..3746a32f5 100644 --- a/app/Models/StandaloneClickhouse.php +++ b/app/Models/StandaloneClickhouse.php @@ -207,4 +207,7 @@ public function scheduledBackups() { return $this->morphMany(ScheduledDatabaseBackup::class, 'database'); } + public function database_name() { + return $this->clickhouse_db; + } } diff --git a/app/Models/StandaloneDragonfly.php b/app/Models/StandaloneDragonfly.php index 7b18666b8..adc1ea6cc 100644 --- a/app/Models/StandaloneDragonfly.php +++ b/app/Models/StandaloneDragonfly.php @@ -207,4 +207,7 @@ public function scheduledBackups() { return $this->morphMany(ScheduledDatabaseBackup::class, 'database'); } + public function database_name() { + return '0'; + } } diff --git a/app/Models/StandaloneKeydb.php b/app/Models/StandaloneKeydb.php index 1dc55228a..ff91322a0 100644 --- a/app/Models/StandaloneKeydb.php +++ b/app/Models/StandaloneKeydb.php @@ -208,5 +208,7 @@ public function scheduledBackups() { return $this->morphMany(ScheduledDatabaseBackup::class, 'database'); } - + public function database_name() { + return '0'; + } } diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php index 5e18bbfde..37d39f882 100644 --- a/app/Models/StandaloneMariadb.php +++ b/app/Models/StandaloneMariadb.php @@ -208,4 +208,7 @@ public function scheduledBackups() { return $this->morphMany(ScheduledDatabaseBackup::class, 'database'); } + public function database_name() { + return $this->mariadb_database; + } } diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php index 8e4d327a3..5538efe1a 100644 --- a/app/Models/StandaloneMongodb.php +++ b/app/Models/StandaloneMongodb.php @@ -223,4 +223,7 @@ public function scheduledBackups() { return $this->morphMany(ScheduledDatabaseBackup::class, 'database'); } + public function database_name() { + return $this->mongo_db; + } } diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php index eede451d7..53e9b6f22 100644 --- a/app/Models/StandaloneMysql.php +++ b/app/Models/StandaloneMysql.php @@ -209,4 +209,7 @@ public function scheduledBackups() { return $this->morphMany(ScheduledDatabaseBackup::class, 'database'); } + public function database_name() { + return $this->mysql_database; + } } diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index cf449a815..6435c49de 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -208,4 +208,7 @@ public function scheduledBackups() { return $this->morphMany(ScheduledDatabaseBackup::class, 'database'); } + public function database_name() { + return $this->postgres_db; + } } diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index da4701df9..de18c8c07 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -204,4 +204,7 @@ public function scheduledBackups() { return $this->morphMany(ScheduledDatabaseBackup::class, 'database'); } + public function database_name() { + return '0'; + } } diff --git a/app/Notifications/Database/BackupFailed.php b/app/Notifications/Database/BackupFailed.php index f149a9d06..3aa63ffd9 100644 --- a/app/Notifications/Database/BackupFailed.php +++ b/app/Notifications/Database/BackupFailed.php @@ -17,11 +17,13 @@ class BackupFailed extends Notification implements ShouldQueue public $tries = 1; public string $name; + public string $database_name; public string $frequency; public function __construct(ScheduledDatabaseBackup $backup, public $database, public $output) { $this->name = $database->name; + $this->database_name = $database->database_name(); $this->frequency = $backup->frequency; } @@ -36,6 +38,7 @@ public function toMail(): MailMessage $mail->subject("Coolify: [ACTION REQUIRED] Backup FAILED for {$this->database->name}"); $mail->view('emails.backup-failed', [ 'name' => $this->name, + 'database_name' => $this->database_name, 'frequency' => $this->frequency, 'output' => $this->output, ]); @@ -44,11 +47,11 @@ public function toMail(): MailMessage public function toDiscord(): string { - return "Coolify: Database backup for {$this->name} with frequency of {$this->frequency} was FAILED.\n\nReason: {$this->output}"; + return "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was FAILED.\n\nReason: {$this->output}"; } public function toTelegram(): array { - $message = "Coolify: Database backup for {$this->name} with frequency of {$this->frequency} was FAILED.\n\nReason: {$this->output}"; + $message = "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was FAILED.\n\nReason: {$this->output}"; return [ "message" => $message, ]; diff --git a/app/Notifications/Database/BackupSuccess.php b/app/Notifications/Database/BackupSuccess.php index bbe0bc6d3..9ca3234e1 100644 --- a/app/Notifications/Database/BackupSuccess.php +++ b/app/Notifications/Database/BackupSuccess.php @@ -14,11 +14,13 @@ class BackupSuccess extends Notification implements ShouldQueue public $tries = 1; public string $name; + public string $database_name; public string $frequency; public function __construct(ScheduledDatabaseBackup $backup, public $database) { $this->name = $database->name; + $this->database_name = $database->database_name(); $this->frequency = $backup->frequency; } @@ -33,6 +35,7 @@ public function toMail(): MailMessage $mail->subject("Coolify: Backup successfully done for {$this->database->name}"); $mail->view('emails.backup-success', [ 'name' => $this->name, + 'database_name' => $this->database_name, 'frequency' => $this->frequency, ]); return $mail; @@ -40,11 +43,11 @@ public function toMail(): MailMessage public function toDiscord(): string { - return "Coolify: Database backup for {$this->name} with frequency of {$this->frequency} was successful."; + return "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was successful."; } public function toTelegram(): array { - $message = "Coolify: Database backup for {$this->name} with frequency of {$this->frequency} was successful."; + $message = "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was successful."; return [ "message" => $message, ]; diff --git a/app/View/Components/Forms/Datalist.php b/app/View/Components/Forms/Datalist.php new file mode 100644 index 000000000..d4ed44266 --- /dev/null +++ b/app/View/Components/Forms/Datalist.php @@ -0,0 +1,38 @@ +id)) $this->id = new Cuid2(7); + if (is_null($this->name)) $this->name = $this->id; + + $this->label = Str::title($this->label); + return view('components.forms.datalist'); + } +} diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 966b1db59..b2c34900e 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -29,11 +29,13 @@ use Illuminate\Database\UniqueConstraintViolationException; use Illuminate\Mail\Message; use Illuminate\Notifications\Messages\MailMessage; +use Illuminate\Process\Pool; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Mail; +use Illuminate\Support\Facades\Process; use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Route; use Illuminate\Support\Str; @@ -1266,6 +1268,11 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal $serviceLabels->push("$removedLabelName=$removedLabel"); } } + if ($serviceLabels->count() > 0) { + $serviceLabels = $serviceLabels->map(function ($value, $key) { + return escapeDollarSign($value); + }); + } $baseName = generateApplicationContainerName($resource, $pull_request_id); $containerName = "$serviceName-$baseName"; if (count($serviceVolumes) > 0) { @@ -1424,6 +1431,14 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal foreach ($definedNetwork as $key => $network) { $networks->put($network, null); } + if (data_get($resource, 'settings.connect_to_docker_network')) { + $network = $resource->destination->network; + $networks->put($network, null); + $topLevelNetworks->put($network, [ + 'name' => $network, + 'external' => true + ]); + } data_set($service, 'networks', $networks->toArray()); // Get variables from the service foreach ($serviceVariables as $variableName => $variable) { @@ -1585,7 +1600,6 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal $fqdns = data_get($domains, "$serviceName.domain"); if ($fqdns) { $fqdns = str($fqdns)->explode(','); - $uuid = new Cuid2(7); if ($pull_request_id !== 0) { $fqdns = $fqdns->map(function ($fqdn) use ($pull_request_id, $resource) { $preview = ApplicationPreview::findPreviewByApplicationAndPullId($resource->id, $pull_request_id); @@ -1604,13 +1618,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal }); } $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik( - uuid: $uuid, + uuid: $resource->uuid, domains: $fqdns, serviceLabels: $serviceLabels )); $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy( network: $resource->destination->network, - uuid: $uuid, + uuid: $resource->uuid, domains: $fqdns, serviceLabels: $serviceLabels )); @@ -2004,3 +2018,37 @@ function parseLineForSudo(string $command, Server $server): string return $command; } + +function get_public_ips() +{ + try { + echo "Refreshing public ips!\n"; + $settings = InstanceSettings::get(); + [$first, $second] = Process::concurrently(function (Pool $pool) { + $pool->path(__DIR__)->command('curl -4s https://ifconfig.io'); + $pool->path(__DIR__)->command('curl -6s https://ifconfig.io'); + }); + $ipv4 = $first->output(); + if ($ipv4) { + $ipv4 = trim($ipv4); + $validate_ipv4 = filter_var($ipv4, FILTER_VALIDATE_IP); + if ($validate_ipv4 == false) { + echo "Invalid ipv4: $ipv4\n"; + return; + } + $settings->update(['public_ipv4' => $ipv4]); + } + $ipv6 = $second->output(); + if ($ipv6) { + $ipv6 = trim($ipv6); + $validate_ipv6 = filter_var($ipv6, FILTER_VALIDATE_IP); + if ($validate_ipv6 == false) { + echo "Invalid ipv6: $ipv6\n"; + return; + } + $settings->update(['public_ipv6' => $ipv6]); + } + } catch (\Throwable $e) { + echo "Error: {$e->getMessage()}\n"; + } +} diff --git a/config/sentry.php b/config/sentry.php index 7ae7ccfda..416daa809 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ // 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.266', + 'release' => '4.0.0-beta.267', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 7001afde8..66b6ee419 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ boolean('connect_to_docker_network')->default(false); + + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('application_settings', function (Blueprint $table) { + $table->dropColumn('connect_to_docker_network'); + }); + } +}; diff --git a/database/seeders/ProductionSeeder.php b/database/seeders/ProductionSeeder.php index 206e92f76..16dc3583e 100644 --- a/database/seeders/ProductionSeeder.php +++ b/database/seeders/ProductionSeeder.php @@ -177,27 +177,7 @@ public function run(): void } } - try { - $settings = InstanceSettings::get(); - if (is_null($settings->public_ipv4)) { - $ipv4 = Process::run('curl -4s https://ifconfig.io')->output(); - if ($ipv4) { - $ipv4 = trim($ipv4); - $ipv4 = filter_var($ipv4, FILTER_VALIDATE_IP); - $settings->update(['public_ipv4' => $ipv4]); - } - } - if (is_null($settings->public_ipv6)) { - $ipv6 = Process::run('curl -6s https://ifconfig.io')->output(); - if ($ipv6) { - $ipv6 = trim($ipv6); - $ipv6 = filter_var($ipv6, FILTER_VALIDATE_IP); - $settings->update(['public_ipv6' => $ipv6]); - } - } - } catch (\Throwable $e) { - echo "Error: {$e->getMessage()}\n"; - } + get_public_ips(); $oauth_settings_seeder = new OauthSettingSeeder(); $oauth_settings_seeder->run(); diff --git a/resources/css/app.css b/resources/css/app.css index a10103ce8..1f218490d 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -133,6 +133,11 @@ .badge { @apply inline-block w-3 h-3 text-xs font-bold leading-none border rounded-full border-neutral-200 dark:border-black; } +.badge-absolute { + @apply absolute top-0 right-0 w-2 h-2 border-none rounded-t-none rounded-r-none; + +} + .badge-success { @apply bg-success; } @@ -195,7 +200,7 @@ .kbd-custom { } .box { - @apply flex lg:flex-row flex-col p-2 transition-colors cursor-pointer min-h-[4rem] dark:bg-coolgray-100 bg-white border text-black dark:text-white hover:text-black border-neutral-200 dark:border-black hover:bg-neutral-100 dark:hover:bg-coollabs-100 dark:hover:text-white hover:no-underline; + @apply relative flex lg:flex-row flex-col p-2 transition-colors cursor-pointer min-h-[4rem] dark:bg-coolgray-100 bg-white border text-black dark:text-white hover:text-black border-neutral-200 dark:border-black hover:bg-neutral-100 dark:hover:bg-coollabs-100 dark:hover:text-white hover:no-underline; } .box-boarding { @apply flex lg:flex-row flex-col p-2 transition-colors cursor-pointer min-h-[4rem] dark:bg-coolgray-100 dark:text-white bg-neutral-50 border border-neutral-200 dark:border-black hover:bg-neutral-100 dark:hover:bg-coollabs-100 dark:hover:text-white hover:text-black hover:no-underline text-black ; diff --git a/resources/views/components/forms/datalist.blade.php b/resources/views/components/forms/datalist.blade.php new file mode 100644 index 000000000..c9710b728 --- /dev/null +++ b/resources/views/components/forms/datalist.blade.php @@ -0,0 +1,44 @@ +
+ + @error($id) + + @enderror + {{-- --}} +
diff --git a/resources/views/emails/backup-failed.blade.php b/resources/views/emails/backup-failed.blade.php index de6a7c981..f50ff0c33 100644 --- a/resources/views/emails/backup-failed.blade.php +++ b/resources/views/emails/backup-failed.blade.php @@ -1,5 +1,5 @@ -Database backup for {{ $name }} with frequency of {{ $frequency }} was FAILED. +Database backup for {{ $name }} (db:{{$database_name}}) with frequency of {{ $frequency }} was FAILED. ### Reason diff --git a/resources/views/emails/backup-success.blade.php b/resources/views/emails/backup-success.blade.php index 0d54a254c..e48df9e6a 100644 --- a/resources/views/emails/backup-success.blade.php +++ b/resources/views/emails/backup-success.blade.php @@ -1,3 +1,3 @@ -Database backup for {{ $name }} with frequency of {{ $frequency }} was successful. +Database backup for {{ $name }} (db:{{ $database_name }}) with frequency of {{ $frequency }} was successful. diff --git a/resources/views/livewire/boarding/index.blade.php b/resources/views/livewire/boarding/index.blade.php index 0f0dd8210..29bddbbaf 100644 --- a/resources/views/livewire/boarding/index.blade.php +++ b/resources/views/livewire/boarding/index.blade.php @@ -1,11 +1,13 @@ @php use App\Enums\ProxyTypes; @endphp
-
+
@if ($currentState === 'welcome')

Welcome to Coolify

Let me help you set up the basics.
- Get + Get Started
@@ -60,7 +62,8 @@ server.
Check this documentation for further help. + href="https://coolify.io/docs/knowledge-base/server/openssh">documentation for further + help. Check again @@ -120,7 +123,8 @@
- No (create + No + (create one for me) @@ -146,7 +150,8 @@ 'root' or skip the boarding process and add a new private key manually to Coolify and to the server. - Check + Check again @endif @@ -207,9 +212,14 @@ - +
+ +
Non-root user is experimental: docs. +
+
- @if ($server_id) - - - @foreach ($servers as $server) - - @endforeach - - @endif + + + @foreach ($servers as $server) + + @endforeach + Continue diff --git a/resources/views/livewire/project/application/advanced.blade.php b/resources/views/livewire/project/application/advanced.blade.php index 75a55c5b9..5d2922a7e 100644 --- a/resources/views/livewire/project/application/advanced.blade.php +++ b/resources/views/livewire/project/application/advanced.blade.php @@ -25,8 +25,21 @@ instantSave id="is_gzip_enabled" /> -

Logs

+ @if ($application->build_pack === 'dockercompose') + + @endif + @if ($application->build_pack === 'dockercompose') +

Network

+
+ +
+ @endif @if (!$application->settings->is_raw_compose_deployment_enabled) +

Logs

@endif diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index 558db9c3c..de83b03ee 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -4,7 +4,7 @@

General

Save - +
General configuration for your application.
@@ -38,13 +38,8 @@
@endif @if ($application->build_pack === 'dockercompose') -
- -
@if (count($parsedServices) > 0 && !$application->settings->is_raw_compose_deployment_enabled) -

Domains

+

Domains

@foreach (data_get($parsedServices, 'services') as $serviceName => $service) @if (!isDatabaseImage(data_get($service, 'image')))
diff --git a/resources/views/livewire/project/application/source.blade.php b/resources/views/livewire/project/application/source.blade.php index 84aec3e81..88347d2d8 100644 --- a/resources/views/livewire/project/application/source.blade.php +++ b/resources/views/livewire/project/application/source.blade.php @@ -27,7 +27,7 @@
-
@@ -36,10 +36,10 @@ label="Commit SHA" />
- @isset($application->private_key_id) + @if(data_get($application, 'private_key_id'))

Deploy Key

Currently attached Private Key: {{ $application->private_key->name }} + class="dark:text-warning">{{ data_get($application, 'private_key.name') }}

Select another Private Key

@@ -49,6 +49,6 @@ class="dark:text-warning">{{ $application->private_key->name }}
@endforeach
- @endisset + @endif
diff --git a/resources/views/livewire/project/database/create-scheduled-backup.blade.php b/resources/views/livewire/project/database/create-scheduled-backup.blade.php index da7871b0b..3b7c9e74d 100644 --- a/resources/views/livewire/project/database/create-scheduled-backup.blade.php +++ b/resources/views/livewire/project/database/create-scheduled-backup.blade.php @@ -10,7 +10,7 @@ @endforeach @endif - + Save diff --git a/resources/views/livewire/project/database/import.blade.php b/resources/views/livewire/project/database/import.blade.php index 01480fcdc..425383704 100644 --- a/resources/views/livewire/project/database/import.blade.php +++ b/resources/views/livewire/project/database/import.blade.php @@ -1,7 +1,7 @@
+ crossorigin="anonymous" referrerpolicy="no-referrer"> @script