Merge pull request #4649 from coollabsio/v4.0.0-beta.380

v4.0.0-beta.380
This commit is contained in:
Andras Bacsai
2024-12-27 11:00:56 +01:00
committed by GitHub
26 changed files with 294 additions and 107 deletions

View File

@@ -2,6 +2,7 @@
namespace App\Console\Commands; namespace App\Console\Commands;
use App\Events\ServerReachabilityChanged;
use App\Models\Team; use App\Models\Team;
use Illuminate\Console\Command; use Illuminate\Console\Command;
@@ -92,6 +93,8 @@ class CloudCleanupSubscriptions extends Command
$server->update([ $server->update([
'ip' => '1.2.3.4', 'ip' => '1.2.3.4',
]); ]);
ServerReachabilityChanged::dispatch($server);
} }
} }
} }

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Events;
use App\Models\Server;
use Illuminate\Foundation\Events\Dispatchable;
class ServerReachabilityChanged
{
use Dispatchable;
public function __construct(
public readonly Server $server
) {
$this->server->isReachableChanged();
}
}

View File

@@ -31,12 +31,7 @@ class ServerCheckJob implements ShouldBeEncrypted, ShouldQueue
return [(new WithoutOverlapping($this->server->uuid))->dontRelease()]; return [(new WithoutOverlapping($this->server->uuid))->dontRelease()];
} }
public function __construct(public Server $server) public function __construct(public Server $server) {}
{
if (isDev()) {
$this->handle();
}
}
public function handle() public function handle()
{ {

View File

@@ -41,8 +41,8 @@ class Email extends Component
#[Validate(['nullable', 'numeric', 'min:1', 'max:65535'])] #[Validate(['nullable', 'numeric', 'min:1', 'max:65535'])]
public ?int $smtpPort = null; public ?int $smtpPort = null;
#[Validate(['nullable', 'string', 'in:tls,ssl,none'])] #[Validate(['nullable', 'string', 'in:starttls,tls,none'])]
public ?string $smtpEncryption = 'tls'; public ?string $smtpEncryption = null;
#[Validate(['nullable', 'string'])] #[Validate(['nullable', 'string'])]
public ?string $smtpUsername = null; public ?string $smtpUsername = null;
@@ -235,7 +235,7 @@ class Email extends Component
'smtpFromName' => 'required|string', 'smtpFromName' => 'required|string',
'smtpHost' => 'required|string', 'smtpHost' => 'required|string',
'smtpPort' => 'required|numeric', 'smtpPort' => 'required|numeric',
'smtpEncryption' => 'required|string|in:tls,ssl,none', 'smtpEncryption' => 'required|string|in:starttls,tls,none',
'smtpUsername' => 'nullable|string', 'smtpUsername' => 'nullable|string',
'smtpPassword' => 'nullable|string', 'smtpPassword' => 'nullable|string',
'smtpTimeout' => 'nullable|numeric', 'smtpTimeout' => 'nullable|numeric',

View File

@@ -4,6 +4,7 @@ namespace App\Livewire\Server;
use App\Actions\Server\StartSentinel; use App\Actions\Server\StartSentinel;
use App\Actions\Server\StopSentinel; use App\Actions\Server\StopSentinel;
use App\Events\ServerReachabilityChanged;
use App\Models\Server; use App\Models\Server;
use Livewire\Attributes\Computed; use Livewire\Attributes\Computed;
use Livewire\Attributes\Validate; use Livewire\Attributes\Validate;
@@ -202,6 +203,7 @@ class Show extends Component
$this->server->settings->is_reachable = $this->isReachable = true; $this->server->settings->is_reachable = $this->isReachable = true;
$this->server->settings->is_usable = $this->isUsable = true; $this->server->settings->is_usable = $this->isUsable = true;
$this->server->settings->save(); $this->server->settings->save();
ServerReachabilityChanged::dispatch($this->server);
$this->dispatch('proxyStatusUpdated'); $this->dispatch('proxyStatusUpdated');
} else { } else {
$this->dispatch('error', 'Server is not reachable.', 'Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help. <br><br>Error: '.$error); $this->dispatch('error', 'Server is not reachable.', 'Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help. <br><br>Error: '.$error);

View File

@@ -35,8 +35,8 @@ class SettingsEmail extends Component
#[Validate(['nullable', 'numeric', 'min:1', 'max:65535'])] #[Validate(['nullable', 'numeric', 'min:1', 'max:65535'])]
public ?int $smtpPort = null; public ?int $smtpPort = null;
#[Validate(['nullable', 'string', 'in:tls,ssl,none'])] #[Validate(['nullable', 'string', 'in:starttls,tls,none'])]
public ?string $smtpEncryption = 'tls'; public ?string $smtpEncryption = null;
#[Validate(['nullable', 'string'])] #[Validate(['nullable', 'string'])]
public ?string $smtpUsername = null; public ?string $smtpUsername = null;
@@ -142,7 +142,7 @@ class SettingsEmail extends Component
'smtpFromName' => 'required|string', 'smtpFromName' => 'required|string',
'smtpHost' => 'required|string', 'smtpHost' => 'required|string',
'smtpPort' => 'required|numeric', 'smtpPort' => 'required|numeric',
'smtpEncryption' => 'required|string|in:tls,ssl,none', 'smtpEncryption' => 'required|string|in:starttls,tls,none',
'smtpUsername' => 'nullable|string', 'smtpUsername' => 'nullable|string',
'smtpPassword' => 'nullable|string', 'smtpPassword' => 'nullable|string',
'smtpTimeout' => 'nullable|numeric', 'smtpTimeout' => 'nullable|numeric',

View File

@@ -6,6 +6,7 @@ use App\Actions\Proxy\StartProxy;
use App\Actions\Server\InstallDocker; use App\Actions\Server\InstallDocker;
use App\Actions\Server\StartSentinel; use App\Actions\Server\StartSentinel;
use App\Enums\ProxyTypes; use App\Enums\ProxyTypes;
use App\Events\ServerReachabilityChanged;
use App\Jobs\CheckAndStartSentinelJob; use App\Jobs\CheckAndStartSentinelJob;
use App\Notifications\Server\Reachable; use App\Notifications\Server\Reachable;
use App\Notifications\Server\Unreachable; use App\Notifications\Server\Unreachable;
@@ -346,7 +347,7 @@ class Server extends BaseModel
'loadBalancer' => [ 'loadBalancer' => [
'servers' => [ 'servers' => [
0 => [ 0 => [
'url' => 'http://coolify:80', 'url' => 'http://coolify:8080',
], ],
], ],
], ],
@@ -444,7 +445,7 @@ $schema://$host {
handle /terminal/ws { handle /terminal/ws {
reverse_proxy coolify-realtime:6002 reverse_proxy coolify-realtime:6002
} }
reverse_proxy coolify:80 reverse_proxy coolify:8080
}"; }";
$base64 = base64_encode($caddy_file); $base64 = base64_encode($caddy_file);
instant_remote_process([ instant_remote_process([
@@ -1024,14 +1025,63 @@ $schema://$host {
$this->refresh(); $this->refresh();
$unreachableNotificationSent = (bool) $this->unreachable_notification_sent; $unreachableNotificationSent = (bool) $this->unreachable_notification_sent;
$isReachable = (bool) $this->settings->is_reachable; $isReachable = (bool) $this->settings->is_reachable;
// If the server is reachable, send the reachable notification if it was sent before
\Log::debug('Server reachability check', [
'server_id' => $this->id,
'is_reachable' => $isReachable,
'notification_sent' => $unreachableNotificationSent,
'unreachable_count' => $this->unreachable_count,
]);
if ($isReachable === true) { if ($isReachable === true) {
$this->unreachable_count = 0;
$this->save();
if ($unreachableNotificationSent === true) { if ($unreachableNotificationSent === true) {
\Log::debug('Server is now reachable, sending notification', [
'server_id' => $this->id,
]);
$this->sendReachableNotification(); $this->sendReachableNotification();
} }
} else {
// If the server is unreachable, send the unreachable notification if it was not sent before return;
if ($unreachableNotificationSent === false) { }
$this->increment('unreachable_count');
\Log::debug('Incremented unreachable count', [
'server_id' => $this->id,
'new_count' => $this->unreachable_count,
]);
if ($this->unreachable_count === 1) {
$this->settings->is_reachable = true;
$this->settings->save();
\Log::debug('First unreachable attempt, marking as reachable', [
'server_id' => $this->id,
]);
return;
}
if ($this->unreachable_count >= 2 && ! $unreachableNotificationSent) {
$failedChecks = 0;
for ($i = 0; $i < 3; $i++) {
$status = $this->serverStatus();
\Log::debug('Additional reachability check', [
'server_id' => $this->id,
'attempt' => $i + 1,
'status' => $status,
]);
sleep(5);
if (! $status) {
$failedChecks++;
}
}
if ($failedChecks === 3 && ! $unreachableNotificationSent) {
\Log::debug('Server confirmed unreachable after 3 attempts, sending notification', [
'server_id' => $this->id,
]);
$this->sendUnreachableNotification(); $this->sendUnreachableNotification();
} }
} }
@@ -1065,6 +1115,7 @@ $schema://$host {
if ($this->settings->is_reachable === false) { if ($this->settings->is_reachable === false) {
$this->settings->is_reachable = true; $this->settings->is_reachable = true;
$this->settings->save(); $this->settings->save();
ServerReachabilityChanged::dispatch($this);
} }
return ['uptime' => true, 'error' => null]; return ['uptime' => true, 'error' => null];
@@ -1075,6 +1126,7 @@ $schema://$host {
if ($this->settings->is_reachable === true) { if ($this->settings->is_reachable === true) {
$this->settings->is_reachable = false; $this->settings->is_reachable = false;
$this->settings->save(); $this->settings->save();
ServerReachabilityChanged::dispatch($this);
} }
return ['uptime' => false, 'error' => $e->getMessage()]; return ['uptime' => false, 'error' => $e->getMessage()];
@@ -1165,6 +1217,7 @@ $schema://$host {
$this->settings->is_reachable = true; $this->settings->is_reachable = true;
$this->settings->is_usable = true; $this->settings->is_usable = true;
$this->settings->save(); $this->settings->save();
ServerReachabilityChanged::dispatch($this);
return true; return true;
} }

View File

@@ -85,9 +85,6 @@ class ServerSetting extends Model
) { ) {
$settings->server->restartSentinel(); $settings->server->restartSentinel();
} }
if ($settings->isDirty('is_reachable')) {
$settings->server->isReachableChanged();
}
}); });
} }

View File

@@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Events\ServerReachabilityChanged;
use App\Notifications\Channels\SendsDiscord; use App\Notifications\Channels\SendsDiscord;
use App\Notifications\Channels\SendsEmail; use App\Notifications\Channels\SendsEmail;
use App\Notifications\Channels\SendsPushover; use App\Notifications\Channels\SendsPushover;
@@ -202,6 +203,7 @@ class Team extends Model implements SendsDiscord, SendsEmail, SendsPushover, Sen
'is_usable' => false, 'is_usable' => false,
'is_reachable' => false, 'is_reachable' => false,
]); ]);
ServerReachabilityChanged::dispatch($server);
} }
} }

View File

@@ -66,17 +66,24 @@ class EmailChannel
} }
if ($emailSettings->smtp_enabled) { if ($emailSettings->smtp_enabled) {
$encryption = match (strtolower($emailSettings->smtp_encryption)) {
'starttls' => null,
'tls' => 'tls',
'none' => null,
default => null,
};
config()->set('mail.default', 'smtp'); config()->set('mail.default', 'smtp');
config()->set('mail.mailers.smtp', [ config()->set('mail.mailers.smtp', [
'transport' => 'smtp', 'transport' => 'smtp',
'host' => $emailSettings->smtp_host, 'host' => $emailSettings->smtp_host,
'port' => $emailSettings->smtp_port, 'port' => $emailSettings->smtp_port,
'encryption' => $emailSettings->smtp_encryption === 'none' ? null : $emailSettings->smtp_encryption, 'encryption' => $encryption,
'username' => $emailSettings->smtp_username, 'username' => $emailSettings->smtp_username,
'password' => $emailSettings->smtp_password, 'password' => $emailSettings->smtp_password,
'timeout' => $emailSettings->smtp_timeout, 'timeout' => $emailSettings->smtp_timeout,
'local_domain' => null, 'local_domain' => null,
'auto_tls' => $emailSettings->smtp_encryption === 'none' ? '0' : '', 'auto_tls' => $emailSettings->smtp_encryption === 'none' ? '0' : '', // If encryption is "none", it will not try to upgrade to TLS via StartTLS to make sure it is unencrypted.
]); ]);
} }
} }

View File

@@ -67,17 +67,26 @@ function set_transanctional_email_settings(?InstanceSettings $settings = null):
return 'resend'; return 'resend';
} }
$encryption = match (strtolower(data_get($settings, 'smtp_encryption'))) {
'starttls' => null,
'tls' => 'tls',
'none' => null,
default => null,
};
if (data_get($settings, 'smtp_enabled')) { if (data_get($settings, 'smtp_enabled')) {
config()->set('mail.default', 'smtp'); config()->set('mail.default', 'smtp');
config()->set('mail.mailers.smtp', [ config()->set('mail.mailers.smtp', [
'transport' => 'smtp', 'transport' => 'smtp',
'host' => data_get($settings, 'smtp_host'), 'host' => data_get($settings, 'smtp_host'),
'port' => data_get($settings, 'smtp_port'), 'port' => data_get($settings, 'smtp_port'),
'encryption' => data_get($settings, 'smtp_encryption'), 'encryption' => $encryption,
'username' => data_get($settings, 'smtp_username'), 'username' => data_get($settings, 'smtp_username'),
'password' => data_get($settings, 'smtp_password'), 'password' => data_get($settings, 'smtp_password'),
'timeout' => data_get($settings, 'smtp_timeout'), 'timeout' => data_get($settings, 'smtp_timeout'),
'local_domain' => null, 'local_domain' => null,
'auto_tls' => data_get($settings, 'smtp_encryption') === 'none' ? '0' : '', // If encryption is "none", it will not try to upgrade to TLS via StartTLS to make sure it is unencrypted.
]); ]);
return 'smtp'; return 'smtp';

View File

@@ -2,7 +2,7 @@
return [ return [
'coolify' => [ 'coolify' => [
'version' => '4.0.0-beta.379', 'version' => '4.0.0-beta.380',
'self_hosted' => env('SELF_HOSTED', true), 'self_hosted' => env('SELF_HOSTED', true),
'autoupdate' => env('AUTOUPDATE'), 'autoupdate' => env('AUTOUPDATE'),
'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'), 'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'),
@@ -47,7 +47,7 @@ return [
], ],
'docker' => [ 'docker' => [
'minimum_required_version' => '26.0', 'minimum_required_version' => '24.0',
], ],
'ssh' => [ 'ssh' => [

View File

@@ -13,7 +13,6 @@ return new class extends Migration
*/ */
public function up(): void public function up(): void
{ {
if (DB::table('instance_settings')->exists()) {
Schema::table('instance_settings', function (Blueprint $table) { Schema::table('instance_settings', function (Blueprint $table) {
$table->text('smtp_from_address')->nullable()->change(); $table->text('smtp_from_address')->nullable()->change();
$table->text('smtp_from_name')->nullable()->change(); $table->text('smtp_from_name')->nullable()->change();
@@ -22,6 +21,7 @@ return new class extends Migration
$table->text('smtp_username')->nullable()->change(); $table->text('smtp_username')->nullable()->change();
}); });
if (DB::table('instance_settings')->exists()) {
$settings = DB::table('instance_settings')->get(); $settings = DB::table('instance_settings')->get();
foreach ($settings as $setting) { foreach ($settings as $setting) {
try { try {
@@ -45,11 +45,11 @@ return new class extends Migration
public function down(): void public function down(): void
{ {
Schema::table('instance_settings', function (Blueprint $table) { Schema::table('instance_settings', function (Blueprint $table) {
$table->text('smtp_from_address')->nullable()->change(); $table->string('smtp_from_address')->nullable()->change();
$table->text('smtp_from_name')->nullable()->change(); $table->string('smtp_from_name')->nullable()->change();
$table->text('smtp_recipients')->nullable()->change(); $table->string('smtp_recipients')->nullable()->change();
$table->text('smtp_host')->nullable()->change(); $table->string('smtp_host')->nullable()->change();
$table->text('smtp_username')->nullable()->change(); $table->string('smtp_username')->nullable()->change();
}); });
if (DB::table('instance_settings')->exists()) { if (DB::table('instance_settings')->exists()) {

View File

@@ -0,0 +1,114 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
class UpdateEmailEncryptionValues extends Migration
{
/**
* Encryption mappings.
*/
private array $encryptionMappings = [
'tls' => 'starttls',
'ssl' => 'tls',
'' => 'none',
];
/**
* Run the migrations.
*/
public function up(): void
{
try {
DB::beginTransaction();
$instanceSettings = DB::table('instance_settings')->get();
foreach ($instanceSettings as $setting) {
try {
if (array_key_exists($setting->smtp_encryption, $this->encryptionMappings)) {
DB::table('instance_settings')
->where('id', $setting->id)
->update([
'smtp_encryption' => $this->encryptionMappings[$setting->smtp_encryption],
]);
}
} catch (\Exception $e) {
\Log::error('Failed to update instance settings: '.$e->getMessage());
}
}
$emailSettings = DB::table('email_notification_settings')->get();
foreach ($emailSettings as $setting) {
try {
if (array_key_exists($setting->smtp_encryption, $this->encryptionMappings)) {
DB::table('email_notification_settings')
->where('id', $setting->id)
->update([
'smtp_encryption' => $this->encryptionMappings[$setting->smtp_encryption],
]);
}
} catch (\Exception $e) {
\Log::error('Failed to update email settings: '.$e->getMessage());
}
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
\Log::error('Failed to update email encryption: '.$e->getMessage());
throw $e;
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
try {
DB::beginTransaction();
$reverseMapping = [
'starttls' => 'tls',
'tls' => 'ssl',
'none' => '',
];
$instanceSettings = DB::table('instance_settings')->get();
foreach ($instanceSettings as $setting) {
try {
if (array_key_exists($setting->smtp_encryption, $reverseMapping)) {
DB::table('instance_settings')
->where('id', $setting->id)
->update([
'smtp_encryption' => $reverseMapping[$setting->smtp_encryption],
]);
}
} catch (\Exception $e) {
\Log::error('Failed to reverse instance settings: '.$e->getMessage());
}
}
$emailSettings = DB::table('email_notification_settings')->get();
foreach ($emailSettings as $setting) {
try {
if (array_key_exists($setting->smtp_encryption, $reverseMapping)) {
DB::table('email_notification_settings')
->where('id', $setting->id)
->update([
'smtp_encryption' => $reverseMapping[$setting->smtp_encryption],
]);
}
} catch (\Exception $e) {
\Log::error('Failed to reverse email settings: '.$e->getMessage());
}
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
\Log::error('Failed to reverse email encryption: '.$e->getMessage());
throw $e;
}
}
}

View File

@@ -4,6 +4,7 @@ namespace Database\Seeders;
use App\Models\OauthSetting; use App\Models\OauthSetting;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Log;
class OauthSettingSeeder extends Seeder class OauthSettingSeeder extends Seeder
{ {
@@ -12,6 +13,7 @@ class OauthSettingSeeder extends Seeder
*/ */
public function run(): void public function run(): void
{ {
try {
$providers = collect([ $providers = collect([
'azure', 'azure',
'bitbucket', 'bitbucket',
@@ -27,27 +29,27 @@ class OauthSettingSeeder extends Seeder
// Before authentik was a provider, providers started with 0 id // Before authentik was a provider, providers started with 0 id
$isOauthAuthentik = OauthSetting::where('provider', 'authentik')->exists(); $isOauthAuthentik = OauthSetting::where('provider', 'authentik')->exists();
if ($isOauthSeeded) { if (! $isOauthSeeded || $isOauthAuthentik) {
if (! $isOauthAuthentik) { foreach ($providers as $provider) {
OauthSetting::updateOrCreate([
'provider' => $provider,
]);
}
return;
}
$allProviders = OauthSetting::all(); $allProviders = OauthSetting::all();
$notFoundProviders = $providers->diff($allProviders->pluck('provider')); $notFoundProviders = $providers->diff($allProviders->pluck('provider'));
$allProviders->each(function ($provider) { $allProviders->each(function ($provider) {
$provider->delete(); $provider->delete();
}); });
$allProviders->each(function ($provider) use ($providers) { $allProviders->each(function ($provider) {
$providerName = $provider->provider; $provider = new OauthSetting;
$provider->provider = $provider->provider;
$foundProvider = $providers->first(function ($provider) use ($providerName) { unset($provider->id);
return $provider === $providerName; $provider->save();
});
if ($foundProvider) {
$newProvder = new OauthSetting;
$newProvder = $provider;
unset($newProvder->id);
$newProvder->save();
}
}); });
foreach ($notFoundProviders as $provider) { foreach ($notFoundProviders as $provider) {
@@ -55,19 +57,9 @@ class OauthSettingSeeder extends Seeder
'provider' => $provider, 'provider' => $provider,
]); ]);
} }
} else {
foreach ($providers as $provider) { } catch (\Exception $e) {
OauthSetting::updateOrCreate([ Log::error($e->getMessage());
'provider' => $provider,
]);
}
}
} else {
foreach ($providers as $provider) {
OauthSetting::updateOrCreate([
'provider' => $provider,
]);
}
} }
} }
} }

View File

@@ -7,7 +7,7 @@ services:
- USER_ID=${USERID:-1000} - USER_ID=${USERID:-1000}
- GROUP_ID=${GROUPID:-1000} - GROUP_ID=${GROUPID:-1000}
ports: ports:
- "${APP_PORT:-8000}:80" - "${APP_PORT:-8000}:8080"
environment: environment:
AUTORUN_ENABLED: false AUTORUN_ENABLED: false
PUSHER_HOST: "${PUSHER_HOST}" PUSHER_HOST: "${PUSHER_HOST}"

View File

@@ -54,11 +54,11 @@ services:
- SSH_MUX_ENABLED - SSH_MUX_ENABLED
- SSH_MUX_PERSIST_TIME - SSH_MUX_PERSIST_TIME
ports: ports:
- "${APP_PORT:-8000}:80" - "${APP_PORT:-8000}:8080"
expose: expose:
- "${APP_PORT:-8000}" - "${APP_PORT:-8000}"
healthcheck: healthcheck:
test: curl --fail http://127.0.0.1:80/api/health || exit 1 test: curl --fail http://127.0.0.1:8080/api/health || exit 1
interval: 5s interval: 5s
retries: 10 retries: 10
timeout: 2s timeout: 2s
@@ -93,7 +93,7 @@ services:
retries: 10 retries: 10
timeout: 2s timeout: 2s
soketi: soketi:
image: 'ghcr.io/coollabsio/coolify-realtime:1.0.4' image: 'ghcr.io/coollabsio/coolify-realtime:1.0.5'
ports: ports:
- "${SOKETI_PORT:-6001}:6001" - "${SOKETI_PORT:-6001}:6001"
- "6002:6002" - "6002:6002"

View File

@@ -48,11 +48,11 @@ services:
- SSH_MUX_ENABLED=false - SSH_MUX_ENABLED=false
- IS_WINDOWS_DOCKER_DESKTOP=true - IS_WINDOWS_DOCKER_DESKTOP=true
ports: ports:
- "${APP_PORT:-8000}:80" - "${APP_PORT:-8000}:8080"
expose: expose:
- "${APP_PORT:-8000}" - "${APP_PORT:-8000}"
healthcheck: healthcheck:
test: curl --fail http://localhost:80/api/health || exit 1 test: curl --fail http://localhost:8080/api/health || exit 1
interval: 5s interval: 5s
retries: 10 retries: 10
timeout: 2s timeout: 2s

View File

@@ -33,7 +33,7 @@ const verifyClient = async (info, callback) => {
try { try {
// Authenticate with Laravel backend // Authenticate with Laravel backend
const response = await axios.post(`http://coolify/terminal/auth`, null, { const response = await axios.post(`http://coolify:8080/terminal/auth`, null, {
headers: { headers: {
'Cookie': `${sessionCookieName}=${laravelSession}`, 'Cookie': `${sessionCookieName}=${laravelSession}`,
'X-XSRF-TOKEN': xsrfToken 'X-XSRF-TOKEN': xsrfToken

View File

@@ -1,5 +1,3 @@
listen 80 default_server;
listen [::]:80 default_server;
listen 8080 default_server; listen 8080 default_server;
listen [::]:8080 default_server; listen [::]:8080 default_server;

View File

@@ -1,5 +1,3 @@
listen 80 default_server;
listen [::]:80 default_server;
listen 8080 default_server; listen 8080 default_server;
listen [::]:8080 default_server; listen [::]:8080 default_server;

View File

@@ -54,11 +54,11 @@ services:
- SSH_MUX_ENABLED - SSH_MUX_ENABLED
- SSH_MUX_PERSIST_TIME - SSH_MUX_PERSIST_TIME
ports: ports:
- "${APP_PORT:-8000}:80" - "${APP_PORT:-8000}:8080"
expose: expose:
- "${APP_PORT:-8000}" - "${APP_PORT:-8000}"
healthcheck: healthcheck:
test: curl --fail http://127.0.0.1:80/api/health || exit 1 test: curl --fail http://127.0.0.1:8080/api/health || exit 1
interval: 5s interval: 5s
retries: 10 retries: 10
timeout: 2s timeout: 2s
@@ -93,7 +93,7 @@ services:
retries: 10 retries: 10
timeout: 2s timeout: 2s
soketi: soketi:
image: 'ghcr.io/coollabsio/coolify-realtime:1.0.4' image: 'ghcr.io/coollabsio/coolify-realtime:1.0.5'
ports: ports:
- "${SOKETI_PORT:-6001}:6001" - "${SOKETI_PORT:-6001}:6001"
- "6002:6002" - "6002:6002"

View File

@@ -48,11 +48,11 @@ services:
- SSH_MUX_ENABLED=false - SSH_MUX_ENABLED=false
- IS_WINDOWS_DOCKER_DESKTOP=true - IS_WINDOWS_DOCKER_DESKTOP=true
ports: ports:
- "${APP_PORT:-8000}:80" - "${APP_PORT:-8000}:8080"
expose: expose:
- "${APP_PORT:-8000}" - "${APP_PORT:-8000}"
healthcheck: healthcheck:
test: curl --fail http://localhost:80/api/health || exit 1 test: curl --fail http://localhost:8080/api/health || exit 1
interval: 5s interval: 5s
retries: 10 retries: 10
timeout: 2s timeout: 2s

View File

@@ -70,9 +70,9 @@
<div class="flex flex-col w-full gap-2 xl:flex-row"> <div class="flex flex-col w-full gap-2 xl:flex-row">
<x-forms.input required id="smtpHost" placeholder="smtp.mailgun.org" label="Host" /> <x-forms.input required id="smtpHost" placeholder="smtp.mailgun.org" label="Host" />
<x-forms.input required id="smtpPort" placeholder="587" label="Port" /> <x-forms.input required id="smtpPort" placeholder="587" label="Port" />
<x-forms.select id="smtpEncryption" label="Encryption"> <x-forms.select required id="smtpEncryption" label="Encryption">
<option value="tls">TLS</option> <option value="starttls">StartTLS</option>
<option value="ssl">SSL</option> <option value="tls">TLS/SSL</option>
<option value="none">None</option> <option value="none">None</option>
</x-forms.select> </x-forms.select>
</div> </div>

View File

@@ -43,9 +43,9 @@
<div class="flex flex-col w-full gap-2 xl:flex-row"> <div class="flex flex-col w-full gap-2 xl:flex-row">
<x-forms.input required id="smtpHost" placeholder="smtp.mailgun.org" label="Host" /> <x-forms.input required id="smtpHost" placeholder="smtp.mailgun.org" label="Host" />
<x-forms.input required id="smtpPort" placeholder="587" label="Port" /> <x-forms.input required id="smtpPort" placeholder="587" label="Port" />
<x-forms.select id="smtpEncryption" label="Encryption"> <x-forms.select required id="smtpEncryption" label="Encryption">
<option value="tls">TLS</option> <option value="starttls">StartTLS</option>
<option value="ssl">SSL</option> <option value="tls">TLS/SSL</option>
<option value="none">None</option> <option value="none">None</option>
</x-forms.select> </x-forms.select>
</div> </div>

View File

@@ -1,10 +1,10 @@
{ {
"coolify": { "coolify": {
"v4": { "v4": {
"version": "4.0.0-beta.379" "version": "4.0.0-beta.380"
}, },
"nightly": { "nightly": {
"version": "4.0.0-beta.380" "version": "4.0.0-beta.381"
}, },
"helper": { "helper": {
"version": "1.0.4" "version": "1.0.4"