mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-14 00:16:42 +00:00
Merge remote-tracking branch 'origin/next' into feature/vultr-cloud-provider
This commit is contained in:
commit
c58b4fd69c
718 files changed
+30292
-7279
No files matched your search
@@ -11,6 +11,8 @@ use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
*/
|
||||
class CloudProviderTokenFactory extends Factory
|
||||
{
|
||||
protected $model = CloudProviderToken::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Team;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends Factory<PrivateKey>
|
||||
*/
|
||||
class PrivateKeyFactory extends Factory
|
||||
{
|
||||
protected $model = PrivateKey::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->words(2, true),
|
||||
'description' => fake()->sentence(),
|
||||
'private_key' => $this->privateKey(),
|
||||
'team_id' => Team::factory(),
|
||||
'is_git_related' => false,
|
||||
];
|
||||
}
|
||||
|
||||
private function privateKey(): string
|
||||
{
|
||||
return '-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk
|
||||
hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA
|
||||
AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV
|
||||
uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
||||
-----END OPENSSH PRIVATE KEY-----';
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<?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('instance_settings', function (Blueprint $table) {
|
||||
$table->string('docker_registry_url')->default('docker.io')->after('is_auto_update_enabled');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('instance_settings', function (Blueprint $table) {
|
||||
$table->dropColumn('docker_registry_url');
|
||||
});
|
||||
}
|
||||
};
|
||||
+9
@@ -11,12 +11,21 @@ return new class extends Migration
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
// SQLite (testing) uses type affinity, so json columns already accept text.
|
||||
if (DB::connection()->getDriverName() !== 'pgsql') {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::statement('ALTER TABLE application_deployment_queues ALTER COLUMN configuration_snapshot TYPE text USING configuration_snapshot::text');
|
||||
DB::statement('ALTER TABLE application_deployment_queues ALTER COLUMN configuration_diff TYPE text USING configuration_diff::text');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (DB::connection()->getDriverName() !== 'pgsql') {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::statement('ALTER TABLE application_deployment_queues ALTER COLUMN configuration_snapshot TYPE json USING configuration_snapshot::json');
|
||||
DB::statement('ALTER TABLE application_deployment_queues ALTER COLUMN configuration_diff TYPE json USING configuration_diff::json');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('teams', function (Blueprint $table) {
|
||||
$table->boolean('is_mcp_server_enabled')->default(true);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('teams', function (Blueprint $table) {
|
||||
$table->dropColumn('is_mcp_server_enabled');
|
||||
});
|
||||
}
|
||||
};
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
<?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
|
||||
{
|
||||
if (Schema::hasColumn('local_file_volumes', 'is_host_file')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('local_file_volumes', function (Blueprint $table) {
|
||||
$table->boolean('is_host_file')->default(false)->after('is_directory');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
if (! Schema::hasColumn('local_file_volumes', 'is_host_file')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('local_file_volumes', function (Blueprint $table) {
|
||||
$table->dropColumn('is_host_file');
|
||||
});
|
||||
}
|
||||
};
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('instance_settings', function (Blueprint $table) {
|
||||
$table->json('webhook_allowed_internal_hosts')->nullable();
|
||||
$table->boolean('webhook_allow_localhost')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('instance_settings', function (Blueprint $table) {
|
||||
$table->dropColumn(['webhook_allowed_internal_hosts', 'webhook_allow_localhost']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -433,6 +433,7 @@ CREATE TABLE IF NOT EXISTS "local_file_volumes" (
|
||||
"created_at" TEXT,
|
||||
"updated_at" TEXT,
|
||||
"is_directory" INTEGER DEFAULT false NOT NULL,
|
||||
"is_host_file" INTEGER DEFAULT false NOT NULL,
|
||||
"chown" TEXT,
|
||||
"chmod" TEXT,
|
||||
"is_based_on_git" INTEGER DEFAULT false NOT NULL
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Enums\ProxyTypes;
|
||||
use App\Models\Application;
|
||||
use App\Models\Environment;
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\GitlabApp;
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
@@ -19,14 +20,33 @@ class DevelopmentRailpackExamplesSeeder extends Seeder
|
||||
{
|
||||
public const PROJECT_UUID = 'railpack-examples';
|
||||
|
||||
public const ENVIRONMENT_UUID = 'railpack-examples-production';
|
||||
|
||||
public const GIT_REPOSITORY = 'coollabsio/coolify-examples';
|
||||
|
||||
public const GIT_BRANCH = 'next';
|
||||
|
||||
public const REPOSITORY_PROJECT_ID = 603035348;
|
||||
|
||||
public const LIMA_SERVERS = [
|
||||
[
|
||||
'server_uuid' => 'lima-ubuntu-2404',
|
||||
'server_name' => 'lima-ubuntu-2404',
|
||||
'port' => 2222,
|
||||
'environment_name' => 'ubuntu24',
|
||||
'environment_uuid' => 'railpack-examples-ubuntu24',
|
||||
'uuid_prefix' => 'ubuntu24-',
|
||||
],
|
||||
[
|
||||
'server_uuid' => 'lima-ubuntu-2604',
|
||||
'server_name' => 'lima-ubuntu-2604',
|
||||
'port' => 2223,
|
||||
'environment_name' => 'ubuntu26',
|
||||
'environment_uuid' => 'railpack-examples-ubuntu26',
|
||||
'uuid_prefix' => 'ubuntu26-',
|
||||
],
|
||||
];
|
||||
|
||||
private const LIMA_SENTINEL_URL = 'http://host.lima.internal:8000';
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
if (! $this->isDevelopmentEnvironment()) {
|
||||
@@ -36,16 +56,22 @@ class DevelopmentRailpackExamplesSeeder extends Seeder
|
||||
}
|
||||
|
||||
$this->ensureDevelopmentPrerequisitesExist();
|
||||
$destination = StandaloneDocker::query()->find(0);
|
||||
|
||||
if (! $destination) {
|
||||
if (! StandaloneDocker::query()->find(0)) {
|
||||
throw new RuntimeException('StandaloneDocker with id=0 is required before running DevelopmentRailpackExamplesSeeder.');
|
||||
}
|
||||
|
||||
$environment = $this->prepareEnvironment();
|
||||
$this->cleanupLegacyLimaProjects();
|
||||
$this->cleanupLegacyProductionExamples();
|
||||
|
||||
foreach (self::examples() as $example) {
|
||||
$this->upsertApplication($environment, $destination, $example);
|
||||
foreach (self::LIMA_SERVERS as $limaServer) {
|
||||
$this->seedEnvironment(
|
||||
environmentUuid: $limaServer['environment_uuid'],
|
||||
environmentName: $limaServer['environment_name'],
|
||||
destination: $this->limaDestination($limaServer['server_uuid']),
|
||||
uuidPrefix: $limaServer['uuid_prefix'],
|
||||
nameSuffix: " ({$limaServer['environment_name']})",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,6 +386,36 @@ class DevelopmentRailpackExamplesSeeder extends Seeder
|
||||
'ports_exposes' => '3000',
|
||||
'git_branch' => 'v4.x',
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-github-deploy-key',
|
||||
'name' => 'Railpack GitHub Deploy Key Example',
|
||||
'git_repository' => 'git@github.com:coollabsio/coolify-examples-deploy-key.git',
|
||||
'git_branch' => 'main',
|
||||
'ports_exposes' => '80',
|
||||
'private_key_id' => 1,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-gitlab-deploy-key',
|
||||
'name' => 'Railpack GitLab Deploy Key Example',
|
||||
'git_repository' => 'git@gitlab.com:coollabsio/php-example.git',
|
||||
'git_branch' => 'main',
|
||||
'ports_exposes' => '80',
|
||||
'source_id' => 1,
|
||||
'source_type' => GitlabApp::class,
|
||||
'private_key_id' => 1,
|
||||
],
|
||||
[
|
||||
'uuid' => 'railpack-gitlab-public-example',
|
||||
'name' => 'Railpack GitLab Public Example',
|
||||
'git_repository' => 'https://gitlab.com/andrasbacsai/coolify-examples.git',
|
||||
'git_branch' => 'main',
|
||||
'base_directory' => '/astro/static',
|
||||
'publish_directory' => '/dist',
|
||||
'ports_exposes' => '80',
|
||||
'source_id' => 1,
|
||||
'source_type' => GitlabApp::class,
|
||||
'is_static' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -409,6 +465,37 @@ KEY,
|
||||
],
|
||||
);
|
||||
|
||||
foreach (self::LIMA_SERVERS as $limaServer) {
|
||||
$server = Server::query()->firstOrCreate(
|
||||
['uuid' => $limaServer['server_uuid']],
|
||||
[
|
||||
'name' => $limaServer['server_name'],
|
||||
'description' => 'This is a Lima VM for local development testing',
|
||||
'ip' => 'host.docker.internal',
|
||||
'port' => $limaServer['port'],
|
||||
'team_id' => 0,
|
||||
'private_key_id' => 1,
|
||||
'proxy' => [
|
||||
'type' => ProxyTypes::TRAEFIK->value,
|
||||
'status' => ProxyStatus::EXITED->value,
|
||||
],
|
||||
],
|
||||
);
|
||||
|
||||
$server->settings->forceFill([
|
||||
'sentinel_custom_url' => self::LIMA_SENTINEL_URL,
|
||||
])->saveQuietly();
|
||||
|
||||
StandaloneDocker::query()->firstOrCreate(
|
||||
['server_id' => $server->id],
|
||||
[
|
||||
'uuid' => "{$limaServer['server_uuid']}-docker",
|
||||
'name' => "{$limaServer['server_name']} Docker",
|
||||
'network' => 'coolify',
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
StandaloneDocker::query()->firstOrCreate(
|
||||
['id' => 0],
|
||||
[
|
||||
@@ -420,6 +507,7 @@ KEY,
|
||||
);
|
||||
|
||||
$this->ensurePublicGithubSourceExists();
|
||||
$this->ensurePublicGitlabSourceExists();
|
||||
}
|
||||
|
||||
private function ensurePublicGithubSourceExists(): void
|
||||
@@ -437,12 +525,91 @@ KEY,
|
||||
);
|
||||
}
|
||||
|
||||
private function ensurePublicGitlabSourceExists(): void
|
||||
{
|
||||
GitlabApp::query()->firstOrCreate(
|
||||
['id' => 1],
|
||||
[
|
||||
'uuid' => 'gitlab-public',
|
||||
'name' => 'Public GitLab',
|
||||
'api_url' => 'https://gitlab.com/api/v4',
|
||||
'html_url' => 'https://gitlab.com',
|
||||
'is_public' => true,
|
||||
'team_id' => 0,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
private function isDevelopmentEnvironment(): bool
|
||||
{
|
||||
return in_array(config('app.env'), ['local', 'development', 'dev'], true);
|
||||
}
|
||||
|
||||
private function prepareEnvironment(): Environment
|
||||
private function limaDestination(string $serverUuid): StandaloneDocker
|
||||
{
|
||||
$limaDestination = Server::query()
|
||||
->where('uuid', $serverUuid)
|
||||
->first()
|
||||
?->standaloneDockers()
|
||||
->first();
|
||||
|
||||
if (! $limaDestination) {
|
||||
throw new RuntimeException("Lima StandaloneDocker destination is required for {$serverUuid} before running DevelopmentRailpackExamplesSeeder.");
|
||||
}
|
||||
|
||||
return $limaDestination;
|
||||
}
|
||||
|
||||
private function cleanupLegacyLimaProjects(): void
|
||||
{
|
||||
Project::query()
|
||||
->whereIn('uuid', [
|
||||
'railpack-examples-lima-ubuntu-2404',
|
||||
'railpack-examples-lima-ubuntu-2604',
|
||||
])
|
||||
->get()
|
||||
->each(function (Project $project): void {
|
||||
Application::withTrashed()
|
||||
->whereIn('environment_id', $project->environments()->pluck('id'))
|
||||
->get()
|
||||
->each
|
||||
->forceDelete();
|
||||
|
||||
$project->delete();
|
||||
});
|
||||
}
|
||||
|
||||
private function cleanupLegacyProductionExamples(): void
|
||||
{
|
||||
$project = Project::query()->where('uuid', self::PROJECT_UUID)->first();
|
||||
|
||||
if (! $project) {
|
||||
return;
|
||||
}
|
||||
|
||||
Application::withTrashed()
|
||||
->whereIn('environment_id', $project->environments()->pluck('id'))
|
||||
->whereIn('uuid', collect(self::examples())->pluck('uuid'))
|
||||
->get()
|
||||
->each
|
||||
->forceDelete();
|
||||
}
|
||||
|
||||
private function seedEnvironment(
|
||||
string $environmentUuid,
|
||||
string $environmentName,
|
||||
StandaloneDocker $destination,
|
||||
string $uuidPrefix = '',
|
||||
string $nameSuffix = '',
|
||||
): void {
|
||||
$environment = $this->prepareEnvironment($environmentUuid, $environmentName);
|
||||
|
||||
foreach (self::examples() as $example) {
|
||||
$this->upsertApplication($environment, $destination, $example, $uuidPrefix, $nameSuffix);
|
||||
}
|
||||
}
|
||||
|
||||
private function prepareEnvironment(string $environmentUuid, string $environmentName): Environment
|
||||
{
|
||||
$project = Project::query()->firstOrNew(['uuid' => self::PROJECT_UUID]);
|
||||
$project->fill([
|
||||
@@ -452,17 +619,29 @@ KEY,
|
||||
]);
|
||||
$project->save();
|
||||
|
||||
$environment = $project->environments()->first();
|
||||
$environment = $project->environments()
|
||||
->where(function ($query) use ($environmentName, $environmentUuid): void {
|
||||
$query
|
||||
->where('name', $environmentName)
|
||||
->orWhere('uuid', $environmentUuid);
|
||||
})
|
||||
->first();
|
||||
|
||||
$existingEnvironment = $project->environments()->first();
|
||||
|
||||
if (! $environment && $project->environments()->count() === 1 && $existingEnvironment?->name === 'production') {
|
||||
$environment = $existingEnvironment;
|
||||
}
|
||||
|
||||
if (! $environment) {
|
||||
$environment = $project->environments()->create([
|
||||
'name' => 'production',
|
||||
'uuid' => self::ENVIRONMENT_UUID,
|
||||
'name' => $environmentName,
|
||||
'uuid' => $environmentUuid,
|
||||
]);
|
||||
} else {
|
||||
$environment->update([
|
||||
'name' => 'production',
|
||||
'uuid' => self::ENVIRONMENT_UUID,
|
||||
'name' => $environmentName,
|
||||
'uuid' => $environmentUuid,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -472,19 +651,21 @@ KEY,
|
||||
/**
|
||||
* @param array<string, mixed> $example
|
||||
*/
|
||||
private function upsertApplication(Environment $environment, StandaloneDocker $destination, array $example): void
|
||||
private function upsertApplication(Environment $environment, StandaloneDocker $destination, array $example, string $uuidPrefix = '', string $nameSuffix = ''): void
|
||||
{
|
||||
$application = Application::withTrashed()->firstOrNew(['uuid' => $example['uuid']]);
|
||||
$uuid = $uuidPrefix.$example['uuid'];
|
||||
$name = $example['name'].$nameSuffix;
|
||||
$application = Application::withTrashed()->firstOrNew(['uuid' => $uuid]);
|
||||
$application->fill([
|
||||
'name' => $example['name'],
|
||||
'description' => $example['name'],
|
||||
'fqdn' => "http://{$example['uuid']}.127.0.0.1.sslip.io",
|
||||
'repository_project_id' => self::REPOSITORY_PROJECT_ID,
|
||||
'git_repository' => self::GIT_REPOSITORY,
|
||||
'name' => $name,
|
||||
'description' => $name,
|
||||
'fqdn' => "http://{$uuid}.127.0.0.1.sslip.io",
|
||||
'repository_project_id' => $example['repository_project_id'] ?? self::REPOSITORY_PROJECT_ID,
|
||||
'git_repository' => $example['git_repository'] ?? self::GIT_REPOSITORY,
|
||||
'git_branch' => $example['git_branch'] ?? self::GIT_BRANCH,
|
||||
'build_pack' => 'railpack',
|
||||
'ports_exposes' => $example['ports_exposes'],
|
||||
'base_directory' => $example['base_directory'],
|
||||
'base_directory' => $example['base_directory'] ?? '/',
|
||||
'publish_directory' => $example['publish_directory'] ?? null,
|
||||
'static_image' => 'nginx:alpine',
|
||||
'install_command' => $example['install_command'] ?? null,
|
||||
@@ -493,8 +674,9 @@ KEY,
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
'source_id' => 0,
|
||||
'source_type' => GithubApp::class,
|
||||
'source_id' => $example['source_id'] ?? 0,
|
||||
'source_type' => $example['source_type'] ?? GithubApp::class,
|
||||
'private_key_id' => $example['private_key_id'] ?? null,
|
||||
]);
|
||||
$application->save();
|
||||
|
||||
|
||||
@@ -7,6 +7,11 @@ use Illuminate\Database\Seeder;
|
||||
|
||||
class ProjectSeeder extends Seeder
|
||||
{
|
||||
private const LIMA_ENVIRONMENTS = [
|
||||
['name' => 'ubuntu24', 'uuid' => 'ubuntu24'],
|
||||
['name' => 'ubuntu26', 'uuid' => 'ubuntu26'],
|
||||
];
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$project = Project::create([
|
||||
@@ -16,7 +21,14 @@ class ProjectSeeder extends Seeder
|
||||
'team_id' => 0,
|
||||
]);
|
||||
|
||||
// Update the auto-created environment with a deterministic UUID
|
||||
$project->environments()->first()->update(['uuid' => 'production']);
|
||||
foreach (self::LIMA_ENVIRONMENTS as $index => $environment) {
|
||||
if ($index === 0) {
|
||||
$project->environments()->first()->update($environment);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$project->environments()->create($environment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,13 @@ use Illuminate\Database\Seeder;
|
||||
|
||||
class ServerSeeder extends Seeder
|
||||
{
|
||||
private const LIMA_SENTINEL_URL = 'http://host.lima.internal:8000';
|
||||
|
||||
private const LIMA_SERVERS = [
|
||||
['uuid' => 'lima-ubuntu-2404', 'name' => 'lima-ubuntu-2404', 'port' => 2222],
|
||||
['uuid' => 'lima-ubuntu-2604', 'name' => 'lima-ubuntu-2604', 'port' => 2223],
|
||||
];
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
Server::create([
|
||||
@@ -24,5 +31,25 @@ class ServerSeeder extends Seeder
|
||||
'status' => ProxyStatus::EXITED->value,
|
||||
],
|
||||
]);
|
||||
|
||||
foreach (self::LIMA_SERVERS as $limaServer) {
|
||||
$server = Server::create([
|
||||
'uuid' => $limaServer['uuid'],
|
||||
'name' => $limaServer['name'],
|
||||
'description' => 'This is a Lima VM for local development testing',
|
||||
'ip' => 'host.docker.internal',
|
||||
'port' => $limaServer['port'],
|
||||
'team_id' => 0,
|
||||
'private_key_id' => 1,
|
||||
'proxy' => [
|
||||
'type' => ProxyTypes::TRAEFIK->value,
|
||||
'status' => ProxyStatus::EXITED->value,
|
||||
],
|
||||
]);
|
||||
|
||||
$server->settings->forceFill([
|
||||
'sentinel_custom_url' => self::LIMA_SENTINEL_URL,
|
||||
])->saveQuietly();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user