@@ -744,8 +744,10 @@ class ApplicationsController extends Controller
|
|||||||
$application->destination_id = $destination->id;
|
$application->destination_id = $destination->id;
|
||||||
$application->destination_type = $destination->getMorphClass();
|
$application->destination_type = $destination->getMorphClass();
|
||||||
$application->environment_id = $environment->id;
|
$application->environment_id = $environment->id;
|
||||||
|
if (isset($useBuildServer)) {
|
||||||
$application->settings->is_build_server_enabled = $useBuildServer;
|
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
|
}
|
||||||
$application->save();
|
$application->save();
|
||||||
$application->refresh();
|
$application->refresh();
|
||||||
if (! $application->settings->is_container_label_readonly_enabled) {
|
if (! $application->settings->is_container_label_readonly_enabled) {
|
||||||
@@ -842,8 +844,10 @@ class ApplicationsController extends Controller
|
|||||||
$application->environment_id = $environment->id;
|
$application->environment_id = $environment->id;
|
||||||
$application->source_type = $githubApp->getMorphClass();
|
$application->source_type = $githubApp->getMorphClass();
|
||||||
$application->source_id = $githubApp->id;
|
$application->source_id = $githubApp->id;
|
||||||
|
if (isset($useBuildServer)) {
|
||||||
$application->settings->is_build_server_enabled = $useBuildServer;
|
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
|
}
|
||||||
$application->save();
|
$application->save();
|
||||||
$application->refresh();
|
$application->refresh();
|
||||||
if (! $application->settings->is_container_label_readonly_enabled) {
|
if (! $application->settings->is_container_label_readonly_enabled) {
|
||||||
@@ -936,8 +940,10 @@ class ApplicationsController extends Controller
|
|||||||
$application->destination_id = $destination->id;
|
$application->destination_id = $destination->id;
|
||||||
$application->destination_type = $destination->getMorphClass();
|
$application->destination_type = $destination->getMorphClass();
|
||||||
$application->environment_id = $environment->id;
|
$application->environment_id = $environment->id;
|
||||||
|
if (isset($useBuildServer)) {
|
||||||
$application->settings->is_build_server_enabled = $useBuildServer;
|
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
|
}
|
||||||
$application->save();
|
$application->save();
|
||||||
$application->refresh();
|
$application->refresh();
|
||||||
if (! $application->settings->is_container_label_readonly_enabled) {
|
if (! $application->settings->is_container_label_readonly_enabled) {
|
||||||
@@ -1017,8 +1023,10 @@ class ApplicationsController extends Controller
|
|||||||
$application->destination_id = $destination->id;
|
$application->destination_id = $destination->id;
|
||||||
$application->destination_type = $destination->getMorphClass();
|
$application->destination_type = $destination->getMorphClass();
|
||||||
$application->environment_id = $environment->id;
|
$application->environment_id = $environment->id;
|
||||||
|
if (isset($useBuildServer)) {
|
||||||
$application->settings->is_build_server_enabled = $useBuildServer;
|
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
|
}
|
||||||
|
|
||||||
$application->git_repository = 'coollabsio/coolify';
|
$application->git_repository = 'coollabsio/coolify';
|
||||||
$application->git_branch = 'main';
|
$application->git_branch = 'main';
|
||||||
@@ -1077,8 +1085,10 @@ class ApplicationsController extends Controller
|
|||||||
$application->destination_id = $destination->id;
|
$application->destination_id = $destination->id;
|
||||||
$application->destination_type = $destination->getMorphClass();
|
$application->destination_type = $destination->getMorphClass();
|
||||||
$application->environment_id = $environment->id;
|
$application->environment_id = $environment->id;
|
||||||
|
if (isset($useBuildServer)) {
|
||||||
$application->settings->is_build_server_enabled = $useBuildServer;
|
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
|
}
|
||||||
|
|
||||||
$application->git_repository = 'coollabsio/coolify';
|
$application->git_repository = 'coollabsio/coolify';
|
||||||
$application->git_branch = 'main';
|
$application->git_branch = 'main';
|
||||||
@@ -1555,8 +1565,11 @@ class ApplicationsController extends Controller
|
|||||||
$instantDeploy = $request->instant_deploy;
|
$instantDeploy = $request->instant_deploy;
|
||||||
|
|
||||||
$use_build_server = $request->use_build_server;
|
$use_build_server = $request->use_build_server;
|
||||||
|
|
||||||
|
if (isset($use_build_server)) {
|
||||||
$application->settings->is_build_server_enabled = $use_build_server;
|
$application->settings->is_build_server_enabled = $use_build_server;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
|
}
|
||||||
|
|
||||||
removeUnnecessaryFieldsFromRequest($request);
|
removeUnnecessaryFieldsFromRequest($request);
|
||||||
|
|
||||||
|
|||||||
@@ -243,6 +243,9 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
try {
|
try {
|
||||||
if (str($databaseType)->contains('postgres')) {
|
if (str($databaseType)->contains('postgres')) {
|
||||||
$this->backup_file = "/pg-dump-$database-".Carbon::now()->timestamp.'.dmp';
|
$this->backup_file = "/pg-dump-$database-".Carbon::now()->timestamp.'.dmp';
|
||||||
|
if ($this->backup->dump_all) {
|
||||||
|
$this->backup_file = '/pg-dump-all-'.Carbon::now()->timestamp.'.gz';
|
||||||
|
}
|
||||||
$this->backup_location = $this->backup_dir.$this->backup_file;
|
$this->backup_location = $this->backup_dir.$this->backup_file;
|
||||||
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
||||||
'database_name' => $database,
|
'database_name' => $database,
|
||||||
@@ -271,6 +274,9 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
$this->backup_standalone_mongodb($database);
|
$this->backup_standalone_mongodb($database);
|
||||||
} elseif (str($databaseType)->contains('mysql')) {
|
} elseif (str($databaseType)->contains('mysql')) {
|
||||||
$this->backup_file = "/mysql-dump-$database-".Carbon::now()->timestamp.'.dmp';
|
$this->backup_file = "/mysql-dump-$database-".Carbon::now()->timestamp.'.dmp';
|
||||||
|
if ($this->backup->dump_all) {
|
||||||
|
$this->backup_file = '/mysql-dump-all-'.Carbon::now()->timestamp.'.gz';
|
||||||
|
}
|
||||||
$this->backup_location = $this->backup_dir.$this->backup_file;
|
$this->backup_location = $this->backup_dir.$this->backup_file;
|
||||||
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
||||||
'database_name' => $database,
|
'database_name' => $database,
|
||||||
@@ -280,6 +286,9 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
$this->backup_standalone_mysql($database);
|
$this->backup_standalone_mysql($database);
|
||||||
} elseif (str($databaseType)->contains('mariadb')) {
|
} elseif (str($databaseType)->contains('mariadb')) {
|
||||||
$this->backup_file = "/mariadb-dump-$database-".Carbon::now()->timestamp.'.dmp';
|
$this->backup_file = "/mariadb-dump-$database-".Carbon::now()->timestamp.'.dmp';
|
||||||
|
if ($this->backup->dump_all) {
|
||||||
|
$this->backup_file = '/mariadb-dump-all-'.Carbon::now()->timestamp.'.gz';
|
||||||
|
}
|
||||||
$this->backup_location = $this->backup_dir.$this->backup_file;
|
$this->backup_location = $this->backup_dir.$this->backup_file;
|
||||||
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
$this->backup_log = ScheduledDatabaseBackupExecution::create([
|
||||||
'database_name' => $database,
|
'database_name' => $database,
|
||||||
@@ -379,7 +388,11 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
if ($this->postgres_password) {
|
if ($this->postgres_password) {
|
||||||
$backupCommand .= " -e PGPASSWORD=$this->postgres_password";
|
$backupCommand .= " -e PGPASSWORD=$this->postgres_password";
|
||||||
}
|
}
|
||||||
|
if ($this->backup->dump_all) {
|
||||||
|
$backupCommand .= " $this->container_name pg_dumpall --username {$this->database->postgres_user} | gzip > $this->backup_location";
|
||||||
|
} else {
|
||||||
$backupCommand .= " $this->container_name pg_dump --format=custom --no-acl --no-owner --username {$this->database->postgres_user} $database > $this->backup_location";
|
$backupCommand .= " $this->container_name pg_dump --format=custom --no-acl --no-owner --username {$this->database->postgres_user} $database > $this->backup_location";
|
||||||
|
}
|
||||||
|
|
||||||
$commands[] = $backupCommand;
|
$commands[] = $backupCommand;
|
||||||
ray($commands);
|
ray($commands);
|
||||||
@@ -400,8 +413,11 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$commands[] = 'mkdir -p '.$this->backup_dir;
|
$commands[] = 'mkdir -p '.$this->backup_dir;
|
||||||
|
if ($this->backup->dump_all) {
|
||||||
|
$commands[] = "docker exec $this->container_name mysqldump -u root -p{$this->database->mysql_root_password} --all-databases --single-transaction --quick --lock-tables=false --compress | gzip > $this->backup_location";
|
||||||
|
} else {
|
||||||
$commands[] = "docker exec $this->container_name mysqldump -u root -p{$this->database->mysql_root_password} $database > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mysqldump -u root -p{$this->database->mysql_root_password} $database > $this->backup_location";
|
||||||
ray($commands);
|
}
|
||||||
$this->backup_output = instant_remote_process($commands, $this->server);
|
$this->backup_output = instant_remote_process($commands, $this->server);
|
||||||
$this->backup_output = trim($this->backup_output);
|
$this->backup_output = trim($this->backup_output);
|
||||||
if ($this->backup_output === '') {
|
if ($this->backup_output === '') {
|
||||||
@@ -419,7 +435,11 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$commands[] = 'mkdir -p '.$this->backup_dir;
|
$commands[] = 'mkdir -p '.$this->backup_dir;
|
||||||
|
if ($this->backup->dump_all) {
|
||||||
|
$commands[] = "docker exec $this->container_name mariadb-dump -u root -p{$this->database->mariadb_root_password} --all-databases --single-transaction --quick --lock-tables=false --compress > $this->backup_location";
|
||||||
|
} else {
|
||||||
$commands[] = "docker exec $this->container_name mariadb-dump -u root -p{$this->database->mariadb_root_password} $database > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mariadb-dump -u root -p{$this->database->mariadb_root_password} $database > $this->backup_location";
|
||||||
|
}
|
||||||
ray($commands);
|
ray($commands);
|
||||||
$this->backup_output = instant_remote_process($commands, $this->server);
|
$this->backup_output = instant_remote_process($commands, $this->server);
|
||||||
$this->backup_output = trim($this->backup_output);
|
$this->backup_output = trim($this->backup_output);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ class BackupEdit extends Component
|
|||||||
'backup.save_s3' => 'required|boolean',
|
'backup.save_s3' => 'required|boolean',
|
||||||
'backup.s3_storage_id' => 'nullable|integer',
|
'backup.s3_storage_id' => 'nullable|integer',
|
||||||
'backup.databases_to_backup' => 'nullable',
|
'backup.databases_to_backup' => 'nullable',
|
||||||
|
'backup.dump_all' => 'required|boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
@@ -40,6 +41,7 @@ class BackupEdit extends Component
|
|||||||
'backup.save_s3' => 'Save to S3',
|
'backup.save_s3' => 'Save to S3',
|
||||||
'backup.s3_storage_id' => 'S3 Storage',
|
'backup.s3_storage_id' => 'S3 Storage',
|
||||||
'backup.databases_to_backup' => 'Databases to Backup',
|
'backup.databases_to_backup' => 'Databases to Backup',
|
||||||
|
'backup.dump_all' => 'Backup All Databases',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $messages = [
|
protected $messages = [
|
||||||
|
|||||||
@@ -108,6 +108,21 @@ class Navbar extends Component
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
StopService::run(service: $this->service, dockerCleanup: false);
|
||||||
|
$this->service->parse();
|
||||||
|
$this->dispatch('imagePulled');
|
||||||
|
$activity = StartService::run($this->service);
|
||||||
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pullAndRestartEvent()
|
||||||
|
{
|
||||||
|
$this->checkDeployments();
|
||||||
|
if ($this->isDeploymentProgress) {
|
||||||
|
$this->dispatch('error', 'There is a deployment in progress.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
PullImage::run($this->service);
|
PullImage::run($this->service);
|
||||||
StopService::run(service: $this->service, dockerCleanup: false);
|
StopService::run(service: $this->service, dockerCleanup: false);
|
||||||
$this->service->parse();
|
$this->service->parse();
|
||||||
|
|||||||
@@ -770,9 +770,34 @@ class Service extends BaseModel
|
|||||||
}
|
}
|
||||||
$fields->put('Code Server', $data->toArray());
|
$fields->put('Code Server', $data->toArray());
|
||||||
break;
|
break;
|
||||||
|
case str($image)->contains('elestio/strapi'):
|
||||||
|
$data = collect([]);
|
||||||
|
$license = $this->environment_variables()->where('key', 'STRAPI_LICENSE')->first();
|
||||||
|
if ($license) {
|
||||||
|
$data = $data->merge([
|
||||||
|
'License' => [
|
||||||
|
'key' => data_get($license, 'key'),
|
||||||
|
'value' => data_get($license, 'value'),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$nodeEnv = $this->environment_variables()->where('key', 'NODE_ENV')->first();
|
||||||
|
if ($nodeEnv) {
|
||||||
|
$data = $data->merge([
|
||||||
|
'Node Environment' => [
|
||||||
|
'key' => data_get($nodeEnv, 'key'),
|
||||||
|
'value' => data_get($nodeEnv, 'value'),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields->put('Strapi', $data->toArray());
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$databases = $this->databases()->get();
|
$databases = $this->databases()->get();
|
||||||
|
ray($databases);
|
||||||
|
|
||||||
foreach ($databases as $database) {
|
foreach ($databases as $database) {
|
||||||
$image = str($database->image)->before(':')->value();
|
$image = str($database->image)->before(':')->value();
|
||||||
@@ -1108,7 +1133,6 @@ class Service extends BaseModel
|
|||||||
$real_value = escapeEnvVariables($env->real_value);
|
$real_value = escapeEnvVariables($env->real_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ray("echo \"{$env->key}={$real_value}\" >> .env");
|
|
||||||
$commands[] = "echo \"{$env->key}={$real_value}\" >> .env";
|
$commands[] = "echo \"{$env->key}={$real_value}\" >> .env";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,4 +115,12 @@ class ServiceDatabase extends BaseModel
|
|||||||
{
|
{
|
||||||
return $this->morphMany(ScheduledDatabaseBackup::class, 'database');
|
return $this->morphMany(ScheduledDatabaseBackup::class, 'database');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isBackupSolutionAvailable()
|
||||||
|
{
|
||||||
|
return str($this->databaseType())->contains('mysql') ||
|
||||||
|
str($this->databaseType())->contains('postgres') ||
|
||||||
|
str($this->databaseType())->contains('mariadb') ||
|
||||||
|
str($this->databaseType())->contains('mongodb');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,4 +294,9 @@ class StandaloneClickhouse extends BaseModel
|
|||||||
return $parsedCollection->toArray();
|
return $parsedCollection->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isBackupSolutionAvailable()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,4 +294,9 @@ class StandaloneDragonfly extends BaseModel
|
|||||||
return $parsedCollection->toArray();
|
return $parsedCollection->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isBackupSolutionAvailable()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,4 +294,9 @@ class StandaloneKeydb extends BaseModel
|
|||||||
return $parsedCollection->toArray();
|
return $parsedCollection->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isBackupSolutionAvailable()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,4 +294,9 @@ class StandaloneMariadb extends BaseModel
|
|||||||
return $parsedCollection->toArray();
|
return $parsedCollection->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isBackupSolutionAvailable()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,4 +314,9 @@ class StandaloneMongodb extends BaseModel
|
|||||||
return $parsedCollection->toArray();
|
return $parsedCollection->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isBackupSolutionAvailable()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -295,4 +295,9 @@ class StandaloneMysql extends BaseModel
|
|||||||
return $parsedCollection->toArray();
|
return $parsedCollection->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isBackupSolutionAvailable()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -296,4 +296,9 @@ class StandalonePostgresql extends BaseModel
|
|||||||
return $parsedCollection->toArray();
|
return $parsedCollection->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isBackupSolutionAvailable()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -290,4 +290,9 @@ class StandaloneRedis extends BaseModel
|
|||||||
return $parsedCollection->toArray();
|
return $parsedCollection->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isBackupSolutionAvailable()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ const DATABASE_DOCKER_IMAGES = [
|
|||||||
'influxdb',
|
'influxdb',
|
||||||
'clickhouse/clickhouse-server',
|
'clickhouse/clickhouse-server',
|
||||||
'supabase/postgres',
|
'supabase/postgres',
|
||||||
|
'elestio/postgres',
|
||||||
];
|
];
|
||||||
const SPECIFIC_SERVICES = [
|
const SPECIFIC_SERVICES = [
|
||||||
'quay.io/minio/minio',
|
'quay.io/minio/minio',
|
||||||
|
|||||||
@@ -708,10 +708,12 @@ function getTopLevelNetworks(Service|Application $resource)
|
|||||||
return $value == $networkName || $key == $networkName;
|
return $value == $networkName || $key == $networkName;
|
||||||
});
|
});
|
||||||
if (! $networkExists) {
|
if (! $networkExists) {
|
||||||
|
if (is_string($networkDetails) || is_int($networkDetails)) {
|
||||||
$topLevelNetworks->put($networkDetails, null);
|
$topLevelNetworks->put($networkDetails, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) {
|
$definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) {
|
||||||
return $value == $definedNetwork;
|
return $value == $definedNetwork;
|
||||||
@@ -758,10 +760,12 @@ function getTopLevelNetworks(Service|Application $resource)
|
|||||||
return $value == $networkName || $key == $networkName;
|
return $value == $networkName || $key == $networkName;
|
||||||
});
|
});
|
||||||
if (! $networkExists) {
|
if (! $networkExists) {
|
||||||
|
if (is_string($networkDetails) || is_int($networkDetails)) {
|
||||||
$topLevelNetworks->put($networkDetails, null);
|
$topLevelNetworks->put($networkDetails, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) {
|
$definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) {
|
||||||
return $value == $definedNetwork;
|
return $value == $definedNetwork;
|
||||||
});
|
});
|
||||||
@@ -1608,10 +1612,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
return $value == $networkName || $key == $networkName;
|
return $value == $networkName || $key == $networkName;
|
||||||
});
|
});
|
||||||
if (! $networkExists) {
|
if (! $networkExists) {
|
||||||
|
if (is_string($networkDetails) || is_int($networkDetails)) {
|
||||||
$topLevelNetworks->put($networkDetails, null);
|
$topLevelNetworks->put($networkDetails, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Collect/create/update ports
|
// Collect/create/update ports
|
||||||
$collectedPorts = collect([]);
|
$collectedPorts = collect([]);
|
||||||
@@ -2523,10 +2529,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
return $value == $networkName || $key == $networkName;
|
return $value == $networkName || $key == $networkName;
|
||||||
});
|
});
|
||||||
if (! $networkExists) {
|
if (! $networkExists) {
|
||||||
|
if (is_string($networkDetails) || is_int($networkDetails)) {
|
||||||
$topLevelNetworks->put($networkDetails, null);
|
$topLevelNetworks->put($networkDetails, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Collect/create/update ports
|
// Collect/create/update ports
|
||||||
$collectedPorts = collect([]);
|
$collectedPorts = collect([]);
|
||||||
if ($servicePorts->count() > 0) {
|
if ($servicePorts->count() > 0) {
|
||||||
@@ -2984,11 +2992,22 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
$predefinedPort = '8000';
|
$predefinedPort = '8000';
|
||||||
}
|
}
|
||||||
if ($isDatabase) {
|
if ($isDatabase) {
|
||||||
|
$applicationFound = ServiceApplication::where('name', $serviceName)->where('image', $image)->where('service_id', $resource->id)->first();
|
||||||
|
if ($applicationFound) {
|
||||||
|
$savedService = $applicationFound;
|
||||||
|
$savedService = ServiceDatabase::firstOrCreate([
|
||||||
|
'name' => $applicationFound->name,
|
||||||
|
'image' => $applicationFound->image,
|
||||||
|
'service_id' => $applicationFound->service_id,
|
||||||
|
]);
|
||||||
|
$applicationFound->delete();
|
||||||
|
} else {
|
||||||
$savedService = ServiceDatabase::firstOrCreate([
|
$savedService = ServiceDatabase::firstOrCreate([
|
||||||
'name' => $serviceName,
|
'name' => $serviceName,
|
||||||
'image' => $image,
|
'image' => $image,
|
||||||
'service_id' => $resource->id,
|
'service_id' => $resource->id,
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$savedService = ServiceApplication::firstOrCreate([
|
$savedService = ServiceApplication::firstOrCreate([
|
||||||
'name' => $serviceName,
|
'name' => $serviceName,
|
||||||
@@ -3209,12 +3228,24 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
if ($serviceName === 'plausible') {
|
if ($serviceName === 'plausible') {
|
||||||
$predefinedPort = '8000';
|
$predefinedPort = '8000';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($isDatabase) {
|
if ($isDatabase) {
|
||||||
|
$applicationFound = ServiceApplication::where('name', $serviceName)->where('image', $image)->where('service_id', $resource->id)->first();
|
||||||
|
if ($applicationFound) {
|
||||||
|
$savedService = $applicationFound;
|
||||||
|
$savedService = ServiceDatabase::firstOrCreate([
|
||||||
|
'name' => $applicationFound->name,
|
||||||
|
'image' => $applicationFound->image,
|
||||||
|
'service_id' => $applicationFound->service_id,
|
||||||
|
]);
|
||||||
|
$applicationFound->delete();
|
||||||
|
} else {
|
||||||
$savedService = ServiceDatabase::firstOrCreate([
|
$savedService = ServiceDatabase::firstOrCreate([
|
||||||
'name' => $serviceName,
|
'name' => $serviceName,
|
||||||
'image' => $image,
|
'image' => $image,
|
||||||
'service_id' => $resource->id,
|
'service_id' => $resource->id,
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$savedService = ServiceApplication::firstOrCreate([
|
$savedService = ServiceApplication::firstOrCreate([
|
||||||
'name' => $serviceName,
|
'name' => $serviceName,
|
||||||
@@ -3889,6 +3920,7 @@ function convertComposeEnvironmentToArray($environment)
|
|||||||
} else {
|
} else {
|
||||||
// Example: $environment = ['FOO=bar', 'BAZ=qux'];
|
// Example: $environment = ['FOO=bar', 'BAZ=qux'];
|
||||||
foreach ($environment as $value) {
|
foreach ($environment as $value) {
|
||||||
|
if (is_string($value)) {
|
||||||
$parts = explode('=', $value, 2);
|
$parts = explode('=', $value, 2);
|
||||||
$key = $parts[0];
|
$key = $parts[0];
|
||||||
$realValue = $parts[1] ?? '';
|
$realValue = $parts[1] ?? '';
|
||||||
@@ -3897,6 +3929,7 @@ function convertComposeEnvironmentToArray($environment)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $convertedServiceVariables;
|
return $convertedServiceVariables;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ return [
|
|||||||
|
|
||||||
// The release version of your application
|
// The release version of your application
|
||||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||||
'release' => '4.0.0-beta.350',
|
'release' => '4.0.0-beta.351',
|
||||||
// When left empty or `null` the Laravel environment will be used
|
// When left empty or `null` the Laravel environment will be used
|
||||||
'environment' => config('app.env'),
|
'environment' => config('app.env'),
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return '4.0.0-beta.350';
|
return '4.0.0-beta.351';
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('scheduled_database_backups', function (Blueprint $table) {
|
||||||
|
$table->boolean('dump_all')->default(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('scheduled_database_backups', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('dump_all');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -46,6 +46,9 @@ services:
|
|||||||
- PUSHER_APP_ID
|
- PUSHER_APP_ID
|
||||||
- PUSHER_APP_KEY
|
- PUSHER_APP_KEY
|
||||||
- PUSHER_APP_SECRET
|
- PUSHER_APP_SECRET
|
||||||
|
- TERMINAL_PROTOCOL
|
||||||
|
- TERMINAL_HOST
|
||||||
|
- TERMINAL_PORT
|
||||||
- AUTOUPDATE
|
- AUTOUPDATE
|
||||||
- SELF_HOSTED
|
- SELF_HOSTED
|
||||||
- SSH_MUX_ENABLED
|
- SSH_MUX_ENABLED
|
||||||
@@ -110,7 +113,7 @@ services:
|
|||||||
retries: 10
|
retries: 10
|
||||||
timeout: 2s
|
timeout: 2s
|
||||||
soketi:
|
soketi:
|
||||||
image: 'ghcr.io/coollabsio/coolify-realtime:1.0.2'
|
image: 'ghcr.io/coollabsio/coolify-realtime:1.0.3'
|
||||||
ports:
|
ports:
|
||||||
- "${SOKETI_PORT:-6001}:6001"
|
- "${SOKETI_PORT:-6001}:6001"
|
||||||
- "6002:6002"
|
- "6002:6002"
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"coolify": {
|
"coolify": {
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.349"
|
"version": "4.0.0-beta.350"
|
||||||
},
|
},
|
||||||
"nightly": {
|
"nightly": {
|
||||||
"version": "4.0.0-beta.350"
|
"version": "4.0.0-beta.351"
|
||||||
},
|
},
|
||||||
"helper": {
|
"helper": {
|
||||||
"version": "1.0.1"
|
"version": "1.0.1"
|
||||||
},
|
},
|
||||||
"realtime": {
|
"realtime": {
|
||||||
"version": "1.0.2"
|
"version": "1.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
public/svgs/bitcoin.svg
Normal file
15
public/svgs/bitcoin.svg
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<!-- Creator: CorelDRAW 2019 (64-Bit) -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="100%" height="100%" version="1.1" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"
|
||||||
|
viewBox="0 0 4091.27 4091.73"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
|
||||||
|
<g id="Layer_x0020_1">
|
||||||
|
<metadata id="CorelCorpID_0Corel-Layer"/>
|
||||||
|
<g id="_1421344023328">
|
||||||
|
<path fill="#F7931A" fill-rule="nonzero" d="M4030.06 2540.77c-273.24,1096.01 -1383.32,1763.02 -2479.46,1489.71 -1095.68,-273.24 -1762.69,-1383.39 -1489.33,-2479.31 273.12,-1096.13 1383.2,-1763.19 2479,-1489.95 1096.06,273.24 1763.03,1383.51 1489.76,2479.57l0.02 -0.02z"/>
|
||||||
|
<path fill="white" fill-rule="nonzero" d="M2947.77 1754.38c40.72,-272.26 -166.56,-418.61 -450,-516.24l91.95 -368.8 -224.5 -55.94 -89.51 359.09c-59.02,-14.72 -119.63,-28.59 -179.87,-42.34l90.16 -361.46 -224.36 -55.94 -92 368.68c-48.84,-11.12 -96.81,-22.11 -143.35,-33.69l0.26 -1.16 -309.59 -77.31 -59.72 239.78c0,0 166.56,38.18 163.05,40.53 90.91,22.69 107.35,82.87 104.62,130.57l-104.74 420.15c6.26,1.59 14.38,3.89 23.34,7.49 -7.49,-1.86 -15.46,-3.89 -23.73,-5.87l-146.81 588.57c-11.11,27.62 -39.31,69.07 -102.87,53.33 2.25,3.26 -163.17,-40.72 -163.17,-40.72l-111.46 256.98 292.15 72.83c54.35,13.63 107.61,27.89 160.06,41.3l-92.9 373.03 224.24 55.94 92 -369.07c61.26,16.63 120.71,31.97 178.91,46.43l-91.69 367.33 224.51 55.94 92.89 -372.33c382.82,72.45 670.67,43.24 791.83,-303.02 97.63,-278.78 -4.86,-439.58 -206.26,-544.44 146.69,-33.83 257.18,-130.31 286.64,-329.61l-0.07 -0.05zm-512.93 719.26c-69.38,278.78 -538.76,128.08 -690.94,90.29l123.28 -494.2c152.17,37.99 640.17,113.17 567.67,403.91zm69.43 -723.3c-63.29,253.58 -453.96,124.75 -580.69,93.16l111.77 -448.21c126.73,31.59 534.85,90.55 468.94,355.05l-0.02 0z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
8
public/svgs/strapi.svg
Normal file
8
public/svgs/strapi.svg
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 22.1867C0 11.7278 0 6.49832 3.24916 3.24916C6.49832 0 11.7278 0 22.1867 0H41.8133C52.2722 0 57.5017 0 60.7508 3.24916C64 6.49832 64 11.7278 64 22.1867V41.8133C64 52.2722 64 57.5017 60.7508 60.7508C57.5017 64 52.2722 64 41.8133 64H22.1867C11.7278 64 6.49832 64 3.24916 60.7508C0 57.5017 0 52.2722 0 41.8133V22.1867Z" fill="#4945FF"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M44.156 19.4131H22.6094V30.4004H33.596V41.3864H44.5827V19.8398C44.5827 19.6041 44.3917 19.4131 44.156 19.4131Z" fill="white"/>
|
||||||
|
<rect x="33.1719" y="30.4004" width="0.426667" height="0.426667" fill="white"/>
|
||||||
|
<path d="M22.6172 30.4004H33.1772C33.4128 30.4004 33.6039 30.5914 33.6039 30.8271V41.3871H23.0439C22.8082 41.3871 22.6172 41.196 22.6172 40.9604V30.4004Z" fill="#9593FF"/>
|
||||||
|
<path d="M33.6016 41.3867H44.5882L33.9657 52.0092C33.8314 52.1436 33.6016 52.0484 33.6016 51.8584V41.3867Z" fill="#9593FF"/>
|
||||||
|
<path d="M22.6151 30.3998H12.1434C11.9534 30.3998 11.8582 30.17 11.9926 30.0356L22.6151 19.4131V30.3998Z" fill="#9593FF"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -8,17 +8,14 @@
|
|||||||
<livewire:project.database.backup-now :backup="$backup" />
|
<livewire:project.database.backup-now :backup="$backup" />
|
||||||
@endif
|
@endif
|
||||||
@if ($backup->database_id !== 0)
|
@if ($backup->database_id !== 0)
|
||||||
<x-modal-confirmation
|
<x-modal-confirmation title="Confirm Backup Schedule Deletion?" buttonTitle="Delete Backups and Schedule"
|
||||||
title="Confirm Backup Schedule Deletion?"
|
isErrorButton submitAction="delete" :checkboxes="$checkboxes" :actions="[
|
||||||
buttonTitle="Delete Backups and Schedule"
|
'The selected backup schedule will be deleted.',
|
||||||
isErrorButton
|
'Scheduled backups for this database will be stopped (if this is the only backup schedule for this database).',
|
||||||
submitAction="delete"
|
]"
|
||||||
:checkboxes="$checkboxes"
|
|
||||||
:actions="['The selected backup schedule will be deleted.', 'Scheduled backups for this database will be stopped (if this is the only backup schedule for this database).']"
|
|
||||||
confirmationText="{{ $backup->database->name }}"
|
confirmationText="{{ $backup->database->name }}"
|
||||||
confirmationLabel="Please confirm the execution of the actions by entering the Database Name of the scheduled backups below"
|
confirmationLabel="Please confirm the execution of the actions by entering the Database Name of the scheduled backups below"
|
||||||
shortConfirmationLabel="Database Name"
|
shortConfirmationLabel="Database Name" />
|
||||||
/>
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="w-48 pb-2">
|
<div class="w-48 pb-2">
|
||||||
@@ -36,24 +33,40 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="flex gap-2">
|
<h3>Settings</h3>
|
||||||
|
<div class="flex gap-2 flex-col ">
|
||||||
@if ($backup->database_type === 'App\Models\StandalonePostgresql')
|
@if ($backup->database_type === 'App\Models\StandalonePostgresql')
|
||||||
|
<div class="w-48">
|
||||||
|
<x-forms.checkbox label="Backup All Databases" id="backup.dump_all" instantSave />
|
||||||
|
</div>
|
||||||
|
@if (!$backup->dump_all)
|
||||||
<x-forms.input label="Databases To Backup"
|
<x-forms.input label="Databases To Backup"
|
||||||
helper="Comma separated list of databases to backup. Empty will include the default one."
|
helper="Comma separated list of databases to backup. Empty will include the default one."
|
||||||
id="backup.databases_to_backup" />
|
id="backup.databases_to_backup" />
|
||||||
|
@endif
|
||||||
@elseif($backup->database_type === 'App\Models\StandaloneMongodb')
|
@elseif($backup->database_type === 'App\Models\StandaloneMongodb')
|
||||||
<x-forms.input label="Databases To Include"
|
<x-forms.input label="Databases To Include"
|
||||||
helper="A list of databases to backup. You can specify which collection(s) per database to exclude from the backup. Empty will include all databases and collections.<br><br>Example:<br><br>database1:collection1,collection2|database2:collection3,collection4<br><br> database1 will include all collections except collection1 and collection2. <br>database2 will include all collections except collection3 and collection4.<br><br>Another Example:<br><br>database1:collection1|database2<br><br> database1 will include all collections except collection1.<br>database2 will include ALL collections."
|
helper="A list of databases to backup. You can specify which collection(s) per database to exclude from the backup. Empty will include all databases and collections.<br><br>Example:<br><br>database1:collection1,collection2|database2:collection3,collection4<br><br> database1 will include all collections except collection1 and collection2. <br>database2 will include all collections except collection3 and collection4.<br><br>Another Example:<br><br>database1:collection1|database2<br><br> database1 will include all collections except collection1.<br>database2 will include ALL collections."
|
||||||
id="backup.databases_to_backup" />
|
id="backup.databases_to_backup" />
|
||||||
@elseif($backup->database_type === 'App\Models\StandaloneMysql')
|
@elseif($backup->database_type === 'App\Models\StandaloneMysql')
|
||||||
|
<div class="w-48">
|
||||||
|
<x-forms.checkbox label="Backup All Databases" id="backup.dump_all" instantSave />
|
||||||
|
</div>
|
||||||
|
@if (!$backup->dump_all)
|
||||||
<x-forms.input label="Databases To Backup"
|
<x-forms.input label="Databases To Backup"
|
||||||
helper="Comma separated list of databases to backup. Empty will include the default one."
|
helper="Comma separated list of databases to backup. Empty will include the default one."
|
||||||
id="backup.databases_to_backup" />
|
id="backup.databases_to_backup" />
|
||||||
|
@endif
|
||||||
@elseif($backup->database_type === 'App\Models\StandaloneMariadb')
|
@elseif($backup->database_type === 'App\Models\StandaloneMariadb')
|
||||||
|
<div class="w-48">
|
||||||
|
<x-forms.checkbox label="Backup All Databases" id="backup.dump_all" instantSave />
|
||||||
|
</div>
|
||||||
|
@if (!$backup->dump_all)
|
||||||
<x-forms.input label="Databases To Backup"
|
<x-forms.input label="Databases To Backup"
|
||||||
helper="Comma separated list of databases to backup. Empty will include the default one."
|
helper="Comma separated list of databases to backup. Empty will include the default one."
|
||||||
id="backup.databases_to_backup" />
|
id="backup.databases_to_backup" />
|
||||||
@endif
|
@endif
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<x-forms.input label="Frequency" id="backup.frequency" />
|
<x-forms.input label="Frequency" id="backup.frequency" />
|
||||||
|
|||||||
@@ -149,6 +149,12 @@
|
|||||||
<div class="text-xs">{{ $database->status }}</div>
|
<div class="text-xs">{{ $database->status }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center px-4">
|
<div class="flex items-center px-4">
|
||||||
|
@if ($database->isBackupSolutionAvailable())
|
||||||
|
<a class="mx-4 text-xs font-bold hover:underline"
|
||||||
|
href="{{ route('project.service.index', [...$parameters, 'stack_service_uuid' => $database->uuid]) }}#backups">
|
||||||
|
Backups
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
<a class="mx-4 text-xs font-bold hover:underline"
|
<a class="mx-4 text-xs font-bold hover:underline"
|
||||||
href="{{ route('project.service.index', [...$parameters, 'stack_service_uuid' => $database->uuid]) }}">
|
href="{{ route('project.service.index', [...$parameters, 'stack_service_uuid' => $database->uuid]) }}">
|
||||||
Settings
|
Settings
|
||||||
|
|||||||
@@ -10,9 +10,7 @@
|
|||||||
<a class="menu-item" :class="activeTab === 'general' && 'menu-item-active'"
|
<a class="menu-item" :class="activeTab === 'general' && 'menu-item-active'"
|
||||||
@click.prevent="activeTab = 'general'; window.location.hash = 'general'; if(window.location.search) window.location.search = ''"
|
@click.prevent="activeTab = 'general'; window.location.hash = 'general'; if(window.location.search) window.location.search = ''"
|
||||||
href="#">General</a>
|
href="#">General</a>
|
||||||
@if (str($serviceDatabase?->databaseType())->contains('mysql') ||
|
@if ($serviceDatabase->isBackupSolutionAvailable())
|
||||||
str($serviceDatabase?->databaseType())->contains('postgres') ||
|
|
||||||
str($serviceDatabase?->databaseType())->contains('mariadb'))
|
|
||||||
<a :class="activeTab === 'backups' && 'menu-item-active'" class="menu-item"
|
<a :class="activeTab === 'backups' && 'menu-item-active'" class="menu-item"
|
||||||
@click.prevent="activeTab = 'backups'; window.location.hash = 'backups'" href="#">Backups</a>
|
@click.prevent="activeTab = 'backups'; window.location.hash = 'backups'" href="#">Backups</a>
|
||||||
@endif
|
@endif
|
||||||
@@ -29,11 +27,13 @@
|
|||||||
@endisset
|
@endisset
|
||||||
@isset($serviceDatabase)
|
@isset($serviceDatabase)
|
||||||
<x-slot:title>
|
<x-slot:title>
|
||||||
{{ data_get_str($service, 'name')->limit(10) }} > {{ data_get_str($serviceDatabase, 'name')->limit(10) }} | Coolify
|
{{ data_get_str($service, 'name')->limit(10) }} >
|
||||||
|
{{ data_get_str($serviceDatabase, 'name')->limit(10) }} | Coolify
|
||||||
</x-slot>
|
</x-slot>
|
||||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||||
<livewire:project.service.database :database="$serviceDatabase" />
|
<livewire:project.service.database :database="$serviceDatabase" />
|
||||||
</div>
|
</div>
|
||||||
|
@if ($serviceDatabase->isBackupSolutionAvailable())
|
||||||
<div x-cloak x-show="activeTab === 'backups'">
|
<div x-cloak x-show="activeTab === 'backups'">
|
||||||
<div class="flex gap-2 ">
|
<div class="flex gap-2 ">
|
||||||
<h2 class="pb-4">Scheduled Backups</h2>
|
<h2 class="pb-4">Scheduled Backups</h2>
|
||||||
@@ -42,8 +42,9 @@
|
|||||||
</x-modal-input>
|
</x-modal-input>
|
||||||
</div>
|
</div>
|
||||||
<livewire:project.database.scheduled-backups :database="$serviceDatabase" />
|
<livewire:project.database.scheduled-backups :database="$serviceDatabase" />
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@endisset
|
@endisset
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -22,7 +22,25 @@
|
|||||||
</nav>
|
</nav>
|
||||||
<div class="flex flex-wrap order-first gap-2 items-center sm:order-last">
|
<div class="flex flex-wrap order-first gap-2 items-center sm:order-last">
|
||||||
@if (str($service->status())->contains('running'))
|
@if (str($service->status())->contains('running'))
|
||||||
<button @click="$wire.dispatch('restartEvent')" class="gap-2 button">
|
<x-dropdown>
|
||||||
|
<x-slot:title>
|
||||||
|
Advanced
|
||||||
|
</x-slot>
|
||||||
|
<div class="dropdown-item" @click="$wire.dispatch('pullAndRestartEvent')">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24" stroke-width="1.5"
|
||||||
|
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path
|
||||||
|
d="M12.983 8.978c3.955 -.182 7.017 -1.446 7.017 -2.978c0 -1.657 -3.582 -3 -8 -3c-1.661 0 -3.204 .19 -4.483 .515m-2.783 1.228c-.471 .382 -.734 .808 -.734 1.257c0 1.22 1.944 2.271 4.734 2.74" />
|
||||||
|
<path
|
||||||
|
d="M4 6v6c0 1.657 3.582 3 8 3c.986 0 1.93 -.067 2.802 -.19m3.187 -.82c1.251 -.53 2.011 -1.228 2.011 -1.99v-6" />
|
||||||
|
<path d="M4 12v6c0 1.657 3.582 3 8 3c3.217 0 5.991 -.712 7.261 -1.74m.739 -3.26v-4" />
|
||||||
|
<path d="M3 3l18 18" />
|
||||||
|
</svg>
|
||||||
|
Pull Latest Images & Restart
|
||||||
|
</div>
|
||||||
|
</x-dropdown>
|
||||||
|
<x-forms.button title="Restart" @click="$wire.dispatch('restartEvent')">
|
||||||
<svg class="w-5 h-5 dark:text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-5 h-5 dark:text-warning" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||||
stroke-width="2">
|
stroke-width="2">
|
||||||
@@ -30,8 +48,8 @@
|
|||||||
<path d="M20 4v5h-5" />
|
<path d="M20 4v5h-5" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
Pull Latest Images & Restart
|
Restart
|
||||||
</button>
|
</x-forms.button>
|
||||||
<x-modal-confirmation title="Confirm Service Stopping?" buttonTitle="Stop" submitAction="stop"
|
<x-modal-confirmation title="Confirm Service Stopping?" buttonTitle="Stop" submitAction="stop"
|
||||||
:checkboxes="$checkboxes" :actions="[__('service.stop'), __('resource.non_persistent')]" :confirmWithText="false" :confirmWithPassword="false" step1ButtonText="Continue"
|
:checkboxes="$checkboxes" :actions="[__('service.stop'), __('resource.non_persistent')]" :confirmWithText="false" :confirmWithPassword="false" step1ButtonText="Continue"
|
||||||
step2ButtonText="Stop Service" :dispatchEvent="true" dispatchEventType="stopEvent">
|
step2ButtonText="Stop Service" :dispatchEvent="true" dispatchEventType="stopEvent">
|
||||||
@@ -135,9 +153,13 @@
|
|||||||
$wire.$call('start');
|
$wire.$call('start');
|
||||||
});
|
});
|
||||||
$wire.$on('restartEvent', () => {
|
$wire.$on('restartEvent', () => {
|
||||||
$wire.$dispatch('info', 'Pulling new images.');
|
$wire.$dispatch('info', 'Service restart in progress.');
|
||||||
$wire.$call('restart');
|
$wire.$call('restart');
|
||||||
});
|
});
|
||||||
|
$wire.$on('pullAndRestartEvent', () => {
|
||||||
|
$wire.$dispatch('info', 'Pulling new images.');
|
||||||
|
$wire.$call('pullAndRestartEvent');
|
||||||
|
});
|
||||||
$wire.on('imagePulled', () => {
|
$wire.on('imagePulled', () => {
|
||||||
window.dispatchEvent(new CustomEvent('startservice'));
|
window.dispatchEvent(new CustomEvent('startservice'));
|
||||||
$wire.$dispatch('info', 'Restarting service.');
|
$wire.$dispatch('info', 'Restarting service.');
|
||||||
|
|||||||
17
templates/compose/bitcoin-core.yaml
Normal file
17
templates/compose/bitcoin-core.yaml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# documentation: https://hub.docker.com/r/ruimarinho/bitcoin-core/
|
||||||
|
# slogan: A self-hosted Bitcoin Core full node.
|
||||||
|
# tags: cryptocurrency,node,blockchain,bitcoin
|
||||||
|
# logo: svgs/bitcoin.svg
|
||||||
|
|
||||||
|
services:
|
||||||
|
bitcoin-core:
|
||||||
|
image: ruimarinho/bitcoin-core:latest
|
||||||
|
environment:
|
||||||
|
- BITCOIN_RPCUSER=${BITCOIN_RPCUSER:-bitcoinuser}
|
||||||
|
- BITCOIN_RPCPASSWORD=${SERVICE_PASSWORD_PASSWORD64}
|
||||||
|
- BITCOIN_NETWORK=${BITCOIN_NETWORK:-mainnet}
|
||||||
|
- BITCOIN_PRINTTOCONSOLE=${BITCOIN_PRINTTOCONSOLE:-1}
|
||||||
|
- BITCOIN_TXINDEX=${BITCOIN_TXINDEX:-1}
|
||||||
|
volumes:
|
||||||
|
- bitcoin_data:/home/bitcoin/.bitcoin
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# documentation: https://docs.docker.com/registry/
|
# documentation: https://docs.docker.com/registry/
|
||||||
# slogan: The Docker Registry is lets you distribute Docker images.
|
# slogan: The Docker Registry lets you distribute Docker images.
|
||||||
# tags: registry,images,docker
|
# tags: registry,images,docker
|
||||||
# logo: svgs/docker-registry.png
|
# logo: svgs/docker-registry.png
|
||||||
# port: 5000
|
# port: 5000
|
||||||
|
|||||||
60
templates/compose/strapi.yaml
Normal file
60
templates/compose/strapi.yaml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# documentation: https://docs.strapi.io/
|
||||||
|
# slogan: Open-source headless CMS to build powerful APIs with built-in content management.
|
||||||
|
# tags: cms, headless, mysql, api
|
||||||
|
# logo: svgs/strapi.svg
|
||||||
|
# port: 1337
|
||||||
|
|
||||||
|
services:
|
||||||
|
strapi:
|
||||||
|
image: "elestio/strapi-development:latest"
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_STRAPI_1337
|
||||||
|
- DATABASE_CLIENT=postgres
|
||||||
|
- DATABASE_HOST=postgresql
|
||||||
|
- DATABASE_PORT=5432
|
||||||
|
- "DATABASE_NAME=${POSTGRESQL_DATABASE:-strapi}"
|
||||||
|
- DATABASE_USERNAME=$SERVICE_USER_POSTGRESQL
|
||||||
|
- DATABASE_PASSWORD=$SERVICE_PASSWORD_POSTGRESQL
|
||||||
|
- JWT_SECRET=$SERVICE_BASE64_64_SECRET
|
||||||
|
- ADMIN_JWT_SECRET=$SERVICE_BASE64_64_SECRET
|
||||||
|
- APP_KEYS=$SERVICE_BASE64_64_KEY
|
||||||
|
- STRAPI_TELEMETRY_DISABLED=${STRAPI_TELEMETRY_DISABLED:-true}
|
||||||
|
- STRAPI_LICENSE=${STRAPI_LICENSE}
|
||||||
|
- NODE_ENV=${NODE_ENV:-development}
|
||||||
|
- BROWSER=${BROWSER:-true}
|
||||||
|
- STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE=${STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE:-en}
|
||||||
|
- STRAPI_ENFORCE_SOURCEMAPS=${STRAPI_ENFORCE_SOURCEMAPS:-false}
|
||||||
|
- FAST_REFRESH=${FAST_REFRESH:-true}
|
||||||
|
volumes:
|
||||||
|
- "strapi-config:/opt/app/config"
|
||||||
|
- "strapi-src:/opt/app/src"
|
||||||
|
- "strapi-uploads:/opt/app/public/uploads"
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- wget
|
||||||
|
- "-q"
|
||||||
|
- "--spider"
|
||||||
|
- "http://127.0.0.1:1337/"
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
|
depends_on:
|
||||||
|
postgresql:
|
||||||
|
condition: service_healthy
|
||||||
|
postgresql:
|
||||||
|
image: "elestio/postgres:latest"
|
||||||
|
environment:
|
||||||
|
- "POSTGRES_DB=${POSTGRESQL_DATABASE:-strapi}"
|
||||||
|
- POSTGRES_USER=$SERVICE_USER_POSTGRESQL
|
||||||
|
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRESQL
|
||||||
|
- PGDATA=/var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- "strapi-postgresql-data:/var/lib/postgresql/data"
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD-SHELL
|
||||||
|
- "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"coolify": {
|
"coolify": {
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.350"
|
"version": "4.0.0-beta.351"
|
||||||
},
|
},
|
||||||
"nightly": {
|
"nightly": {
|
||||||
"version": "4.0.0-beta.351"
|
"version": "4.0.0-beta.352"
|
||||||
},
|
},
|
||||||
"helper": {
|
"helper": {
|
||||||
"version": "1.0.1"
|
"version": "1.0.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user