commit
6ddff8fae1
@ -106,7 +106,6 @@ class StartMariadb
|
|||||||
$this->commands[] = "echo 'Pulling {$database->image} image.'";
|
$this->commands[] = "echo 'Pulling {$database->image} image.'";
|
||||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
||||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||||
$database_name = addslashes($database->name);
|
|
||||||
$this->commands[] = "echo 'Database started.'";
|
$this->commands[] = "echo 'Database started.'";
|
||||||
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,6 @@ class StartMongodb
|
|||||||
$this->commands[] = "echo 'Pulling {$database->image} image.'";
|
$this->commands[] = "echo 'Pulling {$database->image} image.'";
|
||||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
||||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||||
$database_name = addslashes($database->name);
|
|
||||||
$this->commands[] = "echo 'Database started.'";
|
$this->commands[] = "echo 'Database started.'";
|
||||||
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,6 @@ class StartMysql
|
|||||||
$this->commands[] = "echo 'Pulling {$database->image} image.'";
|
$this->commands[] = "echo 'Pulling {$database->image} image.'";
|
||||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
||||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||||
$database_name = addslashes($database->name);
|
|
||||||
$this->commands[] = "echo 'Database started.'";
|
$this->commands[] = "echo 'Database started.'";
|
||||||
return remote_process($this->commands, $database->destination->server,callEventOnFinish: 'DatabaseStatusChanged');
|
return remote_process($this->commands, $database->destination->server,callEventOnFinish: 'DatabaseStatusChanged');
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,6 @@ class StartPostgresql
|
|||||||
$this->commands[] = "echo 'Pulling {$database->image} image.'";
|
$this->commands[] = "echo 'Pulling {$database->image} image.'";
|
||||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
||||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||||
$database_name = addslashes($database->name);
|
|
||||||
$this->commands[] = "echo 'Database started.'";
|
$this->commands[] = "echo 'Database started.'";
|
||||||
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,6 @@ class StartRedis
|
|||||||
$this->commands[] = "echo 'Pulling {$database->image} image.'";
|
$this->commands[] = "echo 'Pulling {$database->image} image.'";
|
||||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
||||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||||
$database_name = addslashes($database->name);
|
|
||||||
$this->commands[] = "echo 'Database started.'";
|
$this->commands[] = "echo 'Database started.'";
|
||||||
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,6 @@ class StartService
|
|||||||
{
|
{
|
||||||
ray('Starting service: ' . $service->name);
|
ray('Starting service: ' . $service->name);
|
||||||
$service->saveComposeConfigs();
|
$service->saveComposeConfigs();
|
||||||
|
|
||||||
$service_name = addslashes($service->name);
|
|
||||||
$server_name = addslashes($service->server->name);
|
|
||||||
|
|
||||||
$commands[] = "cd " . $service->workdir();
|
$commands[] = "cd " . $service->workdir();
|
||||||
$commands[] = "echo 'Saved configuration files to {$service->workdir()}.'";
|
$commands[] = "echo 'Saved configuration files to {$service->workdir()}.'";
|
||||||
$commands[] = "echo 'Creating Docker network.'";
|
$commands[] = "echo 'Creating Docker network.'";
|
||||||
|
@ -206,7 +206,8 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
|||||||
try {
|
try {
|
||||||
config()->set('coolify.mux_enabled', false);
|
config()->set('coolify.mux_enabled', false);
|
||||||
|
|
||||||
instant_remote_process(['uptime'], $this->createdServer, true);
|
// EC2 does not have `uptime` command, lol
|
||||||
|
instant_remote_process(['ls /'], $this->createdServer, true);
|
||||||
|
|
||||||
$this->createdServer->settings()->update([
|
$this->createdServer->settings()->update([
|
||||||
'is_reachable' => true,
|
'is_reachable' => true,
|
||||||
|
@ -17,6 +17,7 @@ class ServiceApplicationView extends Component
|
|||||||
'application.exclude_from_status' => 'required|boolean',
|
'application.exclude_from_status' => 'required|boolean',
|
||||||
'application.required_fqdn' => 'required|boolean',
|
'application.required_fqdn' => 'required|boolean',
|
||||||
'application.is_log_drain_enabled' => 'nullable|boolean',
|
'application.is_log_drain_enabled' => 'nullable|boolean',
|
||||||
|
'application.is_gzip_enabled' => 'nullable|boolean',
|
||||||
];
|
];
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
|
@ -45,8 +45,10 @@ class StackForm extends Component
|
|||||||
$this->service->docker_compose_raw = $raw;
|
$this->service->docker_compose_raw = $raw;
|
||||||
$this->submit();
|
$this->submit();
|
||||||
}
|
}
|
||||||
public function instantSave() {
|
public function instantSave()
|
||||||
|
{
|
||||||
$this->service->save();
|
$this->service->save();
|
||||||
|
$this->dispatch('success', 'Service settings saved successfully.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function submit()
|
public function submit()
|
||||||
|
@ -37,6 +37,9 @@ class Destination extends Component
|
|||||||
$this->networks = $this->networks->reject(function ($network) use ($all_networks) {
|
$this->networks = $this->networks->reject(function ($network) use ($all_networks) {
|
||||||
return $all_networks->pluck('id')->contains($network->id);
|
return $all_networks->pluck('id')->contains($network->id);
|
||||||
});
|
});
|
||||||
|
$this->networks = $this->networks->reject(function ($network) {
|
||||||
|
return $this->resource->destination->server->id == $network->server->id;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
public function redeploy(int $network_id, int $server_id)
|
public function redeploy(int $network_id, int $server_id)
|
||||||
{
|
{
|
||||||
@ -70,7 +73,7 @@ class Destination extends Component
|
|||||||
}
|
}
|
||||||
public function removeServer(int $network_id, int $server_id)
|
public function removeServer(int $network_id, int $server_id)
|
||||||
{
|
{
|
||||||
if ($this->resource->destination->server->id == $server_id) {
|
if ($this->resource->destination->server->id == $server_id && $this->resource->destination->id == $network_id) {
|
||||||
$this->dispatch('error', 'You cannot remove this destination server.', 'You are trying to remove the main server.');
|
$this->dispatch('error', 'You cannot remove this destination server.', 'You are trying to remove the main server.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,9 @@ class Form extends Component
|
|||||||
public ?string $wildcard_domain = null;
|
public ?string $wildcard_domain = null;
|
||||||
public int $cleanup_after_percentage;
|
public int $cleanup_after_percentage;
|
||||||
public bool $dockerInstallationStarted = false;
|
public bool $dockerInstallationStarted = false;
|
||||||
|
public bool $revalidate = false;
|
||||||
|
|
||||||
protected $listeners = ['serverInstalled'];
|
protected $listeners = ['serverInstalled', 'revalidate' => '$refresh'];
|
||||||
|
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'server.name' => 'required',
|
'server.name' => 'required',
|
||||||
@ -68,6 +69,10 @@ class Form extends Component
|
|||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public function revalidate()
|
||||||
|
{
|
||||||
|
$this->revalidate = true;
|
||||||
|
}
|
||||||
public function checkLocalhostConnection()
|
public function checkLocalhostConnection()
|
||||||
{
|
{
|
||||||
$uptime = $this->server->validateConnection();
|
$uptime = $this->server->validateConnection();
|
||||||
|
@ -19,12 +19,12 @@ class ValidateAndInstall extends Component
|
|||||||
public $docker_version = null;
|
public $docker_version = null;
|
||||||
public $proxy_started = false;
|
public $proxy_started = false;
|
||||||
public $error = null;
|
public $error = null;
|
||||||
|
public bool $ask = false;
|
||||||
|
|
||||||
protected $listeners = ['validateServer' => 'init', 'validateDockerEngine', 'validateServerNow' => 'validateServer'];
|
protected $listeners = ['validateServer' => 'init', 'validateDockerEngine', 'validateServerNow' => 'validateServer'];
|
||||||
|
|
||||||
public function init(bool $install = true)
|
public function init(bool $install = true)
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->install = $install;
|
$this->install = $install;
|
||||||
$this->uptime = null;
|
$this->uptime = null;
|
||||||
$this->supported_os_type = null;
|
$this->supported_os_type = null;
|
||||||
@ -34,9 +34,14 @@ class ValidateAndInstall extends Component
|
|||||||
$this->proxy_started = null;
|
$this->proxy_started = null;
|
||||||
$this->error = null;
|
$this->error = null;
|
||||||
$this->number_of_tries = 0;
|
$this->number_of_tries = 0;
|
||||||
|
if (!$this->ask) {
|
||||||
$this->dispatch('validateServerNow');
|
$this->dispatch('validateServerNow');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
public function startValidatingAfterAsking() {
|
||||||
|
$this->ask = false;
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
public function validateServer()
|
public function validateServer()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -400,7 +400,9 @@ class Server extends BaseModel
|
|||||||
if ($server->skipServer()) {
|
if ($server->skipServer()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$uptime = instant_remote_process(['uptime'], $server, false);
|
// EC2 does not have `uptime` command, lol
|
||||||
|
|
||||||
|
$uptime = instant_remote_process(['ls /'], $server, false);
|
||||||
if (!$uptime) {
|
if (!$uptime) {
|
||||||
$server->settings()->update([
|
$server->settings()->update([
|
||||||
'is_reachable' => false,
|
'is_reachable' => false,
|
||||||
|
@ -23,6 +23,10 @@ class ServiceApplication extends BaseModel
|
|||||||
{
|
{
|
||||||
return data_get($this, 'is_log_drain_enabled', false);
|
return data_get($this, 'is_log_drain_enabled', false);
|
||||||
}
|
}
|
||||||
|
public function isGzipEnabled()
|
||||||
|
{
|
||||||
|
return data_get($this, 'is_gzip_enabled', true);
|
||||||
|
}
|
||||||
public function type()
|
public function type()
|
||||||
{
|
{
|
||||||
return 'service';
|
return 'service';
|
||||||
|
@ -21,6 +21,10 @@ class ServiceDatabase extends BaseModel
|
|||||||
{
|
{
|
||||||
return data_get($this, 'is_log_drain_enabled', false);
|
return data_get($this, 'is_log_drain_enabled', false);
|
||||||
}
|
}
|
||||||
|
public function isGzipEnabled()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
public function type()
|
public function type()
|
||||||
{
|
{
|
||||||
return 'service';
|
return 'service';
|
||||||
|
@ -7,7 +7,6 @@ use App\Models\ServiceApplication;
|
|||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Spatie\Url\Url;
|
use Spatie\Url\Url;
|
||||||
use Visus\Cuid2\Cuid2;
|
|
||||||
|
|
||||||
function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null): Collection
|
function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null): Collection
|
||||||
{
|
{
|
||||||
@ -213,7 +212,7 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource,
|
|||||||
}
|
}
|
||||||
return $payload;
|
return $payload;
|
||||||
}
|
}
|
||||||
function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_https_enabled = false, $onlyPort = null, ?Collection $serviceLabels = null)
|
function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_https_enabled = false, $onlyPort = null, ?Collection $serviceLabels = null, ?bool $is_gzip_enabled = true)
|
||||||
{
|
{
|
||||||
$labels = collect([]);
|
$labels = collect([]);
|
||||||
$labels->push('traefik.enable=true');
|
$labels->push('traefik.enable=true');
|
||||||
@ -276,24 +275,36 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
|||||||
}
|
}
|
||||||
if ($path !== '/') {
|
if ($path !== '/') {
|
||||||
$labels->push("traefik.http.middlewares.{$https_label}-stripprefix.stripprefix.prefixes={$path}");
|
$labels->push("traefik.http.middlewares.{$https_label}-stripprefix.stripprefix.prefixes={$path}");
|
||||||
$middlewares = "gzip,{$https_label}-stripprefix";
|
$middlewares = collect(["{$https_label}-stripprefix"]);
|
||||||
|
if ($is_gzip_enabled) {
|
||||||
|
$middlewares->push('gzip');
|
||||||
|
}
|
||||||
if ($basic_auth && $basic_auth_middleware) {
|
if ($basic_auth && $basic_auth_middleware) {
|
||||||
$middlewares = $middlewares . ',' . $basic_auth_middleware;
|
$middlewares->push($basic_auth_middleware);
|
||||||
}
|
}
|
||||||
if ($redirect && $redirect_middleware) {
|
if ($redirect && $redirect_middleware) {
|
||||||
$middlewares = $middlewares . ',' . $redirect_middleware;
|
$middlewares->push($redirect_middleware);
|
||||||
}
|
}
|
||||||
|
if ($middlewares->isNotEmpty()) {
|
||||||
|
$middlewares = $middlewares->join(',');
|
||||||
$labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}");
|
$labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$middlewares = "gzip";
|
$middlewares = collect([]);
|
||||||
|
if ($is_gzip_enabled) {
|
||||||
|
$middlewares->push('gzip');
|
||||||
|
}
|
||||||
if ($basic_auth && $basic_auth_middleware) {
|
if ($basic_auth && $basic_auth_middleware) {
|
||||||
$middlewares = $middlewares . ',' . $basic_auth_middleware;
|
$middlewares->push($basic_auth_middleware);
|
||||||
}
|
}
|
||||||
if ($redirect && $redirect_middleware) {
|
if ($redirect && $redirect_middleware) {
|
||||||
$middlewares = $middlewares . ',' . $redirect_middleware;
|
$middlewares->push($redirect_middleware);
|
||||||
}
|
}
|
||||||
|
if ($middlewares->isNotEmpty()) {
|
||||||
|
$middlewares = $middlewares->join(',');
|
||||||
$labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}");
|
$labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$labels->push("traefik.http.routers.{$https_label}.tls=true");
|
$labels->push("traefik.http.routers.{$https_label}.tls=true");
|
||||||
$labels->push("traefik.http.routers.{$https_label}.tls.certresolver=letsencrypt");
|
$labels->push("traefik.http.routers.{$https_label}.tls.certresolver=letsencrypt");
|
||||||
|
|
||||||
@ -317,25 +328,37 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
|||||||
}
|
}
|
||||||
if ($path !== '/') {
|
if ($path !== '/') {
|
||||||
$labels->push("traefik.http.middlewares.{$http_label}-stripprefix.stripprefix.prefixes={$path}");
|
$labels->push("traefik.http.middlewares.{$http_label}-stripprefix.stripprefix.prefixes={$path}");
|
||||||
$middlewares = "gzip,{$http_label}-stripprefix";
|
$middlewares = collect(["{$http_label}-stripprefix"]);
|
||||||
|
if ($is_gzip_enabled) {
|
||||||
|
$middlewares->push('gzip');
|
||||||
|
}
|
||||||
if ($basic_auth && $basic_auth_middleware) {
|
if ($basic_auth && $basic_auth_middleware) {
|
||||||
$middlewares = $middlewares . ',' . $basic_auth_middleware;
|
$middlewares->push($basic_auth_middleware);
|
||||||
}
|
}
|
||||||
if ($redirect && $redirect_middleware) {
|
if ($redirect && $redirect_middleware) {
|
||||||
$middlewares = $middlewares . ',' . $redirect_middleware;
|
$middlewares->push($redirect_middleware);
|
||||||
}
|
}
|
||||||
|
if ($middlewares->isNotEmpty()) {
|
||||||
|
$middlewares = $middlewares->join(',');
|
||||||
$labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}");
|
$labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$middlewares = "gzip";
|
$middlewares = collect([]);
|
||||||
|
if ($is_gzip_enabled) {
|
||||||
|
$middlewares->push('gzip');
|
||||||
|
}
|
||||||
if ($basic_auth && $basic_auth_middleware) {
|
if ($basic_auth && $basic_auth_middleware) {
|
||||||
$middlewares = $middlewares . ',' . $basic_auth_middleware;
|
$middlewares->push($basic_auth_middleware);
|
||||||
}
|
}
|
||||||
if ($redirect && $redirect_middleware) {
|
if ($redirect && $redirect_middleware) {
|
||||||
$middlewares = $middlewares . ',' . $redirect_middleware;
|
$middlewares->push($redirect_middleware);
|
||||||
}
|
}
|
||||||
|
if ($middlewares->isNotEmpty()) {
|
||||||
|
$middlewares = $middlewares->join(',');
|
||||||
$labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}");
|
$labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -228,56 +228,6 @@ function refresh_server_connection(?PrivateKey $private_key = null)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// function validateServer(Server $server, bool $throwError = false)
|
|
||||||
// {
|
|
||||||
// try {
|
|
||||||
// $uptime = instant_remote_process(['uptime'], $server, $throwError);
|
|
||||||
// if (!$uptime) {
|
|
||||||
// $server->settings->is_reachable = false;
|
|
||||||
// $server->team->notify(new Unreachable($server));
|
|
||||||
// $server->unreachable_notification_sent = true;
|
|
||||||
// $server->save();
|
|
||||||
// return [
|
|
||||||
// "uptime" => null,
|
|
||||||
// "dockerVersion" => null,
|
|
||||||
// ];
|
|
||||||
// }
|
|
||||||
// $server->settings->is_reachable = true;
|
|
||||||
// instant_remote_process(["docker ps"], $server, $throwError);
|
|
||||||
// $dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $server, $throwError);
|
|
||||||
// if (!$dockerVersion) {
|
|
||||||
// $dockerVersion = null;
|
|
||||||
// return [
|
|
||||||
// "uptime" => $uptime,
|
|
||||||
// "dockerVersion" => null,
|
|
||||||
// ];
|
|
||||||
// }
|
|
||||||
// $dockerVersion = checkMinimumDockerEngineVersion($dockerVersion);
|
|
||||||
// if (is_null($dockerVersion)) {
|
|
||||||
// $server->settings->is_usable = false;
|
|
||||||
// } else {
|
|
||||||
// $server->settings->is_usable = true;
|
|
||||||
// if (data_get($server, 'unreachable_notification_sent') === true) {
|
|
||||||
// $server->team->notify(new Revived($server));
|
|
||||||
// $server->unreachable_notification_sent = false;
|
|
||||||
// $server->save();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return [
|
|
||||||
// "uptime" => $uptime,
|
|
||||||
// "dockerVersion" => $dockerVersion,
|
|
||||||
// ];
|
|
||||||
// } catch (\Throwable $e) {
|
|
||||||
// $server->settings->is_reachable = false;
|
|
||||||
// $server->settings->is_usable = false;
|
|
||||||
// throw $e;
|
|
||||||
// } finally {
|
|
||||||
// if (data_get($server, 'settings')) {
|
|
||||||
// $server->settings->save();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
function checkRequiredCommands(Server $server)
|
function checkRequiredCommands(Server $server)
|
||||||
{
|
{
|
||||||
$commands = collect(["jq", "jc"]);
|
$commands = collect(["jq", "jc"]);
|
||||||
|
@ -1039,7 +1039,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
$serviceLabels = $serviceLabels->merge($defaultLabels);
|
$serviceLabels = $serviceLabels->merge($defaultLabels);
|
||||||
if (!$isDatabase && $fqdns->count() > 0) {
|
if (!$isDatabase && $fqdns->count() > 0) {
|
||||||
if ($fqdns) {
|
if ($fqdns) {
|
||||||
$serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($resource->uuid, $fqdns, true, serviceLabels: $serviceLabels));
|
$serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($resource->uuid, $fqdns, true, serviceLabels: $serviceLabels, is_gzip_enabled: $savedService->isGzipEnabled()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($resource->server->isLogDrainEnabled() && $savedService->isLogDrainEnabled()) {
|
if ($resource->server->isLogDrainEnabled() && $savedService->isLogDrainEnabled()) {
|
||||||
|
@ -7,7 +7,7 @@ return [
|
|||||||
|
|
||||||
// The release version of your application
|
// The release version of your application
|
||||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||||
'release' => '4.0.0-beta.218',
|
'release' => '4.0.0-beta.219',
|
||||||
// When left empty or `null` the Laravel environment will be used
|
// When left empty or `null` the Laravel environment will be used
|
||||||
'environment' => config('app.env'),
|
'environment' => config('app.env'),
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return '4.0.0-beta.218';
|
return '4.0.0-beta.219';
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
<?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('service_applications', function (Blueprint $table) {
|
||||||
|
$table->boolean('is_gzip_enabled')->default(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('service_applications', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('is_gzip_enabled');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -241,7 +241,7 @@
|
|||||||
</x-slot:question>
|
</x-slot:question>
|
||||||
<x-slot:actions>
|
<x-slot:actions>
|
||||||
<x-slide-over closeWithX fullScreen>
|
<x-slide-over closeWithX fullScreen>
|
||||||
<x-slot:title>Validating & Configuring</x-slot:title>
|
<x-slot:title>Validate & configure</x-slot:title>
|
||||||
<x-slot:content>
|
<x-slot:content>
|
||||||
<livewire:server.validate-and-install :server="$this->createdServer" />
|
<livewire:server.validate-and-install :server="$this->createdServer" />
|
||||||
</x-slot:content>
|
</x-slot:content>
|
||||||
|
@ -32,7 +32,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="pt-2">Advanced</h3>
|
<h3 class="pt-2">Advanced</h3>
|
||||||
<div class="w-64">
|
<div class="w-96">
|
||||||
|
<x-forms.checkbox instantSave id="application.is_gzip_enabled" label="Enable gzip compression"
|
||||||
|
helper="You can disable gzip compression if you want. Some services are compressing data by default. In this case, you do not need this." />
|
||||||
<x-forms.checkbox instantSave label="Exclude from service status"
|
<x-forms.checkbox instantSave label="Exclude from service status"
|
||||||
helper="If you do not need to monitor this resource, enable. Useful if this service is optional."
|
helper="If you do not need to monitor this resource, enable. Useful if this service is optional."
|
||||||
id="application.exclude_from_status"></x-forms.checkbox>
|
id="application.exclude_from_status"></x-forms.checkbox>
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
<x-forms.input id="service.description" label="Description" />
|
<x-forms.input id="service.description" label="Description" />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-96">
|
<div class="w-96">
|
||||||
<x-forms.checkbox instantSave id="service.connect_to_docker_network" label="Connect To Predefined Network" helper="By default, you do not reach the Coolify defined networks.<br>Starting a docker compose based resource will have an internal network. <br>If you connect to a Coolify defined network, you maybe need to use different internal DNS names to connect to a resource.<br><br>For more information, check <a class='text-white underline' href='https://coolify.io/docs/docker/compose#connect-to-predefined-networks'>this</a>." />
|
<x-forms.checkbox instantSave id="service.connect_to_docker_network" label="Connect To Predefined Network"
|
||||||
|
helper="By default, you do not reach the Coolify defined networks.<br>Starting a docker compose based resource will have an internal network. <br>If you connect to a Coolify defined network, you maybe need to use different internal DNS names to connect to a resource.<br><br>For more information, check <a class='text-white underline' href='https://coolify.io/docs/docker/compose#connect-to-predefined-networks'>this</a>." />
|
||||||
</div>
|
</div>
|
||||||
@if ($fields)
|
@if ($fields)
|
||||||
<div>
|
<div>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<form wire:submit.prevent='submit' class="flex flex-col">
|
<form wire:submit.prevent='submit' class="flex flex-col">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<h2>General</h2>
|
<h2>General</h2>
|
||||||
@if ($server->id === 0)
|
@if ($server->id !== 0)
|
||||||
<x-new-modal buttonTitle="Save" title="Change Localhost" action="submit">
|
<x-new-modal buttonTitle="Save" title="Change Localhost" action="submit">
|
||||||
You could lost a lot of functionalities if you change the server details of the server where Coolify
|
You could lost a lot of functionalities if you change the server details of the server where Coolify
|
||||||
is
|
is
|
||||||
@ -10,16 +10,25 @@
|
|||||||
</x-new-modal>
|
</x-new-modal>
|
||||||
@else
|
@else
|
||||||
<x-forms.button type="submit">Save</x-forms.button>
|
<x-forms.button type="submit">Save</x-forms.button>
|
||||||
|
<x-slide-over closeWithX fullScreen>
|
||||||
|
<x-slot:title>Validate & configure</x-slot:title>
|
||||||
|
<x-slot:content>
|
||||||
|
<livewire:server.validate-and-install :server="$server" ask />
|
||||||
|
</x-slot:content>
|
||||||
|
<x-forms.button @click="slideOverOpen=true" wire:click.prevent='validateServer' isHighlighted>
|
||||||
|
Revalidate server
|
||||||
|
</x-forms.button>
|
||||||
|
</x-slide-over>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@if (!$server->isFunctional())
|
@if ($server->isFunctional())
|
||||||
You can't use this server until it is validated.
|
|
||||||
@else
|
|
||||||
Server is reachable and validated.
|
Server is reachable and validated.
|
||||||
|
@else
|
||||||
|
You can't use this server until it is validated.
|
||||||
@endif
|
@endif
|
||||||
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id !== 0)
|
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id !== 0)
|
||||||
<x-slide-over closeWithX fullScreen>
|
<x-slide-over closeWithX fullScreen>
|
||||||
<x-slot:title>Validating & Configuring</x-slot:title>
|
<x-slot:title>Validate & configure</x-slot:title>
|
||||||
<x-slot:content>
|
<x-slot:content>
|
||||||
<livewire:server.validate-and-install :server="$server" />
|
<livewire:server.validate-and-install :server="$server" />
|
||||||
</x-slot:content>
|
</x-slot:content>
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
|
@if ($ask)
|
||||||
|
This will revalidate the server, install / update Docker Engine, Docker Compose and all related
|
||||||
|
configuration. It will also restart Docker Engine, so your running containers will be unreachable
|
||||||
|
for the time being.
|
||||||
|
<x-forms.button isHighlighted wire:click='startValidatingAfterAsking '>Continue</x-forms.button>
|
||||||
|
@else
|
||||||
@if ($uptime)
|
@if ($uptime)
|
||||||
<div class="flex w-64 gap-2">Server is reachable: <svg class="w-5 h-5 text-success" viewBox="0 0 256 256"
|
<div class="flex w-64 gap-2">Server is reachable: <svg class="w-5 h-5 text-success" viewBox="0 0 256 256"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
@ -35,8 +41,8 @@
|
|||||||
</svg></div>
|
</svg></div>
|
||||||
@else
|
@else
|
||||||
@if ($error)
|
@if ($error)
|
||||||
<div class="flex w-64 gap-2">Server is reachable: <svg class="w-5 h-5 text-error" viewBox="0 0 256 256"
|
<div class="flex w-64 gap-2">Server is reachable: <svg class="w-5 h-5 text-error"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill="currentColor"
|
<path fill="currentColor"
|
||||||
d="M208.49 191.51a12 12 0 0 1-17 17L128 145l-63.51 63.49a12 12 0 0 1-17-17L111 128L47.51 64.49a12 12 0 0 1 17-17L128 111l63.51-63.52a12 12 0 0 1 17 17L145 128Z" />
|
d="M208.49 191.51a12 12 0 0 1-17 17L128 145l-63.51 63.49a12 12 0 0 1-17-17L111 128L47.51 64.49a12 12 0 0 1 17-17L128 111l63.51-63.52a12 12 0 0 1 17 17L145 128Z" />
|
||||||
</svg></div>
|
</svg></div>
|
||||||
@ -47,8 +53,8 @@
|
|||||||
@endif
|
@endif
|
||||||
@if ($uptime && $supported_os_type)
|
@if ($uptime && $supported_os_type)
|
||||||
@if ($docker_installed)
|
@if ($docker_installed)
|
||||||
<div class="flex w-64 gap-2">Docker is installed: <svg class="w-5 h-5 text-success" viewBox="0 0 256 256"
|
<div class="flex w-64 gap-2">Docker is installed: <svg class="w-5 h-5 text-success"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g fill="currentColor">
|
<g fill="currentColor">
|
||||||
<path
|
<path
|
||||||
d="m237.66 85.26l-128.4 128.4a8 8 0 0 1-11.32 0l-71.6-72a8 8 0 0 1 0-11.31l24-24a8 8 0 0 1 11.32 0l36.68 35.32a8 8 0 0 0 11.32 0l92.68-91.32a8 8 0 0 1 11.32 0l24 23.6a8 8 0 0 1 0 11.31"
|
d="m237.66 85.26l-128.4 128.4a8 8 0 0 1-11.32 0l-71.6-72a8 8 0 0 1 0-11.31l24-24a8 8 0 0 1 11.32 0l36.68 35.32a8 8 0 0 0 11.32 0l92.68-91.32a8 8 0 0 1 11.32 0l24 23.6a8 8 0 0 1 0 11.31"
|
||||||
@ -59,8 +65,8 @@
|
|||||||
</svg></div>
|
</svg></div>
|
||||||
@else
|
@else
|
||||||
@if ($error)
|
@if ($error)
|
||||||
<div class="flex w-64 gap-2">Docker is installed: <svg class="w-5 h-5 text-error" viewBox="0 0 256 256"
|
<div class="flex w-64 gap-2">Docker is installed: <svg class="w-5 h-5 text-error"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill="currentColor"
|
<path fill="currentColor"
|
||||||
d="M208.49 191.51a12 12 0 0 1-17 17L128 145l-63.51 63.49a12 12 0 0 1-17-17L111 128L47.51 64.49a12 12 0 0 1 17-17L128 111l63.51-63.52a12 12 0 0 1 17 17L145 128Z" />
|
d="M208.49 191.51a12 12 0 0 1-17 17L128 145l-63.51 63.49a12 12 0 0 1-17-17L111 128L47.51 64.49a12 12 0 0 1 17-17L128 111l63.51-63.52a12 12 0 0 1 17 17L145 128Z" />
|
||||||
</svg></div>
|
</svg></div>
|
||||||
@ -92,8 +98,8 @@
|
|||||||
</svg></div>
|
</svg></div>
|
||||||
@else
|
@else
|
||||||
@if ($error)
|
@if ($error)
|
||||||
<div class="flex w-64 gap-2">Proxy Started: <svg class="w-5 h-5 text-error" viewBox="0 0 256 256"
|
<div class="flex w-64 gap-2">Proxy Started: <svg class="w-5 h-5 text-error"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill="currentColor"
|
<path fill="currentColor"
|
||||||
d="M208.49 191.51a12 12 0 0 1-17 17L128 145l-63.51 63.49a12 12 0 0 1-17-17L111 128L47.51 64.49a12 12 0 0 1 17-17L128 111l63.51-63.52a12 12 0 0 1 17 17L145 128Z" />
|
d="M208.49 191.51a12 12 0 0 1-17 17L128 145l-63.51 63.49a12 12 0 0 1-17-17L111 128L47.51 64.49a12 12 0 0 1 17-17L128 111l63.51-63.52a12 12 0 0 1 17 17L145 128Z" />
|
||||||
</svg></div>
|
</svg></div>
|
||||||
@ -131,4 +137,5 @@
|
|||||||
@isset($error)
|
@isset($error)
|
||||||
<pre class="font-bold whitespace-pre-line text-error">{!! $error !!}</pre>
|
<pre class="font-bold whitespace-pre-line text-error">{!! $error !!}</pre>
|
||||||
@endisset
|
@endisset
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
48
templates/compose/docker-registry.yaml
Normal file
48
templates/compose/docker-registry.yaml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# documentation: https://docs.docker.com/registry/
|
||||||
|
# slogan: The Docker Registry is a stateless, highly scalable server side application that stores and lets you distribute Docker images.
|
||||||
|
# tags: registry,images,docker
|
||||||
|
|
||||||
|
services:
|
||||||
|
registry:
|
||||||
|
image: registry:2
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_REGISTRY
|
||||||
|
- REGISTRY_AUTH=htpasswd
|
||||||
|
- REGISTRY_AUTH_HTPASSWD_REALM=Registry
|
||||||
|
- REGISTRY_AUTH_HTPASSWD_PATH=/auth/registry.password
|
||||||
|
- REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/data
|
||||||
|
volumes:
|
||||||
|
- type: bind
|
||||||
|
source: ./auth/registry.password
|
||||||
|
target: /auth/registry.password
|
||||||
|
isDirectory: false
|
||||||
|
content: >-
|
||||||
|
testuser:$2y$05$/o2JvmI2bhExXIt6Oqxa7ekYB7v3scj1wFEf6tBslJvJOMoPQL.Gy
|
||||||
|
- type: bind
|
||||||
|
source: ./config/config.yml
|
||||||
|
target: /etc/docker/registry/config.yml
|
||||||
|
isDirectory: false
|
||||||
|
content: >-
|
||||||
|
version: 0.1
|
||||||
|
|
||||||
|
log:
|
||||||
|
fields:
|
||||||
|
service: registry
|
||||||
|
storage:
|
||||||
|
cache:
|
||||||
|
blobdescriptor: inmemory
|
||||||
|
filesystem:
|
||||||
|
rootdirectory: /var/lib/registry
|
||||||
|
http:
|
||||||
|
addr: :5000
|
||||||
|
headers:
|
||||||
|
X-Content-Type-Options: [nosniff]
|
||||||
|
health:
|
||||||
|
storagedriver:
|
||||||
|
enabled: true
|
||||||
|
interval: 10s
|
||||||
|
threshold: 3
|
||||||
|
- type: bind
|
||||||
|
source: ./data
|
||||||
|
target: /data
|
||||||
|
isDirectory: true
|
@ -87,6 +87,16 @@
|
|||||||
"sql"
|
"sql"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"docker-registry": {
|
||||||
|
"documentation": "https:\/\/docs.docker.com\/registry\/",
|
||||||
|
"slogan": "The Docker Registry is a stateless, highly scalable server side application that stores and lets you distribute Docker images.",
|
||||||
|
"compose": "c2VydmljZXM6CiAgcmVnaXN0cnk6CiAgICBpbWFnZTogJ3JlZ2lzdHJ5OjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fUkVHSVNUUlkKICAgICAgLSBSRUdJU1RSWV9BVVRIPWh0cGFzc3dkCiAgICAgIC0gUkVHSVNUUllfQVVUSF9IVFBBU1NXRF9SRUFMTT1SZWdpc3RyeQogICAgICAtIFJFR0lTVFJZX0FVVEhfSFRQQVNTV0RfUEFUSD0vYXV0aC9yZWdpc3RyeS5wYXNzd29yZAogICAgICAtIFJFR0lTVFJZX1NUT1JBR0VfRklMRVNZU1RFTV9ST09URElSRUNUT1JZPS9kYXRhCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9hdXRoL3JlZ2lzdHJ5LnBhc3N3b3JkCiAgICAgICAgdGFyZ2V0OiAvYXV0aC9yZWdpc3RyeS5wYXNzd29yZAogICAgICAgIGlzRGlyZWN0b3J5OiBmYWxzZQogICAgICAgIGNvbnRlbnQ6ICd0ZXN0dXNlcjokMnkkMDUkL28ySnZtSTJiaEV4WEl0Nk9xeGE3ZWtZQjd2M3NjajF3RkVmNnRCc2xKdkpPTW9QUUwuR3knCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL2NvbmZpZy9jb25maWcueW1sCiAgICAgICAgdGFyZ2V0OiAvZXRjL2RvY2tlci9yZWdpc3RyeS9jb25maWcueW1sCiAgICAgICAgaXNEaXJlY3Rvcnk6IGZhbHNlCiAgICAgICAgY29udGVudDogInZlcnNpb246IDAuMVxubG9nOlxuICBmaWVsZHM6XG4gICAgc2VydmljZTogcmVnaXN0cnlcbnN0b3JhZ2U6XG4gIGNhY2hlOlxuICAgIGJsb2JkZXNjcmlwdG9yOiBpbm1lbW9yeVxuICBmaWxlc3lzdGVtOlxuICAgIHJvb3RkaXJlY3Rvcnk6IC92YXIvbGliL3JlZ2lzdHJ5XG5odHRwOlxuICBhZGRyOiA6NTAwMFxuICBoZWFkZXJzOlxuICAgIFgtQ29udGVudC1UeXBlLU9wdGlvbnM6IFtub3NuaWZmXVxuaGVhbHRoOlxuICBzdG9yYWdlZHJpdmVyOlxuICAgIGVuYWJsZWQ6IHRydWVcbiAgICBpbnRlcnZhbDogMTBzXG4gICAgdGhyZXNob2xkOiAzIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9kYXRhCiAgICAgICAgdGFyZ2V0OiAvZGF0YQogICAgICAgIGlzRGlyZWN0b3J5OiB0cnVlCg==",
|
||||||
|
"tags": [
|
||||||
|
"registry",
|
||||||
|
"images",
|
||||||
|
"docker"
|
||||||
|
]
|
||||||
|
},
|
||||||
"dokuwiki": {
|
"dokuwiki": {
|
||||||
"documentation": "https:\/\/www.dokuwiki.org\/faq",
|
"documentation": "https:\/\/www.dokuwiki.org\/faq",
|
||||||
"slogan": "A lightweight and easy-to-use wiki platform for creating and managing documentation and knowledge bases with simplicity and flexibility.",
|
"slogan": "A lightweight and easy-to-use wiki platform for creating and managing documentation and knowledge bases with simplicity and flexibility.",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"version": "3.12.36"
|
"version": "3.12.36"
|
||||||
},
|
},
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.218"
|
"version": "4.0.0-beta.219"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user