wip: swarm
fix: gitcompose deployments
This commit is contained in:
		@@ -17,6 +17,12 @@ class CheckProxy
 | 
				
			|||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if ($server->isSwarm()) {
 | 
				
			||||||
 | 
					            $status = getContainerStatus($server, 'coolify-proxy_traefik');
 | 
				
			||||||
 | 
					            $server->proxy->set('status', $status);
 | 
				
			||||||
 | 
					            $server->save();
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
            $status = getContainerStatus($server, 'coolify-proxy');
 | 
					            $status = getContainerStatus($server, 'coolify-proxy');
 | 
				
			||||||
            if ($status === 'running') {
 | 
					            if ($status === 'running') {
 | 
				
			||||||
                $server->proxy->set('status', 'running');
 | 
					                $server->proxy->set('status', 'running');
 | 
				
			||||||
@@ -49,3 +55,4 @@ class CheckProxy
 | 
				
			|||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,6 +58,15 @@ class Deploy extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function stop()
 | 
					    public function stop()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if ($this->server->isSwarm()) {
 | 
				
			||||||
 | 
					                instant_remote_process([
 | 
				
			||||||
 | 
					                    "docker service rm coolify-proxy_traefik",
 | 
				
			||||||
 | 
					                ], $this->server);
 | 
				
			||||||
 | 
					                $this->server->proxy->status = 'exited';
 | 
				
			||||||
 | 
					                $this->server->save();
 | 
				
			||||||
 | 
					                $this->emit('proxyStatusUpdated');
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
                instant_remote_process([
 | 
					                instant_remote_process([
 | 
				
			||||||
                    "docker rm -f coolify-proxy",
 | 
					                    "docker rm -f coolify-proxy",
 | 
				
			||||||
                ], $this->server);
 | 
					                ], $this->server);
 | 
				
			||||||
@@ -65,4 +74,9 @@ class Deploy extends Component
 | 
				
			|||||||
                $this->server->save();
 | 
					                $this->server->save();
 | 
				
			||||||
                $this->emit('proxyStatusUpdated');
 | 
					                $this->emit('proxyStatusUpdated');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					            return handleError($e, $this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ class Status extends Component
 | 
				
			|||||||
    protected $listeners = ['proxyStatusUpdated', 'startProxyPolling'];
 | 
					    protected $listeners = ['proxyStatusUpdated', 'startProxyPolling'];
 | 
				
			||||||
    public function startProxyPolling()
 | 
					    public function startProxyPolling()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->polling = true;
 | 
					        $this->checkProxy();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function proxyStatusUpdated()
 | 
					    public function proxyStatusUpdated()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -220,8 +220,11 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                    $this->application_deployment_queue->addLogEntry("Creating / updating stack.");
 | 
					                    $this->application_deployment_queue->addLogEntry("Creating / updating stack.");
 | 
				
			||||||
                    $this->execute_remote_command(
 | 
					                    $this->execute_remote_command(
 | 
				
			||||||
                        [
 | 
					                        [
 | 
				
			||||||
                            "docker stack deploy --with-registry-auth --prune --compose-file {$this->configuration_dir}/docker-compose.yml {$this->application->uuid}"
 | 
					                            executeInDocker($this->deployment_uuid, "cd {$this->workdir} && docker stack deploy --with-registry-auth -c docker-compose.yml {$this->application->uuid}")
 | 
				
			||||||
                        ],
 | 
					                        ],
 | 
				
			||||||
 | 
					                        [
 | 
				
			||||||
 | 
					                            "echo 'Stack deployed. It may take a few minutes to fully available in your swarm.'"
 | 
				
			||||||
 | 
					                        ]
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -376,7 +379,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                $envs->push($env->key . '=' . $env->value);
 | 
					                $envs->push($env->key . '=' . $env->value);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ray($envs);
 | 
					 | 
				
			||||||
        $envs_base64 = base64_encode($envs->implode("\n"));
 | 
					        $envs_base64 = base64_encode($envs->implode("\n"));
 | 
				
			||||||
        $this->execute_remote_command(
 | 
					        $this->execute_remote_command(
 | 
				
			||||||
            [
 | 
					            [
 | 
				
			||||||
@@ -442,17 +444,21 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
        $this->cleanup_git();
 | 
					        $this->cleanup_git();
 | 
				
			||||||
        $composeFile = $this->application->parseCompose(pull_request_id: $this->pull_request_id);
 | 
					        $composeFile = $this->application->parseCompose(pull_request_id: $this->pull_request_id);
 | 
				
			||||||
        $yaml = Yaml::dump($composeFile->toArray(), 10);
 | 
					        $yaml = Yaml::dump($composeFile->toArray(), 10);
 | 
				
			||||||
 | 
					        ray($composeFile);
 | 
				
			||||||
 | 
					        ray($this->container_name);
 | 
				
			||||||
        $this->docker_compose_base64 = base64_encode($yaml);
 | 
					        $this->docker_compose_base64 = base64_encode($yaml);
 | 
				
			||||||
        $this->execute_remote_command([
 | 
					        $this->execute_remote_command([
 | 
				
			||||||
            executeInDocker($this->deployment_uuid, "echo '{$this->docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yaml"), "hidden" => true
 | 
					            executeInDocker($this->deployment_uuid, "echo '{$this->docker_compose_base64}' | base64 -d > {$this->workdir}{$this->docker_compose_location}"), "hidden" => true
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
        $this->save_environment_variables();
 | 
					        $this->save_environment_variables();
 | 
				
			||||||
        $this->stop_running_container(force: true);
 | 
					        $this->stop_running_container(force: true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ray($this->pull_request_id);
 | 
				
			||||||
        $networkId = $this->application->uuid;
 | 
					        $networkId = $this->application->uuid;
 | 
				
			||||||
        if ($this->pull_request_id !== 0) {
 | 
					        if ($this->pull_request_id !== 0) {
 | 
				
			||||||
            $networkId = "{$this->application->uuid}-{$this->pull_request_id}";
 | 
					            $networkId = "{$this->application->uuid}-{$this->pull_request_id}";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        ray($networkId);
 | 
				
			||||||
        if ($this->server->isSwarm()) {
 | 
					        if ($this->server->isSwarm()) {
 | 
				
			||||||
            // TODO
 | 
					            // TODO
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@@ -832,26 +838,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
        $this->env_args = $this->env_args->implode(' ');
 | 
					        $this->env_args = $this->env_args->implode(' ');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function modify_compose_file()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // ray("{$this->workdir}{$this->docker_compose_location}");
 | 
					 | 
				
			||||||
        $this->execute_remote_command([executeInDocker($this->deployment_uuid, "cat {$this->workdir}{$this->docker_compose_location}"), "hidden" => true, "save" => 'compose_file']);
 | 
					 | 
				
			||||||
        if ($this->saved_outputs->get('compose_file')) {
 | 
					 | 
				
			||||||
            $compose = $this->saved_outputs->get('compose_file');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            $yaml = Yaml::parse($compose);
 | 
					 | 
				
			||||||
        } catch (\Exception $e) {
 | 
					 | 
				
			||||||
            throw new \Exception($e->getMessage());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $services = data_get($yaml, 'services');
 | 
					 | 
				
			||||||
        $topLevelNetworks = collect(data_get($yaml, 'networks', []));
 | 
					 | 
				
			||||||
        $definedNetwork = collect([$this->application->uuid]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $services = collect($services)->map(function ($service, $serviceName) use ($topLevelNetworks, $definedNetwork) {
 | 
					 | 
				
			||||||
            $serviceNetworks = collect(data_get($service, 'networks', []));
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    private function generate_compose_file()
 | 
					    private function generate_compose_file()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $ports = $this->application->settings->is_static ? [80] : $this->application->ports_exposes_array;
 | 
					        $ports = $this->application->settings->is_static ? [80] : $this->application->ports_exposes_array;
 | 
				
			||||||
@@ -952,10 +938,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                    ]
 | 
					                    ]
 | 
				
			||||||
                ]
 | 
					                ]
 | 
				
			||||||
            ];
 | 
					            ];
 | 
				
			||||||
 | 
					 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $docker_compose['services'][$this->container_name]['labels'] = $labels;
 | 
					            $docker_compose['services'][$this->container_name]['labels'] = $labels;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ($this->server->isLogDrainEnabled() && $this->application->isLogDrainEnabled()) {
 | 
					        if ($this->server->isLogDrainEnabled() && $this->application->isLogDrainEnabled()) {
 | 
				
			||||||
            $docker_compose['services'][$this->container_name]['logging'] = [
 | 
					            $docker_compose['services'][$this->container_name]['logging'] = [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,15 +43,37 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            if ($this->server->isSwarm()) {
 | 
					            if ($this->server->isSwarm()) {
 | 
				
			||||||
 | 
					                $containers = instant_remote_process(["docker service inspect $(docker service ls -q) --format '{{json .}}'"], $this->server, false);
 | 
				
			||||||
 | 
					                $containerReplicase = instant_remote_process(["docker service ls --format '{{json .}}'"], $this->server, false);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
                $containers = instant_remote_process(["docker container inspect $(docker container ls -q) --format '{{json .}}'"], $this->server, false);
 | 
					                $containers = instant_remote_process(["docker container inspect $(docker container ls -q) --format '{{json .}}'"], $this->server, false);
 | 
				
			||||||
 | 
					                $containerReplicase = null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (is_null($containers)) {
 | 
					            if (is_null($containers)) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $containers = format_docker_command_output_to_json($containers);
 | 
					            $containers = format_docker_command_output_to_json($containers);
 | 
				
			||||||
 | 
					            if ($containerReplicase) {
 | 
				
			||||||
 | 
					                $containerReplicase = format_docker_command_output_to_json($containerReplicase);
 | 
				
			||||||
 | 
					                foreach ($containerReplicase as $containerReplica) {
 | 
				
			||||||
 | 
					                    $name = data_get($containerReplica, 'Name');
 | 
				
			||||||
 | 
					                    $containers = $containers->map(function ($container) use ($name, $containerReplica) {
 | 
				
			||||||
 | 
					                        if (data_get($container, 'Spec.Name') === $name) {
 | 
				
			||||||
 | 
					                            $replicas = data_get($containerReplica, 'Replicas');
 | 
				
			||||||
 | 
					                            $running = str($replicas)->explode('/')[0];
 | 
				
			||||||
 | 
					                            $total = str($replicas)->explode('/')[1];
 | 
				
			||||||
 | 
					                            if ($running === $total) {
 | 
				
			||||||
 | 
					                                data_set($container, 'State.Status', 'running');
 | 
				
			||||||
 | 
					                                data_set($container, 'State.Health.Status', 'healthy');
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                data_set($container, 'State.Status', 'starting');
 | 
				
			||||||
 | 
					                                data_set($container, 'State.Health.Status', 'unhealthy');
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        return $container;
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            $applications = $this->server->applications();
 | 
					            $applications = $this->server->applications();
 | 
				
			||||||
            $databases = $this->server->databases();
 | 
					            $databases = $this->server->databases();
 | 
				
			||||||
            $services = $this->server->services()->get();
 | 
					            $services = $this->server->services()->get();
 | 
				
			||||||
@@ -63,10 +85,16 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
            $foundServices = [];
 | 
					            $foundServices = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach ($containers as $container) {
 | 
					            foreach ($containers as $container) {
 | 
				
			||||||
 | 
					                if ($this->server->isSwarm()) {
 | 
				
			||||||
 | 
					                    $labels = data_get($container, 'Spec.Labels');
 | 
				
			||||||
 | 
					                    $uuid = data_get($labels, 'coolify.name');
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $labels = data_get($container, 'Config.Labels');
 | 
				
			||||||
 | 
					                    $uuid = data_get($labels, 'com.docker.compose.service');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                $containerStatus = data_get($container, 'State.Status');
 | 
					                $containerStatus = data_get($container, 'State.Status');
 | 
				
			||||||
                $containerHealth = data_get($container, 'State.Health.Status', 'unhealthy');
 | 
					                $containerHealth = data_get($container, 'State.Health.Status', 'unhealthy');
 | 
				
			||||||
                $containerStatus = "$containerStatus ($containerHealth)";
 | 
					                $containerStatus = "$containerStatus ($containerHealth)";
 | 
				
			||||||
                $labels = data_get($container, 'Config.Labels');
 | 
					 | 
				
			||||||
                $labels = Arr::undot(format_docker_labels_to_json($labels));
 | 
					                $labels = Arr::undot(format_docker_labels_to_json($labels));
 | 
				
			||||||
                $applicationId = data_get($labels, 'coolify.applicationId');
 | 
					                $applicationId = data_get($labels, 'coolify.applicationId');
 | 
				
			||||||
                if ($applicationId) {
 | 
					                if ($applicationId) {
 | 
				
			||||||
@@ -98,7 +126,6 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $uuid = data_get($labels, 'com.docker.compose.service');
 | 
					 | 
				
			||||||
                    if ($uuid) {
 | 
					                    if ($uuid) {
 | 
				
			||||||
                        $database = $databases->where('uuid', $uuid)->first();
 | 
					                        $database = $databases->where('uuid', $uuid)->first();
 | 
				
			||||||
                        if ($database) {
 | 
					                        if ($database) {
 | 
				
			||||||
@@ -253,7 +280,11 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
            // Check if proxy is running
 | 
					            // Check if proxy is running
 | 
				
			||||||
            $this->server->proxyType();
 | 
					            $this->server->proxyType();
 | 
				
			||||||
            $foundProxyContainer = $containers->filter(function ($value, $key) {
 | 
					            $foundProxyContainer = $containers->filter(function ($value, $key) {
 | 
				
			||||||
 | 
					                if ($this->server->isSwarm()) {
 | 
				
			||||||
 | 
					                    return data_get($value, 'Spec.Name') === 'coolify-proxy_traefik';
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
                    return data_get($value, 'Name') === '/coolify-proxy';
 | 
					                    return data_get($value, 'Name') === '/coolify-proxy';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            })->first();
 | 
					            })->first();
 | 
				
			||||||
            if (!$foundProxyContainer) {
 | 
					            if (!$foundProxyContainer) {
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -603,6 +603,7 @@ class Application extends BaseModel
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($this->docker_compose_raw) {
 | 
					        if ($this->docker_compose_raw) {
 | 
				
			||||||
            $mainCompose = parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id);
 | 
					            $mainCompose = parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id);
 | 
				
			||||||
 | 
					            ray($this->docker_compose_pr_raw);
 | 
				
			||||||
            if ($this->getMorphClass() === 'App\Models\Application' && $this->docker_compose_pr_raw) {
 | 
					            if ($this->getMorphClass() === 'App\Models\Application' && $this->docker_compose_pr_raw) {
 | 
				
			||||||
                parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id, is_pr: true);
 | 
					                parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id, is_pr: true);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -614,7 +615,7 @@ class Application extends BaseModel
 | 
				
			|||||||
    function loadComposeFile($isInit = false)
 | 
					    function loadComposeFile($isInit = false)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $initialDockerComposeLocation = $this->docker_compose_location;
 | 
					        $initialDockerComposeLocation = $this->docker_compose_location;
 | 
				
			||||||
        $initialDockerComposePrLocation = $this->docker_compose_pr_location;
 | 
					        // $initialDockerComposePrLocation = $this->docker_compose_pr_location;
 | 
				
			||||||
        if ($this->build_pack === 'dockercompose') {
 | 
					        if ($this->build_pack === 'dockercompose') {
 | 
				
			||||||
            if ($isInit && $this->docker_compose_raw) {
 | 
					            if ($isInit && $this->docker_compose_raw) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
@@ -623,11 +624,11 @@ class Application extends BaseModel
 | 
				
			|||||||
            ['commands' => $cloneCommand] = $this->generateGitImportCommands(deployment_uuid: $uuid, only_checkout: true, exec_in_docker: false, custom_base_dir: '.');
 | 
					            ['commands' => $cloneCommand] = $this->generateGitImportCommands(deployment_uuid: $uuid, only_checkout: true, exec_in_docker: false, custom_base_dir: '.');
 | 
				
			||||||
            $workdir = rtrim($this->base_directory, '/');
 | 
					            $workdir = rtrim($this->base_directory, '/');
 | 
				
			||||||
            $composeFile = $this->docker_compose_location;
 | 
					            $composeFile = $this->docker_compose_location;
 | 
				
			||||||
            $prComposeFile = $this->docker_compose_pr_location;
 | 
					            // $prComposeFile = $this->docker_compose_pr_location;
 | 
				
			||||||
            $fileList = collect([".$composeFile"]);
 | 
					            $fileList = collect([".$workdir$composeFile"]);
 | 
				
			||||||
            if ($composeFile !== $prComposeFile) {
 | 
					            // if ($composeFile !== $prComposeFile) {
 | 
				
			||||||
                $fileList->push(".$prComposeFile");
 | 
					            //     $fileList->push(".$prComposeFile");
 | 
				
			||||||
            }
 | 
					            // }
 | 
				
			||||||
            $commands = collect([
 | 
					            $commands = collect([
 | 
				
			||||||
                "mkdir -p /tmp/{$uuid} && cd /tmp/{$uuid}",
 | 
					                "mkdir -p /tmp/{$uuid} && cd /tmp/{$uuid}",
 | 
				
			||||||
                $cloneCommand,
 | 
					                $cloneCommand,
 | 
				
			||||||
@@ -645,24 +646,24 @@ class Application extends BaseModel
 | 
				
			|||||||
                $this->docker_compose_raw = $composeFileContent;
 | 
					                $this->docker_compose_raw = $composeFileContent;
 | 
				
			||||||
                $this->save();
 | 
					                $this->save();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if ($composeFile === $prComposeFile) {
 | 
					            // if ($composeFile === $prComposeFile) {
 | 
				
			||||||
                $this->docker_compose_pr_raw = $composeFileContent;
 | 
					            //     $this->docker_compose_pr_raw = $composeFileContent;
 | 
				
			||||||
                $this->save();
 | 
					            //     $this->save();
 | 
				
			||||||
            } else {
 | 
					            // } else {
 | 
				
			||||||
                $commands = collect([
 | 
					            //     $commands = collect([
 | 
				
			||||||
                    "cd /tmp/{$uuid}",
 | 
					            //         "cd /tmp/{$uuid}",
 | 
				
			||||||
                    "cat .$workdir$prComposeFile",
 | 
					            //         "cat .$workdir$prComposeFile",
 | 
				
			||||||
                ]);
 | 
					            //     ]);
 | 
				
			||||||
                $composePrFileContent = instant_remote_process($commands, $this->destination->server, false);
 | 
					            //     $composePrFileContent = instant_remote_process($commands, $this->destination->server, false);
 | 
				
			||||||
                if (!$composePrFileContent) {
 | 
					            //     if (!$composePrFileContent) {
 | 
				
			||||||
                    $this->docker_compose_pr_location = $initialDockerComposePrLocation;
 | 
					            //         $this->docker_compose_pr_location = $initialDockerComposePrLocation;
 | 
				
			||||||
                    $this->save();
 | 
					            //         $this->save();
 | 
				
			||||||
                    throw new \Exception("Could not load compose file from $workdir$prComposeFile");
 | 
					            //         throw new \Exception("Could not load compose file from $workdir$prComposeFile");
 | 
				
			||||||
                } else {
 | 
					            //     } else {
 | 
				
			||||||
                    $this->docker_compose_pr_raw = $composePrFileContent;
 | 
					            //         $this->docker_compose_pr_raw = $composePrFileContent;
 | 
				
			||||||
                    $this->save();
 | 
					            //         $this->save();
 | 
				
			||||||
                }
 | 
					            //     }
 | 
				
			||||||
            }
 | 
					            // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $commands = collect([
 | 
					            $commands = collect([
 | 
				
			||||||
                "rm -rf /tmp/{$uuid}",
 | 
					                "rm -rf /tmp/{$uuid}",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,7 +93,11 @@ function executeInDocker(string $containerId, string $command)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function getContainerStatus(Server $server, string $container_id, bool $all_data = false, bool $throwError = false)
 | 
					function getContainerStatus(Server $server, string $container_id, bool $all_data = false, bool $throwError = false)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    if ($server->isSwarm()) {
 | 
				
			||||||
 | 
					        $container = instant_remote_process(["docker service ls --filter 'name={$container_id}' --format '{{json .}}' "], $server, $throwError);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
        $container = instant_remote_process(["docker inspect --format '{{json .}}' {$container_id}"], $server, $throwError);
 | 
					        $container = instant_remote_process(["docker inspect --format '{{json .}}' {$container_id}"], $server, $throwError);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (!$container) {
 | 
					    if (!$container) {
 | 
				
			||||||
        return 'exited';
 | 
					        return 'exited';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -101,8 +105,20 @@ function getContainerStatus(Server $server, string $container_id, bool $all_data
 | 
				
			|||||||
    if ($all_data) {
 | 
					    if ($all_data) {
 | 
				
			||||||
        return $container[0];
 | 
					        return $container[0];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if ($server->isSwarm()) {
 | 
				
			||||||
 | 
					        $replicas = data_get($container[0], 'Replicas');
 | 
				
			||||||
 | 
					        $replicas = explode('/', $replicas);
 | 
				
			||||||
 | 
					        $active = (int)$replicas[0];
 | 
				
			||||||
 | 
					        $total = (int)$replicas[1];
 | 
				
			||||||
 | 
					        if ($active === $total) {
 | 
				
			||||||
 | 
					            return 'running';
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return 'starting';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
        return data_get($container[0], 'State.Status', 'exited');
 | 
					        return data_get($container[0], 'State.Status', 'exited');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function generateApplicationContainerName(Application $application, $pull_request_id = 0)
 | 
					function generateApplicationContainerName(Application $application, $pull_request_id = 0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -863,7 +863,6 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
 | 
				
			|||||||
                        $key = Str::of($variableName);
 | 
					                        $key = Str::of($variableName);
 | 
				
			||||||
                        $value = Str::of($variable);
 | 
					                        $value = Str::of($variable);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    // TODO: here is the problem
 | 
					 | 
				
			||||||
                    if ($key->startsWith('SERVICE_FQDN')) {
 | 
					                    if ($key->startsWith('SERVICE_FQDN')) {
 | 
				
			||||||
                        if ($isNew || $savedService->fqdn === null) {
 | 
					                        if ($isNew || $savedService->fqdn === null) {
 | 
				
			||||||
                            $name = $key->after('SERVICE_FQDN_')->beforeLast('_')->lower();
 | 
					                            $name = $key->after('SERVICE_FQDN_')->beforeLast('_')->lower();
 | 
				
			||||||
@@ -1145,6 +1144,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
 | 
				
			|||||||
                    data_set($service, 'volumes', $serviceVolumes->toArray());
 | 
					                    data_set($service, 'volumes', $serviceVolumes->toArray());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
 | 
					                // TODO
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // Decide if the service is a database
 | 
					            // Decide if the service is a database
 | 
				
			||||||
            $isDatabase = isDatabaseImage(data_get_str($service, 'image'));
 | 
					            $isDatabase = isDatabaseImage(data_get_str($service, 'image'));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -207,10 +207,10 @@
 | 
				
			|||||||
                                placeholder="Username to connect to your server. Default is root." label="Username"
 | 
					                                placeholder="Username to connect to your server. Default is root." label="Username"
 | 
				
			||||||
                                id="remoteServerUser" />
 | 
					                                id="remoteServerUser" />
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                        <div class="w-64">
 | 
					                        {{-- <div class="w-64">
 | 
				
			||||||
                            <x-forms.checkbox type="checkbox" id="isSwarmManager"
 | 
					                            <x-forms.checkbox type="checkbox" id="isSwarmManager"
 | 
				
			||||||
                                label="Is it a Swarm Manager?" />
 | 
					                                label="Is it a Swarm Manager?" />
 | 
				
			||||||
                        </div>
 | 
					                        </div> --}}
 | 
				
			||||||
                        <x-forms.button type="submit">Check Connection</x-forms.button>
 | 
					                        <x-forms.button type="submit">Check Connection</x-forms.button>
 | 
				
			||||||
                    </form>
 | 
					                    </form>
 | 
				
			||||||
                </x-slot:actions>
 | 
					                </x-slot:actions>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,8 +54,8 @@
 | 
				
			|||||||
                        helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.<span class='text-warning'>Coolify does not install/setup Cloudflare (cloudflared) on your server.</span>"
 | 
					                        helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.<span class='text-warning'>Coolify does not install/setup Cloudflare (cloudflared) on your server.</span>"
 | 
				
			||||||
                        id="server.settings.is_cloudflare_tunnel" label="Cloudflare Tunnel" />
 | 
					                        id="server.settings.is_cloudflare_tunnel" label="Cloudflare Tunnel" />
 | 
				
			||||||
                @endif
 | 
					                @endif
 | 
				
			||||||
                <x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_manager"
 | 
					                {{-- <x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_manager"
 | 
				
			||||||
                    label="Is it a Swarm Manager?" />
 | 
					                    label="Is it a Swarm Manager?" /> --}}
 | 
				
			||||||
                    {{-- <x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_worker"
 | 
					                    {{-- <x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_worker"
 | 
				
			||||||
                    label="Is it a Swarm Worker?" /> --}}
 | 
					                    label="Is it a Swarm Worker?" /> --}}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,10 +25,10 @@
 | 
				
			|||||||
                    @endif
 | 
					                    @endif
 | 
				
			||||||
                @endforeach
 | 
					                @endforeach
 | 
				
			||||||
            </x-forms.select>
 | 
					            </x-forms.select>
 | 
				
			||||||
            <div class="w-64">
 | 
					            {{-- <div class="w-64">
 | 
				
			||||||
                <x-forms.checkbox type="checkbox" id="is_swarm_manager"
 | 
					                <x-forms.checkbox type="checkbox" id="is_swarm_manager"
 | 
				
			||||||
                    label="Is it a Swarm Manager?" />
 | 
					                    label="Is it a Swarm Manager?" />
 | 
				
			||||||
            </div>
 | 
					            </div> --}}
 | 
				
			||||||
            <x-forms.button type="submit">
 | 
					            <x-forms.button type="submit">
 | 
				
			||||||
                Save New Server
 | 
					                Save New Server
 | 
				
			||||||
            </x-forms.button>
 | 
					            </x-forms.button>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
<div>
 | 
					<div>
 | 
				
			||||||
    @if ($server->isFunctional())
 | 
					    @if ($server->isFunctional())
 | 
				
			||||||
        <div class="flex gap-2" @if ($polling) wire:poll.2000ms='checkProxy' @endif>
 | 
					        <div class="flex gap-2" wire:poll.5000ms='checkProxy'>
 | 
				
			||||||
            @if (data_get($server, 'proxy.status') === 'running')
 | 
					            @if (data_get($server, 'proxy.status') === 'running')
 | 
				
			||||||
                <x-status.running status="Proxy Running" />
 | 
					                <x-status.running status="Proxy Running" />
 | 
				
			||||||
            @elseif (data_get($server, 'proxy.status') === 'restarting')
 | 
					            @elseif (data_get($server, 'proxy.status') === 'restarting')
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user