2024-01-07 15:23:41 +00:00
< ? php
namespace App\Livewire\Settings ;
use App\Models\InstanceSettings ;
2024-08-06 12:36:56 +00:00
use App\Models\Server ;
2024-12-03 23:30:39 +00:00
use Livewire\Attributes\Computed ;
2024-11-05 08:36:40 +00:00
use Livewire\Attributes\Validate ;
2024-01-07 15:23:41 +00:00
use Livewire\Component ;
class Index extends Component
{
public InstanceSettings $settings ;
2024-06-10 20:43:34 +00:00
2025-12-27 15:17:56 +00:00
public ? Server $server = null ;
2024-08-06 12:36:56 +00:00
2026-02-03 21:00:12 +00:00
#[Validate('nullable|string|max:255|url')]
2024-10-28 09:10:27 +00:00
public ? string $fqdn = null ;
2024-08-06 12:36:56 +00:00
2024-11-05 08:36:40 +00:00
#[Validate('required|integer|min:1025|max:65535')]
2024-10-28 09:10:27 +00:00
public int $public_port_min ;
2024-11-05 08:36:40 +00:00
#[Validate('required|integer|min:1025|max:65535')]
2024-10-28 09:10:27 +00:00
public int $public_port_max ;
2024-11-05 08:36:40 +00:00
#[Validate('nullable|string|max:255')]
2024-10-28 09:10:27 +00:00
public ? string $instance_name = null ;
2024-08-06 12:36:56 +00:00
2026-01-05 21:14:51 +00:00
#[Validate('nullable|ipv4')]
2024-10-28 09:10:27 +00:00
public ? string $public_ipv4 = null ;
2026-01-05 21:14:51 +00:00
#[Validate('nullable|ipv6')]
2024-10-28 09:10:27 +00:00
public ? string $public_ipv6 = null ;
2024-11-05 08:36:40 +00:00
#[Validate('required|string|timezone')]
2024-10-28 09:10:27 +00:00
public string $instance_timezone ;
2024-10-17 10:07:35 +00:00
2025-11-03 07:38:43 +00:00
#[Validate('nullable|string|max:50')]
public ? string $dev_helper_version = null ;
2025-08-28 08:52:41 +00:00
public array $domainConflicts = [];
public bool $showDomainConflictModal = false ;
public bool $forceSaveDomains = false ;
2025-11-02 17:13:58 +00:00
public $buildActivityId = null ;
2026-02-03 21:00:12 +00:00
protected array $messages = [
'fqdn.url' => 'Invalid instance URL.' ,
'fqdn.max' => 'URL must not exceed 255 characters.' ,
];
2024-10-28 09:10:27 +00:00
public function render ()
{
return view ( 'livewire.settings.index' );
}
2024-06-10 20:43:34 +00:00
2024-01-07 15:23:41 +00:00
public function mount ()
{
2024-10-28 09:10:27 +00:00
if ( ! isInstanceAdmin ()) {
return redirect () -> route ( 'dashboard' );
2024-01-07 15:23:41 +00:00
}
2025-07-03 13:50:53 +00:00
$this -> settings = instanceSettings ();
2025-12-27 15:17:56 +00:00
if ( ! isCloud ()) {
$this -> server = Server :: findOrFail ( 0 );
}
2025-07-03 13:50:53 +00:00
$this -> fqdn = $this -> settings -> fqdn ;
$this -> public_port_min = $this -> settings -> public_port_min ;
$this -> public_port_max = $this -> settings -> public_port_max ;
$this -> instance_name = $this -> settings -> instance_name ;
$this -> public_ipv4 = $this -> settings -> public_ipv4 ;
$this -> public_ipv6 = $this -> settings -> public_ipv6 ;
$this -> instance_timezone = $this -> settings -> instance_timezone ;
2025-11-03 07:38:43 +00:00
$this -> dev_helper_version = $this -> settings -> dev_helper_version ;
2024-01-07 15:23:41 +00:00
}
2024-06-10 20:43:34 +00:00
2024-12-03 23:30:39 +00:00
#[Computed]
public function timezones () : array
{
return collect ( timezone_identifiers_list ())
-> sort ()
-> values ()
-> toArray ();
}
2024-10-28 09:10:27 +00:00
public function instantSave ( $isSave = true )
2024-08-06 12:36:56 +00:00
{
2024-11-25 16:56:19 +00:00
$this -> validate ();
2026-01-01 10:45:13 +00:00
$this -> settings -> fqdn = $this -> fqdn ? trim ( $this -> fqdn ) : $this -> fqdn ;
2024-10-28 09:10:27 +00:00
$this -> settings -> public_port_min = $this -> public_port_min ;
$this -> settings -> public_port_max = $this -> public_port_max ;
$this -> settings -> instance_name = $this -> instance_name ;
$this -> settings -> public_ipv4 = $this -> public_ipv4 ;
$this -> settings -> public_ipv6 = $this -> public_ipv6 ;
$this -> settings -> instance_timezone = $this -> instance_timezone ;
2025-11-03 07:38:43 +00:00
$this -> settings -> dev_helper_version = $this -> dev_helper_version ;
2024-10-28 09:10:27 +00:00
if ( $isSave ) {
$this -> settings -> save ();
$this -> dispatch ( 'success' , 'Settings updated!' );
}
2024-08-06 12:36:56 +00:00
}
2025-08-28 08:52:41 +00:00
public function confirmDomainUsage ()
{
$this -> forceSaveDomains = true ;
$this -> showDomainConflictModal = false ;
$this -> submit ();
}
2024-08-06 12:36:56 +00:00
public function submit ()
{
try {
$error_show = false ;
$this -> resetErrorBag ();
2024-11-14 09:02:37 +00:00
if ( ! validate_timezone ( $this -> instance_timezone )) {
$this -> instance_timezone = config ( 'app.timezone' );
2025-01-07 14:31:43 +00:00
throw new \Exception ( 'Invalid timezone.' );
} else {
$this -> settings -> instance_timezone = $this -> instance_timezone ;
2024-11-14 09:02:37 +00:00
}
2024-08-06 12:36:56 +00:00
if ( $this -> settings -> public_port_min > $this -> settings -> public_port_max ) {
$this -> addError ( 'settings.public_port_min' , 'The minimum port must be lower than the maximum port.' );
2025-01-07 14:31:43 +00:00
return ;
2024-08-06 12:36:56 +00:00
}
2026-01-02 11:16:52 +00:00
// Trim FQDN to remove leading/trailing whitespace before validation
2026-01-01 10:45:13 +00:00
if ( $this -> fqdn ) {
$this -> fqdn = trim ( $this -> fqdn );
}
2026-01-02 11:16:52 +00:00
$this -> validate ();
2025-12-27 15:17:56 +00:00
if ( $this -> settings -> is_dns_validation_enabled && $this -> fqdn && $this -> server ) {
2025-09-09 07:00:35 +00:00
if ( ! validateDNSEntry ( $this -> fqdn , $this -> server )) {
2025-06-30 06:50:17 +00:00
$this -> dispatch ( 'error' , " Validating DNS failed.<br><br>Make sure you have added the DNS records correctly.<br><br> { $this -> fqdn } -> { $this -> server -> ip } <br><br>Check this <a target='_blank' class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/dns-configuration'>documentation</a> for further help. " );
2025-01-07 14:31:43 +00:00
$error_show = true ;
}
2024-08-06 12:36:56 +00:00
}
2025-06-30 06:50:17 +00:00
if ( $this -> fqdn ) {
2025-08-28 08:52:41 +00:00
if ( ! $this -> forceSaveDomains ) {
$result = checkDomainUsage ( domain : $this -> fqdn );
if ( $result [ 'hasConflicts' ]) {
$this -> domainConflicts = $result [ 'conflicts' ];
$this -> showDomainConflictModal = true ;
return ;
}
} else {
// Reset the force flag after using it
$this -> forceSaveDomains = false ;
}
2024-08-06 12:36:56 +00:00
}
2024-10-28 09:10:27 +00:00
$this -> instantSave ( isSave : false );
2024-08-06 12:36:56 +00:00
$this -> settings -> save ();
2025-12-27 15:17:56 +00:00
if ( $this -> server ) {
$this -> server -> setupDynamicProxyConfiguration ();
}
2024-08-06 12:36:56 +00:00
if ( ! $error_show ) {
$this -> dispatch ( 'success' , 'Instance settings updated successfully!' );
}
2025-01-07 14:31:43 +00:00
} catch ( \Exception $e ) {
2024-08-06 12:36:56 +00:00
return handleError ( $e , $this );
}
}
2025-11-02 17:13:58 +00:00
public function buildHelperImage ()
{
try {
if ( ! isDev ()) {
$this -> dispatch ( 'error' , 'Building helper image is only available in development mode.' );
return ;
}
2025-12-27 15:17:56 +00:00
if ( ! $this -> server ) {
$this -> dispatch ( 'error' , 'Server not available.' );
return ;
}
2025-11-02 17:13:58 +00:00
$version = $this -> dev_helper_version ? : config ( 'constants.coolify.helper_version' );
if ( empty ( $version )) {
$this -> dispatch ( 'error' , 'Please specify a version to build.' );
return ;
}
$buildCommand = " docker build -t ghcr.io/coollabsio/coolify-helper: { $version } -f docker/coolify-helper/Dockerfile . " ;
$activity = remote_process (
command : [ $buildCommand ],
server : $this -> server ,
type : 'build-helper-image'
);
$this -> buildActivityId = $activity -> id ;
$this -> dispatch ( 'activityMonitor' , $activity -> id );
$this -> dispatch ( 'success' , " Building coolify-helper: { $version } ... " );
} catch ( \Exception $e ) {
return handleError ( $e , $this );
}
}
2024-08-26 13:26:08 +00:00
}