Merge branch 'next' into improve-git-and-service-provider

This commit is contained in:
🏔️ Peak
2025-01-09 21:18:30 +01:00
committed by GitHub
45 changed files with 684 additions and 369 deletions

View File

@@ -67,6 +67,10 @@ class StartDatabaseProxy
$type = \App\Models\StandaloneClickhouse::class; $type = \App\Models\StandaloneClickhouse::class;
$containerName = "clickhouse-{$database->service->uuid}"; $containerName = "clickhouse-{$database->service->uuid}";
break; break;
case 'standalone-supabase/postgres':
$type = \App\Models\StandalonePostgresql::class;
$containerName = "supabase-db-{$database->service->uuid}";
break;
} }
} }
if ($type === \App\Models\StandaloneRedis::class) { if ($type === \App\Models\StandaloneRedis::class) {

View File

@@ -112,7 +112,7 @@ class GetContainersStatus
$preview->update(['last_online_at' => now()]); $preview->update(['last_online_at' => now()]);
} }
} else { } else {
//Notify user that this container should not be there. // Notify user that this container should not be there.
} }
} else { } else {
$application = $this->applications->where('id', $applicationId)->first(); $application = $this->applications->where('id', $applicationId)->first();
@@ -125,7 +125,7 @@ class GetContainersStatus
$application->update(['last_online_at' => now()]); $application->update(['last_online_at' => now()]);
} }
} else { } else {
//Notify user that this container should not be there. // Notify user that this container should not be there.
} }
} }
} else { } else {

View File

@@ -183,7 +183,7 @@ class Emails extends Command
'team_id' => 0, 'team_id' => 0,
]); ]);
} }
//$this->mail = (new BackupSuccess($backup->frequency, $db->name))->toMail(); // $this->mail = (new BackupSuccess($backup->frequency, $db->name))->toMail();
$this->sendEmail(); $this->sendEmail();
break; break;
// case 'invitation-link': // case 'invitation-link':

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Events;
use App\Models\Server;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class RestoreJobFinished
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct($data)
{
$scriptPath = data_get($data, 'scriptPath');
$tmpPath = data_get($data, 'tmpPath');
$container = data_get($data, 'container');
$serverId = data_get($data, 'serverId');
if (filled($scriptPath) && filled($tmpPath) && filled($container) && filled($serverId)) {
if (str($tmpPath)->startsWith('/tmp/')
&& str($scriptPath)->startsWith('/tmp/')
&& ! str($tmpPath)->contains('..')
&& ! str($scriptPath)->contains('..')
&& strlen($tmpPath) > 5 // longer than just "/tmp/"
&& strlen($scriptPath) > 5
) {
$commands[] = "docker exec {$container} sh -c 'rm {$scriptPath}'";
$commands[] = "docker exec {$container} sh -c 'rm {$tmpPath}'";
instant_remote_process($commands, Server::find($serverId), throwError: true);
}
}
}
}

View File

@@ -1142,7 +1142,6 @@ class ApplicationsController extends Controller
$application->destination_type = $destination->getMorphClass(); $application->destination_type = $destination->getMorphClass();
$application->environment_id = $environment->id; $application->environment_id = $environment->id;
$application->git_repository = 'coollabsio/coolify'; $application->git_repository = 'coollabsio/coolify';
$application->git_branch = 'main'; $application->git_branch = 'main';
$application->save(); $application->save();

View File

@@ -96,6 +96,7 @@ class ProjectController extends Controller
} }
$project->load(['environments']); $project->load(['environments']);
return response()->json( return response()->json(
serializeApiResponse($project), serializeApiResponse($project),
); );

View File

@@ -14,9 +14,4 @@ class VerifyCsrfToken extends Middleware
protected $except = [ protected $except = [
// //
]; ];
protected function addCookieToResponse($request, $response)
{
return $response;
}
} }

View File

@@ -39,6 +39,8 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
{ {
use Dispatchable, ExecuteRemoteCommand, InteractsWithQueue, Queueable, SerializesModels; use Dispatchable, ExecuteRemoteCommand, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 1;
public $timeout = 3600; public $timeout = 3600;
public static int $batch_counter = 0; public static int $batch_counter = 0;
@@ -166,8 +168,6 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
private bool $preserveRepository = false; private bool $preserveRepository = false;
public $tries = 1;
public function __construct(int $application_deployment_queue_id) public function __construct(int $application_deployment_queue_id)
{ {
$this->onQueue('high'); $this->onQueue('high');

View File

@@ -44,7 +44,7 @@ class SendMessageToPushoverJob implements ShouldBeEncrypted, ShouldQueue
{ {
$response = Http::post('https://api.pushover.net/1/messages.json', $this->message->toPayload($this->token, $this->user)); $response = Http::post('https://api.pushover.net/1/messages.json', $this->message->toPayload($this->token, $this->user));
if ($response->failed()) { if ($response->failed()) {
throw new \RuntimeException('Pushover notification failed with ' . $response->status() . ' status code.' . $response->body()); throw new \RuntimeException('Pushover notification failed with '.$response->status().' status code.'.$response->body());
} }
} }
} }

View File

@@ -40,7 +40,7 @@ class BackupEdit extends Component
#[Validate(['required', 'string'])] #[Validate(['required', 'string'])]
public string $frequency = ''; public string $frequency = '';
#[Validate(['readonly', 'string'])] #[Validate(['string'])]
public string $timezone = ''; public string $timezone = '';
#[Validate(['required', 'integer', 'min:1'])] #[Validate(['required', 'integer', 'min:1'])]
@@ -71,7 +71,6 @@ class BackupEdit extends Component
public function syncData(bool $toModel = false) public function syncData(bool $toModel = false)
{ {
if ($toModel) { if ($toModel) {
$this->customValidate();
$this->backup->enabled = $this->backupEnabled; $this->backup->enabled = $this->backupEnabled;
$this->backup->frequency = $this->frequency; $this->backup->frequency = $this->frequency;
$this->backup->number_of_backups_locally = $this->numberOfBackupsLocally; $this->backup->number_of_backups_locally = $this->numberOfBackupsLocally;
@@ -79,6 +78,7 @@ class BackupEdit extends Component
$this->backup->s3_storage_id = $this->s3StorageId; $this->backup->s3_storage_id = $this->s3StorageId;
$this->backup->databases_to_backup = $this->databasesToBackup; $this->backup->databases_to_backup = $this->databasesToBackup;
$this->backup->dump_all = $this->dumpAll; $this->backup->dump_all = $this->dumpAll;
$this->customValidate();
$this->backup->save(); $this->backup->save();
} else { } else {
$this->backupEnabled = $this->backup->enabled; $this->backupEnabled = $this->backup->enabled;
@@ -187,12 +187,12 @@ class BackupEdit extends Component
private function deleteAssociatedBackupsS3() private function deleteAssociatedBackupsS3()
{ {
//Add function to delete backups from S3 // Add function to delete backups from S3
} }
private function deleteAssociatedBackupsSftp() private function deleteAssociatedBackupsSftp()
{ {
//Add function to delete backups from SFTP // Add function to delete backups from SFTP
} }
private function deleteEmptyBackupFolder($folderPath, $server) private function deleteEmptyBackupFolder($folderPath, $server)

View File

@@ -37,6 +37,12 @@ class Import extends Component
public array $importCommands = []; public array $importCommands = [];
public bool $dumpAll = false;
public string $restoreCommandText = '';
public string $customLocation = '';
public string $postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB'; public string $postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB';
public string $mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE'; public string $mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE';
@@ -56,10 +62,62 @@ class Import extends Component
public function mount() public function mount()
{ {
if (isDev()) {
$this->customLocation = '/data/coolify/pg-dump-all-1736245863.gz';
}
$this->parameters = get_route_parameters(); $this->parameters = get_route_parameters();
$this->getContainers(); $this->getContainers();
} }
public function updatedDumpAll($value)
{
switch ($this->resource->getMorphClass()) {
case \App\Models\StandaloneMariadb::class:
if ($value === true) {
$this->mariadbRestoreCommand = <<<'EOD'
for pid in $(mariadb -u root -p$MARIADB_ROOT_PASSWORD -N -e "SELECT id FROM information_schema.processlist WHERE user != 'root';"); do
mariadb -u root -p$MARIADB_ROOT_PASSWORD -e "KILL $pid" 2>/dev/null || true
done && \
mariadb -u root -p$MARIADB_ROOT_PASSWORD -N -e "SELECT CONCAT('DROP DATABASE IF EXISTS \`',schema_name,'\`;') FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys');" | mariadb -u root -p$MARIADB_ROOT_PASSWORD && \
mariadb -u root -p$MARIADB_ROOT_PASSWORD -e "CREATE DATABASE IF NOT EXISTS \`default\`;" && \
(gunzip -cf $tmpPath 2>/dev/null || cat $tmpPath) | sed -e '/^CREATE DATABASE/d' -e '/^USE \`mysql\`/d' | mariadb -u root -p$MARIADB_ROOT_PASSWORD default
EOD;
$this->restoreCommandText = $this->mariadbRestoreCommand.' && (gunzip -cf <temp_backup_file> 2>/dev/null || cat <temp_backup_file>) | mariadb -u root -p$MARIADB_ROOT_PASSWORD default';
} else {
$this->mariadbRestoreCommand = 'mariadb -u $MARIADB_USER -p$MARIADB_PASSWORD $MARIADB_DATABASE';
}
break;
case \App\Models\StandaloneMysql::class:
if ($value === true) {
$this->mysqlRestoreCommand = <<<'EOD'
for pid in $(mysql -u root -p$MYSQL_ROOT_PASSWORD -N -e "SELECT id FROM information_schema.processlist WHERE user != 'root';"); do
mysql -u root -p$MYSQL_ROOT_PASSWORD -e "KILL $pid" 2>/dev/null || true
done && \
mysql -u root -p$MYSQL_ROOT_PASSWORD -N -e "SELECT CONCAT('DROP DATABASE IF EXISTS \`',schema_name,'\`;') FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys');" | mysql -u root -p$MYSQL_ROOT_PASSWORD && \
mysql -u root -p$MYSQL_ROOT_PASSWORD -e "CREATE DATABASE IF NOT EXISTS \`default\`;" && \
(gunzip -cf $tmpPath 2>/dev/null || cat $tmpPath) | sed -e '/^CREATE DATABASE/d' -e '/^USE \`mysql\`/d' | mysql -u root -p$MYSQL_ROOT_PASSWORD default
EOD;
$this->restoreCommandText = $this->mysqlRestoreCommand.' && (gunzip -cf <temp_backup_file> 2>/dev/null || cat <temp_backup_file>) | mysql -u root -p$MYSQL_ROOT_PASSWORD default';
} else {
$this->mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE';
}
break;
case \App\Models\StandalonePostgresql::class:
if ($value === true) {
$this->postgresqlRestoreCommand = <<<'EOD'
psql -U $POSTGRES_USER -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname IS NOT NULL AND pid <> pg_backend_pid()" && \
psql -U $POSTGRES_USER -t -c "SELECT datname FROM pg_database WHERE NOT datistemplate" | xargs -I {} dropdb -U $POSTGRES_USER --if-exists {} && \
createdb -U $POSTGRES_USER postgres
EOD;
$this->restoreCommandText = $this->postgresqlRestoreCommand.' && (gunzip -cf <temp_backup_file> 2>/dev/null || cat <temp_backup_file>) | psql -U $POSTGRES_USER postgres';
} else {
$this->postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB';
}
break;
}
}
public function getContainers() public function getContainers()
{ {
$this->containers = collect(); $this->containers = collect();
@@ -87,6 +145,24 @@ class Import extends Component
} }
} }
public function checkFile()
{
if (filled($this->customLocation)) {
try {
$result = instant_remote_process(["ls -l {$this->customLocation}"], $this->server, throwError: false);
if (blank($result)) {
$this->dispatch('error', 'The file does not exist or has been deleted.');
return;
}
$this->filename = $this->customLocation;
$this->dispatch('success', 'The file exists.');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
}
public function runImport() public function runImport()
{ {
if ($this->filename === '') { if ($this->filename === '') {
@@ -95,46 +171,83 @@ class Import extends Component
return; return;
} }
try { try {
$uploadedFilename = "upload/{$this->resource->uuid}/restore"; $this->importCommands = [];
$path = Storage::path($uploadedFilename); if (filled($this->customLocation)) {
if (! Storage::exists($uploadedFilename)) { $backupFileName = '/tmp/restore_'.$this->resource->uuid;
$this->importCommands[] = "docker cp {$this->customLocation} {$this->container}:{$backupFileName}";
$tmpPath = $backupFileName;
} else {
$backupFileName = "upload/{$this->resource->uuid}/restore";
$path = Storage::path($backupFileName);
if (! Storage::exists($backupFileName)) {
$this->dispatch('error', 'The file does not exist or has been deleted.'); $this->dispatch('error', 'The file does not exist or has been deleted.');
return; return;
} }
$tmpPath = '/tmp/'.basename($uploadedFilename); $tmpPath = '/tmp/'.basename($backupFileName).'_'.$this->resource->uuid;
instant_scp($path, $tmpPath, $this->server); instant_scp($path, $tmpPath, $this->server);
Storage::delete($uploadedFilename); Storage::delete($backupFileName);
$this->importCommands[] = "docker cp {$tmpPath} {$this->container}:{$tmpPath}"; $this->importCommands[] = "docker cp {$tmpPath} {$this->container}:{$tmpPath}";
}
// Copy the restore command to a script file
$scriptPath = "/tmp/restore_{$this->resource->uuid}.sh";
switch ($this->resource->getMorphClass()) { switch ($this->resource->getMorphClass()) {
case \App\Models\StandaloneMariadb::class: case \App\Models\StandaloneMariadb::class:
$this->importCommands[] = "docker exec {$this->container} sh -c '{$this->mariadbRestoreCommand} < {$tmpPath}'"; $restoreCommand = $this->mariadbRestoreCommand;
$this->importCommands[] = "rm {$tmpPath}"; if ($this->dumpAll) {
$restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | mariadb -u root -p\$MARIADB_ROOT_PASSWORD";
} else {
$restoreCommand .= " < {$tmpPath}";
}
break; break;
case \App\Models\StandaloneMysql::class: case \App\Models\StandaloneMysql::class:
$this->importCommands[] = "docker exec {$this->container} sh -c '{$this->mysqlRestoreCommand} < {$tmpPath}'"; $restoreCommand = $this->mysqlRestoreCommand;
$this->importCommands[] = "rm {$tmpPath}"; if ($this->dumpAll) {
$restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | mysql -u root -p\$MYSQL_ROOT_PASSWORD";
} else {
$restoreCommand .= " < {$tmpPath}";
}
break; break;
case \App\Models\StandalonePostgresql::class: case \App\Models\StandalonePostgresql::class:
$this->importCommands[] = "docker exec {$this->container} sh -c '{$this->postgresqlRestoreCommand} {$tmpPath}'"; $restoreCommand = $this->postgresqlRestoreCommand;
$this->importCommands[] = "rm {$tmpPath}"; if ($this->dumpAll) {
$restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | psql -U \$POSTGRES_USER postgres";
} else {
$restoreCommand .= " {$tmpPath}";
}
break; break;
case \App\Models\StandaloneMongodb::class: case \App\Models\StandaloneMongodb::class:
$this->importCommands[] = "docker exec {$this->container} sh -c '{$this->mongodbRestoreCommand}{$tmpPath}'"; $restoreCommand = $this->mongodbRestoreCommand;
$this->importCommands[] = "rm {$tmpPath}"; if ($this->dumpAll === false) {
$restoreCommand .= " {$tmpPath}";
}
break; break;
} }
$this->importCommands[] = "docker exec {$this->container} sh -c 'rm {$tmpPath}'"; $restoreCommandBase64 = base64_encode($restoreCommand);
$this->importCommands[] = "echo \"{$restoreCommandBase64}\" | base64 -d > {$scriptPath}";
$this->importCommands[] = "chmod +x {$scriptPath}";
$this->importCommands[] = "docker cp {$scriptPath} {$this->container}:{$scriptPath}";
$this->importCommands[] = "docker exec {$this->container} sh -c '{$scriptPath}'";
$this->importCommands[] = "docker exec {$this->container} sh -c 'echo \"Import finished with exit code $?\"'"; $this->importCommands[] = "docker exec {$this->container} sh -c 'echo \"Import finished with exit code $?\"'";
if (! empty($this->importCommands)) { if (! empty($this->importCommands)) {
$activity = remote_process($this->importCommands, $this->server, ignore_errors: true); $activity = remote_process($this->importCommands, $this->server, ignore_errors: true, callEventOnFinish: 'RestoreJobFinished', callEventData: [
'scriptPath' => $scriptPath,
'tmpPath' => $tmpPath,
'container' => $this->container,
'serverId' => $this->server->id,
]);
$this->dispatch('activityMonitor', $activity->id); $this->dispatch('activityMonitor', $activity->id);
} }
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError($e, $this); return handleError($e, $this);
} finally {
$this->filename = null;
$this->importCommands = [];
} }
} }
} }

View File

@@ -23,6 +23,8 @@ class Select extends Component
public Collection|null|Server $servers; public Collection|null|Server $servers;
public bool $onlyBuildServerAvailable = false;
public ?Collection $standaloneDockers; public ?Collection $standaloneDockers;
public ?Collection $swarmDockers; public ?Collection $swarmDockers;
@@ -325,5 +327,11 @@ class Select extends Component
{ {
$this->servers = Server::isUsable()->get()->sortBy('name'); $this->servers = Server::isUsable()->get()->sortBy('name');
$this->allServers = $this->servers; $this->allServers = $this->servers;
if ($this->allServers && $this->allServers->isNotEmpty()) {
$this->onlyBuildServerAvailable = $this->allServers->every(function ($server) {
return $server->isBuildServer();
});
}
} }
} }

View File

@@ -226,16 +226,18 @@ class Index extends Component
} }
} }
public function toggleTwoStepConfirmation($password) public function toggleTwoStepConfirmation($password): bool
{ {
if (! Hash::check($password, Auth::user()->password)) { if (! Hash::check($password, Auth::user()->password)) {
$this->addError('password', 'The provided password is incorrect.'); $this->addError('password', 'The provided password is incorrect.');
return; return false;
} }
$this->settings->disable_two_step_confirmation = $this->disable_two_step_confirmation = true; $this->settings->disable_two_step_confirmation = $this->disable_two_step_confirmation = true;
$this->settings->save(); $this->settings->save();
$this->dispatch('success', 'Two step confirmation has been disabled.'); $this->dispatch('success', 'Two step confirmation has been disabled.');
return true;
} }
} }

View File

@@ -610,7 +610,7 @@ class Application extends BaseModel
}, },
get: function ($value) { get: function ($value) {
if ($this->additional_servers->count() === 0) { if ($this->additional_servers->count() === 0) {
//running (healthy) // running (healthy)
if (str($value)->contains('(')) { if (str($value)->contains('(')) {
$status = str($value)->before('(')->trim()->value(); $status = str($value)->before('(')->trim()->value();
$health = str($value)->after('(')->before(')')->trim()->value() ?? 'unhealthy'; $health = str($value)->after('(')->before(')')->trim()->value() ?? 'unhealthy';

View File

@@ -87,7 +87,6 @@ class ContainerStopped extends CustomEmailNotification
); );
} }
public function toSlack(): SlackMessage public function toSlack(): SlackMessage
{ {
$title = 'Resource stopped'; $title = 'Resource stopped';

View File

@@ -63,7 +63,6 @@ class BackupSuccess extends CustomEmailNotification
]; ];
} }
public function toPushover(): PushoverMessage public function toPushover(): PushoverMessage
{ {
return new PushoverMessage( return new PushoverMessage(
@@ -73,7 +72,6 @@ class BackupSuccess extends CustomEmailNotification
); );
} }
public function toSlack(): SlackMessage public function toSlack(): SlackMessage
{ {
$title = 'Database backup successful'; $title = 'Database backup successful';

View File

@@ -65,8 +65,8 @@ class HighDiskUsage extends CustomEmailNotification
level: 'warning', level: 'warning',
message: "Server '{$this->server->name}' high disk usage detected!<br/><br/><b>Disk usage:</b> {$this->disk_usage}%.<br/><b>Threshold:</b> {$this->server_disk_usage_notification_threshold}%.<br/>Please cleanup your disk to prevent data-loss.", message: "Server '{$this->server->name}' high disk usage detected!<br/><br/><b>Disk usage:</b> {$this->disk_usage}%.<br/><b>Threshold:</b> {$this->server_disk_usage_notification_threshold}%.<br/>Please cleanup your disk to prevent data-loss.",
buttons: [ buttons: [
'Change settings' => base_url().'/server/'.$this->server->uuid."#advanced", 'Change settings' => base_url().'/server/'.$this->server->uuid.'#advanced',
'Tips for cleanup' => "https://coolify.io/docs/knowledge-base/server/automated-cleanup", 'Tips for cleanup' => 'https://coolify.io/docs/knowledge-base/server/automated-cleanup',
], ],
); );
} }

View File

@@ -4,9 +4,9 @@ namespace App\Notifications;
use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\EmailChannel;
use App\Notifications\Channels\PushoverChannel;
use App\Notifications\Channels\SlackChannel; use App\Notifications\Channels\SlackChannel;
use App\Notifications\Channels\TelegramChannel; use App\Notifications\Channels\TelegramChannel;
use App\Notifications\Channels\PushoverChannel;
use App\Notifications\Dto\DiscordMessage; use App\Notifications\Dto\DiscordMessage;
use App\Notifications\Dto\PushoverMessage; use App\Notifications\Dto\PushoverMessage;
use App\Notifications\Dto\SlackMessage; use App\Notifications\Dto\SlackMessage;

View File

@@ -52,11 +52,11 @@
"symfony/yaml": "^7.1.6", "symfony/yaml": "^7.1.6",
"visus/cuid2": "^4.1.0", "visus/cuid2": "^4.1.0",
"yosymfony/toml": "^1.0", "yosymfony/toml": "^1.0",
"zircote/swagger-php": "^4.10" "zircote/swagger-php": "^5.0"
}, },
"require-dev": { "require-dev": {
"barryvdh/laravel-debugbar": "^3.13", "barryvdh/laravel-debugbar": "^3.13",
"driftingly/rector-laravel": "^1.2", "driftingly/rector-laravel": "^2.0",
"fakerphp/faker": "^1.21.0", "fakerphp/faker": "^1.21.0",
"laravel/dusk": "^8.0", "laravel/dusk": "^8.0",
"laravel/pint": "^1.16", "laravel/pint": "^1.16",
@@ -64,10 +64,10 @@
"mockery/mockery": "^1.5.1", "mockery/mockery": "^1.5.1",
"nunomaduro/collision": "^8.1", "nunomaduro/collision": "^8.1",
"pestphp/pest": "^3.5", "pestphp/pest": "^3.5",
"phpstan/phpstan": "^1.12.10", "phpstan/phpstan": "^2.1",
"phpunit/phpunit": "^11.4", "phpunit/phpunit": "^11.5",
"rector/rector": "^1.2", "rector/rector": "^2.0",
"serversideup/spin": "^2.3", "serversideup/spin": "^3.0",
"spatie/laravel-ignition": "^2.1.0", "spatie/laravel-ignition": "^2.1.0",
"symfony/http-client": "^7.1" "symfony/http-client": "^7.1"
}, },

109
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "aa98760c097f486cac380aa701e4317c", "content-hash": "ccced2490c39e4f6f1bf9b036bfa3ef0",
"packages": [ "packages": [
{ {
"name": "3sidedcube/laravel-redoc", "name": "3sidedcube/laravel-redoc",
@@ -928,16 +928,16 @@
}, },
{ {
"name": "aws/aws-sdk-php", "name": "aws/aws-sdk-php",
"version": "3.336.8", "version": "3.336.11",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/aws/aws-sdk-php.git", "url": "https://github.com/aws/aws-sdk-php.git",
"reference": "933da0d1b9b1ac9b37d5e32e127d4581b1aabaf6" "reference": "442039c766a82f06ecfecb0ac2c610d6aaba228d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/933da0d1b9b1ac9b37d5e32e127d4581b1aabaf6", "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/442039c766a82f06ecfecb0ac2c610d6aaba228d",
"reference": "933da0d1b9b1ac9b37d5e32e127d4581b1aabaf6", "reference": "442039c766a82f06ecfecb0ac2c610d6aaba228d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1020,9 +1020,9 @@
"support": { "support": {
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
"issues": "https://github.com/aws/aws-sdk-php/issues", "issues": "https://github.com/aws/aws-sdk-php/issues",
"source": "https://github.com/aws/aws-sdk-php/tree/3.336.8" "source": "https://github.com/aws/aws-sdk-php/tree/3.336.11"
}, },
"time": "2025-01-03T19:06:11+00:00" "time": "2025-01-08T19:06:59+00:00"
}, },
{ {
"name": "bacon/bacon-qr-code", "name": "bacon/bacon-qr-code",
@@ -4754,12 +4754,12 @@
"version": "3.8.4", "version": "3.8.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/briannesbitt/Carbon.git", "url": "https://github.com/CarbonPHP/carbon.git",
"reference": "129700ed449b1f02d70272d2ac802357c8c30c58" "reference": "129700ed449b1f02d70272d2ac802357c8c30c58"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/129700ed449b1f02d70272d2ac802357c8c30c58", "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/129700ed449b1f02d70272d2ac802357c8c30c58",
"reference": "129700ed449b1f02d70272d2ac802357c8c30c58", "reference": "129700ed449b1f02d70272d2ac802357c8c30c58",
"shasum": "" "shasum": ""
}, },
@@ -11756,36 +11756,41 @@
}, },
{ {
"name": "zircote/swagger-php", "name": "zircote/swagger-php",
"version": "4.11.1", "version": "5.0.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/zircote/swagger-php.git", "url": "https://github.com/zircote/swagger-php.git",
"reference": "7df10e8ec47db07c031db317a25bef962b4e5de1" "reference": "2d365300e9bc64b935fca99a8f0bc8fe4314deb4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/7df10e8ec47db07c031db317a25bef962b4e5de1", "url": "https://api.github.com/repos/zircote/swagger-php/zipball/2d365300e9bc64b935fca99a8f0bc8fe4314deb4",
"reference": "7df10e8ec47db07c031db317a25bef962b4e5de1", "reference": "2d365300e9bc64b935fca99a8f0bc8fe4314deb4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-json": "*", "ext-json": "*",
"php": ">=7.2", "nikic/php-parser": "^4.19 || ^5.0",
"php": ">=7.4",
"psr/log": "^1.1 || ^2.0 || ^3.0", "psr/log": "^1.1 || ^2.0 || ^3.0",
"symfony/deprecation-contracts": "^2 || ^3", "symfony/deprecation-contracts": "^2 || ^3",
"symfony/finder": ">=2.2", "symfony/finder": "^5.0 || ^6.0 || ^7.0",
"symfony/yaml": ">=3.3" "symfony/yaml": "^5.0 || ^6.0 || ^7.0"
},
"conflict": {
"symfony/process": ">=6, <6.4.14"
}, },
"require-dev": { "require-dev": {
"composer/package-versions-deprecated": "^1.11", "composer/package-versions-deprecated": "^1.11",
"doctrine/annotations": "^1.7 || ^2.0", "doctrine/annotations": "^2.0",
"friendsofphp/php-cs-fixer": "^2.17 || 3.62.0", "friendsofphp/php-cs-fixer": "^3.62.0",
"phpstan/phpstan": "^1.6", "phpstan/phpstan": "^1.6 || ^2.0",
"phpunit/phpunit": ">=8", "phpunit/phpunit": "^9.0",
"vimeo/psalm": "^4.23" "rector/rector": "^1.0 || ^2.0",
"vimeo/psalm": "^4.30 || ^5.0"
}, },
"suggest": { "suggest": {
"doctrine/annotations": "^1.7 || ^2.0" "doctrine/annotations": "^2.0"
}, },
"bin": [ "bin": [
"bin/openapi" "bin/openapi"
@@ -11793,7 +11798,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "4.x-dev" "dev-master": "5.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -11831,9 +11836,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/zircote/swagger-php/issues", "issues": "https://github.com/zircote/swagger-php/issues",
"source": "https://github.com/zircote/swagger-php/tree/4.11.1" "source": "https://github.com/zircote/swagger-php/tree/5.0.1"
}, },
"time": "2024-10-15T19:20:02+00:00" "time": "2025-01-09T02:31:15+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
@@ -12016,21 +12021,21 @@
}, },
{ {
"name": "driftingly/rector-laravel", "name": "driftingly/rector-laravel",
"version": "1.2.6", "version": "2.0.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/driftingly/rector-laravel.git", "url": "https://github.com/driftingly/rector-laravel.git",
"reference": "010e050488e0c1ec305736b081db04d9b834c709" "reference": "973d87d51c1a0d42340758bbddaef15a14155a54"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/010e050488e0c1ec305736b081db04d9b834c709", "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/973d87d51c1a0d42340758bbddaef15a14155a54",
"reference": "010e050488e0c1ec305736b081db04d9b834c709", "reference": "973d87d51c1a0d42340758bbddaef15a14155a54",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.2 || ^8.0", "php": "^7.2 || ^8.0",
"rector/rector": "^1.0" "rector/rector": "^2.0"
}, },
"type": "rector-extension", "type": "rector-extension",
"autoload": { "autoload": {
@@ -12045,9 +12050,9 @@
"description": "Rector upgrades rules for Laravel Framework", "description": "Rector upgrades rules for Laravel Framework",
"support": { "support": {
"issues": "https://github.com/driftingly/rector-laravel/issues", "issues": "https://github.com/driftingly/rector-laravel/issues",
"source": "https://github.com/driftingly/rector-laravel/tree/1.2.6" "source": "https://github.com/driftingly/rector-laravel/tree/2.0.1"
}, },
"time": "2024-12-05T17:29:03+00:00" "time": "2025-01-03T16:28:38+00:00"
}, },
{ {
"name": "fakerphp/faker", "name": "fakerphp/faker",
@@ -13320,20 +13325,20 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "1.12.15", "version": "2.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "c91d4e8bc056f46cf653656e6f71004b254574d1" "reference": "cd6e973e04b4c2b94c86e8612b5a65f0da0e08e7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/c91d4e8bc056f46cf653656e6f71004b254574d1", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/cd6e973e04b4c2b94c86e8612b5a65f0da0e08e7",
"reference": "c91d4e8bc056f46cf653656e6f71004b254574d1", "reference": "cd6e973e04b4c2b94c86e8612b5a65f0da0e08e7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.2|^8.0" "php": "^7.4|^8.0"
}, },
"conflict": { "conflict": {
"phpstan/phpstan-shim": "*" "phpstan/phpstan-shim": "*"
@@ -13374,7 +13379,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-01-05T16:40:22+00:00" "time": "2025-01-05T16:43:48+00:00"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
@@ -13802,21 +13807,21 @@
}, },
{ {
"name": "rector/rector", "name": "rector/rector",
"version": "1.2.10", "version": "2.0.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/rectorphp/rector.git", "url": "https://github.com/rectorphp/rector.git",
"reference": "40f9cf38c05296bd32f444121336a521a293fa61" "reference": "fa0cb009dc3df084bf549032ae4080a0481a2036"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/40f9cf38c05296bd32f444121336a521a293fa61", "url": "https://api.github.com/repos/rectorphp/rector/zipball/fa0cb009dc3df084bf549032ae4080a0481a2036",
"reference": "40f9cf38c05296bd32f444121336a521a293fa61", "reference": "fa0cb009dc3df084bf549032ae4080a0481a2036",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.2|^8.0", "php": "^7.4|^8.0",
"phpstan/phpstan": "^1.12.5" "phpstan/phpstan": "^2.1.1"
}, },
"conflict": { "conflict": {
"rector/rector-doctrine": "*", "rector/rector-doctrine": "*",
@@ -13849,7 +13854,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/rectorphp/rector/issues", "issues": "https://github.com/rectorphp/rector/issues",
"source": "https://github.com/rectorphp/rector/tree/1.2.10" "source": "https://github.com/rectorphp/rector/tree/2.0.6"
}, },
"funding": [ "funding": [
{ {
@@ -13857,7 +13862,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-11-08T13:59:10+00:00" "time": "2025-01-06T10:38:36+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",
@@ -14787,16 +14792,16 @@
}, },
{ {
"name": "serversideup/spin", "name": "serversideup/spin",
"version": "v2.3.0", "version": "v3.0.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/serversideup/spin.git", "url": "https://github.com/serversideup/spin.git",
"reference": "e7f742dfe54146196da26876670f368c11852df3" "reference": "ed3ee8f2b9eeaf9e2a0654438441a1eb8ccf5d3d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/serversideup/spin/zipball/e7f742dfe54146196da26876670f368c11852df3", "url": "https://api.github.com/repos/serversideup/spin/zipball/ed3ee8f2b9eeaf9e2a0654438441a1eb8ccf5d3d",
"reference": "e7f742dfe54146196da26876670f368c11852df3", "reference": "ed3ee8f2b9eeaf9e2a0654438441a1eb8ccf5d3d",
"shasum": "" "shasum": ""
}, },
"bin": [ "bin": [
@@ -14820,7 +14825,7 @@
"description": "Replicate your production environment locally using Docker. Just run \"spin up\". It's really that easy.", "description": "Replicate your production environment locally using Docker. Just run \"spin up\". It's really that easy.",
"support": { "support": {
"issues": "https://github.com/serversideup/spin/issues", "issues": "https://github.com/serversideup/spin/issues",
"source": "https://github.com/serversideup/spin/tree/v2.3.0" "source": "https://github.com/serversideup/spin/tree/v3.0.1"
}, },
"funding": [ "funding": [
{ {
@@ -14828,7 +14833,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-10-15T15:12:28+00:00" "time": "2024-12-20T17:23:06+00:00"
}, },
{ {
"name": "spatie/error-solutions", "name": "spatie/error-solutions",

View File

@@ -1,19 +1,19 @@
# Versions # Versions
# https://hub.docker.com/_/alpine # https://hub.docker.com/_/alpine
ARG BASE_IMAGE=alpine:3.20 ARG BASE_IMAGE=alpine:3.21
# https://download.docker.com/linux/static/stable/ # https://download.docker.com/linux/static/stable/
ARG DOCKER_VERSION=27.3.1 ARG DOCKER_VERSION=27.4.1
# https://github.com/docker/compose/releases # https://github.com/docker/compose/releases
ARG DOCKER_COMPOSE_VERSION=2.30.3 ARG DOCKER_COMPOSE_VERSION=2.32.2
# https://github.com/docker/buildx/releases # https://github.com/docker/buildx/releases
ARG DOCKER_BUILDX_VERSION=0.18.0 ARG DOCKER_BUILDX_VERSION=0.19.3
# https://github.com/buildpacks/pack/releases # https://github.com/buildpacks/pack/releases
ARG PACK_VERSION=0.35.1 ARG PACK_VERSION=0.36.2
# https://github.com/railwayapp/nixpacks/releases # https://github.com/railwayapp/nixpacks/releases
ARG NIXPACKS_VERSION=1.29.0 ARG NIXPACKS_VERSION=1.30.0
# https://hub.docker.com/r/minio/mc/tags # https://github.com/minio/mc/releases
ARG MINIO_VERSION=RELEASE.2024-03-07T00-31-49Z ARG MINIO_VERSION=RELEASE.2024-11-21T17-21-54Z
FROM minio/mc:${MINIO_VERSION} AS minio-client FROM minio/mc:${MINIO_VERSION} AS minio-client

View File

@@ -1,9 +1,13 @@
FROM quay.io/soketi/soketi:1.6-16-alpine # Versions
# https://github.com/soketi/soketi/releases
ARG SOKETI_VERSION=1.6-16-alpine
# https://github.com/cloudflare/cloudflared/releases
ARG CLOUDFLARED_VERSION=2025.1.0
FROM quay.io/soketi/soketi:${SOKETI_VERSION}
ARG TARGETPLATFORM ARG TARGETPLATFORM
# https://github.com/cloudflare/cloudflared/releases ARG CLOUDFLARED_VERSION
ARG CLOUDFLARED_VERSION=2024.4.1
WORKDIR /terminal WORKDIR /terminal
RUN apk add --no-cache openssh-client make g++ python3 curl RUN apk add --no-cache openssh-client make g++ python3 curl
@@ -13,14 +17,12 @@ RUN npm rebuild node-pty --update-binary
COPY docker/coolify-realtime/soketi-entrypoint.sh /soketi-entrypoint.sh COPY docker/coolify-realtime/soketi-entrypoint.sh /soketi-entrypoint.sh
COPY docker/coolify-realtime/terminal-server.js /terminal/terminal-server.js COPY docker/coolify-realtime/terminal-server.js /terminal/terminal-server.js
RUN /bin/sh -c "if [[ ${TARGETPLATFORM} == 'linux/amd64' ]]; then \ # Install Cloudflared based on architecture
echo 'amd64' && \ RUN if [ "${TARGETPLATFORM}" = "linux/amd64" ]; then \
curl -sSL https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared && chmod +x /usr/local/bin/cloudflared \ curl -sSL "https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-amd64" -o /usr/local/bin/cloudflared; \
;fi" elif [ "${TARGETPLATFORM}" = "linux/arm64" ]; then \
curl -sSL "https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-arm64" -o /usr/local/bin/cloudflared; \
RUN /bin/sh -c "if [[ ${TARGETPLATFORM} == 'linux/arm64' ]]; then \ fi && \
echo 'arm64' && \ chmod +x /usr/local/bin/cloudflared
curl -L https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-arm64 -o /usr/local/bin/cloudflared && chmod +x /usr/local/bin/cloudflared \
;fi"
ENTRYPOINT ["/bin/sh", "/soketi-entrypoint.sh"] ENTRYPOINT ["/bin/sh", "/soketi-entrypoint.sh"]

View File

@@ -7,9 +7,9 @@
"dependencies": { "dependencies": {
"@xterm/addon-fit": "0.10.0", "@xterm/addon-fit": "0.10.0",
"@xterm/xterm": "5.5.0", "@xterm/xterm": "5.5.0",
"axios": "1.7.7", "axios": "1.7.9",
"cookie": "1.0.1", "cookie": "1.0.2",
"dotenv": "16.4.5", "dotenv": "16.4.7",
"node-pty": "1.0.0", "node-pty": "1.0.0",
"ws": "8.18.0" "ws": "8.18.0"
} }
@@ -36,9 +36,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/axios": { "node_modules/axios": {
"version": "1.7.7", "version": "1.7.9",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"follow-redirects": "^1.15.6", "follow-redirects": "^1.15.6",
@@ -59,9 +59,9 @@
} }
}, },
"node_modules/cookie": { "node_modules/cookie": {
"version": "1.0.1", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.1.tgz", "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
"integrity": "sha512-Xd8lFX4LM9QEEwxQpF9J9NTUh8pmdJO0cyRJhFiDoLTk2eH8FXlRv2IFGYVadZpqI3j8fhNrSdKCeYPxiAhLXw==", "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
@@ -77,9 +77,9 @@
} }
}, },
"node_modules/dotenv": { "node_modules/dotenv": {
"version": "16.4.5", "version": "16.4.7",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
"integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"engines": { "engines": {
"node": ">=12" "node": ">=12"

View File

@@ -4,9 +4,9 @@
"dependencies": { "dependencies": {
"@xterm/addon-fit": "0.10.0", "@xterm/addon-fit": "0.10.0",
"@xterm/xterm": "5.5.0", "@xterm/xterm": "5.5.0",
"cookie": "1.0.1", "cookie": "1.0.2",
"axios": "1.7.7", "axios": "1.7.9",
"dotenv": "16.4.5", "dotenv": "16.4.7",
"node-pty": "1.0.0", "node-pty": "1.0.0",
"ws": "8.18.0" "ws": "8.18.0"
} }

View File

@@ -2,9 +2,9 @@
# https://hub.docker.com/r/serversideup/php/tags?name=8.4-fpm-nginx-alpine # https://hub.docker.com/r/serversideup/php/tags?name=8.4-fpm-nginx-alpine
ARG SERVERSIDEUP_PHP_VERSION=8.4-fpm-nginx-alpine ARG SERVERSIDEUP_PHP_VERSION=8.4-fpm-nginx-alpine
# https://github.com/minio/mc/releases # https://github.com/minio/mc/releases
ARG MINIO_VERSION=RELEASE.2024-11-17T19-35-25Z ARG MINIO_VERSION=RELEASE.2024-11-21T17-21-54Z
# https://github.com/cloudflare/cloudflared/releases # https://github.com/cloudflare/cloudflared/releases
ARG CLOUDFLARED_VERSION=2024.11.1 ARG CLOUDFLARED_VERSION=2025.1.0
# https://www.postgresql.org/support/versioning/ # https://www.postgresql.org/support/versioning/
ARG POSTGRES_VERSION=15 ARG POSTGRES_VERSION=15

View File

@@ -7,4 +7,4 @@ ignore_repeated_source = On
upload_max_filesize = 256M upload_max_filesize = 256M
post_max_size = 256M post_max_size = 256M
memory_limit = ${PHP_MEMORY_LIMIT:-256M} memory_limit = ${PHP_MEMORY_LIMIT:-512M}

View File

@@ -2,9 +2,9 @@
# https://hub.docker.com/r/serversideup/php/tags?name=8.4-fpm-nginx-alpine # https://hub.docker.com/r/serversideup/php/tags?name=8.4-fpm-nginx-alpine
ARG SERVERSIDEUP_PHP_VERSION=8.4-fpm-nginx-alpine ARG SERVERSIDEUP_PHP_VERSION=8.4-fpm-nginx-alpine
# https://github.com/minio/mc/releases # https://github.com/minio/mc/releases
ARG MINIO_VERSION=RELEASE.2024-11-17T19-35-25Z ARG MINIO_VERSION=RELEASE.2024-11-21T17-21-54Z
# https://github.com/cloudflare/cloudflared/releases # https://github.com/cloudflare/cloudflared/releases
ARG CLOUDFLARED_VERSION=2024.11.1 ARG CLOUDFLARED_VERSION=2025.1.0
# https://www.postgresql.org/support/versioning/ # https://www.postgresql.org/support/versioning/
ARG POSTGRES_VERSION=15 ARG POSTGRES_VERSION=15

View File

@@ -7,4 +7,4 @@ ignore_repeated_source = On
upload_max_filesize = 256M upload_max_filesize = 256M
post_max_size = 256M post_max_size = 256M
memory_limit = ${PHP_MEMORY_LIMIT:-256M} memory_limit = ${PHP_MEMORY_LIMIT:-512M}

View File

@@ -1,10 +1,10 @@
# Versions # Versions
# https://download.docker.com/linux/static/stable/ # https://download.docker.com/linux/static/stable/
ARG DOCKER_VERSION=27.3.1 ARG DOCKER_VERSION=27.4.1
# https://github.com/docker/compose/releases # https://github.com/docker/compose/releases
ARG DOCKER_COMPOSE_VERSION=2.30.3 ARG DOCKER_COMPOSE_VERSION=2.32.2
# https://github.com/docker/buildx/releases # https://github.com/docker/buildx/releases
ARG DOCKER_BUILDX_VERSION=0.18.0 ARG DOCKER_BUILDX_VERSION=0.19.3
FROM debian:12-slim FROM debian:12-slim

263
package-lock.json generated
View File

@@ -6,11 +6,11 @@
"": { "": {
"name": "coolify", "name": "coolify",
"dependencies": { "dependencies": {
"@tailwindcss/forms": "0.5.9", "@tailwindcss/forms": "0.5.10",
"@tailwindcss/typography": "0.5.15", "@tailwindcss/typography": "0.5.16",
"@xterm/addon-fit": "^0.10.0", "@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0", "@xterm/xterm": "^5.5.0",
"ioredis": "5.4.1" "ioredis": "5.4.2"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "5.2.1", "@vitejs/plugin-vue": "5.2.1",
@@ -21,8 +21,8 @@
"postcss": "8.4.49", "postcss": "8.4.49",
"pusher-js": "8.4.0-rc2", "pusher-js": "8.4.0-rc2",
"tailwind-scrollbar": "^3.1.0", "tailwind-scrollbar": "^3.1.0",
"tailwindcss": "3.4.16", "tailwindcss": "3.4.17",
"vite": "6.0.3", "vite": "6.0.7",
"vue": "3.5.13" "vue": "3.5.13"
} }
}, },
@@ -88,9 +88,9 @@
} }
}, },
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
"integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -105,9 +105,9 @@
} }
}, },
"node_modules/@esbuild/android-arm": { "node_modules/@esbuild/android-arm": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
"integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -122,9 +122,9 @@
} }
}, },
"node_modules/@esbuild/android-arm64": { "node_modules/@esbuild/android-arm64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
"integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -139,9 +139,9 @@
} }
}, },
"node_modules/@esbuild/android-x64": { "node_modules/@esbuild/android-x64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
"integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -156,9 +156,9 @@
} }
}, },
"node_modules/@esbuild/darwin-arm64": { "node_modules/@esbuild/darwin-arm64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
"integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -173,9 +173,9 @@
} }
}, },
"node_modules/@esbuild/darwin-x64": { "node_modules/@esbuild/darwin-x64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
"integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -190,9 +190,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-arm64": { "node_modules/@esbuild/freebsd-arm64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
"integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -207,9 +207,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-x64": { "node_modules/@esbuild/freebsd-x64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
"integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -224,9 +224,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm": { "node_modules/@esbuild/linux-arm": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
"integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -241,9 +241,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm64": { "node_modules/@esbuild/linux-arm64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
"integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -258,9 +258,9 @@
} }
}, },
"node_modules/@esbuild/linux-ia32": { "node_modules/@esbuild/linux-ia32": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
"integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -275,9 +275,9 @@
} }
}, },
"node_modules/@esbuild/linux-loong64": { "node_modules/@esbuild/linux-loong64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
"integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@@ -292,9 +292,9 @@
} }
}, },
"node_modules/@esbuild/linux-mips64el": { "node_modules/@esbuild/linux-mips64el": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
"integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
"cpu": [ "cpu": [
"mips64el" "mips64el"
], ],
@@ -309,9 +309,9 @@
} }
}, },
"node_modules/@esbuild/linux-ppc64": { "node_modules/@esbuild/linux-ppc64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
"integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -326,9 +326,9 @@
} }
}, },
"node_modules/@esbuild/linux-riscv64": { "node_modules/@esbuild/linux-riscv64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
"integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -343,9 +343,9 @@
} }
}, },
"node_modules/@esbuild/linux-s390x": { "node_modules/@esbuild/linux-s390x": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
"integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -360,9 +360,9 @@
} }
}, },
"node_modules/@esbuild/linux-x64": { "node_modules/@esbuild/linux-x64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
"integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -376,10 +376,27 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
"integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": { "node_modules/@esbuild/netbsd-x64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
"integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -394,9 +411,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-arm64": { "node_modules/@esbuild/openbsd-arm64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
"integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -411,9 +428,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-x64": { "node_modules/@esbuild/openbsd-x64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
"integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -428,9 +445,9 @@
} }
}, },
"node_modules/@esbuild/sunos-x64": { "node_modules/@esbuild/sunos-x64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
"integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -445,9 +462,9 @@
} }
}, },
"node_modules/@esbuild/win32-arm64": { "node_modules/@esbuild/win32-arm64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
"integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -462,9 +479,9 @@
} }
}, },
"node_modules/@esbuild/win32-ia32": { "node_modules/@esbuild/win32-ia32": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
"integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -479,9 +496,9 @@
} }
}, },
"node_modules/@esbuild/win32-x64": { "node_modules/@esbuild/win32-x64": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
"integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -860,21 +877,21 @@
] ]
}, },
"node_modules/@tailwindcss/forms": { "node_modules/@tailwindcss/forms": {
"version": "0.5.9", "version": "0.5.10",
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.9.tgz", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.10.tgz",
"integrity": "sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==", "integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"mini-svg-data-uri": "^1.2.3" "mini-svg-data-uri": "^1.2.3"
}, },
"peerDependencies": { "peerDependencies": {
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20" "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1"
} }
}, },
"node_modules/@tailwindcss/typography": { "node_modules/@tailwindcss/typography": {
"version": "0.5.15", "version": "0.5.16",
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.15.tgz", "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
"integrity": "sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==", "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"lodash.castarray": "^4.4.0", "lodash.castarray": "^4.4.0",
@@ -883,7 +900,7 @@
"postcss-selector-parser": "6.0.10" "postcss-selector-parser": "6.0.10"
}, },
"peerDependencies": { "peerDependencies": {
"tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20" "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
} }
}, },
"node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": {
@@ -1482,9 +1499,9 @@
} }
}, },
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.24.0", "version": "0.24.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
"integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
@@ -1495,30 +1512,31 @@
"node": ">=18" "node": ">=18"
}, },
"optionalDependencies": { "optionalDependencies": {
"@esbuild/aix-ppc64": "0.24.0", "@esbuild/aix-ppc64": "0.24.2",
"@esbuild/android-arm": "0.24.0", "@esbuild/android-arm": "0.24.2",
"@esbuild/android-arm64": "0.24.0", "@esbuild/android-arm64": "0.24.2",
"@esbuild/android-x64": "0.24.0", "@esbuild/android-x64": "0.24.2",
"@esbuild/darwin-arm64": "0.24.0", "@esbuild/darwin-arm64": "0.24.2",
"@esbuild/darwin-x64": "0.24.0", "@esbuild/darwin-x64": "0.24.2",
"@esbuild/freebsd-arm64": "0.24.0", "@esbuild/freebsd-arm64": "0.24.2",
"@esbuild/freebsd-x64": "0.24.0", "@esbuild/freebsd-x64": "0.24.2",
"@esbuild/linux-arm": "0.24.0", "@esbuild/linux-arm": "0.24.2",
"@esbuild/linux-arm64": "0.24.0", "@esbuild/linux-arm64": "0.24.2",
"@esbuild/linux-ia32": "0.24.0", "@esbuild/linux-ia32": "0.24.2",
"@esbuild/linux-loong64": "0.24.0", "@esbuild/linux-loong64": "0.24.2",
"@esbuild/linux-mips64el": "0.24.0", "@esbuild/linux-mips64el": "0.24.2",
"@esbuild/linux-ppc64": "0.24.0", "@esbuild/linux-ppc64": "0.24.2",
"@esbuild/linux-riscv64": "0.24.0", "@esbuild/linux-riscv64": "0.24.2",
"@esbuild/linux-s390x": "0.24.0", "@esbuild/linux-s390x": "0.24.2",
"@esbuild/linux-x64": "0.24.0", "@esbuild/linux-x64": "0.24.2",
"@esbuild/netbsd-x64": "0.24.0", "@esbuild/netbsd-arm64": "0.24.2",
"@esbuild/openbsd-arm64": "0.24.0", "@esbuild/netbsd-x64": "0.24.2",
"@esbuild/openbsd-x64": "0.24.0", "@esbuild/openbsd-arm64": "0.24.2",
"@esbuild/sunos-x64": "0.24.0", "@esbuild/openbsd-x64": "0.24.2",
"@esbuild/win32-arm64": "0.24.0", "@esbuild/sunos-x64": "0.24.2",
"@esbuild/win32-ia32": "0.24.0", "@esbuild/win32-arm64": "0.24.2",
"@esbuild/win32-x64": "0.24.0" "@esbuild/win32-ia32": "0.24.2",
"@esbuild/win32-x64": "0.24.2"
} }
}, },
"node_modules/escalade": { "node_modules/escalade": {
@@ -1720,9 +1738,10 @@
"peer": true "peer": true
}, },
"node_modules/ioredis": { "node_modules/ioredis": {
"version": "5.4.1", "version": "5.4.2",
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz", "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.2.tgz",
"integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==", "integrity": "sha512-0SZXGNGZ+WzISQ67QDyZ2x0+wVxjjUndtD8oSeik/4ajifeiRufed8fCb8QW8VMyi4MXcS+UO1k/0NGhvq1PAg==",
"license": "MIT",
"dependencies": { "dependencies": {
"@ioredis/commands": "^1.1.1", "@ioredis/commands": "^1.1.1",
"cluster-key-slot": "^1.1.0", "cluster-key-slot": "^1.1.0",
@@ -2648,9 +2667,9 @@
} }
}, },
"node_modules/tailwindcss": { "node_modules/tailwindcss": {
"version": "3.4.16", "version": "3.4.17",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.16.tgz", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
"integrity": "sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==", "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@alloc/quick-lru": "^5.2.0", "@alloc/quick-lru": "^5.2.0",
@@ -2765,13 +2784,13 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "6.0.3", "version": "6.0.7",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.0.3.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.7.tgz",
"integrity": "sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==", "integrity": "sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"esbuild": "^0.24.0", "esbuild": "^0.24.2",
"postcss": "^8.4.49", "postcss": "^8.4.49",
"rollup": "^4.23.0" "rollup": "^4.23.0"
}, },

View File

@@ -15,15 +15,15 @@
"postcss": "8.4.49", "postcss": "8.4.49",
"pusher-js": "8.4.0-rc2", "pusher-js": "8.4.0-rc2",
"tailwind-scrollbar": "^3.1.0", "tailwind-scrollbar": "^3.1.0",
"tailwindcss": "3.4.16", "tailwindcss": "3.4.17",
"vite": "6.0.3", "vite": "6.0.7",
"vue": "3.5.13" "vue": "3.5.13"
}, },
"dependencies": { "dependencies": {
"@tailwindcss/forms": "0.5.9", "@tailwindcss/forms": "0.5.10",
"@tailwindcss/typography": "0.5.15", "@tailwindcss/typography": "0.5.16",
"@xterm/addon-fit": "^0.10.0", "@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0", "@xterm/xterm": "^5.5.0",
"ioredis": "5.4.1" "ioredis": "5.4.2"
} }
} }

1
public/js/dropzone.js Normal file

File diff suppressed because one or more lines are too long

BIN
public/svgs/teable.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -35,7 +35,7 @@
</div> </div>
<div class="flex items-center justify-center gap-2 text-xs font-bold"> <div class="flex items-center justify-center gap-2 text-xs font-bold">
@if ($project->environments->first()) @if ($project->environments->first())
<a class="hover:underline" <a class="hover:underline" wire:click.stop
href="{{ route('project.resource.create', [ href="{{ route('project.resource.create', [
'project_uuid' => $project->uuid, 'project_uuid' => $project->uuid,
'environment_uuid' => $project->environments->first()->uuid, 'environment_uuid' => $project->environments->first()->uuid,
@@ -43,7 +43,7 @@
<span class="p-2 font-bold">+ Add Resource</span> <span class="p-2 font-bold">+ Add Resource</span>
</a> </a>
@endif @endif
<a class="hover:underline" <a class="hover:underline" wire:click.stop
href="{{ route('project.edit', ['project_uuid' => $project->uuid]) }}"> href="{{ route('project.edit', ['project_uuid' => $project->uuid]) }}">
Settings Settings
</a> </a>

View File

@@ -1 +1 @@
<x-forms.button wire:click='backup_now'>Backup Now</x-forms.button> <x-forms.button wire:click='backupNow'>Backup Now</x-forms.button>

View File

@@ -20,8 +20,8 @@
href="{{ route('project.database.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}" href="{{ route('project.database.persistent-storage', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>Persistent Storage</a> wire:navigate>Persistent Storage</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.database.import-backups', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}" href="{{ route('project.database.import-backups', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Import
wire:navigate>Import Backups</a> Backups</a>
<a class='menu-item' wire:current.exact="menu-item-active" <a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.database.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}" href="{{ route('project.database.webhooks', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>Webhooks</a> wire:navigate>Webhooks</a>

View File

@@ -1,9 +1,7 @@
<div x-data="{ error: $wire.entangle('error'), filesize: $wire.entangle('filesize'), filename: $wire.entangle('filename'), isUploading: $wire.entangle('isUploading'), progress: $wire.entangle('progress') }"> <div x-data="{ error: $wire.entangle('error'), filesize: $wire.entangle('filesize'), filename: $wire.entangle('filename'), isUploading: $wire.entangle('isUploading'), progress: $wire.entangle('progress') }">
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/dropzone.min.js" <script type="text/javascript" src="{{ URL::asset('js/dropzone.js') }}"></script>
integrity="sha512-U2WE1ktpMTuRBPoCFDzomoIorbOyUv0sP8B+INA3EzNAhehbzED1rOJg6bCqPf/Tuposxb5ja/MAUnC8THSbLQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
@script @script
<script> <script data-navigate-once>
Dropzone.options.myDropzone = { Dropzone.options.myDropzone = {
chunking: true, chunking: true,
method: "POST", method: "POST",
@@ -14,7 +12,7 @@
parallelChunkUploads: false, parallelChunkUploads: false,
init: function() { init: function() {
let button = this.element.querySelector('button'); let button = this.element.querySelector('button');
button.innerText = 'Select or Drop a backup file here' button.innerText = 'Select or drop a backup file here.'
this.on('sending', function(file, xhr, formData) { this.on('sending', function(file, xhr, formData) {
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
formData.append("_token", token); formData.append("_token", token);
@@ -52,28 +50,56 @@
</div> </div>
@if (str(data_get($resource, 'status'))->startsWith('running')) @if (str(data_get($resource, 'status'))->startsWith('running'))
@if ($resource->type() === 'standalone-postgresql') @if ($resource->type() === 'standalone-postgresql')
<x-forms.input class="mb-2" label="Custom Import Command" @if ($dumpAll)
wire:model='postgresqlRestoreCommand'></x-forms.input> <x-forms.textarea rows="6" readonly label="Custom Import Command"
@elseif ($resource->type() === 'standalone-mysql') wire:model='restoreCommandText'></x-forms.textarea>
<x-forms.input class="mb-2" label="Custom Import Command" @else
wire:model='mysqlRestoreCommand'></x-forms.input> <x-forms.input label="Custom Import Command" wire:model='postgresqlRestoreCommand'></x-forms.input>
@elseif ($resource->type() === 'standalone-mariadb')
<x-forms.input class="mb-2" label="Custom Import Command"
wire:model='mariadbRestoreCommand'></x-forms.input>
@endif @endif
<div class="w-48 pt-2">
<x-forms.checkbox label="Includes all databases" wire:model.live='dumpAll'></x-forms.checkbox>
</div>
@elseif ($resource->type() === 'standalone-mysql')
@if ($dumpAll)
<x-forms.textarea rows="14" readonly label="Custom Import Command"
wire:model='restoreCommandText'></x-forms.textarea>
@else
<x-forms.input label="Custom Import Command" wire:model='mysqlRestoreCommand'></x-forms.input>
@endif
<div class="w-48 pt-2">
<x-forms.checkbox label="Includes all databases" wire:model.live='dumpAll'></x-forms.checkbox>
</div>
@elseif ($resource->type() === 'standalone-mariadb')
@if ($dumpAll)
<x-forms.textarea rows="14" readonly label="Custom Import Command"
wire:model='restoreCommandText'></x-forms.textarea>
@else
<x-forms.input label="Custom Import Command" wire:model='mariadbRestoreCommand'></x-forms.input>
@endif
<div class="w-48 pt-2">
<x-forms.checkbox label="Includes all databases" wire:model.live='dumpAll'></x-forms.checkbox>
</div>
@endif
<h3 class="pt-6">Backup File</h3>
<form class="flex gap-2 items-end">
<x-forms.input label="Location of the backup file on the server"
placeholder="e.g. /home/user/backup.sql.gz" wire:model='customLocation'></x-forms.input>
<x-forms.button class="w-full" wire:click='checkFile'>Check File</x-forms.button>
</form>
<div class="pt-2 text-center text-xl font-bold">
Or
</div>
<form action="/upload/backup/{{ $resource->uuid }}" class="dropzone" id="my-dropzone" wire:ignore>
@csrf
</form>
<div x-show="isUploading"> <div x-show="isUploading">
<progress max="100" x-bind:value="progress" class="progress progress-warning"></progress> <progress max="100" x-bind:value="progress" class="progress progress-warning"></progress>
</div> </div>
<h3 class="pt-6" x-show="filename && !error">File Information</h3>
<div x-show="filename && !error"> <div x-show="filename && !error">
<div>File: <span x-text="filename ?? 'N/A'"></span> <span x-text="filesize">/ </span></div> <div>Location: <span x-text="filename ?? 'N/A'"></span> <span x-text="filesize">/ </span></div>
<x-forms.button class="w-full my-4" wire:click='runImport'>Restore Backup</x-forms.button> <x-forms.button class="w-full my-4" wire:click='runImport'>Restore Backup</x-forms.button>
</div> </div>
<form action="/upload/backup/{{ $resource->uuid }}" class="dropzone" id="my-dropzone">
@csrf
</form>
<div class="container w-full mx-auto"> <div class="container w-full mx-auto">
<livewire:activity-monitor header="Database Restore Output" /> <livewire:activity-monitor header="Database Restore Output" />
</div> </div>

View File

@@ -216,6 +216,12 @@
<h2>Select a server</h2> <h2>Select a server</h2>
<div class="pb-5"></div> <div class="pb-5"></div>
<div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap"> <div class="flex flex-col justify-center gap-4 text-left xl:flex-row xl:flex-wrap">
@if ($onlyBuildServerAvailable)
<div> Only build servers are available, you need at least one server that is not set as build
server. <a class="underline dark:text-white" href="/servers">
Go to servers page
</a> </div>
@else
@forelse($servers as $server) @forelse($servers as $server)
<div class="w-full box group" wire:click="setServer({{ $server }})"> <div class="w-full box group" wire:click="setServer({{ $server }})">
<div class="flex flex-col mx-6"> <div class="flex flex-col mx-6">
@@ -228,16 +234,15 @@
</div> </div>
@empty @empty
<div> <div>
<div>No validated & reachable servers found. <a class="underline dark:text-white" href="/servers">
<div>No validated & reachable servers found. <a class="underline dark:text-white"
href="/servers">
Go to servers page Go to servers page
</a></div> </a></div>
</div> </div>
@endforelse @endforelse
@endif
</div> </div>
{{-- @if ($isDatabase)
<div class="text-center">Swarm clusters are excluded from this type of resource at the moment. It will
be activated soon. Stay tuned.</div>
@endif --}}
@endif @endif
@if ($current_step === 'destinations') @if ($current_step === 'destinations')
<h2>Select a destination</h2> <h2>Select a destination</h2>

View File

@@ -130,38 +130,23 @@
</div> </div>
<h4 class="py-4">Confirmation Settings</h4> <h4 class="py-4">Confirmation Settings</h4>
<div x-data="{ open: false }" class="mb-32 md:w-[40rem]">
<button type="button" @click.prevent="open = !open"
class="flex items-center justify-between w-full p-4 rounded-md
dark:bg-coolgray-100 dark:hover:bg-coolgray-200
bg-gray-100 hover:bg-gray-200">
<span class="font-medium">Two-Step Confirmation Settings</span>
<svg class="w-5 h-5 transition-transform" :class="{ 'rotate-180': open }" fill="none"
stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div x-show="open" x-transition class="mt-4">
@if ($disable_two_step_confirmation) @if ($disable_two_step_confirmation)
<div class="md:w-96 pb-4"> <div class="md:w-96 pb-4">
<x-forms.checkbox instantSave id="disable_two_step_confirmation" <x-forms.checkbox instantSave id="disable_two_step_confirmation" label="Disable Two Step Confirmation"
label="Disable Two Step Confirmation"
helper="When disabled, you will not need to confirm actions with a text and user password. This significantly reduces security and may lead to accidental deletions or unwanted changes. Use with extreme caution, especially on production servers." /> helper="When disabled, you will not need to confirm actions with a text and user password. This significantly reduces security and may lead to accidental deletions or unwanted changes. Use with extreme caution, especially on production servers." />
</div> </div>
@else @else
<div class="md:w-96 pb-4"> <div class="md:w-96 pb-4">
<x-modal-confirmation title="Disable Two Step Confirmation?" <x-modal-confirmation title="Disable Two Step Confirmation?"
buttonTitle="Disable Two Step Confirmation" isErrorButton buttonTitle="Disable Two Step Confirmation" isErrorButton submitAction="toggleTwoStepConfirmation"
submitAction="toggleTwoStepConfirmation" :actions="[ :actions="[
'Two Step confimation will be disabled globally.', 'Two Step confimation will be disabled globally.',
'Disabling two step confirmation reduces security (as anyone can easily delete anything).', 'Disabling two step confirmation reduces security (as anyone can easily delete anything).',
'The risk of accidental actions will increase.', 'The risk of accidental actions will increase.',
]" ]" confirmationText="DISABLE TWO STEP CONFIRMATION"
confirmationText="DISABLE TWO STEP CONFIRMATION"
confirmationLabel="Please type the confirmation text to disable two step confirmation." confirmationLabel="Please type the confirmation text to disable two step confirmation."
shortConfirmationLabel="Confirmation text" shortConfirmationLabel="Confirmation text" step3ButtonText="Disable Two Step Confirmation" />
step3ButtonText="Disable Two Step Confirmation" />
</div> </div>
<div class="w-full px-4 py-2 mb-4 text-white rounded-sm border-l-4 border-red-500 bg-error"> <div class="w-full px-4 py-2 mb-4 text-white rounded-sm border-l-4 border-red-500 bg-error">
<p class="font-bold">Warning!</p> <p class="font-bold">Warning!</p>
@@ -170,7 +155,5 @@
the risk of accidental actions. This is not recommended for production servers.</p> the risk of accidental actions. This is not recommended for production servers.</p>
</div> </div>
@endif @endif
</div>
</div>
</form> </form>
</div> </div>

View File

@@ -542,7 +542,7 @@ echo -e "You can access Coolify through your Public IP: http://$(curl -4s https:
set +e set +e
DEFAULT_PRIVATE_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p') DEFAULT_PRIVATE_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
PRIVATE_IPS=$(hostname -I) PRIVATE_IPS=$(hostname -I 2>/dev/null || ip -o addr show scope global | awk '{print $4}' | cut -d/ -f1)
set -e set -e
if [ -n "$PRIVATE_IPS" ]; then if [ -n "$PRIVATE_IPS" ]; then

View File

@@ -12,6 +12,8 @@ services:
condition: service_healthy condition: service_healthy
environment: environment:
- SERVICE_FQDN_LABELSTUDIO_8080 - SERVICE_FQDN_LABELSTUDIO_8080
- CSRF_TRUSTED_ORIGINS=${SERVICE_FQDN_LABELSTUDIO}
- EXPERIMENTAL_FEATURES=${EXPERIMENTAL_FEATURES:-false}
- DJANGO_DB=${DJANGO_DB:-default} - DJANGO_DB=${DJANGO_DB:-default}
- POSTGRE_NAME=${POSTGRES_DB:-labelstudio} - POSTGRE_NAME=${POSTGRES_DB:-labelstudio}
- POSTGRE_USER=${SERVICE_USER_POSTGRES} - POSTGRE_USER=${SERVICE_USER_POSTGRES}

View File

@@ -15,6 +15,7 @@ services:
condition: service_healthy condition: service_healthy
environment: environment:
- SERVICE_FQDN_SUPABASEKONG_8000 - SERVICE_FQDN_SUPABASEKONG_8000
- KONG_PORT_MAPS=443:8000
- JWT_SECRET=${SERVICE_PASSWORD_JWT} - JWT_SECRET=${SERVICE_PASSWORD_JWT}
- KONG_DATABASE=off - KONG_DATABASE=off
- KONG_DECLARATIVE_CONFIG=/home/kong/kong.yml - KONG_DECLARATIVE_CONFIG=/home/kong/kong.yml
@@ -278,7 +279,7 @@ services:
config: config:
hide_credentials: true hide_credentials: true
supabase-studio: supabase-studio:
image: supabase/studio:20240923-2e3e90c image: supabase/studio:20241202-71e5240
healthcheck: healthcheck:
test: test:
[ [
@@ -317,7 +318,7 @@ services:
# NEXT_ANALYTICS_BACKEND_PROVIDER=bigquery # NEXT_ANALYTICS_BACKEND_PROVIDER=bigquery
- 'OPENAI_API_KEY=${OPENAI_API_KEY}' - 'OPENAI_API_KEY=${OPENAI_API_KEY}'
supabase-db: supabase-db:
image: supabase/postgres:15.1.1.78 image: supabase/postgres:15.6.1.146
healthcheck: healthcheck:
test: pg_isready -U postgres -h 127.0.0.1 test: pg_isready -U postgres -h 127.0.0.1
interval: 5s interval: 5s
@@ -367,6 +368,7 @@ services:
\c _supabase \c _supabase
create schema if not exists _supavisor; create schema if not exists _supavisor;
alter schema _supavisor owner to :pguser; alter schema _supavisor owner to :pguser;
\c postgres
- type: bind - type: bind
source: ./volumes/db/webhooks.sql source: ./volumes/db/webhooks.sql
target: /docker-entrypoint-initdb.d/init-scripts/98-webhooks.sql target: /docker-entrypoint-initdb.d/init-scripts/98-webhooks.sql
@@ -610,6 +612,7 @@ services:
\c _supabase \c _supabase
create schema if not exists _analytics; create schema if not exists _analytics;
alter schema _analytics owner to :pguser; alter schema _analytics owner to :pguser;
\c postgres
# Use named volume to persist pgsodium decryption key between restarts # Use named volume to persist pgsodium decryption key between restarts
- supabase-db-config:/etc/postgresql-custom - supabase-db-config:/etc/postgresql-custom
@@ -928,7 +931,7 @@ services:
command: "postgrest" command: "postgrest"
exclude_from_hc: true exclude_from_hc: true
supabase-auth: supabase-auth:
image: supabase/gotrue:v2.158.1 image: supabase/gotrue:v2.164.0
depends_on: depends_on:
supabase-db: supabase-db:
# Disable this if you are using an external Postgres database # Disable this if you are using an external Postgres database
@@ -1019,7 +1022,7 @@ services:
realtime-dev: realtime-dev:
# This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain # This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain
image: supabase/realtime:v2.30.34 image: supabase/realtime:v2.33.70
container_name: realtime-dev.supabase-realtime container_name: realtime-dev.supabase-realtime
depends_on: depends_on:
supabase-db: supabase-db:
@@ -1062,6 +1065,9 @@ services:
- RLIMIT_NOFILE=10000 - RLIMIT_NOFILE=10000
- APP_NAME=realtime - APP_NAME=realtime
- SEED_SELF_HOST=true - SEED_SELF_HOST=true
- LOG_LEVEL=error
- RUN_JANITOR=true
- JANITOR_INTERVAL=60000
command: > command: >
sh -c "/app/bin/migrate && /app/bin/realtime eval 'Realtime.Release.seeds(Realtime.Repo)' && /app/bin/server" sh -c "/app/bin/migrate && /app/bin/realtime eval 'Realtime.Release.seeds(Realtime.Repo)' && /app/bin/server"
supabase-minio: supabase-minio:
@@ -1099,7 +1105,7 @@ services:
exit 0 exit 0
supabase-storage: supabase-storage:
image: supabase/storage-api:v1.10.1 image: supabase/storage-api:v1.14.6
depends_on: depends_on:
supabase-db: supabase-db:
# Disable this if you are using an external Postgres database # Disable this if you are using an external Postgres database
@@ -1138,12 +1144,14 @@ services:
- UPLOAD_FILE_SIZE_LIMIT=524288000 - UPLOAD_FILE_SIZE_LIMIT=524288000
- UPLOAD_FILE_SIZE_LIMIT_STANDARD=524288000 - UPLOAD_FILE_SIZE_LIMIT_STANDARD=524288000
- UPLOAD_SIGNED_URL_EXPIRATION_TIME=120 - UPLOAD_SIGNED_URL_EXPIRATION_TIME=120
- TUS_URL_PATH=/upload/resumable - TUS_URL_PATH=upload/resumable
- TUS_MAX_SIZE=3600000 - TUS_MAX_SIZE=3600000
- ENABLE_IMAGE_TRANSFORMATION=true - ENABLE_IMAGE_TRANSFORMATION=true
- IMGPROXY_URL=http://imgproxy:8080 - IMGPROXY_URL=http://imgproxy:8080
- IMGPROXY_REQUEST_TIMEOUT=15 - IMGPROXY_REQUEST_TIMEOUT=15
- DATABASE_SEARCH_PATH=storage - DATABASE_SEARCH_PATH=storage
- NODE_ENV=production
- REQUEST_ALLOW_X_FORWARDED_PATH=true
# - ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzA4OTg4NDAwLAogICJleHAiOiAxODY2ODQxMjAwCn0.jCDqsoXGT58JnAjf27KOowNQsokkk0aR7rdbGG18P-8 # - ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzA4OTg4NDAwLAogICJleHAiOiAxODY2ODQxMjAwCn0.jCDqsoXGT58JnAjf27KOowNQsokkk0aR7rdbGG18P-8
# - SERVICE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogInNlcnZpY2Vfcm9sZSIsCiAgImlzcyI6ICJzdXBhYmFzZSIsCiAgImlhdCI6IDE3MDg5ODg0MDAsCiAgImV4cCI6IDE4NjY4NDEyMDAKfQ.GA7yF2BmqTzqGkP_oqDdJAQVt0djjIxGYuhE0zFDJV4 # - SERVICE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogInNlcnZpY2Vfcm9sZSIsCiAgImlzcyI6ICJzdXBhYmFzZSIsCiAgImlhdCI6IDE3MDg5ODg0MDAsCiAgImV4cCI6IDE4NjY4NDEyMDAKfQ.GA7yF2BmqTzqGkP_oqDdJAQVt0djjIxGYuhE0zFDJV4
@@ -1183,7 +1191,7 @@ services:
- ./volumes/storage:/var/lib/storage - ./volumes/storage:/var/lib/storage
supabase-meta: supabase-meta:
image: supabase/postgres-meta:v0.83.2 image: supabase/postgres-meta:v0.84.2
depends_on: depends_on:
supabase-db: supabase-db:
# Disable this if you are using an external Postgres database # Disable this if you are using an external Postgres database
@@ -1199,7 +1207,7 @@ services:
- PG_META_DB_PASSWORD=${SERVICE_PASSWORD_POSTGRES} - PG_META_DB_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
supabase-edge-functions: supabase-edge-functions:
image: supabase/edge-runtime:v1.58.3 image: supabase/edge-runtime:v1.65.3
depends_on: depends_on:
supabase-analytics: supabase-analytics:
condition: service_healthy condition: service_healthy

View File

@@ -0,0 +1,88 @@
# documentation: https://help.teable.io/
# slogan: Teable is a powerful visual interface built on relational databases (PostgreSQL).
# tags: airtable, teable, database, visual, interface, relational, postgresql
# logo: svgs/teable.png
# port: 3000
services:
teable:
image: ghcr.io/teableio/teable:latest
volumes:
- teable_data:/app/.assets:rw
environment:
- SERVICE_FQDN_TEABLE_3000
- PUBLIC_ORIGIN=${SERVICE_FQDN_TEABLE}
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
- SECRET_KEY=${SERVICE_PASSWORD_64_SECRET}
- TZ=${TIMEZONE}
- PRISMA_DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@teable-db:${POSTGRES_PORT}/${POSTGRES_DB}
- NEXT_ENV_IMAGES_ALL_REMOTE=true
- PORT=3000
- REDIS_PASSWORD=${SERVICE_PASSWORD_REDIS}
- BACKEND_CACHE_PROVIDER=redis
- BACKEND_CACHE_REDIS_URI=redis://default:${SERVICE_PASSWORD_REDIS}@teable-cache:6379/0
- BACKEND_MAIL_HOST=${BACKEND_MAIL_HOST}
- BACKEND_MAIL_PORT=${BACKEND_MAIL_PORT}
- BACKEND_MAIL_SECURE=${BACKEND_MAIL_SECURE}
- BACKEND_MAIL_SENDER=${BACKEND_MAIL_SENDER}
- BACKEND_MAIL_SENDER_NAME=${BACKEND_MAIL_SENDER_NAME}
- BACKEND_MAIL_AUTH_USER=${BACKEND_MAIL_AUTH_USER}
- BACKEND_MAIL_AUTH_PASS=${BACKEND_MAIL_AUTH_PASS}
depends_on:
teable-cache:
condition: service_healthy
healthcheck:
test:
- CMD
- curl
- '-f'
- 'http://127.0.0.1:3000'
interval: 5s
timeout: 20s
retries: 10
teable-db:
image: postgres:15.4
volumes:
- teable_db_data:/var/lib/postgresql/data:rw
environment:
- TZ=${TIMEZONE}
- POSTGRES_DB=${POSTGRES_DB:-teable}
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
- POSTGRES_USER=${SERVICE_USER_POSTGRES}
- POSTGRES_PORT=${POSTGRES_PORT:-5432}
healthcheck:
test:
- CMD-SHELL
- 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}'
interval: 5s
timeout: 20s
retries: 10
teable-db-migrate:
image: ghcr.io/teableio/teable-db-migrate:latest
restart: no
environment:
- TZ=${TIMEZONE}
- PRISMA_DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@teable-db:${POSTGRES_PORT}/${POSTGRES_DB}
depends_on:
teable-db:
condition: service_healthy
teable-cache:
image: redis:7.2.4
environment:
- REDIS_PORT=6379
- REDIS_DB=0
- REDIS_PASSWORD=${SERVICE_PASSWORD_REDIS}
volumes:
- teable_cache_data:/data:rw
command: redis-server --appendonly yes --requirepass ${SERVICE_PASSWORD_REDIS}
healthcheck:
test:
- CMD
- redis-cli
- '--raw'
- incr
- ping
interval: 10s
timeout: 3s
retries: 3

View File

@@ -23,6 +23,12 @@ services:
- RESEND_API_KEY=${RESEND_API_KEY} - RESEND_API_KEY=${RESEND_API_KEY}
- FROM_EMAIL=${FROM_EMAIL} - FROM_EMAIL=${FROM_EMAIL}
- REPLY_TO_EMAIL=${REPLY_TO_EMAIL} - REPLY_TO_EMAIL=${REPLY_TO_EMAIL}
- REDIS_HOST=${REDIS_HOST}
- REDIS_PORT=${REDIS_PORT}
- REDIS_USERNAME=${REDIS_USERNAME}
- REDIS_PASSWORD=${REDIS_PASSWORD}
- REDIS_TLS_DISABLED=${REDIS_TLS_DISABLED:-true}
healthcheck: healthcheck:
test: "timeout 10s bash -c ':> /dev/tcp/127.0.0.1/3000' || exit 1" test: "timeout 10s bash -c ':> /dev/tcp/127.0.0.1/3000' || exit 1"
interval: 10s interval: 10s

File diff suppressed because one or more lines are too long