chore: remove functions from shared.php

- Removed all notification functions from shared.php to make it easier to maintain and test.
This commit is contained in:
peaklabs-dev
2024-12-09 15:38:21 +01:00
parent df6c5c55e1
commit d289f41ff6

View File

@@ -25,23 +25,15 @@ use App\Models\StandalonePostgresql;
use App\Models\StandaloneRedis; use App\Models\StandaloneRedis;
use App\Models\Team; use App\Models\Team;
use App\Models\User; use App\Models\User;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\SlackChannel;
use App\Notifications\Channels\TelegramChannel;
use App\Notifications\Internal\GeneralNotification;
use Carbon\CarbonImmutable; use Carbon\CarbonImmutable;
use DanHarrin\LivewireRateLimiting\Exceptions\TooManyRequestsException; use DanHarrin\LivewireRateLimiting\Exceptions\TooManyRequestsException;
use Illuminate\Database\UniqueConstraintViolationException; use Illuminate\Database\UniqueConstraintViolationException;
use Illuminate\Mail\Message;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Process\Pool; use Illuminate\Process\Pool;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Process; use Illuminate\Support\Facades\Process;
use Illuminate\Support\Facades\RateLimiter; use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Request;
@@ -68,27 +60,27 @@ function base_configuration_dir(): string
} }
function application_configuration_dir(): string function application_configuration_dir(): string
{ {
return base_configuration_dir() . '/applications'; return base_configuration_dir().'/applications';
} }
function service_configuration_dir(): string function service_configuration_dir(): string
{ {
return base_configuration_dir() . '/services'; return base_configuration_dir().'/services';
} }
function database_configuration_dir(): string function database_configuration_dir(): string
{ {
return base_configuration_dir() . '/databases'; return base_configuration_dir().'/databases';
} }
function database_proxy_dir($uuid): string function database_proxy_dir($uuid): string
{ {
return base_configuration_dir() . "/databases/$uuid/proxy"; return base_configuration_dir()."/databases/$uuid/proxy";
} }
function backup_dir(): string function backup_dir(): string
{ {
return base_configuration_dir() . '/backups'; return base_configuration_dir().'/backups';
} }
function metrics_dir(): string function metrics_dir(): string
{ {
return base_configuration_dir() . '/metrics'; return base_configuration_dir().'/metrics';
} }
function sanitize_string(?string $input = null): ?string function sanitize_string(?string $input = null): ?string
@@ -139,15 +131,15 @@ function showBoarding(): bool
} }
function refreshSession(?Team $team = null): void function refreshSession(?Team $team = null): void
{ {
if (!$team) { if (! $team) {
if (Auth::user()->currentTeam()) { if (Auth::user()->currentTeam()) {
$team = Team::find(Auth::user()->currentTeam()->id); $team = Team::find(Auth::user()->currentTeam()->id);
} else { } else {
$team = User::find(Auth::id())->teams->first(); $team = User::find(Auth::id())->teams->first();
} }
} }
Cache::forget('team:' . Auth::id()); Cache::forget('team:'.Auth::id());
Cache::remember('team:' . Auth::id(), 3600, function () use ($team) { Cache::remember('team:'.Auth::id(), 3600, function () use ($team) {
return $team; return $team;
}); });
session(['currentTeam' => $team]); session(['currentTeam' => $team]);
@@ -179,7 +171,7 @@ function handleError(?Throwable $error = null, ?Livewire\Component $livewire = n
$message = null; $message = null;
} }
if ($customErrorMessage) { if ($customErrorMessage) {
$message = $customErrorMessage . ' ' . $message; $message = $customErrorMessage.' '.$message;
} }
if (isset($livewire)) { if (isset($livewire)) {
@@ -252,7 +244,7 @@ function generateSSHKey(string $type = 'rsa')
function formatPrivateKey(string $privateKey) function formatPrivateKey(string $privateKey)
{ {
$privateKey = trim($privateKey); $privateKey = trim($privateKey);
if (!str_ends_with($privateKey, "\n")) { if (! str_ends_with($privateKey, "\n")) {
$privateKey .= "\n"; $privateKey .= "\n";
} }
@@ -267,43 +259,6 @@ function generate_application_name(string $git_repository, string $git_branch, ?
return Str::kebab("$git_repository:$git_branch-$cuid"); return Str::kebab("$git_repository:$git_branch-$cuid");
} }
function is_transactional_emails_active(): bool
{
return isEmailEnabled(\App\Models\InstanceSettings::get());
}
function set_transanctional_email_settings(?InstanceSettings $settings = null): ?string
{
if (!$settings) {
$settings = instanceSettings();
}
config()->set('mail.from.address', data_get($settings, 'smtp_from_address'));
config()->set('mail.from.name', data_get($settings, 'smtp_from_name'));
if (data_get($settings, 'resend_enabled')) {
config()->set('mail.default', 'resend');
config()->set('resend.api_key', data_get($settings, 'resend_api_key'));
return 'resend';
}
if (data_get($settings, 'smtp_enabled')) {
config()->set('mail.default', 'smtp');
config()->set('mail.mailers.smtp', [
'transport' => 'smtp',
'host' => data_get($settings, 'smtp_host'),
'port' => data_get($settings, 'smtp_port'),
'encryption' => data_get($settings, 'smtp_encryption'),
'username' => data_get($settings, 'smtp_username'),
'password' => data_get($settings, 'smtp_password'),
'timeout' => data_get($settings, 'smtp_timeout'),
'local_domain' => null,
]);
return 'smtp';
}
return null;
}
function base_ip(): string function base_ip(): string
{ {
if (isDev()) { if (isDev()) {
@@ -374,7 +329,7 @@ function isSubscribed()
function isProduction(): bool function isProduction(): bool
{ {
return !isDev(); return ! isDev();
} }
function isDev(): bool function isDev(): bool
{ {
@@ -414,85 +369,7 @@ function validate_timezone(string $timezone): bool
{ {
return in_array($timezone, timezone_identifiers_list()); return in_array($timezone, timezone_identifiers_list());
} }
function send_internal_notification(string $message): void
{
try {
$team = Team::find(0);
$team?->notify(new GeneralNotification($message));
} catch (\Throwable $e) {
ray($e->getMessage());
}
}
function send_user_an_email(MailMessage $mail, string $email, ?string $cc = null): void
{
$settings = instanceSettings();
$type = set_transanctional_email_settings($settings);
if (!$type) {
throw new Exception('No email settings found.');
}
if ($cc) {
Mail::send(
[],
[],
fn(Message $message) => $message
->to($email)
->replyTo($email)
->cc($cc)
->subject($mail->subject)
->html((string) $mail->render())
);
} else {
Mail::send(
[],
[],
fn(Message $message) => $message
->to($email)
->subject($mail->subject)
->html((string) $mail->render())
);
}
}
function isTestEmailEnabled($notifiable)
{
if (data_get($notifiable, 'use_instance_email_settings') && isInstanceAdmin()) {
return true;
} elseif (data_get($notifiable, 'smtp_enabled') || data_get($notifiable, 'resend_enabled') && auth()->user()->isAdminFromSession()) {
return true;
}
return false;
}
function isEmailEnabled($notifiable)
{
return data_get($notifiable, 'smtp_enabled') || data_get($notifiable, 'resend_enabled') || data_get($notifiable, 'use_instance_email_settings');
}
function setNotificationChannels($notifiable, $event)
{
$channels = [];
$isEmailEnabled = isEmailEnabled($notifiable);
$isSlackEnabled = data_get($notifiable, 'slack_enabled');
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isTelegramEnabled = data_get($notifiable, 'telegram_enabled');
$isSubscribedToEmailEvent = data_get($notifiable, "smtp_notifications_$event");
$isSubscribedToDiscordEvent = data_get($notifiable, "discord_notifications_$event");
$isSubscribedToTelegramEvent = data_get($notifiable, "telegram_notifications_$event");
$isSubscribedToSlackEvent = data_get($notifiable, "slack_notifications_$event");
if ($isDiscordEnabled && $isSubscribedToDiscordEvent) {
$channels[] = DiscordChannel::class;
}
if ($isEmailEnabled && $isSubscribedToEmailEvent) {
$channels[] = EmailChannel::class;
}
if ($isTelegramEnabled && $isSubscribedToTelegramEvent) {
$channels[] = TelegramChannel::class;
}
if ($isSlackEnabled && $isSubscribedToSlackEvent) {
$channels[] = SlackChannel::class;
}
return $channels;
}
function parseEnvFormatToArray($env_file_contents) function parseEnvFormatToArray($env_file_contents)
{ {
$env_array = []; $env_array = [];
@@ -594,7 +471,7 @@ function getResourceByUuid(string $uuid, ?int $teamId = null)
return null; return null;
} }
$resource = queryResourcesByUuid($uuid); $resource = queryResourcesByUuid($uuid);
if (!is_null($resource) && $resource->environment->project->team_id === $teamId) { if (! is_null($resource) && $resource->environment->project->team_id === $teamId) {
return $resource; return $resource;
} }
@@ -686,29 +563,29 @@ function queryResourcesByUuid(string $uuid)
function generateTagDeployWebhook($tag_name) function generateTagDeployWebhook($tag_name)
{ {
$baseUrl = base_url(); $baseUrl = base_url();
$api = Url::fromString($baseUrl) . '/api/v1'; $api = Url::fromString($baseUrl).'/api/v1';
$endpoint = "/deploy?tag=$tag_name"; $endpoint = "/deploy?tag=$tag_name";
return $api . $endpoint; return $api.$endpoint;
} }
function generateDeployWebhook($resource) function generateDeployWebhook($resource)
{ {
$baseUrl = base_url(); $baseUrl = base_url();
$api = Url::fromString($baseUrl) . '/api/v1'; $api = Url::fromString($baseUrl).'/api/v1';
$endpoint = '/deploy'; $endpoint = '/deploy';
$uuid = data_get($resource, 'uuid'); $uuid = data_get($resource, 'uuid');
return $api . $endpoint . "?uuid=$uuid&force=false"; return $api.$endpoint."?uuid=$uuid&force=false";
} }
function generateGitManualWebhook($resource, $type) function generateGitManualWebhook($resource, $type)
{ {
if ($resource->source_id !== 0 && !is_null($resource->source_id)) { if ($resource->source_id !== 0 && ! is_null($resource->source_id)) {
return null; return null;
} }
if ($resource->getMorphClass() === \App\Models\Application::class) { if ($resource->getMorphClass() === \App\Models\Application::class) {
$baseUrl = base_url(); $baseUrl = base_url();
return Url::fromString($baseUrl) . "/webhooks/source/$type/events/manual"; return Url::fromString($baseUrl)."/webhooks/source/$type/events/manual";
} }
return null; return null;
@@ -735,7 +612,7 @@ function getTopLevelNetworks(Service|Application $resource)
$hasHostNetworkMode = data_get($service, 'network_mode') === 'host' ? true : false; $hasHostNetworkMode = data_get($service, 'network_mode') === 'host' ? true : false;
// Only add 'networks' key if 'network_mode' is not 'host' // Only add 'networks' key if 'network_mode' is not 'host'
if (!$hasHostNetworkMode) { if (! $hasHostNetworkMode) {
// Collect/create/update networks // Collect/create/update networks
if ($serviceNetworks->count() > 0) { if ($serviceNetworks->count() > 0) {
foreach ($serviceNetworks as $networkName => $networkDetails) { foreach ($serviceNetworks as $networkName => $networkDetails) {
@@ -749,7 +626,7 @@ function getTopLevelNetworks(Service|Application $resource)
$networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) { $networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) {
return $value == $networkName || $key == $networkName; return $value == $networkName || $key == $networkName;
}); });
if (!$networkExists) { if (! $networkExists) {
if (is_string($networkDetails) || is_int($networkDetails)) { if (is_string($networkDetails) || is_int($networkDetails)) {
$topLevelNetworks->put($networkDetails, null); $topLevelNetworks->put($networkDetails, null);
} }
@@ -760,7 +637,7 @@ function getTopLevelNetworks(Service|Application $resource)
$definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) { $definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) {
return $value == $definedNetwork; return $value == $definedNetwork;
}); });
if (!$definedNetworkExists) { if (! $definedNetworkExists) {
foreach ($definedNetwork as $network) { foreach ($definedNetwork as $network) {
$topLevelNetworks->put($network, [ $topLevelNetworks->put($network, [
'name' => $network, 'name' => $network,
@@ -801,7 +678,7 @@ function getTopLevelNetworks(Service|Application $resource)
$networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) { $networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) {
return $value == $networkName || $key == $networkName; return $value == $networkName || $key == $networkName;
}); });
if (!$networkExists) { if (! $networkExists) {
if (is_string($networkDetails) || is_int($networkDetails)) { if (is_string($networkDetails) || is_int($networkDetails)) {
$topLevelNetworks->put($networkDetails, null); $topLevelNetworks->put($networkDetails, null);
} }
@@ -811,7 +688,7 @@ function getTopLevelNetworks(Service|Application $resource)
$definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) { $definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) {
return $value == $definedNetwork; return $value == $definedNetwork;
}); });
if (!$definedNetworkExists) { if (! $definedNetworkExists) {
foreach ($definedNetwork as $network) { foreach ($definedNetwork as $network) {
$topLevelNetworks->put($network, [ $topLevelNetworks->put($network, [
'name' => $network, 'name' => $network,
@@ -947,7 +824,7 @@ function generateEnvValue(string $command, Service|Application|null $service = n
case 'PASSWORD_64': case 'PASSWORD_64':
$generatedValue = Str::password(length: 64, symbols: false); $generatedValue = Str::password(length: 64, symbols: false);
break; break;
// This is not base64, it's just a random string // This is not base64, it's just a random string
case 'BASE64_64': case 'BASE64_64':
$generatedValue = Str::random(64); $generatedValue = Str::random(64);
break; break;
@@ -958,7 +835,7 @@ function generateEnvValue(string $command, Service|Application|null $service = n
case 'BASE64_32': case 'BASE64_32':
$generatedValue = Str::random(32); $generatedValue = Str::random(32);
break; break;
// This is base64, // This is base64,
case 'REALBASE64_64': case 'REALBASE64_64':
$generatedValue = base64_encode(Str::random(64)); $generatedValue = base64_encode(Str::random(64));
break; break;
@@ -1058,7 +935,7 @@ function validate_dns_entry(string $fqdn, Server $server)
} }
$settings = instanceSettings(); $settings = instanceSettings();
$is_dns_validation_enabled = data_get($settings, 'is_dns_validation_enabled'); $is_dns_validation_enabled = data_get($settings, 'is_dns_validation_enabled');
if (!$is_dns_validation_enabled) { if (! $is_dns_validation_enabled) {
return true; return true;
} }
$dns_servers = data_get($settings, 'custom_dns_servers'); $dns_servers = data_get($settings, 'custom_dns_servers');
@@ -1076,7 +953,7 @@ function validate_dns_entry(string $fqdn, Server $server)
$query = new DNSQuery($dns_server); $query = new DNSQuery($dns_server);
$results = $query->query($host, $type); $results = $query->query($host, $type);
if ($results === false || $query->hasError()) { if ($results === false || $query->hasError()) {
ray('Error: ' . $query->getLasterror()); ray('Error: '.$query->getLasterror());
} else { } else {
foreach ($results as $result) { foreach ($results as $result) {
if ($result->getType() == $type) { if ($result->getType() == $type) {
@@ -1086,7 +963,7 @@ function validate_dns_entry(string $fqdn, Server $server)
break; break;
} }
if ($result->getData() === $ip) { if ($result->getData() === $ip) {
ray($host . ' has IP address ' . $result->getData()); ray($host.' has IP address '.$result->getData());
ray($result->getString()); ray($result->getString());
$found_matching_ip = true; $found_matching_ip = true;
break; break;
@@ -1134,15 +1011,15 @@ function checkIfDomainIsAlreadyUsed(Collection|array $domains, ?string $teamId =
$applications = Application::ownedByCurrentTeamAPI($teamId)->get(['fqdn', 'uuid']); $applications = Application::ownedByCurrentTeamAPI($teamId)->get(['fqdn', 'uuid']);
$serviceApplications = ServiceApplication::ownedByCurrentTeamAPI($teamId)->get(['fqdn', 'uuid']); $serviceApplications = ServiceApplication::ownedByCurrentTeamAPI($teamId)->get(['fqdn', 'uuid']);
if ($uuid) { if ($uuid) {
$applications = $applications->filter(fn($app) => $app->uuid !== $uuid); $applications = $applications->filter(fn ($app) => $app->uuid !== $uuid);
$serviceApplications = $serviceApplications->filter(fn($app) => $app->uuid !== $uuid); $serviceApplications = $serviceApplications->filter(fn ($app) => $app->uuid !== $uuid);
} }
$domainFound = false; $domainFound = false;
foreach ($applications as $app) { foreach ($applications as $app) {
if (is_null($app->fqdn)) { if (is_null($app->fqdn)) {
continue; continue;
} }
$list_of_domains = collect(explode(',', $app->fqdn))->filter(fn($fqdn) => $fqdn !== ''); $list_of_domains = collect(explode(',', $app->fqdn))->filter(fn ($fqdn) => $fqdn !== '');
foreach ($list_of_domains as $domain) { foreach ($list_of_domains as $domain) {
if (str($domain)->endsWith('/')) { if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/'); $domain = str($domain)->beforeLast('/');
@@ -1161,7 +1038,7 @@ function checkIfDomainIsAlreadyUsed(Collection|array $domains, ?string $teamId =
if (str($app->fqdn)->isEmpty()) { if (str($app->fqdn)->isEmpty()) {
continue; continue;
} }
$list_of_domains = collect(explode(',', $app->fqdn))->filter(fn($fqdn) => $fqdn !== ''); $list_of_domains = collect(explode(',', $app->fqdn))->filter(fn ($fqdn) => $fqdn !== '');
foreach ($list_of_domains as $domain) { foreach ($list_of_domains as $domain) {
if (str($domain)->endsWith('/')) { if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/'); $domain = str($domain)->beforeLast('/');
@@ -1211,7 +1088,7 @@ function check_domain_usage(ServiceApplication|Application|null $resource = null
}); });
$apps = Application::all(); $apps = Application::all();
foreach ($apps as $app) { foreach ($apps as $app) {
$list_of_domains = collect(explode(',', $app->fqdn))->filter(fn($fqdn) => $fqdn !== ''); $list_of_domains = collect(explode(',', $app->fqdn))->filter(fn ($fqdn) => $fqdn !== '');
foreach ($list_of_domains as $domain) { foreach ($list_of_domains as $domain) {
if (str($domain)->endsWith('/')) { if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/'); $domain = str($domain)->beforeLast('/');
@@ -1230,7 +1107,7 @@ function check_domain_usage(ServiceApplication|Application|null $resource = null
} }
$apps = ServiceApplication::all(); $apps = ServiceApplication::all();
foreach ($apps as $app) { foreach ($apps as $app) {
$list_of_domains = collect(explode(',', $app->fqdn))->filter(fn($fqdn) => $fqdn !== ''); $list_of_domains = collect(explode(',', $app->fqdn))->filter(fn ($fqdn) => $fqdn !== '');
foreach ($list_of_domains as $domain) { foreach ($list_of_domains as $domain) {
if (str($domain)->endsWith('/')) { if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/'); $domain = str($domain)->beforeLast('/');
@@ -1266,7 +1143,7 @@ function parseCommandsByLineForSudo(Collection $commands, Server $server): array
{ {
$commands = $commands->map(function ($line) { $commands = $commands->map(function ($line) {
if ( if (
!str(trim($line))->startsWith([ ! str(trim($line))->startsWith([
'cd', 'cd',
'command', 'command',
'echo', 'echo',
@@ -1287,7 +1164,7 @@ function parseCommandsByLineForSudo(Collection $commands, Server $server): array
$commands = $commands->map(function ($line) use ($server) { $commands = $commands->map(function ($line) use ($server) {
if (Str::startsWith($line, 'sudo mkdir -p')) { if (Str::startsWith($line, 'sudo mkdir -p')) {
return "$line && sudo chown -R $server->user:$server->user " . Str::after($line, 'sudo mkdir -p') . ' && sudo chmod -R o-rwx ' . Str::after($line, 'sudo mkdir -p'); return "$line && sudo chown -R $server->user:$server->user ".Str::after($line, 'sudo mkdir -p').' && sudo chmod -R o-rwx '.Str::after($line, 'sudo mkdir -p');
} }
return $line; return $line;
@@ -1315,11 +1192,11 @@ function parseCommandsByLineForSudo(Collection $commands, Server $server): array
} }
function parseLineForSudo(string $command, Server $server): string function parseLineForSudo(string $command, Server $server): string
{ {
if (!str($command)->startSwith('cd') && !str($command)->startSwith('command')) { if (! str($command)->startSwith('cd') && ! str($command)->startSwith('command')) {
$command = "sudo $command"; $command = "sudo $command";
} }
if (Str::startsWith($command, 'sudo mkdir -p')) { if (Str::startsWith($command, 'sudo mkdir -p')) {
$command = "$command && sudo chown -R $server->user:$server->user " . Str::after($command, 'sudo mkdir -p') . ' && sudo chmod -R o-rwx ' . Str::after($command, 'sudo mkdir -p'); $command = "$command && sudo chown -R $server->user:$server->user ".Str::after($command, 'sudo mkdir -p').' && sudo chmod -R o-rwx '.Str::after($command, 'sudo mkdir -p');
} }
if (str($command)->contains('$(') || str($command)->contains('`')) { if (str($command)->contains('$(') || str($command)->contains('`')) {
$command = str($command)->replace('$(', '$(sudo ')->replace('`', '`sudo ')->value(); $command = str($command)->replace('$(', '$(sudo ')->replace('`', '`sudo ')->value();
@@ -1441,7 +1318,7 @@ function parseServiceVolumes($serviceVolumes, $resource, $topLevelVolumes, $pull
$isDirectory = data_get($foundConfig, 'is_directory'); $isDirectory = data_get($foundConfig, 'is_directory');
} else { } else {
$isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null); $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null);
if ((is_null($isDirectory) || !$isDirectory) && is_null($content)) { if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) {
// if isDirectory is not set (or false) & content is also not set, we assume it is a directory // if isDirectory is not set (or false) & content is also not set, we assume it is a directory
ray('setting isDirectory to true'); ray('setting isDirectory to true');
$isDirectory = true; $isDirectory = true;
@@ -1456,9 +1333,9 @@ function parseServiceVolumes($serviceVolumes, $resource, $topLevelVolumes, $pull
return $volume; return $volume;
} }
if (get_class($resource) === \App\Models\Application::class) { if (get_class($resource) === \App\Models\Application::class) {
$dir = base_configuration_dir() . '/applications/' . $resource->uuid; $dir = base_configuration_dir().'/applications/'.$resource->uuid;
} else { } else {
$dir = base_configuration_dir() . '/services/' . $resource->service->uuid; $dir = base_configuration_dir().'/services/'.$resource->service->uuid;
} }
if ($source->startsWith('.')) { if ($source->startsWith('.')) {
@@ -1468,9 +1345,9 @@ function parseServiceVolumes($serviceVolumes, $resource, $topLevelVolumes, $pull
$source = $source->replaceFirst('~', $dir); $source = $source->replaceFirst('~', $dir);
} }
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$source = $source . "-pr-$pull_request_id"; $source = $source."-pr-$pull_request_id";
} }
if (!$resource?->settings?->is_preserve_repository_enabled || $foundConfig?->is_based_on_git) { if (! $resource?->settings?->is_preserve_repository_enabled || $foundConfig?->is_based_on_git) {
LocalFileVolume::updateOrCreate( LocalFileVolume::updateOrCreate(
[ [
'mount_path' => $target, 'mount_path' => $target,
@@ -1599,7 +1476,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
if ($serviceLabels->count() > 0) { if ($serviceLabels->count() > 0) {
$removedLabels = collect([]); $removedLabels = collect([]);
$serviceLabels = $serviceLabels->filter(function ($serviceLabel, $serviceLabelName) use ($removedLabels) { $serviceLabels = $serviceLabels->filter(function ($serviceLabel, $serviceLabelName) use ($removedLabels) {
if (!str($serviceLabel)->contains('=')) { if (! str($serviceLabel)->contains('=')) {
$removedLabels->put($serviceLabelName, $serviceLabel); $removedLabels->put($serviceLabelName, $serviceLabel);
return false; return false;
@@ -1681,7 +1558,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) { $networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) {
return $value == $networkName || $key == $networkName; return $value == $networkName || $key == $networkName;
}); });
if (!$networkExists) { if (! $networkExists) {
if (is_string($networkDetails) || is_int($networkDetails)) { if (is_string($networkDetails) || is_int($networkDetails)) {
$topLevelNetworks->put($networkDetails, null); $topLevelNetworks->put($networkDetails, null);
} }
@@ -1707,12 +1584,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$savedService->ports = $collectedPorts->implode(','); $savedService->ports = $collectedPorts->implode(',');
$savedService->save(); $savedService->save();
if (!$hasHostNetworkMode) { if (! $hasHostNetworkMode) {
// Add Coolify specific networks // Add Coolify specific networks
$definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) { $definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) {
return $value == $definedNetwork; return $value == $definedNetwork;
}); });
if (!$definedNetworkExists) { if (! $definedNetworkExists) {
foreach ($definedNetwork as $network) { foreach ($definedNetwork as $network) {
$topLevelNetworks->put($network, [ $topLevelNetworks->put($network, [
'name' => $network, 'name' => $network,
@@ -1924,9 +1801,9 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$fqdn = "$fqdn$path"; $fqdn = "$fqdn$path";
} }
if (!$isDatabase) { if (! $isDatabase) {
if ($savedService->fqdn) { if ($savedService->fqdn) {
data_set($savedService, 'fqdn', $savedService->fqdn . ',' . $fqdn); data_set($savedService, 'fqdn', $savedService->fqdn.','.$fqdn);
} else { } else {
data_set($savedService, 'fqdn', $fqdn); data_set($savedService, 'fqdn', $fqdn);
} }
@@ -1941,7 +1818,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
]); ]);
} }
// Caddy needs exact port in some cases. // Caddy needs exact port in some cases.
if ($predefinedPort && !$key->endsWith("_{$predefinedPort}")) { if ($predefinedPort && ! $key->endsWith("_{$predefinedPort}")) {
$fqdns_exploded = str($savedService->fqdn)->explode(','); $fqdns_exploded = str($savedService->fqdn)->explode(',');
if ($fqdns_exploded->count() > 1) { if ($fqdns_exploded->count() > 1) {
continue; continue;
@@ -1981,12 +1858,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
'service_id' => $resource->id, 'service_id' => $resource->id,
])->first(); ])->first();
['command' => $command, 'forService' => $forService, 'generatedValue' => $generatedValue, 'port' => $port] = parseEnvVariable($value); ['command' => $command, 'forService' => $forService, 'generatedValue' => $generatedValue, 'port' => $port] = parseEnvVariable($value);
if (!is_null($command)) { if (! is_null($command)) {
if ($command?->value() === 'FQDN' || $command?->value() === 'URL') { if ($command?->value() === 'FQDN' || $command?->value() === 'URL') {
if (Str::lower($forService) === $serviceName) { if (Str::lower($forService) === $serviceName) {
$fqdn = generateFqdn($resource->server, $containerName); $fqdn = generateFqdn($resource->server, $containerName);
} else { } else {
$fqdn = generateFqdn($resource->server, Str::lower($forService) . '-' . $resource->uuid); $fqdn = generateFqdn($resource->server, Str::lower($forService).'-'.$resource->uuid);
} }
if ($port) { if ($port) {
$fqdn = "$fqdn:$port"; $fqdn = "$fqdn:$port";
@@ -2016,13 +1893,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
'is_preview' => false, 'is_preview' => false,
]); ]);
} }
if (!$isDatabase) { if (! $isDatabase) {
if ($command->value() === 'FQDN' && is_null($savedService->fqdn) && !$foundEnv) { if ($command->value() === 'FQDN' && is_null($savedService->fqdn) && ! $foundEnv) {
$savedService->fqdn = $fqdn; $savedService->fqdn = $fqdn;
$savedService->save(); $savedService->save();
} }
// Caddy needs exact port in some cases. // Caddy needs exact port in some cases.
if ($predefinedPort && !$key->endsWith("_{$predefinedPort}") && $command?->value() === 'FQDN' && $resource->server->proxyType() === 'CADDY') { if ($predefinedPort && ! $key->endsWith("_{$predefinedPort}") && $command?->value() === 'FQDN' && $resource->server->proxyType() === 'CADDY') {
$fqdns_exploded = str($savedService->fqdn)->explode(','); $fqdns_exploded = str($savedService->fqdn)->explode(',');
if ($fqdns_exploded->count() > 1) { if ($fqdns_exploded->count() > 1) {
continue; continue;
@@ -2044,7 +1921,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
} }
} else { } else {
$generatedValue = generateEnvValue($command, $resource); $generatedValue = generateEnvValue($command, $resource);
if (!$foundEnv) { if (! $foundEnv) {
EnvironmentVariable::create([ EnvironmentVariable::create([
'key' => $key, 'key' => $key,
'value' => $generatedValue, 'value' => $generatedValue,
@@ -2099,7 +1976,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
} }
$defaultLabels = defaultLabels($resource->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id); $defaultLabels = defaultLabels($resource->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id);
$serviceLabels = $serviceLabels->merge($defaultLabels); $serviceLabels = $serviceLabels->merge($defaultLabels);
if (!$isDatabase && $fqdns->count() > 0) { if (! $isDatabase && $fqdns->count() > 0) {
if ($fqdns) { if ($fqdns) {
$shouldGenerateLabelsExactly = $resource->server->settings->generate_exact_labels; $shouldGenerateLabelsExactly = $resource->server->settings->generate_exact_labels;
if ($shouldGenerateLabelsExactly) { if ($shouldGenerateLabelsExactly) {
@@ -2167,7 +2044,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
} }
data_set($service, 'labels', $serviceLabels->toArray()); data_set($service, 'labels', $serviceLabels->toArray());
data_forget($service, 'is_database'); data_forget($service, 'is_database');
if (!data_get($service, 'restart')) { if (! data_get($service, 'restart')) {
data_set($service, 'restart', RESTART_MODE); data_set($service, 'restart', RESTART_MODE);
} }
if (data_get($service, 'restart') === 'no' || data_get($service, 'exclude_from_hc')) { if (data_get($service, 'restart') === 'no' || data_get($service, 'exclude_from_hc')) {
@@ -2206,21 +2083,21 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$parsedServiceVariables->put('COOLIFY_CONTAINER_NAME', "$serviceName-{$resource->uuid}"); $parsedServiceVariables->put('COOLIFY_CONTAINER_NAME', "$serviceName-{$resource->uuid}");
// TODO: move this in a shared function // TODO: move this in a shared function
if (!$parsedServiceVariables->has('COOLIFY_APP_NAME')) { if (! $parsedServiceVariables->has('COOLIFY_APP_NAME')) {
$parsedServiceVariables->put('COOLIFY_APP_NAME', "\"{$resource->name}\""); $parsedServiceVariables->put('COOLIFY_APP_NAME', "\"{$resource->name}\"");
} }
if (!$parsedServiceVariables->has('COOLIFY_SERVER_IP')) { if (! $parsedServiceVariables->has('COOLIFY_SERVER_IP')) {
$parsedServiceVariables->put('COOLIFY_SERVER_IP', "\"{$resource->destination->server->ip}\""); $parsedServiceVariables->put('COOLIFY_SERVER_IP', "\"{$resource->destination->server->ip}\"");
} }
if (!$parsedServiceVariables->has('COOLIFY_ENVIRONMENT_NAME')) { if (! $parsedServiceVariables->has('COOLIFY_ENVIRONMENT_NAME')) {
$parsedServiceVariables->put('COOLIFY_ENVIRONMENT_NAME', "\"{$resource->environment->name}\""); $parsedServiceVariables->put('COOLIFY_ENVIRONMENT_NAME', "\"{$resource->environment->name}\"");
} }
if (!$parsedServiceVariables->has('COOLIFY_PROJECT_NAME')) { if (! $parsedServiceVariables->has('COOLIFY_PROJECT_NAME')) {
$parsedServiceVariables->put('COOLIFY_PROJECT_NAME', "\"{$resource->project()->name}\""); $parsedServiceVariables->put('COOLIFY_PROJECT_NAME', "\"{$resource->project()->name}\"");
} }
$parsedServiceVariables = $parsedServiceVariables->map(function ($value, $key) use ($envs_from_coolify) { $parsedServiceVariables = $parsedServiceVariables->map(function ($value, $key) use ($envs_from_coolify) {
if (!str($value)->startsWith('$')) { if (! str($value)->startsWith('$')) {
$found_env = $envs_from_coolify->where('key', $key)->first(); $found_env = $envs_from_coolify->where('key', $key)->first();
if ($found_env) { if ($found_env) {
return $found_env->value; return $found_env->value;
@@ -2304,7 +2181,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
if ($serviceLabels->count() > 0) { if ($serviceLabels->count() > 0) {
$removedLabels = collect([]); $removedLabels = collect([]);
$serviceLabels = $serviceLabels->filter(function ($serviceLabel, $serviceLabelName) use ($removedLabels) { $serviceLabels = $serviceLabels->filter(function ($serviceLabel, $serviceLabelName) use ($removedLabels) {
if (!str($serviceLabel)->contains('=')) { if (! str($serviceLabel)->contains('=')) {
$removedLabels->put($serviceLabelName, $serviceLabel); $removedLabels->put($serviceLabelName, $serviceLabel);
return false; return false;
@@ -2324,11 +2201,11 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $topLevelVolumes, $pull_request_id) { $serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $topLevelVolumes, $pull_request_id) {
if (is_string($volume)) { if (is_string($volume)) {
$volume = str($volume); $volume = str($volume);
if ($volume->contains(':') && !$volume->startsWith('/')) { if ($volume->contains(':') && ! $volume->startsWith('/')) {
$name = $volume->before(':'); $name = $volume->before(':');
$mount = $volume->after(':'); $mount = $volume->after(':');
if ($name->startsWith('.') || $name->startsWith('~')) { if ($name->startsWith('.') || $name->startsWith('~')) {
$dir = base_configuration_dir() . '/applications/' . $resource->uuid; $dir = base_configuration_dir().'/applications/'.$resource->uuid;
if ($name->startsWith('.')) { if ($name->startsWith('.')) {
$name = $name->replaceFirst('.', $dir); $name = $name->replaceFirst('.', $dir);
} }
@@ -2336,12 +2213,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$name = $name->replaceFirst('~', $dir); $name = $name->replaceFirst('~', $dir);
} }
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$name = $name . "-pr-$pull_request_id"; $name = $name."-pr-$pull_request_id";
} }
$volume = str("$name:$mount"); $volume = str("$name:$mount");
} else { } else {
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$name = $name . "-pr-$pull_request_id"; $name = $name."-pr-$pull_request_id";
$volume = str("$name:$mount"); $volume = str("$name:$mount");
if ($topLevelVolumes->has($name)) { if ($topLevelVolumes->has($name)) {
$v = $topLevelVolumes->get($name); $v = $topLevelVolumes->get($name);
@@ -2380,7 +2257,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$name = $volume->before(':'); $name = $volume->before(':');
$mount = $volume->after(':'); $mount = $volume->after(':');
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$name = $name . "-pr-$pull_request_id"; $name = $name."-pr-$pull_request_id";
} }
$volume = str("$name:$mount"); $volume = str("$name:$mount");
} }
@@ -2391,7 +2268,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$read_only = data_get($volume, 'read_only'); $read_only = data_get($volume, 'read_only');
if ($source && $target) { if ($source && $target) {
if ((str($source)->startsWith('.') || str($source)->startsWith('~'))) { if ((str($source)->startsWith('.') || str($source)->startsWith('~'))) {
$dir = base_configuration_dir() . '/applications/' . $resource->uuid; $dir = base_configuration_dir().'/applications/'.$resource->uuid;
if (str($source, '.')) { if (str($source, '.')) {
$source = str($source)->replaceFirst('.', $dir); $source = str($source)->replaceFirst('.', $dir);
} }
@@ -2399,23 +2276,23 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$source = str($source)->replaceFirst('~', $dir); $source = str($source)->replaceFirst('~', $dir);
} }
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$source = $source . "-pr-$pull_request_id"; $source = $source."-pr-$pull_request_id";
} }
if ($read_only) { if ($read_only) {
data_set($volume, 'source', $source . ':' . $target . ':ro'); data_set($volume, 'source', $source.':'.$target.':ro');
} else { } else {
data_set($volume, 'source', $source . ':' . $target); data_set($volume, 'source', $source.':'.$target);
} }
} else { } else {
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$source = $source . "-pr-$pull_request_id"; $source = $source."-pr-$pull_request_id";
} }
if ($read_only) { if ($read_only) {
data_set($volume, 'source', $source . ':' . $target . ':ro'); data_set($volume, 'source', $source.':'.$target.':ro');
} else { } else {
data_set($volume, 'source', $source . ':' . $target); data_set($volume, 'source', $source.':'.$target);
} }
if (!str($source)->startsWith('/')) { if (! str($source)->startsWith('/')) {
if ($topLevelVolumes->has($source)) { if ($topLevelVolumes->has($source)) {
$v = $topLevelVolumes->get($source); $v = $topLevelVolumes->get($source);
if (data_get($v, 'driver_opts.type') === 'cifs') { if (data_get($v, 'driver_opts.type') === 'cifs') {
@@ -2448,11 +2325,11 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $topLevelVolumes, $pull_request_id) { $serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $topLevelVolumes, $pull_request_id) {
if (is_string($volume)) { if (is_string($volume)) {
$volume = str($volume); $volume = str($volume);
if ($volume->contains(':') && !$volume->startsWith('/')) { if ($volume->contains(':') && ! $volume->startsWith('/')) {
$name = $volume->before(':'); $name = $volume->before(':');
$mount = $volume->after(':'); $mount = $volume->after(':');
if ($name->startsWith('.') || $name->startsWith('~')) { if ($name->startsWith('.') || $name->startsWith('~')) {
$dir = base_configuration_dir() . '/applications/' . $resource->uuid; $dir = base_configuration_dir().'/applications/'.$resource->uuid;
if ($name->startsWith('.')) { if ($name->startsWith('.')) {
$name = $name->replaceFirst('.', $dir); $name = $name->replaceFirst('.', $dir);
} }
@@ -2460,13 +2337,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$name = $name->replaceFirst('~', $dir); $name = $name->replaceFirst('~', $dir);
} }
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$name = $name . "-pr-$pull_request_id"; $name = $name."-pr-$pull_request_id";
} }
$volume = str("$name:$mount"); $volume = str("$name:$mount");
} else { } else {
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$uuid = $resource->uuid; $uuid = $resource->uuid;
$name = $uuid . "-$name-pr-$pull_request_id"; $name = $uuid."-$name-pr-$pull_request_id";
$volume = str("$name:$mount"); $volume = str("$name:$mount");
if ($topLevelVolumes->has($name)) { if ($topLevelVolumes->has($name)) {
$v = $topLevelVolumes->get($name); $v = $topLevelVolumes->get($name);
@@ -2485,7 +2362,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
} }
} else { } else {
$uuid = $resource->uuid; $uuid = $resource->uuid;
$name = str($uuid . "-$name"); $name = str($uuid."-$name");
$volume = str("$name:$mount"); $volume = str("$name:$mount");
if ($topLevelVolumes->has($name->value())) { if ($topLevelVolumes->has($name->value())) {
$v = $topLevelVolumes->get($name->value()); $v = $topLevelVolumes->get($name->value());
@@ -2508,7 +2385,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$name = $volume->before(':'); $name = $volume->before(':');
$mount = $volume->after(':'); $mount = $volume->after(':');
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$name = $name . "-pr-$pull_request_id"; $name = $name."-pr-$pull_request_id";
} }
$volume = str("$name:$mount"); $volume = str("$name:$mount");
} }
@@ -2520,7 +2397,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
if ($source && $target) { if ($source && $target) {
$uuid = $resource->uuid; $uuid = $resource->uuid;
if ((str($source)->startsWith('.') || str($source)->startsWith('~') || str($source)->startsWith('/'))) { if ((str($source)->startsWith('.') || str($source)->startsWith('~') || str($source)->startsWith('/'))) {
$dir = base_configuration_dir() . '/applications/' . $resource->uuid; $dir = base_configuration_dir().'/applications/'.$resource->uuid;
if (str($source, '.')) { if (str($source, '.')) {
$source = str($source)->replaceFirst('.', $dir); $source = str($source)->replaceFirst('.', $dir);
} }
@@ -2528,22 +2405,22 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$source = str($source)->replaceFirst('~', $dir); $source = str($source)->replaceFirst('~', $dir);
} }
if ($read_only) { if ($read_only) {
data_set($volume, 'source', $source . ':' . $target . ':ro'); data_set($volume, 'source', $source.':'.$target.':ro');
} else { } else {
data_set($volume, 'source', $source . ':' . $target); data_set($volume, 'source', $source.':'.$target);
} }
} else { } else {
if ($pull_request_id === 0) { if ($pull_request_id === 0) {
$source = $uuid . "-$source"; $source = $uuid."-$source";
} else { } else {
$source = $uuid . "-$source-pr-$pull_request_id"; $source = $uuid."-$source-pr-$pull_request_id";
} }
if ($read_only) { if ($read_only) {
data_set($volume, 'source', $source . ':' . $target . ':ro'); data_set($volume, 'source', $source.':'.$target.':ro');
} else { } else {
data_set($volume, 'source', $source . ':' . $target); data_set($volume, 'source', $source.':'.$target);
} }
if (!str($source)->startsWith('/')) { if (! str($source)->startsWith('/')) {
if ($topLevelVolumes->has($source)) { if ($topLevelVolumes->has($source)) {
$v = $topLevelVolumes->get($source); $v = $topLevelVolumes->get($source);
if (data_get($v, 'driver_opts.type') === 'cifs') { if (data_get($v, 'driver_opts.type') === 'cifs') {
@@ -2576,7 +2453,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
if ($pull_request_id !== 0 && count($serviceDependencies) > 0) { if ($pull_request_id !== 0 && count($serviceDependencies) > 0) {
$serviceDependencies = $serviceDependencies->map(function ($dependency) use ($pull_request_id) { $serviceDependencies = $serviceDependencies->map(function ($dependency) use ($pull_request_id) {
return $dependency . "-pr-$pull_request_id"; return $dependency."-pr-$pull_request_id";
}); });
data_set($service, 'depends_on', $serviceDependencies->toArray()); data_set($service, 'depends_on', $serviceDependencies->toArray());
} }
@@ -2598,7 +2475,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) { $networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) {
return $value == $networkName || $key == $networkName; return $value == $networkName || $key == $networkName;
}); });
if (!$networkExists) { if (! $networkExists) {
if (is_string($networkDetails) || is_int($networkDetails)) { if (is_string($networkDetails) || is_int($networkDetails)) {
$topLevelNetworks->put($networkDetails, null); $topLevelNetworks->put($networkDetails, null);
} }
@@ -2626,7 +2503,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) { $definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) {
return $value == $definedNetwork; return $value == $definedNetwork;
}); });
if (!$definedNetworkExists) { if (! $definedNetworkExists) {
foreach ($definedNetwork as $network) { foreach ($definedNetwork as $network) {
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$topLevelNetworks->put($network, [ $topLevelNetworks->put($network, [
@@ -2744,12 +2621,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
'application_id' => $resource->id, 'application_id' => $resource->id,
])->first(); ])->first();
['command' => $command, 'forService' => $forService, 'generatedValue' => $generatedValue, 'port' => $port] = parseEnvVariable($value); ['command' => $command, 'forService' => $forService, 'generatedValue' => $generatedValue, 'port' => $port] = parseEnvVariable($value);
if (!is_null($command)) { if (! is_null($command)) {
if ($command?->value() === 'FQDN' || $command?->value() === 'URL') { if ($command?->value() === 'FQDN' || $command?->value() === 'URL') {
if (Str::lower($forService) === $serviceName) { if (Str::lower($forService) === $serviceName) {
$fqdn = generateFqdn($server, $containerName); $fqdn = generateFqdn($server, $containerName);
} else { } else {
$fqdn = generateFqdn($server, Str::lower($forService) . '-' . $resource->uuid); $fqdn = generateFqdn($server, Str::lower($forService).'-'.$resource->uuid);
} }
if ($port) { if ($port) {
$fqdn = "$fqdn:$port"; $fqdn = "$fqdn:$port";
@@ -2770,7 +2647,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
} }
} else { } else {
$generatedValue = generateEnvValue($command); $generatedValue = generateEnvValue($command);
if (!$foundEnv) { if (! $foundEnv) {
EnvironmentVariable::create([ EnvironmentVariable::create([
'key' => $key, 'key' => $key,
'value' => $generatedValue, 'value' => $generatedValue,
@@ -2942,7 +2819,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
} }
data_set($service, 'labels', $serviceLabels->toArray()); data_set($service, 'labels', $serviceLabels->toArray());
data_forget($service, 'is_database'); data_forget($service, 'is_database');
if (!data_get($service, 'restart')) { if (! data_get($service, 'restart')) {
data_set($service, 'restart', RESTART_MODE); data_set($service, 'restart', RESTART_MODE);
} }
data_set($service, 'container_name', $containerName); data_set($service, 'container_name', $containerName);
@@ -2953,7 +2830,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
}); });
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$services->each(function ($service, $serviceName) use ($pull_request_id, $services) { $services->each(function ($service, $serviceName) use ($pull_request_id, $services) {
$services[$serviceName . "-pr-$pull_request_id"] = $service; $services[$serviceName."-pr-$pull_request_id"] = $service;
data_forget($services, $serviceName); data_forget($services, $serviceName);
}); });
} }
@@ -2981,7 +2858,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$uuid = data_get($resource, 'uuid'); $uuid = data_get($resource, 'uuid');
$compose = data_get($resource, 'docker_compose_raw'); $compose = data_get($resource, 'docker_compose_raw');
if (!$compose) { if (! $compose) {
return collect([]); return collect([]);
} }
@@ -3374,29 +3251,29 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$isDirectory = data_get($foundConfig, 'is_directory'); $isDirectory = data_get($foundConfig, 'is_directory');
} else { } else {
// if isDirectory is not set (or false) & content is also not set, we assume it is a directory // if isDirectory is not set (or false) & content is also not set, we assume it is a directory
if ((is_null($isDirectory) || !$isDirectory) && is_null($content)) { if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) {
$isDirectory = true; $isDirectory = true;
} }
} }
} }
if ($type->value() === 'bind') { if ($type->value() === 'bind') {
if ($source->value() === '/var/run/docker.sock') { if ($source->value() === '/var/run/docker.sock') {
$volume = $source->value() . ':' . $target->value(); $volume = $source->value().':'.$target->value();
} elseif ($source->value() === '/tmp' || $source->value() === '/tmp/') { } elseif ($source->value() === '/tmp' || $source->value() === '/tmp/') {
$volume = $source->value() . ':' . $target->value(); $volume = $source->value().':'.$target->value();
} else { } else {
if ((int) $resource->compose_parsing_version >= 4) { if ((int) $resource->compose_parsing_version >= 4) {
if ($isApplication) { if ($isApplication) {
$mainDirectory = str(base_configuration_dir() . '/applications/' . $uuid); $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid);
} elseif ($isService) { } elseif ($isService) {
$mainDirectory = str(base_configuration_dir() . '/services/' . $uuid); $mainDirectory = str(base_configuration_dir().'/services/'.$uuid);
} }
} else { } else {
$mainDirectory = str(base_configuration_dir() . '/applications/' . $uuid); $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid);
} }
$source = replaceLocalSource($source, $mainDirectory); $source = replaceLocalSource($source, $mainDirectory);
if ($isApplication && $isPullRequest) { if ($isApplication && $isPullRequest) {
$source = $source . "-pr-$pullRequestId"; $source = $source."-pr-$pullRequestId";
} }
LocalFileVolume::updateOrCreate( LocalFileVolume::updateOrCreate(
[ [
@@ -3416,12 +3293,12 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
if (isDev()) { if (isDev()) {
if ((int) $resource->compose_parsing_version >= 4) { if ((int) $resource->compose_parsing_version >= 4) {
if ($isApplication) { if ($isApplication) {
$source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/applications/' . $uuid); $source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/applications/'.$uuid);
} elseif ($isService) { } elseif ($isService) {
$source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/services/' . $uuid); $source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/services/'.$uuid);
} }
} else { } else {
$source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/applications/' . $uuid); $source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/applications/'.$uuid);
} }
} }
$volume = "$source:$target"; $volume = "$source:$target";
@@ -3488,7 +3365,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$depends_on = $newDependsOn; $depends_on = $newDependsOn;
} }
} }
if (!$use_network_mode) { if (! $use_network_mode) {
if ($topLevel->get('networks')?->count() > 0) { if ($topLevel->get('networks')?->count() > 0) {
foreach ($topLevel->get('networks') as $networkName => $network) { foreach ($topLevel->get('networks') as $networkName => $network) {
if ($networkName === 'default') { if ($networkName === 'default') {
@@ -3501,7 +3378,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$networkExists = $networks->contains(function ($value, $key) use ($networkName) { $networkExists = $networks->contains(function ($value, $key) use ($networkName) {
return $value == $networkName || $key == $networkName; return $value == $networkName || $key == $networkName;
}); });
if (!$networkExists) { if (! $networkExists) {
$networks->put($networkName, null); $networks->put($networkName, null);
} }
} }
@@ -3509,7 +3386,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) { $baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) {
return $value == $baseNetwork; return $value == $baseNetwork;
}); });
if (!$baseNetworkExists) { if (! $baseNetworkExists) {
foreach ($baseNetwork as $network) { foreach ($baseNetwork as $network) {
$topLevel->get('networks')->put($network, [ $topLevel->get('networks')->put($network, [
'name' => $network, 'name' => $network,
@@ -3541,7 +3418,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$networks_temp = collect(); $networks_temp = collect();
if (!$use_network_mode) { if (! $use_network_mode) {
foreach ($networks as $key => $network) { foreach ($networks as $key => $network) {
if (gettype($network) === 'string') { if (gettype($network) === 'string') {
// networks: // networks:
@@ -3572,7 +3449,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$normalEnvironments = $environment->diffKeys($allMagicEnvironments); $normalEnvironments = $environment->diffKeys($allMagicEnvironments);
$normalEnvironments = $normalEnvironments->filter(function ($value, $key) { $normalEnvironments = $normalEnvironments->filter(function ($value, $key) {
return !str($value)->startsWith('SERVICE_'); return ! str($value)->startsWith('SERVICE_');
}); });
foreach ($normalEnvironments as $key => $value) { foreach ($normalEnvironments as $key => $value) {
@@ -3592,7 +3469,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
continue; continue;
} }
if (!$value->startsWith('$')) { if (! $value->startsWith('$')) {
continue; continue;
} }
if ($key->value() === $parsedValue->value()) { if ($key->value() === $parsedValue->value()) {
@@ -3723,7 +3600,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$defaultLabels = defaultLabels($resource->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id); $defaultLabels = defaultLabels($resource->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id);
} }
// Add COOLIFY_FQDN & COOLIFY_URL to environment // Add COOLIFY_FQDN & COOLIFY_URL to environment
if (!$isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
$coolifyEnvironments->put('COOLIFY_URL', $fqdns->implode(',')); $coolifyEnvironments->put('COOLIFY_URL', $fqdns->implode(','));
$urls = $fqdns->map(function ($fqdn) { $urls = $fqdns->map(function ($fqdn) {
@@ -3735,7 +3612,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
if ($environment->count() > 0) { if ($environment->count() > 0) {
$environment = $environment->filter(function ($value, $key) { $environment = $environment->filter(function ($value, $key) {
return !str($key)->startsWith('SERVICE_FQDN_'); return ! str($key)->startsWith('SERVICE_FQDN_');
})->map(function ($value, $key) use ($resource) { })->map(function ($value, $key) use ($resource) {
// if value is empty, set it to null so if you set the environment variable in the .env file (Coolify's UI), it will used // if value is empty, set it to null so if you set the environment variable in the .env file (Coolify's UI), it will used
if (str($value)->isEmpty()) { if (str($value)->isEmpty()) {
@@ -3762,7 +3639,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
}); });
} }
} }
if (!$isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
if ($isApplication) { if ($isApplication) {
$shouldGenerateLabelsExactly = $resource->destination->server->settings->generate_exact_labels; $shouldGenerateLabelsExactly = $resource->destination->server->settings->generate_exact_labels;
$uuid = $resource->uuid; $uuid = $resource->uuid;
@@ -3855,7 +3732,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
'restart' => $restart->value(), 'restart' => $restart->value(),
'labels' => $serviceLabels, 'labels' => $serviceLabels,
]); ]);
if (!$use_network_mode) { if (! $use_network_mode) {
$payload['networks'] = $networks_temp; $payload['networks'] = $networks_temp;
} }
if ($ports->count() > 0) { if ($ports->count() > 0) {
@@ -3915,7 +3792,7 @@ function isAssociativeArray($array)
$array = $array->toArray(); $array = $array->toArray();
} }
if (!is_array($array)) { if (! is_array($array)) {
throw new \InvalidArgumentException('Input must be an array or a Collection.'); throw new \InvalidArgumentException('Input must be an array or a Collection.');
} }
@@ -4028,7 +3905,7 @@ function instanceSettings()
function loadConfigFromGit(string $repository, string $branch, string $base_directory, int $server_id, int $team_id) function loadConfigFromGit(string $repository, string $branch, string $base_directory, int $server_id, int $team_id)
{ {
$server = Server::find($server_id)->where('team_id', $team_id)->first(); $server = Server::find($server_id)->where('team_id', $team_id)->first();
if (!$server) { if (! $server) {
return; return;
} }
$uuid = new Cuid2; $uuid = new Cuid2;
@@ -4055,7 +3932,7 @@ function loadConfigFromGit(string $repository, string $branch, string $base_dire
function loggy($message = null, array $context = []) function loggy($message = null, array $context = [])
{ {
if (!isDev()) { if (! isDev()) {
return; return;
} }
if (function_exists('ray') && config('app.debug')) { if (function_exists('ray') && config('app.debug')) {
@@ -4090,7 +3967,7 @@ function isEmailRateLimited(string $limiterKey, int $decaySeconds = 3600, ?calla
$limiterKey, $limiterKey,
$maxAttempts = 0, $maxAttempts = 0,
function () use (&$rateLimited, &$limiterKey, $callbackOnSuccess) { function () use (&$rateLimited, &$limiterKey, $callbackOnSuccess) {
isDev() && loggy('Rate limit not reached for ' . $limiterKey); isDev() && loggy('Rate limit not reached for '.$limiterKey);
$rateLimited = false; $rateLimited = false;
if ($callbackOnSuccess) { if ($callbackOnSuccess) {
@@ -4099,8 +3976,8 @@ function isEmailRateLimited(string $limiterKey, int $decaySeconds = 3600, ?calla
}, },
$decaySeconds, $decaySeconds,
); );
if (!$executed) { if (! $executed) {
isDev() && loggy('Rate limit reached for ' . $limiterKey . '. Rate limiter will be disabled for ' . $decaySeconds . ' seconds.'); isDev() && loggy('Rate limit reached for '.$limiterKey.'. Rate limiter will be disabled for '.$decaySeconds.' seconds.');
$rateLimited = true; $rateLimited = true;
} }