mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-14 16:52:45 -04:00
Applications and service applications can now use the server resolver,
no resolver ("none"), or a custom resolver name. This allows servers
that mix Let's Encrypt domains with domains that use their own
certificates, such as Cloudflare Origin CA. The setting is available in
the UI and the API.
Closes #12138
186 lines
7.3 KiB
PHP
186 lines
7.3 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use OpenApi\Attributes as OA;
|
|
|
|
#[OA\Schema(
|
|
description: 'Application settings.',
|
|
type: 'object',
|
|
properties: [
|
|
'is_static' => ['type' => 'boolean'],
|
|
'is_git_submodules_enabled' => ['type' => 'boolean'],
|
|
'is_git_lfs_enabled' => ['type' => 'boolean'],
|
|
'is_auto_deploy_enabled' => ['type' => 'boolean'],
|
|
'is_force_https_enabled' => ['type' => 'boolean'],
|
|
'is_debug_enabled' => ['type' => 'boolean'],
|
|
'is_preview_deployments_enabled' => ['type' => 'boolean'],
|
|
'is_log_drain_enabled' => ['type' => 'boolean'],
|
|
'is_gpu_enabled' => ['type' => 'boolean'],
|
|
'gpu_driver' => ['type' => 'string', 'nullable' => true],
|
|
'gpu_count' => ['type' => 'string', 'nullable' => true],
|
|
'gpu_device_ids' => ['type' => 'string', 'nullable' => true],
|
|
'gpu_options' => ['type' => 'string', 'nullable' => true],
|
|
'is_include_timestamps' => ['type' => 'boolean'],
|
|
'is_swarm_only_worker_nodes' => ['type' => 'boolean'],
|
|
'is_raw_compose_deployment_enabled' => ['type' => 'boolean'],
|
|
'is_build_server_enabled' => ['type' => 'boolean'],
|
|
'is_consistent_container_name_enabled' => ['type' => 'boolean'],
|
|
'is_gzip_enabled' => ['type' => 'boolean'],
|
|
'traefik_certificate_resolver' => ['type' => 'string', 'nullable' => true, 'description' => 'Traefik certificate resolver override. Null uses the server setting, "none" uses no resolver.'],
|
|
'is_stripprefix_enabled' => ['type' => 'boolean'],
|
|
'connect_to_docker_network' => ['type' => 'boolean'],
|
|
'custom_internal_name' => ['type' => 'string', 'nullable' => true],
|
|
'custom_container_name_prefix' => ['type' => 'string', 'nullable' => true],
|
|
'is_container_label_escape_enabled' => ['type' => 'boolean'],
|
|
'is_env_sorting_enabled' => ['type' => 'boolean'],
|
|
'is_container_label_readonly_enabled' => ['type' => 'boolean'],
|
|
'is_preserve_repository_enabled' => ['type' => 'boolean'],
|
|
'disable_build_cache' => ['type' => 'boolean'],
|
|
'is_spa' => ['type' => 'boolean'],
|
|
'is_git_shallow_clone_enabled' => ['type' => 'boolean'],
|
|
'is_pr_deployments_public_enabled' => ['type' => 'boolean'],
|
|
'use_build_secrets' => ['type' => 'boolean'],
|
|
'inject_build_args_to_dockerfile' => ['type' => 'boolean'],
|
|
'include_source_commit_in_build' => ['type' => 'boolean'],
|
|
'docker_images_to_keep' => ['type' => 'integer'],
|
|
'stop_grace_period' => ['type' => 'integer', 'nullable' => true],
|
|
]
|
|
)]
|
|
class ApplicationSetting extends Model
|
|
{
|
|
/**
|
|
* Keeps generated names (prefix, timestamp and for compose apps the service name) well below the
|
|
* 63 character DNS label limit, with room for a longer suffix in the future.
|
|
*/
|
|
public const MAX_CONTAINER_NAME_PREFIX_LENGTH = 30;
|
|
|
|
protected $casts = [
|
|
'is_static' => 'boolean',
|
|
'is_spa' => 'boolean',
|
|
'is_build_server_enabled' => 'boolean',
|
|
'is_preserve_repository_enabled' => 'boolean',
|
|
'is_container_label_escape_enabled' => 'boolean',
|
|
'is_container_label_readonly_enabled' => 'boolean',
|
|
'use_build_secrets' => 'boolean',
|
|
'inject_build_args_to_dockerfile' => 'boolean',
|
|
'include_source_commit_in_build' => 'boolean',
|
|
'is_auto_deploy_enabled' => 'boolean',
|
|
'is_force_https_enabled' => 'boolean',
|
|
'is_debug_enabled' => 'boolean',
|
|
'is_preview_deployments_enabled' => 'boolean',
|
|
'is_pr_deployments_public_enabled' => 'boolean',
|
|
'is_git_submodules_enabled' => 'boolean',
|
|
'is_git_lfs_enabled' => 'boolean',
|
|
'is_git_shallow_clone_enabled' => 'boolean',
|
|
'docker_images_to_keep' => 'integer',
|
|
'stop_grace_period' => 'integer',
|
|
'is_log_drain_enabled' => 'boolean',
|
|
'is_gpu_enabled' => 'boolean',
|
|
'is_include_timestamps' => 'boolean',
|
|
'is_swarm_only_worker_nodes' => 'boolean',
|
|
'is_raw_compose_deployment_enabled' => 'boolean',
|
|
'is_consistent_container_name_enabled' => 'boolean',
|
|
'is_gzip_enabled' => 'boolean',
|
|
'is_stripprefix_enabled' => 'boolean',
|
|
'connect_to_docker_network' => 'boolean',
|
|
'is_env_sorting_enabled' => 'boolean',
|
|
'disable_build_cache' => 'boolean',
|
|
];
|
|
|
|
protected $fillable = [
|
|
'application_id',
|
|
'is_static',
|
|
'is_git_submodules_enabled',
|
|
'is_git_lfs_enabled',
|
|
'is_auto_deploy_enabled',
|
|
'is_force_https_enabled',
|
|
'is_debug_enabled',
|
|
'is_preview_deployments_enabled',
|
|
'is_log_drain_enabled',
|
|
'is_gpu_enabled',
|
|
'gpu_driver',
|
|
'gpu_count',
|
|
'gpu_device_ids',
|
|
'gpu_options',
|
|
'is_include_timestamps',
|
|
'is_swarm_only_worker_nodes',
|
|
'is_raw_compose_deployment_enabled',
|
|
'is_build_server_enabled',
|
|
'is_consistent_container_name_enabled',
|
|
'is_gzip_enabled',
|
|
'traefik_certificate_resolver',
|
|
'is_stripprefix_enabled',
|
|
'connect_to_docker_network',
|
|
'custom_internal_name',
|
|
'custom_container_name_prefix',
|
|
'is_container_label_escape_enabled',
|
|
'is_env_sorting_enabled',
|
|
'is_container_label_readonly_enabled',
|
|
'is_preserve_repository_enabled',
|
|
'disable_build_cache',
|
|
'is_spa',
|
|
'is_git_shallow_clone_enabled',
|
|
'is_pr_deployments_public_enabled',
|
|
'use_build_secrets',
|
|
'inject_build_args_to_dockerfile',
|
|
'include_source_commit_in_build',
|
|
'docker_images_to_keep',
|
|
'stop_grace_period',
|
|
];
|
|
|
|
/**
|
|
* Like custom container names, a prefix must be unique per server so that uuid, custom container
|
|
* name and prefix each identify one container when resolving connections.
|
|
*/
|
|
public static function isContainerNamePrefixInUse(string $prefix, Server $server, ?int $ignoreApplicationId = null): bool
|
|
{
|
|
return $server->applications()->contains(function (Application $application) use ($prefix, $ignoreApplicationId) {
|
|
return $application->id !== $ignoreApplicationId
|
|
&& in_array($prefix, [$application->uuid, $application->settings->custom_container_name_prefix, $application->settings->custom_internal_name], true);
|
|
});
|
|
}
|
|
|
|
public function stopGracePeriodSeconds(): int
|
|
{
|
|
if (
|
|
$this->stop_grace_period >= MIN_STOP_GRACE_PERIOD_SECONDS &&
|
|
$this->stop_grace_period <= MAX_STOP_GRACE_PERIOD_SECONDS
|
|
) {
|
|
return $this->stop_grace_period;
|
|
}
|
|
|
|
return DEFAULT_STOP_GRACE_PERIOD_SECONDS;
|
|
}
|
|
|
|
public function deploymentStopGracePeriodSeconds(): int
|
|
{
|
|
if (isDev() && $this->stop_grace_period === null) {
|
|
return MIN_STOP_GRACE_PERIOD_SECONDS;
|
|
}
|
|
|
|
return $this->stopGracePeriodSeconds();
|
|
}
|
|
|
|
public function isStatic(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
set: function ($value) {
|
|
if ($value) {
|
|
$this->application->ports_exposes = 80;
|
|
}
|
|
$this->application->save();
|
|
|
|
return $value;
|
|
}
|
|
);
|
|
}
|
|
|
|
public function application()
|
|
{
|
|
return $this->belongsTo(Application::class);
|
|
}
|
|
}
|