wip: swarm
This commit is contained in:
parent
928b68043b
commit
2d7bbbe300
@ -30,7 +30,7 @@ public function handle(Server $server, bool $async = true): string|Activity
|
||||
"mkdir -p $proxy_path && cd $proxy_path",
|
||||
"echo 'Creating required Docker Compose file.'",
|
||||
"echo 'Starting coolify-proxy.'",
|
||||
// "docker stack deploy -c docker-compose.yaml coolify-proxy",
|
||||
"cd $proxy_path && docker stack deploy -c docker-compose.yml coolify-proxy",
|
||||
"echo 'Proxy started successfully.'"
|
||||
]);
|
||||
} else {
|
||||
|
@ -76,10 +76,20 @@ public function handle(Server $server)
|
||||
"echo 'Restarting Docker Engine...'",
|
||||
"systemctl enable docker >/dev/null 2>&1 || true",
|
||||
"systemctl restart docker",
|
||||
"echo 'Creating default Docker network (coolify)...'",
|
||||
"docker network create --attachable coolify >/dev/null 2>&1 || true",
|
||||
"echo 'Done!'"
|
||||
]);
|
||||
if ($server->isSwarm()) {
|
||||
$command = $command->merge([
|
||||
"docker network create --attachable --driver overlay coolify-overlay >/dev/null 2>&1 || true",
|
||||
]);
|
||||
} else {
|
||||
$command = $command->merge([
|
||||
"docker network create --attachable coolify >/dev/null 2>&1 || true",
|
||||
]);
|
||||
$command = $command->merge([
|
||||
"echo 'Done!'",
|
||||
]);
|
||||
}
|
||||
|
||||
return remote_process($command, $server);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ class Index extends Component
|
||||
public ?string $remoteServerHost = null;
|
||||
public ?int $remoteServerPort = 22;
|
||||
public ?string $remoteServerUser = 'root';
|
||||
public bool $isPartOfSwarm = false;
|
||||
public bool $isSwarmManager = false;
|
||||
public ?Server $createdServer = null;
|
||||
|
||||
public Collection $projects;
|
||||
@ -183,7 +183,7 @@ public function saveServer()
|
||||
'private_key_id' => $this->createdPrivateKey->id,
|
||||
'team_id' => currentTeam()->id,
|
||||
]);
|
||||
$this->createdServer->settings->is_part_of_swarm = $this->isPartOfSwarm;
|
||||
$this->createdServer->settings->is_swarm_manager = $this->isSwarmManager;
|
||||
$this->createdServer->settings->save();
|
||||
$this->createdServer->addInitialNetwork();
|
||||
$this->validateServer();
|
||||
|
@ -24,7 +24,8 @@ class Form extends Component
|
||||
'server.port' => 'required',
|
||||
'server.settings.is_cloudflare_tunnel' => 'required|boolean',
|
||||
'server.settings.is_reachable' => 'required',
|
||||
'server.settings.is_part_of_swarm' => 'required|boolean',
|
||||
'server.settings.is_swarm_manager' => 'required|boolean',
|
||||
// 'server.settings.is_swarm_worker' => 'required|boolean',
|
||||
'wildcard_domain' => 'nullable|url',
|
||||
];
|
||||
protected $validationAttributes = [
|
||||
@ -34,8 +35,9 @@ class Form extends Component
|
||||
'server.user' => 'User',
|
||||
'server.port' => 'Port',
|
||||
'server.settings.is_cloudflare_tunnel' => 'Cloudflare Tunnel',
|
||||
'server.settings.is_reachable' => 'is reachable',
|
||||
'server.settings.is_part_of_swarm' => 'is part of swarm'
|
||||
'server.settings.is_reachable' => 'Is reachable',
|
||||
'server.settings.is_swarm_manager' => 'Swarm Manager',
|
||||
// 'server.settings.is_swarm_worker' => 'Swarm Worker',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
|
@ -21,7 +21,7 @@ class ByIp extends Component
|
||||
public string $ip;
|
||||
public string $user = 'root';
|
||||
public int $port = 22;
|
||||
public bool $is_part_of_swarm = false;
|
||||
public bool $is_swarm_manager = false;
|
||||
|
||||
protected $rules = [
|
||||
'name' => 'required|string',
|
||||
@ -29,7 +29,7 @@ class ByIp extends Component
|
||||
'ip' => 'required',
|
||||
'user' => 'required|string',
|
||||
'port' => 'required|integer',
|
||||
'is_part_of_swarm' => 'required|boolean',
|
||||
'is_swarm_manager' => 'required|boolean',
|
||||
];
|
||||
protected $validationAttributes = [
|
||||
'name' => 'Name',
|
||||
@ -37,7 +37,7 @@ class ByIp extends Component
|
||||
'ip' => 'IP Address/Domain',
|
||||
'user' => 'User',
|
||||
'port' => 'Port',
|
||||
'is_part_of_swarm' => 'Is part of swarm',
|
||||
'is_swarm_manager' => 'Swarm Manager',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
@ -76,7 +76,7 @@ public function submit()
|
||||
"status" => ProxyStatus::EXITED->value,
|
||||
],
|
||||
]);
|
||||
$server->settings->is_part_of_swarm = $this->is_part_of_swarm;
|
||||
$server->settings->is_swarm_manager = $this->is_swarm_manager;
|
||||
$server->settings->save();
|
||||
$server->addInitialNetwork();
|
||||
return redirect()->route('server.show', $server->uuid);
|
||||
|
@ -453,11 +453,16 @@ private function deploy_docker_compose_buildpack()
|
||||
if ($this->pull_request_id !== 0) {
|
||||
$networkId = "{$this->application->uuid}-{$this->pull_request_id}";
|
||||
}
|
||||
if ($this->server->isSwarm()) {
|
||||
// TODO
|
||||
} else {
|
||||
$this->execute_remote_command([
|
||||
"docker network create --attachable '{$networkId}' >/dev/null || true", "hidden" => true, "ignore_errors" => true
|
||||
], [
|
||||
"docker network connect {$networkId} coolify-proxy || true", "hidden" => true, "ignore_errors" => true
|
||||
]);
|
||||
}
|
||||
|
||||
$this->start_by_compose_file();
|
||||
$this->application->loadComposeFile(isInit: false);
|
||||
}
|
||||
|
@ -42,6 +42,11 @@ public function handle()
|
||||
if (!$this->server->isServerReady()) {
|
||||
return;
|
||||
};
|
||||
if ($this->server->isSwarm()) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
$containers = instant_remote_process(["docker container inspect $(docker container ls -q) --format '{{json .}}'"], $this->server, false);
|
||||
if (is_null($containers)) {
|
||||
return;
|
||||
|
@ -378,7 +378,7 @@ public function validateOS(): bool | Stringable
|
||||
}
|
||||
public function isSwarm()
|
||||
{
|
||||
return data_get($this, 'settings.is_part_of_swarm');
|
||||
return data_get($this, 'settings.is_swarm_manager') || data_get($this, 'settings.is_swarm_worker');
|
||||
}
|
||||
public function validateConnection()
|
||||
{
|
||||
|
@ -54,9 +54,15 @@ function connectProxyToNetworks(Server $server)
|
||||
function generate_default_proxy_configuration(Server $server)
|
||||
{
|
||||
$proxy_path = get_proxy_path();
|
||||
if ($server->isSwarm()) {
|
||||
$networks = collect($server->swarmDockers)->map(function ($docker) {
|
||||
return $docker['network'];
|
||||
})->unique();
|
||||
} else {
|
||||
$networks = collect($server->standaloneDockers)->map(function ($docker) {
|
||||
return $docker['network'];
|
||||
})->unique();
|
||||
}
|
||||
if ($networks->count() === 0) {
|
||||
$networks = collect(['coolify']);
|
||||
}
|
||||
@ -66,6 +72,16 @@ function generate_default_proxy_configuration(Server $server)
|
||||
"external" => true,
|
||||
];
|
||||
});
|
||||
$labels = [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.traefik.entrypoints=http",
|
||||
"traefik.http.routers.traefik.middlewares=traefik-basic-auth@file",
|
||||
"traefik.http.routers.traefik.service=api@internal",
|
||||
"traefik.http.services.traefik.loadbalancer.server.port=8080",
|
||||
// Global Middlewares
|
||||
"traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https",
|
||||
"traefik.http.middlewares.gzip.compress=true",
|
||||
];
|
||||
$config = [
|
||||
"version" => "3.8",
|
||||
"networks" => $array_of_networks->toArray(),
|
||||
@ -109,16 +125,7 @@ function generate_default_proxy_configuration(Server $server)
|
||||
"--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json",
|
||||
"--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http",
|
||||
],
|
||||
"labels" => [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.traefik.entrypoints=http",
|
||||
"traefik.http.routers.traefik.middlewares=traefik-basic-auth@file",
|
||||
"traefik.http.routers.traefik.service=api@internal",
|
||||
"traefik.http.services.traefik.loadbalancer.server.port=8080",
|
||||
// Global Middlewares
|
||||
"traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https",
|
||||
"traefik.http.middlewares.gzip.compress=true",
|
||||
],
|
||||
"labels" => $labels,
|
||||
],
|
||||
],
|
||||
];
|
||||
@ -128,8 +135,13 @@ function generate_default_proxy_configuration(Server $server)
|
||||
$config['services']['traefik']['command'][] = "--accesslog.bufferingsize=100";
|
||||
}
|
||||
if ($server->isSwarm()) {
|
||||
data_forget($config, 'services.traefik.container_name');
|
||||
data_forget($config, 'services.traefik.restart');
|
||||
data_forget($config, 'services.traefik.labels');
|
||||
|
||||
$config['services']['traefik']['command'][] = "--providers.docker.swarmMode=true";
|
||||
$config['services']['traefik']['deploy'] = [
|
||||
"labels" => $labels,
|
||||
"placement" => [
|
||||
"constraints" => [
|
||||
"node.role==manager",
|
||||
@ -139,7 +151,7 @@ function generate_default_proxy_configuration(Server $server)
|
||||
} else {
|
||||
$config['services']['traefik']['command'][] = "--providers.docker=true";
|
||||
}
|
||||
$config = Yaml::dump($config, 4, 2);
|
||||
$config = Yaml::dump($config, 12, 2);
|
||||
SaveConfiguration::run($server, $config);
|
||||
return $config;
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('server_settings', function (Blueprint $table) {
|
||||
$table->renameColumn('is_part_of_swarm', 'is_swarm_manager');
|
||||
$table->boolean('is_swarm_worker')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('server_settings', function (Blueprint $table) {
|
||||
$table->renameColumn('is_swarm_manager', 'is_part_of_swarm');
|
||||
$table->dropColumn('is_swarm_worker');
|
||||
});
|
||||
}
|
||||
};
|
@ -15,6 +15,8 @@
|
||||
<div class="flex-1"></div>
|
||||
@if ($application->build_pack === 'dockercompose' && is_null($application->docker_compose_raw))
|
||||
<div>Please load a Compose file.</div>
|
||||
@elseif ($application->destination->server->isSwarm() && str($application->docker_registry_image_name)->isEmpty())
|
||||
Swarm Deployments requires a Docker Image in a Registry.
|
||||
@else
|
||||
<x-applications.advanced :application="$application" />
|
||||
@if ($application->status !== 'exited')
|
||||
|
@ -208,7 +208,7 @@
|
||||
id="remoteServerUser" />
|
||||
</div>
|
||||
<div class="w-64">
|
||||
<x-forms.checkbox type="checkbox" id="isPartOfSwarm"
|
||||
<x-forms.checkbox type="checkbox" id="isSwarmManager"
|
||||
label="Is it a Swarm Manager?" />
|
||||
</div>
|
||||
<x-forms.button type="submit">Check Connection</x-forms.button>
|
||||
|
@ -54,8 +54,10 @@
|
||||
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" />
|
||||
@endif
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_part_of_swarm"
|
||||
<x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_manager"
|
||||
label="Is it a Swarm Manager?" />
|
||||
{{-- <x-forms.checkbox instantSave type="checkbox" id="server.settings.is_swarm_worker"
|
||||
label="Is it a Swarm Worker?" /> --}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<div class="w-64">
|
||||
<x-forms.checkbox type="checkbox" id="is_part_of_swarm"
|
||||
<x-forms.checkbox type="checkbox" id="is_swarm_manager"
|
||||
label="Is it a Swarm Manager?" />
|
||||
</div>
|
||||
<x-forms.button type="submit">
|
||||
|
@ -16,6 +16,7 @@ curl -fsSL $CDN/.env.production -o /data/coolify/source/.env.production
|
||||
sort -u -t '=' -k 1,1 /data/coolify/source/.env /data/coolify/source/.env.production | sed '/^$/d' > /data/coolify/source/.env.temp && mv /data/coolify/source/.env.temp /data/coolify/source/.env
|
||||
|
||||
# Make sure coolify network exists
|
||||
docker network create coolify 2>/dev/null
|
||||
docker network create --attachable coolify 2>/dev/null
|
||||
# docker network create --attachable --driver=overlay coolify-overlay 2>/dev/null
|
||||
|
||||
docker run --pull always -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/coollabsio/coolify-helper bash -c "LATEST_IMAGE=${1:-} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml up -d --pull always --remove-orphans --force-recreate"
|
||||
|
Loading…
Reference in New Issue
Block a user