Merge pull request #1469 from coollabsio/next

v4.0.0-beta.144
This commit is contained in:
Andras Bacsai 2023-11-17 21:28:18 +01:00 committed by GitHub
commit 9f3dbc3cbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 413 additions and 69 deletions

View File

@ -69,7 +69,7 @@ public function handle(StandaloneMariadb $database)
]
]
];
if ($this->database->destination->server->isDrainLogActivated()) {
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
$docker_compose['services'][$container_name]['logging'] = [
'driver' => 'fluentd',
'options' => [

View File

@ -76,7 +76,7 @@ public function handle(StandaloneMongodb $database)
]
]
];
if ($this->database->destination->server->isDrainLogActivated()) {
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
$docker_compose['services'][$container_name]['logging'] = [
'driver' => 'fluentd',
'options' => [

View File

@ -69,7 +69,7 @@ public function handle(StandaloneMysql $database)
]
]
];
if ($this->database->destination->server->isDrainLogActivated()) {
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
$docker_compose['services'][$container_name]['logging'] = [
'driver' => 'fluentd',
'options' => [

View File

@ -79,7 +79,8 @@ public function handle(StandalonePostgresql $database)
]
]
];
if ($this->database->destination->server->isDrainLogActivated()) {
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
ray('Log Drain Enabled');
$docker_compose['services'][$container_name]['logging'] = [
'driver' => 'fluentd',
'options' => [

View File

@ -78,7 +78,7 @@ public function handle(StandaloneRedis $database)
]
]
];
if ($this->database->destination->server->isDrainLogActivated()) {
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
$docker_compose['services'][$container_name]['logging'] = [
'driver' => 'fluentd',
'options' => [
@ -166,6 +166,5 @@ private function add_custom_redis()
$content = $this->database->redis_conf;
$content_base64 = base64_encode($content);
$this->commands[] = "echo '{$content_base64}' | base64 -d > $this->configuration_dir/{$filename}";
}
}

View File

@ -8,8 +8,17 @@
class InstallLogDrain
{
use AsAction;
public function handle(Server $server, string $type)
public function handle(Server $server)
{
if ($server->settings->is_logdrain_newrelic_enabled) {
$type = 'newrelic';
} else if ($server->settings->is_logdrain_highlight_enabled) {
$type = 'highlight';
} else if ($server->settings->is_logdrain_axiom_enabled) {
$type = 'axiom';
} else {
$type = 'none';
}
try {
if ($type === 'none') {
$command = [
@ -127,6 +136,7 @@ public function handle(Server $server, string $type)
- ./parsers.conf:/parsers.conf
ports:
- 127.0.0.1:24224:24224
restart: unless-stopped
");
$readme = base64_encode('# New Relic Log Drain
This log drain is based on [Fluent Bit](https://fluentbit.io/) and New Relic Log Forwarder.

View File

@ -2,6 +2,7 @@
namespace App\Console;
use App\Jobs\CheckLogDrainContainerJob;
use App\Jobs\CleanupInstanceStuffsJob;
use App\Jobs\DatabaseBackupJob;
use App\Jobs\InstanceAutoUpdateJob;
@ -61,6 +62,9 @@ private function check_resources($schedule)
foreach ($servers as $server) {
$schedule->job(new ServerStatusJob($server))->everyTenMinutes()->onOneServer();
$schedule->job(new ContainerStatusJob($server))->everyMinute()->onOneServer();
if ($server->isLogDrainEnabled()) {
$schedule->job(new CheckLogDrainContainerJob($server))->everyMinute()->onOneServer();
}
}
}
private function instance_auto_update($schedule)

View File

@ -32,7 +32,7 @@ class General extends Component
public bool $is_preview_deployments_enabled;
public bool $is_auto_deploy_enabled;
public bool $is_force_https_enabled;
public bool $is_log_drain_enabled;
protected $rules = [
'application.name' => 'required',
@ -101,6 +101,7 @@ public function mount()
$this->is_preview_deployments_enabled = $this->application->settings->is_preview_deployments_enabled;
$this->is_auto_deploy_enabled = $this->application->settings->is_auto_deploy_enabled;
$this->is_force_https_enabled = $this->application->settings->is_force_https_enabled;
$this->is_log_drain_enabled = $this->application->settings->is_log_drain_enabled;
}
$this->checkLabelUpdates();
}
@ -136,6 +137,14 @@ public function instantSave()
$this->application->settings->is_preview_deployments_enabled = $this->is_preview_deployments_enabled;
$this->application->settings->is_auto_deploy_enabled = $this->is_auto_deploy_enabled;
$this->application->settings->is_force_https_enabled = $this->is_force_https_enabled;
$this->application->settings->is_log_drain_enabled = $this->is_log_drain_enabled;
if ($this->is_log_drain_enabled) {
if (!$this->application->destination->server->isLogDrainEnabled()) {
$this->application->settings->is_log_drain_enabled = $this->is_log_drain_enabled = false;
$this->emit('error', 'Log drain is not enabled on the server. Please enable it first.');
return;
}
}
$this->application->settings->save();
$this->application->save();
$this->application->refresh();

View File

@ -28,6 +28,7 @@ class General extends Component
'database.ports_mappings' => 'nullable',
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
];
protected $validationAttributes = [
'database.name' => 'Name',
@ -50,6 +51,20 @@ public function mount()
$this->db_url_public = $this->database->getDbUrl();
}
}
public function instantSaveAdvanced() {
try {
if (!$this->database->destination->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->emit('error', 'Log drain is not enabled on the server. Please enable it first.');
return;
}
$this->database->save();
$this->emit('success', 'Database updated successfully.');
$this->emit('success', 'You need to restart the service for the changes to take effect.');
} catch (Exception $e) {
return handleError($e, $this);
}
}
public function submit()
{
try {

View File

@ -27,6 +27,7 @@ class General extends Component
'database.ports_mappings' => 'nullable',
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
];
protected $validationAttributes = [
'database.name' => 'Name',
@ -48,7 +49,21 @@ public function mount()
$this->db_url_public = $this->database->getDbUrl();
}
}
public function instantSaveAdvanced()
{
try {
if (!$this->database->destination->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->emit('error', 'Log drain is not enabled on the server. Please enable it first.');
return;
}
$this->database->save();
$this->emit('success', 'Database updated successfully.');
$this->emit('success', 'You need to restart the service for the changes to take effect.');
} catch (Exception $e) {
return handleError($e, $this);
}
}
public function submit()
{
try {

View File

@ -28,6 +28,7 @@ class General extends Component
'database.ports_mappings' => 'nullable',
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
];
protected $validationAttributes = [
'database.name' => 'Name',
@ -50,6 +51,21 @@ public function mount()
$this->db_url_public = $this->database->getDbUrl();
}
}
public function instantSaveAdvanced()
{
try {
if (!$this->database->destination->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->emit('error', 'Log drain is not enabled on the server. Please enable it first.');
return;
}
$this->database->save();
$this->emit('success', 'Database updated successfully.');
$this->emit('success', 'You need to restart the service for the changes to take effect.');
} catch (Exception $e) {
return handleError($e, $this);
}
}
public function submit()
{
try {

View File

@ -34,6 +34,7 @@ class General extends Component
'database.ports_mappings' => 'nullable',
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
];
protected $validationAttributes = [
'database.name' => 'Name',
@ -57,6 +58,20 @@ public function mount()
$this->db_url_public = $this->database->getDbUrl();
}
}
public function instantSaveAdvanced() {
try {
if (!$this->database->destination->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->emit('error', 'Log drain is not enabled on the server. Please enable it first.');
return;
}
$this->database->save();
$this->emit('success', 'Database updated successfully.');
$this->emit('success', 'You need to restart the service for the changes to take effect.');
} catch (Exception $e) {
return handleError($e, $this);
}
}
public function instantSave()
{
try {

View File

@ -25,6 +25,7 @@ class General extends Component
'database.ports_mappings' => 'nullable',
'database.is_public' => 'nullable|boolean',
'database.public_port' => 'nullable|integer',
'database.is_log_drain_enabled' => 'nullable|boolean',
];
protected $validationAttributes = [
'database.name' => 'Name',
@ -43,6 +44,20 @@ public function mount()
$this->db_url_public = $this->database->getDbUrl();
}
}
public function instantSaveAdvanced() {
try {
if (!$this->database->destination->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->emit('error', 'Log drain is not enabled on the server. Please enable it first.');
return;
}
$this->database->save();
$this->emit('success', 'Database updated successfully.');
$this->emit('success', 'You need to restart the service for the changes to take effect.');
} catch (Exception $e) {
return handleError($e, $this);
}
}
public function submit()
{
try {

View File

@ -16,6 +16,7 @@ class Application extends Component
'application.image' => 'required',
'application.exclude_from_status' => 'required|boolean',
'application.required_fqdn' => 'required|boolean',
'application.is_log_drain_enabled' => 'nullable|boolean',
];
public function render()
{
@ -25,7 +26,11 @@ public function instantSave()
{
$this->submit();
}
public function instantSaveAdvanced()
{
$this->submit();
$this->emit('success', 'You need to restart the service for the changes to take effect.');
}
public function delete()
{
try {
@ -44,6 +49,11 @@ public function submit()
{
try {
$this->validate();
if (!$this->application->service->destination->server->isLogDrainEnabled()) {
$this->application->is_log_drain_enabled = false;
$this->emit('error', 'Log drain is not enabled on the server. Please enable it first.');
return;
}
$this->application->save();
updateCompose($this->application);
$this->emit('success', 'Application saved successfully.');

View File

@ -21,18 +21,31 @@ class Database extends Component
'database.exclude_from_status' => 'required|boolean',
'database.public_port' => 'nullable|integer',
'database.is_public' => 'required|boolean',
'database.is_log_drain_enabled' => 'required|boolean',
];
public function render()
{
return view('livewire.project.service.database');
}
public function mount() {
public function mount()
{
if ($this->database->is_public) {
$this->db_url_public = $this->database->getServiceDatabaseUrl();
}
$this->refreshFileStorages();
}
public function instantSave() {
public function instantSaveAdvanced()
{
if (!$this->database->service->destination->server->isLogDrainEnabled()) {
$this->database->is_log_drain_enabled = false;
$this->emit('error', 'Log drain is not enabled on the server. Please enable it first.');
return;
}
$this->submit();
$this->emit('success', 'You need to restart the service for the changes to take effect.');
}
public function instantSave()
{
if ($this->database->is_public && !$this->database->public_port) {
$this->emit('error', 'Public port is required.');
$this->database->is_public = false;

View File

@ -2,6 +2,7 @@
namespace App\Http\Livewire\Server;
use App\Actions\Server\InstallLogDrain;
use App\Models\Server;
use Livewire\Component;
@ -46,14 +47,8 @@ public function mount()
public function configureLogDrain()
{
try {
if ($this->server->settings->is_logdrain_newrelic_enabled) {
$this->server->logDrain('newrelic');
} else if ($this->server->settings->is_logdrain_highlight_enabled) {
$this->server->logDrain('highlight');
} else if ($this->server->settings->is_logdrain_axiom_enabled) {
$this->server->logDrain('axiom');
} else {
$this->server->logDrain('none');
InstallLogDrain::run($this->server);
if (!$this->server->isLogDrainEnabled()) {
$this->emit('serverRefresh');
$this->emit('success', 'Log drain service stopped.');
return;

View File

@ -864,7 +864,7 @@ private function generate_compose_file()
]
]
];
if ($this->server->isDrainLogActivated()) {
if ($this->server->isLogDrainEnabled() && $this->application->isLogDrainEnabled()) {
$docker_compose['services'][$this->container_name]['logging'] = [
'driver' => 'fluentd',
'options' => [

View File

@ -0,0 +1,88 @@
<?php
namespace App\Jobs;
use App\Actions\Server\InstallLogDrain;
use App\Models\Server;
use App\Notifications\Container\ContainerRestarted;
use App\Notifications\Container\ContainerStopped;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Middleware\WithoutOverlapping;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Sleep;
class CheckLogDrainContainerJob implements ShouldQueue, ShouldBeEncrypted
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(public Server $server)
{
}
public function middleware(): array
{
return [(new WithoutOverlapping($this->server->id))->dontRelease()];
}
public function uniqueId(): int
{
return $this->server->id;
}
public function healthcheck()
{
$status = instant_remote_process(["docker inspect --format='{{json .State.Status}}' coolify-log-drain"], $this->server, false);
if (str($status)->contains('running')) {
return true;
} else {
return false;
}
}
public function handle(): void
{
// ray("checking log drain statuses for {$this->server->id}");
try {
if (!$this->server->isServerReady()) {
return;
};
$containers = instant_remote_process(["docker container ls -q"], $this->server);
if (!$containers) {
return;
}
$containers = instant_remote_process(["docker container inspect $(docker container ls -q) --format '{{json .}}'"], $this->server);
$containers = format_docker_command_output_to_json($containers);
$foundLogDrainContainer = $containers->filter(function ($value, $key) {
return data_get($value, 'Name') === '/coolify-log-drain';
})->first();
if (!$foundLogDrainContainer || !$this->healthcheck()) {
ray('Log drain container not found or unhealthy. Restarting...');
InstallLogDrain::run($this->server);
Sleep::for(10)->seconds();
if ($this->healthcheck()) {
if ($this->server->log_drain_notification_sent) {
$this->server->team->notify(new ContainerRestarted('Coolify Log Drainer', $this->server));
$this->server->update(['log_drain_notification_sent' => false]);
}
return;
}
if (!$this->server->log_drain_notification_sent) {
ray('Log drain container still unhealthy. Sending notification...');
$this->server->team->notify(new ContainerStopped('Coolify Log Drainer', $this->server, null));
$this->server->update(['log_drain_notification_sent' => true]);
}
} else {
if ($this->server->log_drain_notification_sent) {
$this->server->team->notify(new ContainerRestarted('Coolify Log Drainer', $this->server));
$this->server->update(['log_drain_notification_sent' => false]);
}
}
} catch (\Throwable $e) {
send_internal_notification("CheckLogDrainContainerJob failed on ({$this->server->id}) with: " . $e->getMessage());
ray($e->getMessage());
handleError($e);
}
}
}

View File

@ -52,29 +52,7 @@ public function handle(): void
$databases = $this->server->databases();
$services = $this->server->services()->get();
$previews = $this->server->previews();
$this->server->proxyType();
/// Check if proxy is running
$foundProxyContainer = $containers->filter(function ($value, $key) {
return data_get($value, 'Name') === '/coolify-proxy';
})->first();
if (!$foundProxyContainer) {
try {
$shouldStart = CheckProxy::run($this->server);
if ($shouldStart) {
StartProxy::run($this->server, false);
$this->server->team->notify(new ContainerRestarted('coolify-proxy', $this->server));
} else {
ray('Proxy could not be started.');
}
} catch (\Throwable $e) {
ray($e);
}
} else {
$this->server->proxy->status = data_get($foundProxyContainer, 'State.Status');
$this->server->save();
$connectProxyToDockerNetworks = connectProxyToNetworks($this->server);
instant_remote_process($connectProxyToDockerNetworks, $this->server, false);
}
$foundApplications = [];
$foundApplicationPreviews = [];
$foundDatabases = [];
@ -267,6 +245,30 @@ public function handle(): void
}
$this->server->team->notify(new ContainerStopped($containerName, $this->server, $url));
}
// Check if proxy is running
$this->server->proxyType();
$foundProxyContainer = $containers->filter(function ($value, $key) {
return data_get($value, 'Name') === '/coolify-proxy';
})->first();
if (!$foundProxyContainer) {
try {
$shouldStart = CheckProxy::run($this->server);
if ($shouldStart) {
StartProxy::run($this->server, false);
$this->server->team->notify(new ContainerRestarted('coolify-proxy', $this->server));
} else {
ray('Proxy could not be started.');
}
} catch (\Throwable $e) {
ray($e);
}
} else {
$this->server->proxy->status = data_get($foundProxyContainer, 'State.Status');
$this->server->save();
$connectProxyToDockerNetworks = connectProxyToNetworks($this->server);
instant_remote_process($connectProxyToDockerNetworks, $this->server, false);
}
} catch (\Throwable $e) {
send_internal_notification("ContainerStatusJob failed on ({$this->server->id}) with: " . $e->getMessage());
ray($e->getMessage());

View File

@ -300,6 +300,9 @@ public function isHealthcheckDisabled(): bool
}
return false;
}
public function isLogDrainEnabled() {
return data_get($this, 'settings.is_log_drain_enabled', false);
}
public function isConfigurationChanged($save = false)
{
$newConfigHash = $this->fqdn . $this->git_repository . $this->git_branch . $this->git_commit_sha . $this->build_pack . $this->static_image . $this->install_command . $this->build_command . $this->start_command . $this->port_exposes . $this->port_mappings . $this->base_directory . $this->publish_directory . $this->health_check_path . $this->health_check_port . $this->health_check_host . $this->health_check_method . $this->health_check_return_code . $this->health_check_scheme . $this->health_check_response_text . $this->health_check_interval . $this->health_check_timeout . $this->health_check_retries . $this->health_check_start_period . $this->health_check_enabled . $this->limits_memory . $this->limits_swap . $this->limits_swappiness . $this->limits_reservation . $this->limits_cpus . $this->limits_cpuset . $this->limits_cpu_shares . $this->dockerfile . $this->dockerfile_location . $this->custom_labels;

View File

@ -296,15 +296,11 @@ public function isProxyShouldRun()
// }
return true;
}
public function logDrain($type)
{
InstallLogDrain::run($this, $type);
}
public function isFunctional()
{
return $this->settings->is_reachable && $this->settings->is_usable;
}
public function isDrainLogActivated()
public function isLogDrainEnabled()
{
return $this->settings->is_logdrain_newrelic_enabled || $this->settings->is_logdrain_highlight_enabled || $this->settings->is_logdrain_axiom_enabled;
}

View File

@ -797,7 +797,7 @@ public function parse(bool $isNew = false): Collection
$serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($this->uuid, $fqdns, true));
}
}
if ($this->server->isDrainLogActivated()) {
if ($this->server->isLogDrainEnabled() && $savedService->isLogDrainEnabled()) {
data_set($service, 'logging', [
'driver' => 'fluentd',
'options' => [

View File

@ -18,6 +18,10 @@ protected static function booted()
$service->fileStorages()->delete();
});
}
public function isLogDrainEnabled()
{
return data_get($this, 'is_log_drain_enabled', false);
}
public function type()
{
return 'service';

View File

@ -16,6 +16,10 @@ protected static function booted()
$service->fileStorages()->delete();
});
}
public function isLogDrainEnabled()
{
return data_get($this, 'is_log_drain_enabled', false);
}
public function type()
{
return 'service';

View File

@ -41,6 +41,10 @@ protected static function booted()
$database->environment_variables()->delete();
});
}
public function isLogDrainEnabled()
{
return data_get($this, 'is_log_drain_enabled', false);
}
public function type(): string
{
return 'standalone-mariadb';

View File

@ -44,7 +44,10 @@ protected static function booted()
$database->environment_variables()->delete();
});
}
public function isLogDrainEnabled()
{
return data_get($this, 'is_log_drain_enabled', false);
}
public function mongoInitdbRootPassword(): Attribute
{
return Attribute::make(

View File

@ -46,6 +46,11 @@ public function type(): string
return 'standalone-mysql';
}
public function isLogDrainEnabled()
{
return data_get($this, 'is_log_drain_enabled', false);
}
public function portsMappings(): Attribute
{
return Attribute::make(

View File

@ -42,6 +42,11 @@ protected static function booted()
});
}
public function isLogDrainEnabled()
{
return data_get($this, 'is_log_drain_enabled', false);
}
public function portsMappings(): Attribute
{
return Attribute::make(

View File

@ -37,6 +37,11 @@ protected static function booted()
});
}
public function isLogDrainEnabled()
{
return data_get($this, 'is_log_drain_enabled', false);
}
public function portsMappings(): Attribute
{
return Attribute::make(

View File

@ -27,7 +27,7 @@ public function via(object $notifiable): array
public function toMail(): MailMessage
{
$mail = new MailMessage();
$mail->subject("Coolify: Container ({$this->name}) has been restarted automatically on {$this->server->name}");
$mail->subject("Coolify: A service ({$this->name}) has been restarted automatically on {$this->server->name}");
$mail->view('emails.container-restarted', [
'containerName' => $this->name,
'serverName' => $this->server->name,
@ -38,12 +38,12 @@ public function toMail(): MailMessage
public function toDiscord(): string
{
$message = "Coolify: Container ({$this->name}) has been restarted automatically on {$this->server->name}";
$message = "Coolify: A service ({$this->name}) has been restarted automatically on {$this->server->name}";
return $message;
}
public function toTelegram(): array
{
$message = "Coolify: Container ({$this->name}) has been restarted automatically on {$this->server->name}";
$message = "Coolify: A service ({$this->name}) has been restarted automatically on {$this->server->name}";
$payload = [
"message" => $message,
];

View File

@ -26,7 +26,7 @@ public function via(object $notifiable): array
public function toMail(): MailMessage
{
$mail = new MailMessage();
$mail->subject("Coolify: Container ({$this->name}) has been stopped on {$this->server->name}");
$mail->subject("Coolify: A service ({$this->name}) has been stopped on {$this->server->name}");
$mail->view('emails.container-stopped', [
'containerName' => $this->name,
'serverName' => $this->server->name,
@ -37,12 +37,12 @@ public function toMail(): MailMessage
public function toDiscord(): string
{
$message = "Coolify: Container ({$this->name}) has been stopped on {$this->server->name}";
$message = "Coolify: A service ({$this->name}) has been stopped on {$this->server->name}";
return $message;
}
public function toTelegram(): array
{
$message = "Coolify: Container ($this->name} has been stopped on {$this->server->name}";
$message = "Coolify: A service ($this->name} has been stopped on {$this->server->name}";
$payload = [
"message" => $message,
];

View File

@ -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.143',
'release' => '4.0.0-beta.144',
// When left empty or `null` the Laravel environment will be used
'environment' => config('app.env'),

View File

@ -1,3 +1,3 @@
<?php
return '4.0.0-beta.143';
return '4.0.0-beta.144';

View File

@ -0,0 +1,76 @@
<?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('application_settings', function (Blueprint $table) {
$table->boolean('is_log_drain_enabled')->default(false);
});
Schema::table('standalone_redis', function (Blueprint $table) {
$table->boolean('is_log_drain_enabled')->default(false);
});
Schema::table('standalone_mysqls', function (Blueprint $table) {
$table->boolean('is_log_drain_enabled')->default(false);
});
Schema::table('standalone_mariadbs', function (Blueprint $table) {
$table->boolean('is_log_drain_enabled')->default(false);
});
Schema::table('standalone_postgresqls', function (Blueprint $table) {
$table->boolean('is_log_drain_enabled')->default(false);
});
Schema::table('standalone_mongodbs', function (Blueprint $table) {
$table->boolean('is_log_drain_enabled')->default(false);
});
Schema::table('service_applications', function (Blueprint $table) {
$table->boolean('is_log_drain_enabled')->default(false);
});
Schema::table('service_databases', function (Blueprint $table) {
$table->boolean('is_log_drain_enabled')->default(false);
});
Schema::table('servers', function (Blueprint $table) {
$table->boolean('log_drain_notification_sent')->default(false);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('application_settings', function (Blueprint $table) {
$table->dropColumn('is_log_drain_enabled');
});
Schema::table('standalone_redis', function (Blueprint $table) {
$table->dropColumn('is_log_drain_enabled');
});
Schema::table('standalone_mysqls', function (Blueprint $table) {
$table->dropColumn('is_log_drain_enabled');
});
Schema::table('standalone_mariadbs', function (Blueprint $table) {
$table->dropColumn('is_log_drain_enabled');
});
Schema::table('standalone_postgresqls', function (Blueprint $table) {
$table->dropColumn('is_log_drain_enabled');
});
Schema::table('standalone_mongodbs', function (Blueprint $table) {
$table->dropColumn('is_log_drain_enabled');
});
Schema::table('service_applications', function (Blueprint $table) {
$table->dropColumn('is_log_drain_enabled');
});
Schema::table('service_databases', function (Blueprint $table) {
$table->dropColumn('is_log_drain_enabled');
});
Schema::table('servers', function (Blueprint $table) {
$table->dropColumn('log_drain_notification_sent');
});
}
};

View File

@ -1,6 +1,6 @@
<x-emails.layout>
Container ({{ $containerName }}) has been restarted automatically on {{$serverName}}, because it was stopped unexpectedly.
A service ({{ $containerName }}) has been restarted automatically on {{$serverName}}, because it was stopped unexpectedly.
@if ($containerName === 'coolify-proxy')
Coolify Proxy should run on your server as you have FQDNs set up in one of your resources.

View File

@ -1,6 +1,6 @@
<x-emails.layout>
Container {{ $containerName }} has been stopped unexpectedly on {{$serverName}}.
A service ({{ $containerName }}) has been stopped unexpectedly on {{$serverName}}.
@if ($url)
Please check what is going on [here]({{ $url }}).

View File

@ -114,6 +114,8 @@
</div>
<h3>Advanced</h3>
<div class="flex flex-col">
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." instantSave
id="is_log_drain_enabled" label="Drain Logs" />
<x-forms.checkbox
helper="Your application will be available only on https if your domain starts with https://..."
instantSave id="is_force_https_enabled" label="Force Https" />

View File

@ -59,5 +59,10 @@
@endif
</div>
<x-forms.textarea label="Custom MariaDB Configuration" rows="10" id="database.mariadb_conf" />
<h3 class="pt-4">Advanced</h3>
<div class="flex flex-col">
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings."
instantSave="instantSaveAdvanced" id="database.is_log_drain_enabled" label="Drain Logs" />
</div>
</form>
</div>

View File

@ -16,8 +16,8 @@
<div class="flex gap-2">
<x-forms.input label="Initial Username" id="database.mongo_initdb_root_username"
placeholder="If empty: postgres" readonly helper="You can only change this in the database." />
<x-forms.input label="Initial Password" id="database.mongo_initdb_root_password" type="password" required
readonly helper="You can only change this in the database." />
<x-forms.input label="Initial Password" id="database.mongo_initdb_root_password" type="password"
required readonly helper="You can only change this in the database." />
<x-forms.input label="Initial Database" id="database.mongo_initdb_database"
placeholder="If empty, it will be the same as Username." readonly
helper="You can only change this in the database." />
@ -53,5 +53,10 @@
@endif
</div>
<x-forms.textarea label="Custom MongoDB Configuration" rows="10" id="database.mongo_conf" />
<h3 class="pt-4">Advanced</h3>
<div class="flex flex-col">
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings."
instantSave="instantSaveAdvanced" id="database.is_log_drain_enabled" label="Drain Logs" />
</div>
</form>
</div>

View File

@ -59,5 +59,10 @@
@endif
</div>
<x-forms.textarea label="Custom Mysql Configuration" rows="10" id="database.mysql_conf" />
<h3 class="pt-4">Advanced</h3>
<div class="flex flex-col">
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings."
instantSave="instantSaveAdvanced" id="database.is_log_drain_enabled" label="Drain Logs" />
</div>
</form>
</div>

View File

@ -74,6 +74,11 @@
</div>
<x-forms.textarea label="Custom PostgreSQL Configuration" rows="10" id="database.postgres_conf" />
</form>
<h3 class="pt-4">Advanced</h3>
<div class="flex flex-col">
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." instantSave="instantSaveAdvanced"
id="database.is_log_drain_enabled" label="Drain Logs" />
</div>
<div class="pb-16">
<div class="flex gap-2 pt-4 pb-2">
<h3>Initialization scripts</h3>
@ -87,4 +92,5 @@
@endforelse
</div>
</div>
</div>

View File

@ -33,5 +33,10 @@
<x-forms.textarea
helper="<a target='_blank' class='text-white underline' href='https://raw.githubusercontent.com/redis/redis/7.2/redis.conf'>Redis Default Configuration</a>"
label="Custom Redis Configuration" rows="10" id="database.redis_conf" />
<h3 class="pt-4">Advanced</h3>
<div class="flex flex-col">
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings."
instantSave="instantSaveAdvanced" id="database.is_log_drain_enabled" label="Drain Logs" />
</div>
</form>
</div>

View File

@ -36,6 +36,8 @@
<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."
id="application.exclude_from_status"></x-forms.checkbox>
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings."
instantSave="instantSaveAdvanced" id="application.is_log_drain_enabled" label="Drain Logs" />
</div>
</form>
</div>

View File

@ -32,6 +32,8 @@
<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."
id="database.exclude_from_status"></x-forms.checkbox>
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings."
instantSave="instantSaveAdvanced" id="database.is_log_drain_enabled" label="Drain Logs" />
</div>
</form>
</div>

View File

@ -1,7 +1,7 @@
<div>
<x-server.navbar :server="$server" :parameters="$parameters" />
<h2>Log Drains</h2>
<div class="pb-4">Sends resource logs to external services.</div>
<div class="pb-4">Sends service logs to 3rd party tools.</div>
<div class="flex flex-col gap-4 pt-4">
<div class="p-4 border border-coolgray-500">
<form wire:submit.prevent='submit("newrelic")' class="flex flex-col">

View File

@ -4,7 +4,7 @@
"version": "3.12.36"
},
"v4": {
"version": "4.0.0-beta.143"
"version": "4.0.0-beta.144"
}
}
}