commit
35c76c8e2a
@ -13,6 +13,9 @@ public function handle(Server $server, $fromUI = false)
|
||||
if ($server->proxyType() === 'NONE') {
|
||||
return false;
|
||||
}
|
||||
if (!$server->validateConnection()) {
|
||||
throw new \Exception("Server Connection Error");
|
||||
}
|
||||
if (!$server->isProxyShouldRun()) {
|
||||
if ($fromUI) {
|
||||
throw new \Exception("Proxy should not run. You selected the Custom Proxy.");
|
||||
|
@ -45,7 +45,6 @@ public function handle(bool $force = false, bool $async = false)
|
||||
}
|
||||
$this->update();
|
||||
}
|
||||
send_internal_notification("Instance updated from {$this->currentVersion} -> {$this->latestVersion}");
|
||||
} catch (\Throwable $e) {
|
||||
ray('InstanceAutoUpdateJob failed');
|
||||
ray($e->getMessage());
|
||||
@ -83,6 +82,7 @@ private function update()
|
||||
"bash /data/coolify/source/upgrade.sh $this->latestVersion"
|
||||
], $this->server);
|
||||
}
|
||||
send_internal_notification("Instance updated from {$this->currentVersion} -> {$this->latestVersion}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -179,6 +179,11 @@ public function __construct(int $application_deployment_queue_id)
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
if (!$this->server->isFunctional()) {
|
||||
$this->application_deployment_queue->addLogEntry("Server is not functional.");
|
||||
$this->fail("Server is not functional.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Generate custom host<->ip mapping
|
||||
$allContainers = instant_remote_process(["docker network inspect {$this->destination->network} -f '{{json .Containers}}' "], $this->server);
|
||||
@ -646,21 +651,21 @@ private function generate_image_names()
|
||||
{
|
||||
if ($this->application->dockerfile) {
|
||||
if ($this->application->docker_registry_image_name) {
|
||||
$this->build_image_name = Str::lower("{$this->application->docker_registry_image_name}:build");
|
||||
$this->production_image_name = Str::lower("{$this->application->docker_registry_image_name}:latest");
|
||||
$this->build_image_name = "{$this->application->docker_registry_image_name}:build";
|
||||
$this->production_image_name = "{$this->application->docker_registry_image_name}:latest";
|
||||
} else {
|
||||
$this->build_image_name = Str::lower("{$this->application->uuid}:build");
|
||||
$this->production_image_name = Str::lower("{$this->application->uuid}:latest");
|
||||
$this->build_image_name = "{$this->application->uuid}:build";
|
||||
$this->production_image_name = "{$this->application->uuid}:latest";
|
||||
}
|
||||
} else if ($this->application->build_pack === 'dockerimage') {
|
||||
$this->production_image_name = Str::lower("{$this->dockerImage}:{$this->dockerImageTag}");
|
||||
$this->production_image_name = "{$this->dockerImage}:{$this->dockerImageTag}";
|
||||
} else if ($this->pull_request_id !== 0) {
|
||||
if ($this->application->docker_registry_image_name) {
|
||||
$this->build_image_name = Str::lower("{$this->application->docker_registry_image_name}:pr-{$this->pull_request_id}-build");
|
||||
$this->production_image_name = Str::lower("{$this->application->docker_registry_image_name}:pr-{$this->pull_request_id}");
|
||||
$this->build_image_name = "{$this->application->docker_registry_image_name}:pr-{$this->pull_request_id}-build";
|
||||
$this->production_image_name = "{$this->application->docker_registry_image_name}:pr-{$this->pull_request_id}";
|
||||
} else {
|
||||
$this->build_image_name = Str::lower("{$this->application->uuid}:pr-{$this->pull_request_id}-build");
|
||||
$this->production_image_name = Str::lower("{$this->application->uuid}:pr-{$this->pull_request_id}");
|
||||
$this->build_image_name = "{$this->application->uuid}:pr-{$this->pull_request_id}-build";
|
||||
$this->production_image_name = "{$this->application->uuid}:pr-{$this->pull_request_id}";
|
||||
}
|
||||
} else {
|
||||
$this->dockerImageTag = str($this->commit)->substr(0, 128);
|
||||
@ -668,11 +673,11 @@ private function generate_image_names()
|
||||
$this->dockerImageTag = $this->application->docker_registry_image_tag;
|
||||
}
|
||||
if ($this->application->docker_registry_image_name) {
|
||||
$this->build_image_name = Str::lower("{$this->application->docker_registry_image_name}:{$this->dockerImageTag}-build");
|
||||
$this->production_image_name = Str::lower("{$this->application->docker_registry_image_name}:{$this->dockerImageTag}");
|
||||
$this->build_image_name = "{$this->application->docker_registry_image_name}:{$this->dockerImageTag}-build";
|
||||
$this->production_image_name = "{$this->application->docker_registry_image_name}:{$this->dockerImageTag}";
|
||||
} else {
|
||||
$this->build_image_name = Str::lower("{$this->application->uuid}:{$this->dockerImageTag}-build");
|
||||
$this->production_image_name = Str::lower("{$this->application->uuid}:{$this->dockerImageTag}");
|
||||
$this->build_image_name = "{$this->application->uuid}:{$this->dockerImageTag}-build";
|
||||
$this->production_image_name = "{$this->application->uuid}:{$this->dockerImageTag}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1001,11 +1006,6 @@ private function generate_git_import_commands()
|
||||
return $commands;
|
||||
}
|
||||
|
||||
private function set_git_import_settings($git_clone_command)
|
||||
{
|
||||
return $this->application->setGitImportSettings($this->deployment_uuid, $git_clone_command);
|
||||
}
|
||||
|
||||
private function cleanup_git()
|
||||
{
|
||||
$this->execute_remote_command(
|
||||
@ -1814,7 +1814,6 @@ private function next(string $status)
|
||||
|
||||
public function failed(Throwable $exception): void
|
||||
{
|
||||
|
||||
$this->next(ApplicationDeploymentStatus::FAILED->value);
|
||||
$this->application_deployment_queue->addLogEntry("Oops something is not okay, are you okay? 😢", 'stderr');
|
||||
if (str($exception->getMessage())->isNotEmpty()) {
|
||||
|
@ -163,18 +163,16 @@ public function loadComposeFile($isInit = false)
|
||||
}
|
||||
public function generateDomain(string $serviceName)
|
||||
{
|
||||
$domain = $this->parsedServiceDomains[$serviceName]['domain'] ?? null;
|
||||
if (!$domain) {
|
||||
$uuid = new Cuid2(7);
|
||||
$domain = generateFqdn($this->application->destination->server, $uuid);
|
||||
$this->parsedServiceDomains[$serviceName]['domain'] = $domain;
|
||||
$this->application->docker_compose_domains = json_encode($this->parsedServiceDomains);
|
||||
$this->application->save();
|
||||
}
|
||||
$uuid = new Cuid2(7);
|
||||
$domain = generateFqdn($this->application->destination->server, $uuid);
|
||||
$this->parsedServiceDomains[$serviceName]['domain'] = $domain;
|
||||
$this->application->docker_compose_domains = json_encode($this->parsedServiceDomains);
|
||||
$this->application->save();
|
||||
$this->dispatch('success', 'Domain generated.');
|
||||
return $domain;
|
||||
}
|
||||
public function updatedApplicationBaseDirectory() {
|
||||
raY('asdf');
|
||||
public function updatedApplicationBaseDirectory()
|
||||
{
|
||||
if ($this->application->build_pack === 'dockercompose') {
|
||||
$this->loadComposeFile();
|
||||
}
|
||||
@ -206,30 +204,47 @@ public function getWildcardDomain()
|
||||
$fqdn = generateFqdn($server, $this->application->uuid);
|
||||
$this->application->fqdn = $fqdn;
|
||||
$this->application->save();
|
||||
$this->updatedApplicationFqdn();
|
||||
$this->dispatch('success', 'Wildcard domain generated.');
|
||||
}
|
||||
}
|
||||
public function resetDefaultLabels($showToaster = true)
|
||||
public function resetDefaultLabels()
|
||||
{
|
||||
$this->customLabels = str(implode("|", generateLabelsApplication($this->application)))->replace("|", "\n");
|
||||
$this->ports_exposes = $this->application->ports_exposes;
|
||||
$this->submit($showToaster);
|
||||
|
||||
$this->application->custom_labels = base64_encode($this->customLabels);
|
||||
$this->application->save();
|
||||
}
|
||||
|
||||
public function updatedApplicationFqdn()
|
||||
public function checkFqdns($showToaster = true)
|
||||
{
|
||||
$this->application->fqdn = str($this->application->fqdn)->replaceEnd(',', '')->trim();
|
||||
$this->application->fqdn = str($this->application->fqdn)->replaceStart(',', '')->trim();
|
||||
$this->application->fqdn = str($this->application->fqdn)->trim()->explode(',')->map(function ($domain) {
|
||||
return str($domain)->trim()->lower();
|
||||
});
|
||||
$this->application->fqdn = $this->application->fqdn->unique()->implode(',');
|
||||
$this->application->save();
|
||||
$this->resetDefaultLabels(false);
|
||||
if (data_get($this->application, 'fqdn')) {
|
||||
$domains = str($this->application->fqdn)->trim()->explode(',');
|
||||
if ($this->application->additional_servers->count() === 0) {
|
||||
foreach ($domains as $domain) {
|
||||
if (!validate_dns_entry($domain, $this->application->destination->server)) {
|
||||
$showToaster && $this->dispatch('error', "Validating DNS ($domain) failed.", "Make sure you have added the DNS records correctly.<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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
check_domain_usage(resource: $this->application);
|
||||
$this->application->fqdn = $domains->implode(',');
|
||||
}
|
||||
}
|
||||
public function submit($showToaster = true)
|
||||
{
|
||||
try {
|
||||
$this->application->fqdn = str($this->application->fqdn)->replaceEnd(',', '')->trim();
|
||||
$this->application->fqdn = str($this->application->fqdn)->replaceStart(',', '')->trim();
|
||||
$this->application->fqdn = str($this->application->fqdn)->trim()->explode(',')->map(function ($domain) {
|
||||
return str($domain)->trim()->lower();
|
||||
});
|
||||
$this->application->fqdn = $this->application->fqdn->unique()->implode(',');
|
||||
|
||||
$this->checkFqdns();
|
||||
|
||||
$this->application->save();
|
||||
|
||||
if (!$this->customLabels && $this->application->destination->server->proxyType() !== 'NONE') {
|
||||
$this->customLabels = str(implode("|", generateLabelsApplication($this->application)))->replace("|", "\n");
|
||||
$this->application->custom_labels = base64_encode($this->customLabels);
|
||||
@ -241,25 +256,14 @@ public function submit($showToaster = true)
|
||||
}
|
||||
$this->validate();
|
||||
if ($this->ports_exposes !== $this->application->ports_exposes) {
|
||||
$this->resetDefaultLabels(false);
|
||||
$this->resetDefaultLabels();
|
||||
}
|
||||
if (data_get($this->application, 'build_pack') === 'dockerimage') {
|
||||
$this->validate([
|
||||
'application.docker_registry_image_name' => 'required',
|
||||
]);
|
||||
}
|
||||
if (data_get($this->application, 'fqdn')) {
|
||||
$domains = str($this->application->fqdn)->trim()->explode(',');
|
||||
if ($this->application->additional_servers->count() === 0) {
|
||||
foreach ($domains as $domain) {
|
||||
if (!validate_dns_entry($domain, $this->application->destination->server)) {
|
||||
$showToaster && $this->dispatch('error', "Validating DNS ($domain) failed.", "Make sure you have added the DNS records correctly.<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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
check_fqdn_usage($this->application);
|
||||
$this->application->fqdn = $domains->implode(',');
|
||||
}
|
||||
|
||||
if (data_get($this->application, 'custom_docker_run_options')) {
|
||||
$this->application->custom_docker_run_options = str($this->application->custom_docker_run_options)->trim();
|
||||
}
|
||||
@ -277,6 +281,15 @@ public function submit($showToaster = true)
|
||||
}
|
||||
if ($this->application->build_pack === 'dockercompose') {
|
||||
$this->application->docker_compose_domains = json_encode($this->parsedServiceDomains);
|
||||
foreach ($this->parsedServiceDomains as $serviceName => $service) {
|
||||
$domain = data_get($service, 'domain');
|
||||
if ($domain) {
|
||||
if (!validate_dns_entry($domain, $this->application->destination->server)) {
|
||||
$showToaster && $this->dispatch('error', "Validating DNS ($domain) failed.", "Make sure you have added the DNS records correctly.<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.");
|
||||
}
|
||||
check_domain_usage(resource: $this->application);
|
||||
}
|
||||
}
|
||||
if ($this->application->settings->is_raw_compose_deployment_enabled) {
|
||||
$this->application->parseRawCompose();
|
||||
} else {
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
class Index extends Component
|
||||
{
|
||||
public Service $service;
|
||||
public ?Service $service = null;
|
||||
public ?ServiceApplication $serviceApplication = null;
|
||||
public ?ServiceDatabase $serviceDatabase = null;
|
||||
public array $parameters;
|
||||
@ -26,7 +26,10 @@ public function mount()
|
||||
$this->services = collect([]);
|
||||
$this->parameters = get_route_parameters();
|
||||
$this->query = request()->query();
|
||||
$this->service = Service::whereUuid($this->parameters['service_uuid'])->firstOrFail();
|
||||
$this->service = Service::whereUuid($this->parameters['service_uuid'])->first();
|
||||
if (!$this->service) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
$service = $this->service->applications()->whereUuid($this->parameters['stack_service_uuid'])->first();
|
||||
if ($service) {
|
||||
$this->serviceApplication = $service;
|
||||
|
@ -65,12 +65,12 @@ public function mount()
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
check_fqdn_usage($this->application);
|
||||
check_domain_usage(resource: $this->application);
|
||||
$this->validate();
|
||||
$this->application->save();
|
||||
updateCompose($this->application);
|
||||
if (str($this->application->fqdn)->contains(',')) {
|
||||
$this->dispatch('warning', 'Some services do not support multiple domains, which can lead to problems and is NOT RECOMMENDED.');
|
||||
$this->dispatch('warning', 'Some services do not support multiple domains, which can lead to problems and is NOT RECOMMENDED.<br><br>Only use multiple domains if you know what you are doing.');
|
||||
} else {
|
||||
$this->dispatch('success', 'Service saved.');
|
||||
}
|
||||
|
@ -59,23 +59,37 @@ public function instantSave()
|
||||
|
||||
public function submit()
|
||||
{
|
||||
$this->resetErrorBag();
|
||||
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.');
|
||||
return;
|
||||
try {
|
||||
$error_show = false;
|
||||
$this->server = Server::findOrFail(0);
|
||||
$this->resetErrorBag();
|
||||
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.');
|
||||
return;
|
||||
}
|
||||
$this->validate();
|
||||
|
||||
if ($this->settings->is_dns_validation_enabled) {
|
||||
if (!validate_dns_entry($this->settings->fqdn, $this->server)) {
|
||||
$this->dispatch('error', "Validating DNS ({$this->settings->fqdn}) failed.<br><br>Make sure you have added the DNS records correctly.<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.");
|
||||
$error_show = true;
|
||||
}
|
||||
}
|
||||
check_domain_usage(domain: $this->settings->fqdn);
|
||||
$this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->replaceEnd(',', '')->trim();
|
||||
$this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->trim()->explode(',')->map(function ($dns) {
|
||||
return str($dns)->trim()->lower();
|
||||
});
|
||||
$this->settings->custom_dns_servers = $this->settings->custom_dns_servers->unique();
|
||||
$this->settings->custom_dns_servers = $this->settings->custom_dns_servers->implode(',');
|
||||
|
||||
$this->settings->save();
|
||||
$this->server->setupDynamicProxyConfiguration();
|
||||
if (!$error_show) {
|
||||
$this->dispatch('success', 'Instance settings updated successfully!');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
$this->validate();
|
||||
|
||||
$this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->replaceEnd(',', '')->trim();
|
||||
$this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->trim()->explode(',')->map(function ($dns) {
|
||||
return str($dns)->trim()->lower();
|
||||
});
|
||||
$this->settings->custom_dns_servers = $this->settings->custom_dns_servers->unique();
|
||||
$this->settings->custom_dns_servers = $this->settings->custom_dns_servers->implode(',');
|
||||
|
||||
$this->settings->save();
|
||||
$this->server = Server::findOrFail(0);
|
||||
$this->server->setupDynamicProxyConfiguration();
|
||||
$this->dispatch('success', 'Instance settings updated successfully!');
|
||||
}
|
||||
}
|
||||
|
@ -32,10 +32,10 @@ public function checkUpdate()
|
||||
public function upgrade()
|
||||
{
|
||||
try {
|
||||
$this->rateLimit(1, 30);
|
||||
if ($this->showProgress) {
|
||||
return;
|
||||
}
|
||||
$this->rateLimit(1, 30);
|
||||
$this->showProgress = true;
|
||||
UpdateCoolify::run(force: true, async: true);
|
||||
$this->dispatch('success', "Updating Coolify to {$this->latestVersion} version...");
|
||||
|
@ -598,21 +598,30 @@ function generateGitImportCommands(string $deployment_uuid, int $pull_request_id
|
||||
} else {
|
||||
$github_access_token = generate_github_installation_token($this->source);
|
||||
if ($exec_in_docker) {
|
||||
$commands->push(executeInDocker($deployment_uuid, "{$git_clone_command} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository}.git {$baseDir}"));
|
||||
$git_clone_command = "{$git_clone_command} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository}.git {$baseDir}";
|
||||
$fullRepoUrl = "$source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository}.git";
|
||||
} else {
|
||||
$commands->push("{$git_clone_command} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository} {$baseDir}");
|
||||
$git_clone_command = "{$git_clone_command} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository} {$baseDir}";
|
||||
$fullRepoUrl = "$source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository}";
|
||||
}
|
||||
$git_clone_command = $this->setGitImportSettings($deployment_uuid, $git_clone_command, public: false);
|
||||
if ($exec_in_docker) {
|
||||
$commands->push(executeInDocker($deployment_uuid, $git_clone_command));
|
||||
} else {
|
||||
$commands->push($git_clone_command);
|
||||
}
|
||||
}
|
||||
if ($pull_request_id !== 0) {
|
||||
$branch = "pull/{$pull_request_id}/head:$pr_branch_name";
|
||||
|
||||
$git_checkout_command = $this->buildGitCheckoutCommand($pr_branch_name);
|
||||
if ($exec_in_docker) {
|
||||
$commands->push(executeInDocker($deployment_uuid, "cd {$baseDir} && git fetch origin {$branch} && git checkout $pr_branch_name"));
|
||||
$commands->push(executeInDocker($deployment_uuid, "cd {$baseDir} && git fetch origin {$branch} && $git_checkout_command"));
|
||||
} else {
|
||||
$commands->push("cd {$baseDir} && git fetch origin {$branch} && git checkout $pr_branch_name");
|
||||
$commands->push("cd {$baseDir} && git fetch origin {$branch} && $git_checkout_command");
|
||||
}
|
||||
}
|
||||
ray($commands);
|
||||
return [
|
||||
'commands' => $commands->implode(' && '),
|
||||
'branch' => $branch,
|
||||
@ -654,7 +663,7 @@ function generateGitImportCommands(string $deployment_uuid, int $pull_request_id
|
||||
} else {
|
||||
$commands->push("echo 'Checking out $branch'");
|
||||
}
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git fetch origin $branch && git checkout $pr_branch_name";
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git fetch origin $branch && " . $this->buildGitCheckoutCommand($pr_branch_name);
|
||||
} else if ($git_type === 'github') {
|
||||
$branch = "pull/{$pull_request_id}/head:$pr_branch_name";
|
||||
if ($exec_in_docker) {
|
||||
@ -662,14 +671,14 @@ function generateGitImportCommands(string $deployment_uuid, int $pull_request_id
|
||||
} else {
|
||||
$commands->push("echo 'Checking out $branch'");
|
||||
}
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git fetch origin $branch && git checkout $pr_branch_name";
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git fetch origin $branch && " . $this->buildGitCheckoutCommand($pr_branch_name);
|
||||
} else if ($git_type === 'bitbucket') {
|
||||
if ($exec_in_docker) {
|
||||
$commands->push(executeInDocker($deployment_uuid, "echo 'Checking out $branch'"));
|
||||
} else {
|
||||
$commands->push("echo 'Checking out $branch'");
|
||||
}
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git checkout $commit";
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" " . $this->buildGitCheckoutCommand($commit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -697,7 +706,7 @@ function generateGitImportCommands(string $deployment_uuid, int $pull_request_id
|
||||
} else {
|
||||
$commands->push("echo 'Checking out $branch'");
|
||||
}
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git fetch origin $branch && git checkout $pr_branch_name";
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git fetch origin $branch && " . $this->buildGitCheckoutCommand($pr_branch_name);
|
||||
} else if ($git_type === 'github') {
|
||||
$branch = "pull/{$pull_request_id}/head:$pr_branch_name";
|
||||
if ($exec_in_docker) {
|
||||
@ -705,14 +714,14 @@ function generateGitImportCommands(string $deployment_uuid, int $pull_request_id
|
||||
} else {
|
||||
$commands->push("echo 'Checking out $branch'");
|
||||
}
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git fetch origin $branch && git checkout $pr_branch_name";
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git fetch origin $branch && " . $this->buildGitCheckoutCommand($pr_branch_name);
|
||||
} else if ($git_type === 'bitbucket') {
|
||||
if ($exec_in_docker) {
|
||||
$commands->push(executeInDocker($deployment_uuid, "echo 'Checking out $branch'"));
|
||||
} else {
|
||||
$commands->push("echo 'Checking out $branch'");
|
||||
}
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git checkout $commit";
|
||||
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" " . $this->buildGitCheckoutCommand($commit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -904,6 +913,16 @@ public function fqdns(): Attribute
|
||||
: explode(',', $this->fqdn),
|
||||
);
|
||||
}
|
||||
protected function buildGitCheckoutCommand($target): string
|
||||
{
|
||||
$command = "git checkout $target";
|
||||
|
||||
if ($this->settings->is_git_submodules_enabled) {
|
||||
$command .= " && git submodule update --init --recursive";
|
||||
}
|
||||
|
||||
return $command;
|
||||
}
|
||||
public function watchPaths(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
|
@ -550,21 +550,21 @@ public function startUnmanaged($id)
|
||||
}
|
||||
public function loadUnmanagedContainers()
|
||||
{
|
||||
if ($this->isFunctional()) {
|
||||
$containers = instant_remote_process(["docker ps -a --format '{{json .}}' "], $this);
|
||||
$containers = format_docker_command_output_to_json($containers);
|
||||
$containers = $containers->map(function ($container) {
|
||||
$labels = data_get($container, 'Labels');
|
||||
if (!str($labels)->contains("coolify.managed")) {
|
||||
return $container;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
$containers = $containers->filter();
|
||||
return collect($containers);
|
||||
} else {
|
||||
return collect([]);
|
||||
}
|
||||
if ($this->isFunctional()) {
|
||||
$containers = instant_remote_process(["docker ps -a --format '{{json .}}' "], $this);
|
||||
$containers = format_docker_command_output_to_json($containers);
|
||||
$containers = $containers->map(function ($container) {
|
||||
$labels = data_get($container, 'Labels');
|
||||
if (!str($labels)->contains("coolify.managed")) {
|
||||
return $container;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
$containers = $containers->filter();
|
||||
return collect($containers);
|
||||
} else {
|
||||
return collect([]);
|
||||
}
|
||||
}
|
||||
public function hasDefinedResources()
|
||||
{
|
||||
@ -690,7 +690,13 @@ public function isProxyShouldRun()
|
||||
}
|
||||
public function isFunctional()
|
||||
{
|
||||
return $this->settings->is_reachable && $this->settings->is_usable && !$this->settings->force_disabled;
|
||||
$isFunctional = $this->settings->is_reachable && $this->settings->is_usable && !$this->settings->force_disabled;
|
||||
['private_key_filename' => $private_key_filename, 'mux_filename' => $mux_filename] = server_ssh_configuration($this);
|
||||
if (!$isFunctional) {
|
||||
Storage::disk('ssh-keys')->delete($private_key_filename);
|
||||
Storage::disk('ssh-mux')->delete($mux_filename);
|
||||
}
|
||||
return $isFunctional;
|
||||
}
|
||||
public function isLogDrainEnabled()
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Notifications\Server;
|
||||
|
||||
use App\Jobs\ContainerStatusJob;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Notifications\Channels\DiscordChannel;
|
||||
@ -21,6 +22,7 @@ public function __construct(public Server $server)
|
||||
if ($this->server->unreachable_notification_sent === false) {
|
||||
return;
|
||||
}
|
||||
dispatch(new ContainerStatusJob($server));
|
||||
}
|
||||
|
||||
public function via(object $notifiable): array
|
||||
|
@ -37,7 +37,7 @@
|
||||
// Based on /etc/os-release
|
||||
const SUPPORTED_OS = [
|
||||
'ubuntu debian raspbian',
|
||||
'centos fedora rhel ol rocky',
|
||||
'centos fedora rhel ol rocky amzn',
|
||||
'sles opensuse-leap opensuse-tumbleweed'
|
||||
];
|
||||
|
||||
|
@ -55,17 +55,30 @@ function remote_process(
|
||||
),
|
||||
])();
|
||||
}
|
||||
|
||||
function server_ssh_configuration(Server $server)
|
||||
{
|
||||
$uuid = data_get($server, 'uuid');
|
||||
if (is_null($uuid)) {
|
||||
throw new \Exception("Server does not have a uuid");
|
||||
}
|
||||
$private_key_filename = "id.root@{$server->uuid}";
|
||||
$location = '/var/www/html/storage/app/ssh/keys/' . $private_key_filename;
|
||||
$mux_filename = '/var/www/html/storage/app/ssh/mux/' . $server->muxFilename();
|
||||
return [
|
||||
'location' => $location,
|
||||
'mux_filename' => $mux_filename,
|
||||
'private_key_filename' => $private_key_filename
|
||||
];
|
||||
}
|
||||
function savePrivateKeyToFs(Server $server)
|
||||
{
|
||||
if (data_get($server, 'privateKey.private_key') === null) {
|
||||
throw new \Exception("Server {$server->name} does not have a private key");
|
||||
}
|
||||
$sshKeyFileLocation = "id.root@{$server->uuid}";
|
||||
['location' => $location, 'private_key_filename' => $private_key_filename] = server_ssh_configuration($server);
|
||||
Storage::disk('ssh-keys')->makeDirectory('.');
|
||||
Storage::disk('ssh-mux')->makeDirectory('.');
|
||||
Storage::disk('ssh-keys')->put($sshKeyFileLocation, $server->privateKey->private_key);
|
||||
$location = '/var/www/html/storage/app/ssh/keys/' . $sshKeyFileLocation;
|
||||
Storage::disk('ssh-keys')->put($private_key_filename, $server->privateKey->private_key);
|
||||
return $location;
|
||||
}
|
||||
|
||||
@ -223,6 +236,13 @@ function remove_iip($text)
|
||||
$text = preg_replace('/x-access-token:.*?(?=@)/', "x-access-token:" . REDACTED, $text);
|
||||
return preg_replace('/\x1b\[[0-9;]*m/', '', $text);
|
||||
}
|
||||
function remove_mux_and_private_key(Server $server)
|
||||
{
|
||||
$muxFilename = $server->muxFilename();
|
||||
$privateKeyLocation = savePrivateKeyToFs($server);
|
||||
Storage::disk('ssh-mux')->delete($muxFilename);
|
||||
Storage::disk('ssh-keys')->delete($privateKeyLocation);
|
||||
}
|
||||
function refresh_server_connection(?PrivateKey $private_key = null)
|
||||
{
|
||||
if (is_null($private_key)) {
|
||||
|
@ -88,33 +88,106 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
||||
$dockerCompose = Yaml::parse($dockerComposeRaw);
|
||||
|
||||
// Switch Image
|
||||
$image = data_get($resource, 'image');
|
||||
data_set($dockerCompose, "services.{$name}.image", $image);
|
||||
$dockerComposeRaw = Yaml::dump($dockerCompose, 10, 2);
|
||||
$resource->service->docker_compose_raw = $dockerComposeRaw;
|
||||
$resource->service->save();
|
||||
|
||||
if ($resource->fqdn && !str($resource->fqdn)->contains(',')) {
|
||||
// Update FQDN
|
||||
$variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper();
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$fqdn = Url::fromString($resource->fqdn);
|
||||
$fqdn = $fqdn->getScheme() . '://' . $fqdn->getHost();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
$variableName = "SERVICE_URL_" . Str::of($resource->name)->upper();
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$url = Url::fromString($resource->fqdn);
|
||||
$url = $url->getHost();
|
||||
if ($generatedEnv) {
|
||||
$url = Str::of($resource->fqdn)->after('://');
|
||||
$generatedEnv->value = $url;
|
||||
$generatedEnv->save();
|
||||
$updatedImage = data_get_str($resource, 'image');
|
||||
$currentImage = data_get_str($dockerCompose, "services.{$name}.image");
|
||||
if ($currentImage !== $updatedImage) {
|
||||
data_set($dockerCompose, "services.{$name}.image", $updatedImage->value());
|
||||
$dockerComposeRaw = Yaml::dump($dockerCompose, 10, 2);
|
||||
$resource->service->docker_compose_raw = $dockerComposeRaw;
|
||||
$resource->service->save();
|
||||
$resource->image = $updatedImage;
|
||||
$resource->save();
|
||||
}
|
||||
if ($resource->fqdn) {
|
||||
$resourceFqdns = str($resource->fqdn)->explode(',');
|
||||
if ($resourceFqdns->count() === 1) {
|
||||
$resourceFqdns = $resourceFqdns->first();
|
||||
$variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper()->replace('-', '');
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$fqdn = Url::fromString($resourceFqdns);
|
||||
$port = $fqdn->getPort();
|
||||
$fqdn = $fqdn->getScheme() . '://' . $fqdn->getHost();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
if ($port) {
|
||||
$variableName = $variableName . "_$port";
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn . ':' . $port;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
}
|
||||
$variableName = "SERVICE_URL_" . Str::of($resource->name)->upper()->replace('-', '');
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$url = Url::fromString($fqdn);
|
||||
$port = $url->getPort();
|
||||
$url = $url->getHost();
|
||||
if ($generatedEnv) {
|
||||
$url = Str::of($fqdn)->after('://');
|
||||
$generatedEnv->value = $url;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
if ($port) {
|
||||
$variableName = $variableName . "_$port";
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $url . ':' . $port;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
}
|
||||
} else if ($resourceFqdns->count() > 1) {
|
||||
foreach ($resourceFqdns as $fqdn) {
|
||||
$host = Url::fromString($fqdn);
|
||||
$port = $host->getPort();
|
||||
$url = $host->getHost();
|
||||
$host = $host->getScheme() . '://' . $host->getHost();
|
||||
if ($port) {
|
||||
$port_envs = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'like', "SERVICE_FQDN_%_$port")->get();
|
||||
foreach ($port_envs as $port_env) {
|
||||
$service_fqdn = str($port_env->key)->beforeLast('_')->after('SERVICE_FQDN_');
|
||||
$env = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'SERVICE_FQDN_' . $service_fqdn)->first();
|
||||
if ($env) {
|
||||
$env->value = $host;
|
||||
$env->save();
|
||||
}
|
||||
$port_env->value = $host . ':' . $port;
|
||||
$port_env->save();
|
||||
}
|
||||
$port_envs_url = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'like', "SERVICE_URL_%_$port")->get();
|
||||
foreach ($port_envs_url as $port_env_url) {
|
||||
$service_url = str($port_env_url->key)->beforeLast('_')->after('SERVICE_URL_');
|
||||
$env = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'SERVICE_URL_' . $service_url)->first();
|
||||
if ($env) {
|
||||
$env->value = $url;
|
||||
$env->save();
|
||||
}
|
||||
$port_env_url->value = $url . ':' . $port;
|
||||
$port_env_url->save();
|
||||
}
|
||||
} else {
|
||||
$variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper()->replace('-', '');
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$fqdn = Url::fromString($fqdn);
|
||||
$fqdn = $fqdn->getScheme() . '://' . $fqdn->getHost();
|
||||
if ($generatedEnv) {
|
||||
$generatedEnv->value = $fqdn;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
$variableName = "SERVICE_URL_" . Str::of($resource->name)->upper()->replace('-', '');
|
||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
||||
$url = Url::fromString($fqdn);
|
||||
$url = $url->getHost();
|
||||
if ($generatedEnv) {
|
||||
$url = Str::of($fqdn)->after('://');
|
||||
$generatedEnv->value = $url;
|
||||
$generatedEnv->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e);
|
||||
}
|
||||
|
@ -443,7 +443,7 @@ function sslip(Server $server)
|
||||
|
||||
function getServiceTemplates()
|
||||
{
|
||||
if (!isDev()) {
|
||||
if (isDev()) {
|
||||
$services = File::get(base_path('templates/service-templates.json'));
|
||||
$services = collect(json_decode($services))->sortKeys();
|
||||
} else {
|
||||
@ -1168,6 +1168,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
// });
|
||||
// ray($withoutServiceEnvs);
|
||||
// data_set($service, 'environment', $withoutServiceEnvs->toArray());
|
||||
updateCompose($savedService);
|
||||
return $service;
|
||||
});
|
||||
$finalServices = [
|
||||
@ -1856,13 +1857,26 @@ function ip_match($ip, $cidrs, &$match = null)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function check_fqdn_usage(ServiceApplication|Application $own_resource)
|
||||
function check_domain_usage(ServiceApplication|Application|null $resource = null, ?string $domain = null)
|
||||
{
|
||||
$domains = collect($own_resource->fqdns)->map(function ($domain) {
|
||||
if ($resource) {
|
||||
if ($resource->getMorphClass() === 'App\Models\Application' && $resource->build_pack === 'dockercompose') {
|
||||
$domains = data_get(json_decode($resource->docker_compose_domains, true), "*.domain");
|
||||
ray($domains);
|
||||
$domains = collect($domains);
|
||||
} else {
|
||||
$domains = collect($resource->fqdns);
|
||||
}
|
||||
} else if ($domain) {
|
||||
$domains = collect($domain);
|
||||
} else {
|
||||
throw new \RuntimeException("No resource or FQDN provided.");
|
||||
}
|
||||
$domains = $domains->map(function ($domain) {
|
||||
if (str($domain)->endsWith('/')) {
|
||||
$domain = str($domain)->beforeLast('/');
|
||||
}
|
||||
return str($domain)->replace('http://', '')->replace('https://', '');
|
||||
return str($domain);
|
||||
});
|
||||
$apps = Application::all();
|
||||
foreach ($apps as $app) {
|
||||
@ -1871,10 +1885,15 @@ function check_fqdn_usage(ServiceApplication|Application $own_resource)
|
||||
if (str($domain)->endsWith('/')) {
|
||||
$domain = str($domain)->beforeLast('/');
|
||||
}
|
||||
$naked_domain = str($domain)->replace('http://', '')->replace('https://', '')->value();
|
||||
$naked_domain = str($domain)->value();
|
||||
if ($domains->contains($naked_domain)) {
|
||||
if ($app->uuid !== $own_resource->uuid) {
|
||||
throw new \RuntimeException("Domain $naked_domain is already in use by another resource:<br> {$app->name}.");
|
||||
if (data_get($resource, 'uuid')) {
|
||||
ray($resource->uuid, $app->uuid);
|
||||
if ($resource->uuid !== $app->uuid) {
|
||||
throw new \RuntimeException("Domain $naked_domain is already in use by another resource called: <br><br>{$app->name}.");
|
||||
}
|
||||
} else if ($domain) {
|
||||
throw new \RuntimeException("Domain $naked_domain is already in use by another resource called: <br><br>{$app->name}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1886,12 +1905,29 @@ function check_fqdn_usage(ServiceApplication|Application $own_resource)
|
||||
if (str($domain)->endsWith('/')) {
|
||||
$domain = str($domain)->beforeLast('/');
|
||||
}
|
||||
$naked_domain = str($domain)->replace('http://', '')->replace('https://', '')->value();
|
||||
$naked_domain = str($domain)->value();
|
||||
if ($domains->contains($naked_domain)) {
|
||||
if ($app->uuid !== $own_resource->uuid) {
|
||||
throw new \RuntimeException("Domain $naked_domain is already in use by another resource.");
|
||||
if (data_get($resource, 'uuid')) {
|
||||
if ($resource->uuid !== $app->uuid) {
|
||||
throw new \RuntimeException("Domain $naked_domain is already in use by another resource called: <br><br>{$app->name}.");
|
||||
}
|
||||
} else if ($domain) {
|
||||
throw new \RuntimeException("Domain $naked_domain is already in use by another resource called: <br><br>{$app->name}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($resource) {
|
||||
$settings = InstanceSettings::get();
|
||||
if (data_get($settings, 'fqdn')) {
|
||||
$domain = data_get($settings, 'fqdn');
|
||||
if (str($domain)->endsWith('/')) {
|
||||
$domain = str($domain)->beforeLast('/');
|
||||
}
|
||||
$naked_domain = str($domain)->value();
|
||||
if ($domains->contains($naked_domain)) {
|
||||
throw new \RuntimeException("Domain $naked_domain is already in use by this Coolify instance.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.251',
|
||||
'release' => '4.0.0-beta.252',
|
||||
// When left empty or `null` the Laravel environment will be used
|
||||
'environment' => config('app.env'),
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
return '4.0.0-beta.251';
|
||||
return '4.0.0-beta.252';
|
||||
|
34
package-lock.json
generated
34
package-lock.json
generated
@ -6,8 +6,8 @@
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@tailwindcss/forms": "0.5.7",
|
||||
"@tailwindcss/typography": "0.5.10",
|
||||
"alpinejs": "3.13.7",
|
||||
"@tailwindcss/typography": "0.5.12",
|
||||
"alpinejs": "3.13.8",
|
||||
"ioredis": "5.3.2",
|
||||
"tailwindcss-scrollbar": "0.1.0"
|
||||
},
|
||||
@ -19,8 +19,8 @@
|
||||
"laravel-vite-plugin": "0.8.1",
|
||||
"postcss": "8.4.38",
|
||||
"pusher-js": "8.4.0-rc2",
|
||||
"tailwindcss": "3.4.1",
|
||||
"vite": "4.5.2",
|
||||
"tailwindcss": "3.4.3",
|
||||
"vite": "4.5.3",
|
||||
"vue": "3.4.21"
|
||||
}
|
||||
},
|
||||
@ -496,9 +496,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/typography": {
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.10.tgz",
|
||||
"integrity": "sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==",
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.12.tgz",
|
||||
"integrity": "sha512-CNwpBpconcP7ppxmuq3qvaCxiRWnbhANpY/ruH4L5qs2GCiVDJXde/pjj2HWPV1+Q4G9+V/etrwUYopdcjAlyg==",
|
||||
"dependencies": {
|
||||
"lodash.castarray": "^4.4.0",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
@ -683,9 +683,9 @@
|
||||
"integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA=="
|
||||
},
|
||||
"node_modules/alpinejs": {
|
||||
"version": "3.13.7",
|
||||
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.7.tgz",
|
||||
"integrity": "sha512-rcTyjTANbsePq1hb7eSekt3qjI94HLGeO6JaRjCssCVbIIc+qBrc7pO5S/+2JB6oojIibjM6FA+xRI3zhGPZIg==",
|
||||
"version": "3.13.8",
|
||||
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.8.tgz",
|
||||
"integrity": "sha512-XolbBJryCndomtaHd/KHQjQeD/L72FJxy/YhLLFD4Lr7zzGcpcbg+UgXteMR2pYg1KhRUr6V4O3GfN1zJAmRWw==",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "~3.1.1"
|
||||
}
|
||||
@ -1900,9 +1900,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
|
||||
"integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==",
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
|
||||
"integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==",
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
@ -1912,7 +1912,7 @@
|
||||
"fast-glob": "^3.3.0",
|
||||
"glob-parent": "^6.0.2",
|
||||
"is-glob": "^4.0.3",
|
||||
"jiti": "^1.19.1",
|
||||
"jiti": "^1.21.0",
|
||||
"lilconfig": "^2.1.0",
|
||||
"micromatch": "^4.0.5",
|
||||
"normalize-path": "^3.0.0",
|
||||
@ -2020,9 +2020,9 @@
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz",
|
||||
"integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==",
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
|
||||
"integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.18.10",
|
||||
|
@ -13,14 +13,14 @@
|
||||
"laravel-vite-plugin": "0.8.1",
|
||||
"postcss": "8.4.38",
|
||||
"pusher-js": "8.4.0-rc2",
|
||||
"tailwindcss": "3.4.1",
|
||||
"vite": "4.5.2",
|
||||
"tailwindcss": "3.4.3",
|
||||
"vite": "4.5.3",
|
||||
"vue": "3.4.21"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/forms": "0.5.7",
|
||||
"@tailwindcss/typography": "0.5.10",
|
||||
"alpinejs": "3.13.7",
|
||||
"@tailwindcss/typography": "0.5.12",
|
||||
"alpinejs": "3.13.8",
|
||||
"ioredis": "5.3.2",
|
||||
"tailwindcss-scrollbar": "0.1.0"
|
||||
}
|
||||
|
@ -66,7 +66,7 @@
|
||||
</div>
|
||||
@endif
|
||||
@foreach ($enabled_oauth_providers as $provider_setting)
|
||||
<x-forms.button type="button"
|
||||
<x-forms.button class="w-full" type="button"
|
||||
onclick="document.location.href='/auth/{{ $provider_setting->provider }}/redirect'">
|
||||
{{ __("auth.login.$provider_setting->provider") }}
|
||||
</x-forms.button>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<nav class="flex flex-col flex-1 pl-2 bg-white border-r dark:border-coolgray-200 dark:bg-base" x-data="{
|
||||
<nav class="flex flex-col flex-1 bg-white border-r dark:border-coolgray-200 dark:bg-base" x-data="{
|
||||
switchWidth() {
|
||||
if (this.full === 'full') {
|
||||
localStorage.removeItem('pageWidth');
|
||||
|
@ -19,22 +19,17 @@
|
||||
@if ($projects->count() > 0)
|
||||
<div class="grid grid-cols-1 gap-2 xl:grid-cols-2">
|
||||
@foreach ($projects as $project)
|
||||
<div class="gap-2 border border-transparent cursor-pointer box group">
|
||||
@if (data_get($project, 'environments')->count() === 1)
|
||||
<a class="flex flex-col justify-center flex-1 mx-6"
|
||||
href="{{ route('project.resource.index', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => data_get($project, 'environments.0.name', 'production')]) }}">
|
||||
<div class="box-title">{{ $project->name }}</div>
|
||||
<div class="box-description"> {{ $project->description }}</div>
|
||||
</a>
|
||||
@else
|
||||
<a class="flex flex-col justify-center flex-1 mx-6"
|
||||
href="{{ route('project.show', ['project_uuid' => data_get($project, 'uuid')]) }}">
|
||||
<div class="box-title">{{ $project->name }}</div>
|
||||
<div class="box-description">
|
||||
{{ $project->description }}</div>
|
||||
</a>
|
||||
@endif
|
||||
<div class="flex items-center justify-center gap-2 pt-4 pb-2 mr-4 text-xs lg:py-0 lg:justify-normal">
|
||||
<div class="gap-2 border border-transparent cursor-pointer box group"
|
||||
@if (data_get($project, 'environments')->count() === 1) onclick="gotoProject('{{ data_get($project, 'uuid') }}', '{{ data_get($project, 'environments.0.name', 'production') }}')"
|
||||
@else
|
||||
onclick="window.location.href = '{{ route('project.show', ['project_uuid' => data_get($project, 'uuid')]) }}'" @endif>
|
||||
<div class="flex flex-col justify-center flex-1 mx-6">
|
||||
<div class="box-title">{{ $project->name }}</div>
|
||||
<div class="box-description">
|
||||
{{ $project->description }}</div>
|
||||
</div>
|
||||
<span
|
||||
class="flex items-center justify-center gap-2 pt-4 pb-2 mr-4 text-xs lg:py-0 lg:justify-normal">
|
||||
<a class="hover:underline"
|
||||
href="{{ route('project.resource.create', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => data_get($project, 'environments.0.name', 'production')]) }}">
|
||||
<span class="p-2 font-bold">+
|
||||
@ -44,7 +39,7 @@
|
||||
href="{{ route('project.edit', ['project_uuid' => data_get($project, 'uuid')]) }}">
|
||||
Settings
|
||||
</a>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
@ -81,15 +81,14 @@ class="fixed top-4 right-16" x-on:click="toggleScroll"><svg class="icon" viewBox
|
||||
d="M9.793 12.793a1 1 0 0 1 1.497 1.32l-.083.094L6.414 19H9a1 1 0 0 1 .117 1.993L9 21H4a1 1 0 0 1-.993-.883L3 20v-5a1 1 0 0 1 1.993-.117L5 15v2.586l4.793-4.793ZM20 3a1 1 0 0 1 .993.883L21 4v5a1 1 0 0 1-1.993.117L19 9V6.414l-4.793 4.793a1 1 0 0 1-1.497-1.32l.083-.094L17.586 5H15a1 1 0 0 1-.117-1.993L15 3h5Z" />
|
||||
</g>
|
||||
</svg></button>
|
||||
<div id="logs" class="flex flex-col">
|
||||
<div id="logs" class="flex flex-col font-mono">
|
||||
@if (decode_remote_command_output($application_deployment_queue)->count() > 0)
|
||||
@foreach (decode_remote_command_output($application_deployment_queue) as $line)
|
||||
<div @class([
|
||||
'font-mono',
|
||||
'dark:text-warning whitespace-pre-line' => $line['hidden'],
|
||||
'text-red-500 font-bold whitespace-pre-line' => $line['type'] == 'stderr',
|
||||
<span @class([
|
||||
'dark:text-warning' => $line['hidden'],
|
||||
'text-red-500 font-bold' => $line['type'] == 'stderr',
|
||||
])>[{{ $line['timestamp'] }}] @if ($line['hidden'])
|
||||
<br>COMMAND: <br>{{ $line['command'] }} <br><br>OUTPUT:
|
||||
<br>COMMAND: {{ $line['command'] }}<br>OUTPUT :
|
||||
@endif @if (str($line['output'])->contains('http://') || str($line['output'])->contains('https://'))
|
||||
@php
|
||||
$line['output'] = preg_replace(
|
||||
@ -101,7 +100,7 @@ class="fixed top-4 right-16" x-on:click="toggleScroll"><svg class="icon" viewBox
|
||||
@else
|
||||
{{ $line['output'] }}
|
||||
@endif
|
||||
</div>
|
||||
</span>
|
||||
@endforeach
|
||||
@else
|
||||
<span class="font-mono text-neutral-400">No logs yet.</span>
|
||||
|
@ -59,10 +59,8 @@
|
||||
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io, https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. "
|
||||
label="Domains for {{ str($serviceName)->headline() }}"
|
||||
id="parsedServiceDomains.{{ $serviceName }}.domain"></x-forms.input>
|
||||
@if (!data_get($parsedServiceDomains, "$serviceName.domain"))
|
||||
<x-forms.button wire:click="generateDomain('{{ $serviceName }}')">Generate
|
||||
Domain</x-forms.button>
|
||||
@endif
|
||||
<x-forms.button wire:click="generateDomain('{{ $serviceName }}')">Generate
|
||||
Domain</x-forms.button>
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
@ -205,10 +203,10 @@ class="underline" href="https://coolify.io/docs/knowledge-base/docker/registry"
|
||||
|
||||
</div>
|
||||
@if ($this->application->is_github_based() && !$this->application->is_public_repository())
|
||||
<div class="pb-4">
|
||||
<x-forms.textarea helper="Gitignore-style rules to filter Git based webhook deployments."
|
||||
placeholder="src/pages/**" id="application.watch_paths" label="Watch Paths" />
|
||||
</div>
|
||||
<div class="pb-4">
|
||||
<x-forms.textarea helper="Gitignore-style rules to filter Git based webhook deployments."
|
||||
placeholder="src/pages/**" id="application.watch_paths" label="Watch Paths" />
|
||||
</div>
|
||||
@endif
|
||||
<x-forms.input
|
||||
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>"
|
||||
|
@ -25,14 +25,16 @@
|
||||
</div>
|
||||
<div class="pb-4">Code source of your application.</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input placeholder="coollabsio/coolify-example" id="application.git_repository"
|
||||
label="Repository" />
|
||||
<x-forms.input placeholder="main" id="application.git_branch" label="Branch" />
|
||||
</div>
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="HEAD" id="application.git_commit_sha" placeholder="HEAD" label="Commit SHA" />
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input placeholder="coollabsio/coolify-example" id="application.git_repository"
|
||||
label="Repository" />
|
||||
<x-forms.input placeholder="main" id="application.git_branch" label="Branch" />
|
||||
</div>
|
||||
<div class="flex items-end gap-2">
|
||||
<x-forms.input placeholder="HEAD" id="application.git_commit_sha" placeholder="HEAD"
|
||||
label="Commit SHA" />
|
||||
</div>
|
||||
</div>
|
||||
@isset($application->private_key_id)
|
||||
<h3 class="pt-4">Deploy Key</h3>
|
||||
|
@ -27,7 +27,7 @@
|
||||
helper="More info <a class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/environment-variables#shared-variables' target='_blank'>here</a>."></x-helper>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
@forelse ($project->environment_variables->sort()->sortBy('real_value') as $env)
|
||||
@forelse ($project->environment_variables->sort()->sortBy('key') as $env)
|
||||
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" type="project" />
|
||||
@empty
|
||||
|
@ -52,7 +52,7 @@
|
||||
helper="More info <a class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/environment-variables#shared-variables' target='_blank'>here</a>."></x-helper>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
@forelse ($environment->environment_variables->sort()->sortBy('real_value') as $env)
|
||||
@forelse ($environment->environment_variables->sort()->sortBy('key') as $env)
|
||||
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" type="environment" />
|
||||
@empty
|
||||
|
@ -1,27 +1,17 @@
|
||||
<div tabindex="0" x-data="{ open: false }"
|
||||
class="transition border rounded cursor-pointer collapse collapse-arrow border-coolgray-200"
|
||||
:class="open ? 'collapse-open' : 'collapse-close'">
|
||||
<div class="flex flex-col justify-center text-sm select-text collapse-title" x-on:click="open = !open">
|
||||
<div class="p-4 transition border rounded cursor-pointer border-coolgray-200">
|
||||
<div class="flex flex-col justify-center pb-4 text-sm select-text">
|
||||
<h2>{{ $service->name }}</h2>
|
||||
<div>{{ $workdir }}{{ $fs_path }} -> {{ $fileStorage->mount_path }}</div>
|
||||
</div>
|
||||
<div class="collapse-content">
|
||||
<div>
|
||||
<form wire:submit='submit' class="flex flex-col gap-2">
|
||||
<div class="w-64">
|
||||
<x-forms.checkbox instantSave label="Is directory?" id="fileStorage.is_directory"></x-forms.checkbox>
|
||||
</div>
|
||||
{{-- @if ($fileStorage->is_directory)
|
||||
<x-forms.input readonly label="Directory on Filesystem (save files here)" id="fs_path"></x-forms.input>
|
||||
@else --}}
|
||||
{{-- <div class="flex gap-2">
|
||||
<x-forms.input readonly label="File in Docker Compose file" id="fileStorage.fs_path"></x-forms.input>
|
||||
<x-forms.input readonly label="File on Filesystem (save files here)" id="fs_path"></x-forms.input>
|
||||
</div>
|
||||
<x-forms.input readonly label="Mount (in container)" id="fileStorage.mount_path"></x-forms.input> --}}
|
||||
@if (!$fileStorage->is_directory)
|
||||
<x-forms.textarea label="Content" rows="20" id="fileStorage.content"></x-forms.textarea>
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
@endif
|
||||
{{-- @endif --}}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -32,7 +32,7 @@
|
||||
@endif
|
||||
@endif
|
||||
@else
|
||||
@if ($resource->persistentStorages()->get()->count() > 0 || $resource->fileStorages()->get()->count() > 0)
|
||||
@if ($resource->persistentStorages()->get()->count() > 0)
|
||||
<h3 class="pt-4">{{ Str::headline($resource->name) }} </h3>
|
||||
@endif
|
||||
@if ($resource->persistentStorages()->get()->count() > 0)
|
||||
|
@ -16,7 +16,7 @@
|
||||
@endif
|
||||
</div>
|
||||
@if ($view === 'normal')
|
||||
@forelse ($resource->environment_variables->sort()->sortBy('real_value') as $env)
|
||||
@forelse ($resource->environment_variables->sort()->sortBy('key') as $env)
|
||||
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" :type="$resource->type()" />
|
||||
@empty
|
||||
@ -27,7 +27,7 @@
|
||||
<h3>Preview Deployments</h3>
|
||||
<div>Environment (secrets) variables for Preview Deployments.</div>
|
||||
</div>
|
||||
@foreach ($resource->environment_variables_preview->sort()->sortBy('real_value') as $env)
|
||||
@foreach ($resource->environment_variables_preview->sort()->sortBy('key') as $env)
|
||||
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" :type="$resource->type()" />
|
||||
@endforeach
|
||||
|
@ -12,7 +12,7 @@ class="dark:text-warning text-coollabs">@{{ team.VARIABLENAME }}</span> <x-helpe
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
@forelse ($team->environment_variables->sort()->sortBy('real_value') as $env)
|
||||
@forelse ($team->environment_variables->sort()->sortBy('key') as $env)
|
||||
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||
:env="$env" type="team" />
|
||||
@empty
|
||||
|
@ -6,7 +6,7 @@ set -e # Exit immediately if a command exits with a non-zero status
|
||||
#set -u # Treat unset variables as an error and exit
|
||||
set -o pipefail # Cause a pipeline to return the status of the last command that exited with a non-zero status
|
||||
|
||||
VERSION="1.2.3"
|
||||
VERSION="1.3.0"
|
||||
DOCKER_VERSION="24.0"
|
||||
|
||||
CDN="https://cdn.coollabs.io/coolify"
|
||||
@ -18,6 +18,11 @@ else
|
||||
OS_VERSION=$(grep -w "VERSION_ID" /etc/os-release | cut -d "=" -f 2 | tr -d '"')
|
||||
fi
|
||||
|
||||
# Install xargs on Amazon Linux 2023 - lol
|
||||
if [ "$OS_TYPE" = 'amzn' ]; then
|
||||
dnf install -y findutils >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
LATEST_VERSION=$(curl --silent $CDN/versions.json | grep -i version | sed -n '2p' | xargs | awk '{print $2}' | tr -d ',')
|
||||
DATE=$(date +"%Y%m%d-%H%M%S")
|
||||
|
||||
@ -27,7 +32,7 @@ if [ $EUID != 0 ]; then
|
||||
fi
|
||||
|
||||
case "$OS_TYPE" in
|
||||
arch | ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed | almalinux) ;;
|
||||
arch | ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed | almalinux | amzn) ;;
|
||||
*)
|
||||
echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now."
|
||||
exit
|
||||
@ -64,8 +69,12 @@ ubuntu | debian | raspbian)
|
||||
apt update -y >/dev/null 2>&1
|
||||
apt install -y curl wget git jq >/dev/null 2>&1
|
||||
;;
|
||||
centos | fedora | rhel | ol | rocky | almalinux)
|
||||
dnf install -y curl wget git jq >/dev/null 2>&1
|
||||
centos | fedora | rhel | ol | rocky | almalinux | amzn)
|
||||
if [ "$OS_TYPE" = "amzn" ]; then
|
||||
dnf install -y wget git jq >/dev/null 2>&1
|
||||
else
|
||||
dnf install -y curl wget git jq >/dev/null 2>&1
|
||||
fi
|
||||
;;
|
||||
sles | opensuse-leap | opensuse-tumbleweed)
|
||||
zypper refresh >/dev/null 2>&1
|
||||
@ -133,6 +142,7 @@ if [ -x "$(command -v snap)" ]; then
|
||||
fi
|
||||
|
||||
if ! [ -x "$(command -v docker)" ]; then
|
||||
# Almalinux
|
||||
if [ "$OS_TYPE" == 'almalinux' ]; then
|
||||
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
|
||||
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
@ -146,6 +156,7 @@ if ! [ -x "$(command -v docker)" ]; then
|
||||
set +e
|
||||
if ! [ -x "$(command -v docker)" ]; then
|
||||
echo "Docker is not installed. Installing Docker."
|
||||
# Arch Linux
|
||||
if [ "$OS_TYPE" = "arch" ]; then
|
||||
pacman -Sy docker docker-compose --noconfirm
|
||||
systemctl enable docker.service
|
||||
@ -157,19 +168,38 @@ if ! [ -x "$(command -v docker)" ]; then
|
||||
exit
|
||||
fi
|
||||
else
|
||||
curl https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh
|
||||
if [ -x "$(command -v docker)" ]; then
|
||||
echo "Docker installed successfully."
|
||||
else
|
||||
echo "Docker installation failed with Rancher script. Trying with official script."
|
||||
curl https://get.docker.com | sh -s -- --version ${DOCKER_VERSION}
|
||||
# Amazon Linux 2023
|
||||
if [ "$OS_TYPE" = "amzn" ]; then
|
||||
dnf install docker -y
|
||||
DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker}
|
||||
mkdir -p $DOCKER_CONFIG/cli-plugins
|
||||
curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o $DOCKER_CONFIG/cli-plugins/docker-compose
|
||||
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
|
||||
systemctl start docker
|
||||
systemctl enable docker
|
||||
if [ -x "$(command -v docker)" ]; then
|
||||
echo "Docker installed successfully."
|
||||
else
|
||||
echo "Docker installation failed with official script."
|
||||
echo "Maybe your OS is not supported?"
|
||||
echo "Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
|
||||
exit 1
|
||||
echo "Failed to install Docker with pacman. Try to install it manually."
|
||||
echo "Please visit https://wiki.archlinux.org/title/docker for more information."
|
||||
exit
|
||||
fi
|
||||
else
|
||||
# Automated Docker installation
|
||||
curl https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh
|
||||
if [ -x "$(command -v docker)" ]; then
|
||||
echo "Docker installed successfully."
|
||||
else
|
||||
echo "Docker installation failed with Rancher script. Trying with official script."
|
||||
curl https://get.docker.com | sh -s -- --version ${DOCKER_VERSION}
|
||||
if [ -x "$(command -v docker)" ]; then
|
||||
echo "Docker installed successfully."
|
||||
else
|
||||
echo "Docker installation failed with official script."
|
||||
echo "Maybe your OS is not supported?"
|
||||
echo "Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
@ -15,3 +15,8 @@ services:
|
||||
environment:
|
||||
- SERVICE_FQDN_SPDF_8080
|
||||
- DOCKER_ENABLE_SECURITY=false
|
||||
healthcheck:
|
||||
test: 'curl --fail -I http://localhost:8080 || exit 1'
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
|
@ -15,7 +15,7 @@ services:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- SERVICE_FQDN_SUPABASE_8000
|
||||
- JWT_SERCET=${SERVICE_PASSWORD_JWT}
|
||||
- JWT_SECRET=${SERVICE_PASSWORD_JWT}
|
||||
- KONG_DATABASE=off
|
||||
- KONG_DECLARATIVE_CONFIG=/home/kong/kong.yml
|
||||
# https://github.com/supabase/cli/issues/14
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
||||
{
|
||||
"coolify": {
|
||||
"v4": {
|
||||
"version": "4.0.0-beta.251"
|
||||
"version": "4.0.0-beta.252"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user