Compare commits
119 Commits
v4.0.0-bet
...
fix-server
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
742df4f5df | ||
|
|
2522ecf832 | ||
|
|
40f2c7a1f9 | ||
|
|
3f8324d09e | ||
|
|
eee292b02f | ||
|
|
2b4dc1f9c8 | ||
|
|
dd29827a14 | ||
|
|
dfe290b546 | ||
|
|
4eeb7ee7c6 | ||
|
|
51813463b8 | ||
|
|
da8a45391c | ||
|
|
673081ffb3 | ||
|
|
8f6c01ba49 | ||
|
|
40852995b4 | ||
|
|
e6bb1deaa9 | ||
|
|
2dc3177a7a | ||
|
|
facbd9a50d | ||
|
|
a0532afb24 | ||
|
|
a725a6eaf2 | ||
|
|
3fd3660960 | ||
|
|
5898e0ac4a | ||
|
|
4f4743cc7f | ||
|
|
3b3362daf0 | ||
|
|
cd199ed81d | ||
|
|
7e32a37729 | ||
|
|
58c3cea0c0 | ||
|
|
1c10a43321 | ||
|
|
370a0b1eec | ||
|
|
282ff4e670 | ||
|
|
af09472679 | ||
|
|
053ee63606 | ||
|
|
a8d8df7d8b | ||
|
|
283fe47f5c | ||
|
|
88367d8af1 | ||
|
|
506f733632 | ||
|
|
9f2e7851f7 | ||
|
|
8269e9d29d | ||
|
|
8803cae54c | ||
|
|
c1930e3dfc | ||
|
|
c717b6859b | ||
|
|
4624a381b1 | ||
|
|
6928b0a2c8 | ||
|
|
2da6f66e85 | ||
|
|
a1124a885d | ||
|
|
9448d0f0d2 | ||
|
|
e446354d97 | ||
|
|
c8aa09359f | ||
|
|
128d732438 | ||
|
|
3b97bb1341 | ||
|
|
a4c8f83d17 | ||
|
|
0ca9885ddf | ||
|
|
4f4453b17c | ||
|
|
d60d90de92 | ||
|
|
ce49f4806d | ||
|
|
82daf6c420 | ||
|
|
f1eb43815e | ||
|
|
be9041d592 | ||
|
|
c2c0afa0ba | ||
|
|
611f70d79f | ||
|
|
59c54b8aec | ||
|
|
f0f685b78a | ||
|
|
c54d77515b | ||
|
|
9435be7cce | ||
|
|
f2ccc4059d | ||
|
|
21c6510e9d | ||
|
|
2ca73695b3 | ||
|
|
31193a9f66 | ||
|
|
9f5257bf8a | ||
|
|
78a34dbef1 | ||
|
|
f4d650b03f | ||
|
|
97ee34f1a1 | ||
|
|
9014062b48 | ||
|
|
a8f230b5eb | ||
|
|
94ee525e0a | ||
|
|
d4ace01633 | ||
|
|
49bcd7b8e6 | ||
|
|
5f613df4e0 | ||
|
|
65aeebd9fa | ||
|
|
f26d2e1d0b | ||
|
|
a1d395ff0c | ||
|
|
4e9126887f | ||
|
|
5fa650122d | ||
|
|
ee7f8200ac | ||
|
|
d2a8f31a1c | ||
|
|
2468d0044b | ||
|
|
81b8a58415 | ||
|
|
7442d19611 | ||
|
|
8c024ddb57 | ||
|
|
d990a5691d | ||
|
|
2181ef381b | ||
|
|
c80f5be974 | ||
|
|
358f6575f8 | ||
|
|
de0f34734b | ||
|
|
33cb2d150d | ||
|
|
5f07b473e9 | ||
|
|
5bcd813792 | ||
|
|
a0bb523507 | ||
|
|
0b4fc38d6b | ||
|
|
82c834915d | ||
|
|
d637675ce3 | ||
|
|
e71c04a0c7 | ||
|
|
885b3bdea7 | ||
|
|
9d6757aeb7 | ||
|
|
d84d0a816b | ||
|
|
0da31c34b5 | ||
|
|
ccdaf59ecb | ||
|
|
3fc9cf90ab | ||
|
|
c4be720b20 | ||
|
|
aabe27efd1 | ||
|
|
1b0e2e1257 | ||
|
|
2cf0f4facc | ||
|
|
0494f9a7e5 | ||
|
|
c402d7f543 | ||
|
|
565cb54dba | ||
|
|
eb5765979f | ||
|
|
1e46b63041 | ||
|
|
71bb1f5e17 | ||
|
|
ce926afdaa | ||
|
|
18ae29ba99 |
1
.github/workflows/coolify-helper.yml
vendored
@@ -98,3 +98,4 @@ jobs:
|
||||
if: always()
|
||||
with:
|
||||
webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class CheckConfiguration
|
||||
];
|
||||
$proxy_configuration = instant_remote_process($payload, $server, false);
|
||||
if ($reset || ! $proxy_configuration || is_null($proxy_configuration)) {
|
||||
$proxy_configuration = str(generate_default_proxy_configuration($server))->trim()->value;
|
||||
$proxy_configuration = str(generate_default_proxy_configuration($server))->trim()->value();
|
||||
}
|
||||
if (! $proxy_configuration || is_null($proxy_configuration)) {
|
||||
throw new \Exception('Could not generate proxy configuration');
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
|
||||
namespace App\Actions\Proxy;
|
||||
|
||||
use App\Enums\ProxyTypes;
|
||||
use App\Models\Server;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
class CheckProxy
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
public function handle(Server $server, $fromUI = false)
|
||||
// It should return if the proxy should be started (true) or not (false)
|
||||
public function handle(Server $server, $fromUI = false): bool
|
||||
{
|
||||
if (! $server->isFunctional()) {
|
||||
return false;
|
||||
@@ -62,22 +65,42 @@ class CheckProxy
|
||||
$ip = 'host.docker.internal';
|
||||
}
|
||||
|
||||
$connection80 = @fsockopen($ip, '80');
|
||||
$connection443 = @fsockopen($ip, '443');
|
||||
$port80 = is_resource($connection80) && fclose($connection80);
|
||||
$port443 = is_resource($connection443) && fclose($connection443);
|
||||
if ($port80) {
|
||||
if ($fromUI) {
|
||||
throw new \Exception("Port 80 is in use.<br>You must stop the process using this port.<br>Docs: <a target='_blank' href='https://coolify.io/docs'>https://coolify.io/docs</a><br>Discord: <a target='_blank' href='https://coollabs.io/discord'>https://coollabs.io/discord</a>");
|
||||
$portsToCheck = ['80', '443'];
|
||||
|
||||
try {
|
||||
if ($server->proxyType() !== ProxyTypes::NONE->value) {
|
||||
$proxyCompose = CheckConfiguration::run($server);
|
||||
if (isset($proxyCompose)) {
|
||||
$yaml = Yaml::parse($proxyCompose);
|
||||
$portsToCheck = [];
|
||||
if ($server->proxyType() === ProxyTypes::TRAEFIK->value) {
|
||||
$ports = data_get($yaml, 'services.traefik.ports');
|
||||
} elseif ($server->proxyType() === ProxyTypes::CADDY->value) {
|
||||
$ports = data_get($yaml, 'services.caddy.ports');
|
||||
}
|
||||
if (isset($ports)) {
|
||||
foreach ($ports as $port) {
|
||||
$portsToCheck[] = str($port)->before(':')->value();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
$portsToCheck = [];
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
ray($e->getMessage());
|
||||
}
|
||||
if ($port443) {
|
||||
if ($fromUI) {
|
||||
throw new \Exception("Port 443 is in use.<br>You must stop the process using this port.<br>Docs: <a target='_blank' href='https://coolify.io/docs'>https://coolify.io/docs</a><br>Discord: <a target='_blank' href='https://coollabs.io/discord'>https://coollabs.io/discord</a>");
|
||||
} else {
|
||||
return false;
|
||||
if (count($portsToCheck) === 0) {
|
||||
return false;
|
||||
}
|
||||
foreach ($portsToCheck as $port) {
|
||||
$connection = @fsockopen($ip, $port);
|
||||
if (is_resource($connection) && fclose($connection)) {
|
||||
if ($fromUI) {
|
||||
throw new \Exception("Port $port is in use.<br>You must stop the process using this port.<br>Docs: <a target='_blank' href='https://coolify.io/docs'>https://coolify.io/docs</a><br>Discord: <a target='_blank' href='https://coollabs.io/discord'>https://coollabs.io/discord</a>");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class StartProxy
|
||||
}
|
||||
SaveConfiguration::run($server, $configuration);
|
||||
$docker_compose_yml_base64 = base64_encode($configuration);
|
||||
$server->proxy->last_applied_settings = str($docker_compose_yml_base64)->pipe('md5')->value;
|
||||
$server->proxy->last_applied_settings = str($docker_compose_yml_base64)->pipe('md5')->value();
|
||||
$server->save();
|
||||
if ($server->isSwarm()) {
|
||||
$commands = $commands->merge([
|
||||
|
||||
@@ -18,7 +18,7 @@ class CheckApplicationDeploymentQueue extends Command
|
||||
$deployments = ApplicationDeploymentQueue::whereIn('status', [
|
||||
ApplicationDeploymentStatus::IN_PROGRESS,
|
||||
ApplicationDeploymentStatus::QUEUED,
|
||||
])->where('created_at', '>=', now()->subSeconds($seconds))->get();
|
||||
])->where('created_at', '<=', now()->subSeconds($seconds))->get();
|
||||
if ($deployments->isEmpty()) {
|
||||
$this->info('No deployments found in the last '.$seconds.' seconds.');
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ class ServicesGenerate extends Command
|
||||
if ($logo->count() > 0) {
|
||||
$logo = str($logo[0])->after('# logo:')->trim()->value();
|
||||
} else {
|
||||
$logo = 'svgs/unknown.svg';
|
||||
$logo = 'svgs/coolify.png';
|
||||
}
|
||||
$minversion = collect(preg_grep('/^# minversion:/', explode("\n", $content)))->values();
|
||||
if ($minversion->count() > 0) {
|
||||
|
||||
@@ -66,7 +66,12 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
||||
public function handle(): void
|
||||
{
|
||||
try {
|
||||
$this->team = Team::findOrFail($this->backup->team_id);
|
||||
$this->team = Team::find($this->backup->team_id);
|
||||
if (! $this->team) {
|
||||
$this->backup->delete();
|
||||
|
||||
return;
|
||||
}
|
||||
if (data_get($this->backup, 'database_type') === 'App\Models\ServiceDatabase') {
|
||||
$this->database = data_get($this->backup, 'database');
|
||||
$this->server = $this->database->service->server;
|
||||
|
||||
@@ -61,6 +61,7 @@ class Help extends Component
|
||||
send_user_an_email($mail, auth()->user()?->email, 'hi@coollabs.io');
|
||||
}
|
||||
$this->dispatch('success', 'Feedback sent.', 'We will get in touch with you as soon as possible.');
|
||||
$this->reset('description', 'subject');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ class ScheduledBackups extends Component
|
||||
public function mount(): void
|
||||
{
|
||||
if ($this->selectedBackupId) {
|
||||
$this->setSelectedBackup($this->selectedBackupId);
|
||||
$this->setSelectedBackup($this->selectedBackupId, true);
|
||||
}
|
||||
$this->parameters = get_route_parameters();
|
||||
if ($this->database->getMorphClass() === 'App\Models\ServiceDatabase') {
|
||||
@@ -37,10 +37,13 @@ class ScheduledBackups extends Component
|
||||
$this->s3s = currentTeam()->s3s;
|
||||
}
|
||||
|
||||
public function setSelectedBackup($backupId)
|
||||
public function setSelectedBackup($backupId, $force = false)
|
||||
{
|
||||
if ($this->selectedBackupId === $backupId && ! $force) {
|
||||
return;
|
||||
}
|
||||
$this->selectedBackupId = $backupId;
|
||||
$this->selectedBackup = $this->database->scheduledBackups->find($this->selectedBackupId);
|
||||
$this->selectedBackup = $this->database->scheduledBackups->find($backupId);
|
||||
if (is_null($this->selectedBackup)) {
|
||||
$this->selectedBackupId = null;
|
||||
}
|
||||
|
||||
@@ -48,14 +48,6 @@ class Add extends Component
|
||||
public function submit()
|
||||
{
|
||||
$this->validate();
|
||||
// if (str($this->value)->startsWith('{{') && str($this->value)->endsWith('}}')) {
|
||||
// $type = str($this->value)->after('{{')->before('.')->value;
|
||||
// if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) {
|
||||
// $this->dispatch('error', 'Invalid shared variable type.', 'Valid types are: team, project, environment.');
|
||||
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
$this->dispatch('saveKey', [
|
||||
'key' => $this->key,
|
||||
'value' => $this->value,
|
||||
|
||||
@@ -53,30 +53,16 @@ class All extends Component
|
||||
|
||||
public function sortEnvironmentVariables()
|
||||
{
|
||||
if ($this->resource->type() === 'application') {
|
||||
$this->resource->load(['environment_variables', 'environment_variables_preview']);
|
||||
} else {
|
||||
$this->resource->load(['environment_variables']);
|
||||
if (! data_get($this->resource, 'settings.is_env_sorting_enabled')) {
|
||||
if ($this->resource->environment_variables) {
|
||||
$this->resource->environment_variables = $this->resource->environment_variables->sortBy('order')->values();
|
||||
}
|
||||
|
||||
if ($this->resource->environment_variables_preview) {
|
||||
$this->resource->environment_variables_preview = $this->resource->environment_variables_preview->sortBy('order')->values();
|
||||
}
|
||||
}
|
||||
|
||||
$sortBy = data_get($this->resource, 'settings.is_env_sorting_enabled') ? 'key' : 'order';
|
||||
|
||||
$sortFunction = function ($variables) use ($sortBy) {
|
||||
if (! $variables) {
|
||||
return $variables;
|
||||
}
|
||||
if ($sortBy === 'key') {
|
||||
return $variables->sortBy(function ($item) {
|
||||
return strtolower($item->key);
|
||||
}, SORT_NATURAL | SORT_FLAG_CASE)->values();
|
||||
} else {
|
||||
return $variables->sortBy('order')->values();
|
||||
}
|
||||
};
|
||||
|
||||
$this->resource->environment_variables = $sortFunction($this->resource->environment_variables);
|
||||
$this->resource->environment_variables_preview = $sortFunction($this->resource->environment_variables_preview);
|
||||
|
||||
$this->getDevView();
|
||||
}
|
||||
|
||||
@@ -121,6 +107,8 @@ class All extends Component
|
||||
$this->sortEnvironmentVariables();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
} finally {
|
||||
$this->refreshEnvs();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace App\Livewire\Server\Proxy;
|
||||
|
||||
use App\Actions\Docker\GetContainersStatus;
|
||||
use App\Actions\Proxy\CheckProxy;
|
||||
use App\Jobs\ContainerStatusJob;
|
||||
use App\Actions\Proxy\StartProxy;
|
||||
use App\Models\Server;
|
||||
use Livewire\Component;
|
||||
|
||||
@@ -44,7 +44,10 @@ class Status extends Component
|
||||
}
|
||||
$this->numberOfPolls++;
|
||||
}
|
||||
CheckProxy::run($this->server, true);
|
||||
$shouldStart = CheckProxy::run($this->server, true);
|
||||
if ($shouldStart) {
|
||||
StartProxy::run($this->server, false);
|
||||
}
|
||||
$this->dispatch('proxyStatusUpdated');
|
||||
if ($this->server->proxy->status === 'running') {
|
||||
$this->polling = false;
|
||||
|
||||
@@ -24,9 +24,11 @@ class Project extends BaseModel
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
protected $appends = ['default_environment'];
|
||||
|
||||
public static function ownedByCurrentTeam()
|
||||
{
|
||||
return Project::whereTeamId(currentTeam()->id)->orderBy('name');
|
||||
return Project::whereTeamId(currentTeam()->id)->orderByRaw('LOWER(name)');
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
@@ -131,7 +133,7 @@ class Project extends BaseModel
|
||||
return $this->postgresqls()->get()->merge($this->redis()->get())->merge($this->mongodbs()->get())->merge($this->mysqls()->get())->merge($this->mariadbs()->get())->merge($this->keydbs()->get())->merge($this->dragonflies()->get())->merge($this->clickhouses()->get());
|
||||
}
|
||||
|
||||
public function default_environment()
|
||||
public function getDefaultEnvironmentAttribute()
|
||||
{
|
||||
$default = $this->environments()->where('name', 'production')->first();
|
||||
if ($default) {
|
||||
|
||||
@@ -448,11 +448,19 @@ $schema://$host {
|
||||
// Should move everything except /caddy and /nginx to /traefik
|
||||
// The code needs to be modified as well, so maybe it does not worth it
|
||||
if ($proxyType === ProxyTypes::TRAEFIK->value) {
|
||||
$proxy_path = $proxy_path;
|
||||
// Do nothing
|
||||
} elseif ($proxyType === ProxyTypes::CADDY->value) {
|
||||
$proxy_path = $proxy_path.'/caddy';
|
||||
if (isDev()) {
|
||||
$proxy_path = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/caddy';
|
||||
} else {
|
||||
$proxy_path = $proxy_path.'/caddy';
|
||||
}
|
||||
} elseif ($proxyType === ProxyTypes::NGINX->value) {
|
||||
$proxy_path = $proxy_path.'/nginx';
|
||||
if (isDev()) {
|
||||
$proxy_path = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/nginx';
|
||||
} else {
|
||||
$proxy_path = $proxy_path.'/nginx';
|
||||
}
|
||||
}
|
||||
|
||||
return $proxy_path;
|
||||
@@ -460,15 +468,6 @@ $schema://$host {
|
||||
|
||||
public function proxyType()
|
||||
{
|
||||
// $proxyType = $this->proxy->get('type');
|
||||
// if ($proxyType === ProxyTypes::NONE->value) {
|
||||
// return $proxyType;
|
||||
// }
|
||||
// if (is_null($proxyType)) {
|
||||
// $this->proxy->type = ProxyTypes::TRAEFIK->value;
|
||||
// $this->proxy->status = ProxyStatus::EXITED->value;
|
||||
// $this->save();
|
||||
// }
|
||||
return data_get($this->proxy, 'type');
|
||||
}
|
||||
|
||||
|
||||
@@ -283,9 +283,147 @@ class Service extends BaseModel
|
||||
$fields = collect([]);
|
||||
$applications = $this->applications()->get();
|
||||
foreach ($applications as $application) {
|
||||
$image = str($application->image)->before(':')->value();
|
||||
$image = str($application->image)->before(':');
|
||||
if ($image->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
switch ($image) {
|
||||
case str($image)?->contains('rabbitmq'):
|
||||
case $image->contains('label-studio'):
|
||||
$data = collect([]);
|
||||
$username = $this->environment_variables()->where('key', 'LABEL_STUDIO_USERNAME')->first();
|
||||
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_LABELSTUDIO')->first();
|
||||
if ($username) {
|
||||
$data = $data->merge([
|
||||
'Username' => [
|
||||
'key' => 'LABEL_STUDIO_USERNAME',
|
||||
'value' => data_get($username, 'value'),
|
||||
'rules' => 'required',
|
||||
],
|
||||
]);
|
||||
}
|
||||
if ($password) {
|
||||
$data = $data->merge([
|
||||
'Password' => [
|
||||
'key' => 'LABEL_STUDIO_PASSWORD',
|
||||
'value' => data_get($password, 'value'),
|
||||
'rules' => 'required',
|
||||
'isPassword' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
$fields->put('Label Studio', $data->toArray());
|
||||
break;
|
||||
case $image->contains('litellm'):
|
||||
$data = collect([]);
|
||||
$username = $this->environment_variables()->where('key', 'SERVICE_USER_UI')->first();
|
||||
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_UI')->first();
|
||||
if ($username) {
|
||||
$data = $data->merge([
|
||||
'Username' => [
|
||||
'key' => data_get($username, 'key'),
|
||||
'value' => data_get($username, 'value'),
|
||||
'rules' => 'required',
|
||||
],
|
||||
]);
|
||||
}
|
||||
if ($password) {
|
||||
$data = $data->merge([
|
||||
'Password' => [
|
||||
'key' => data_get($password, 'key'),
|
||||
'value' => data_get($password, 'value'),
|
||||
'rules' => 'required',
|
||||
'isPassword' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
$fields->put('Litellm', $data->toArray());
|
||||
break;
|
||||
case $image->contains('langfuse'):
|
||||
$data = collect([]);
|
||||
$email = $this->environment_variables()->where('key', 'LANGFUSE_INIT_USER_EMAIL')->first();
|
||||
if ($email) {
|
||||
$data = $data->merge([
|
||||
'Admin Email' => [
|
||||
'key' => 'LANGFUSE_INIT_USER_EMAIL',
|
||||
'value' => data_get($email, 'value'),
|
||||
'rules' => 'required|email',
|
||||
],
|
||||
]);
|
||||
}
|
||||
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_LANGFUSE')->first();
|
||||
ray('password', $password);
|
||||
if ($password) {
|
||||
$data = $data->merge([
|
||||
'Admin Password' => [
|
||||
'key' => 'LANGFUSE_INIT_USER_PASSWORD',
|
||||
'value' => data_get($password, 'value'),
|
||||
'rules' => 'required',
|
||||
'isPassword' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
$fields->put('Langfuse', $data->toArray());
|
||||
break;
|
||||
case $image->contains('invoiceninja'):
|
||||
$data = collect([]);
|
||||
$email = $this->environment_variables()->where('key', 'IN_USER_EMAIL')->first();
|
||||
$data = $data->merge([
|
||||
'Email' => [
|
||||
'key' => 'IN_USER_EMAIL',
|
||||
'value' => data_get($email, 'value'),
|
||||
'rules' => 'required|email',
|
||||
],
|
||||
]);
|
||||
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_INVOICENINJAUSER')->first();
|
||||
$data = $data->merge([
|
||||
'Password' => [
|
||||
'key' => 'IN_PASSWORD',
|
||||
'value' => data_get($password, 'value'),
|
||||
'rules' => 'required',
|
||||
'isPassword' => true,
|
||||
],
|
||||
]);
|
||||
$fields->put('Invoice Ninja', $data->toArray());
|
||||
break;
|
||||
case $image->contains('argilla'):
|
||||
$data = collect([]);
|
||||
$api_key = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_APIKEY')->first();
|
||||
$data = $data->merge([
|
||||
'API Key' => [
|
||||
'key' => data_get($api_key, 'key'),
|
||||
'value' => data_get($api_key, 'value'),
|
||||
'isPassword' => true,
|
||||
'rules' => 'required',
|
||||
],
|
||||
]);
|
||||
$data = $data->merge([
|
||||
'API Key' => [
|
||||
'key' => data_get($api_key, 'key'),
|
||||
'value' => data_get($api_key, 'value'),
|
||||
'isPassword' => true,
|
||||
'rules' => 'required',
|
||||
],
|
||||
]);
|
||||
$username = $this->environment_variables()->where('key', 'ARGILLA_USERNAME')->first();
|
||||
$data = $data->merge([
|
||||
'Username' => [
|
||||
'key' => data_get($username, 'key'),
|
||||
'value' => data_get($username, 'value'),
|
||||
'rules' => 'required',
|
||||
],
|
||||
]);
|
||||
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_ARGILLA')->first();
|
||||
$data = $data->merge([
|
||||
'Password' => [
|
||||
'key' => data_get($password, 'key'),
|
||||
'value' => data_get($password, 'value'),
|
||||
'rules' => 'required',
|
||||
'isPassword' => true,
|
||||
],
|
||||
]);
|
||||
$fields->put('Argilla', $data->toArray());
|
||||
break;
|
||||
case $image->contains('rabbitmq'):
|
||||
$data = collect([]);
|
||||
$host_port = $this->environment_variables()->where('key', 'PORT')->first();
|
||||
$username = $this->environment_variables()->where('key', 'SERVICE_USER_RABBITMQ')->first();
|
||||
@@ -320,7 +458,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('RabbitMQ', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('tolgee'):
|
||||
case $image->contains('tolgee'):
|
||||
$data = collect([]);
|
||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_TOLGEE')->first();
|
||||
$data = $data->merge([
|
||||
@@ -343,7 +481,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('Tolgee', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('logto'):
|
||||
case $image->contains('logto'):
|
||||
$data = collect([]);
|
||||
$logto_endpoint = $this->environment_variables()->where('key', 'LOGTO_ENDPOINT')->first();
|
||||
$logto_admin_endpoint = $this->environment_variables()->where('key', 'LOGTO_ADMIN_ENDPOINT')->first();
|
||||
@@ -367,7 +505,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('Logto', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('unleash-server'):
|
||||
case $image->contains('unleash-server'):
|
||||
$data = collect([]);
|
||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_UNLEASH')->first();
|
||||
$data = $data->merge([
|
||||
@@ -390,7 +528,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('Unleash', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('grafana'):
|
||||
case $image->contains('grafana'):
|
||||
$data = collect([]);
|
||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_GRAFANA')->first();
|
||||
$data = $data->merge([
|
||||
@@ -413,7 +551,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('Grafana', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('directus'):
|
||||
case $image->contains('directus'):
|
||||
$data = collect([]);
|
||||
$admin_email = $this->environment_variables()->where('key', 'ADMIN_EMAIL')->first();
|
||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_ADMIN')->first();
|
||||
@@ -439,7 +577,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('Directus', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('kong'):
|
||||
case $image->contains('kong'):
|
||||
$data = collect([]);
|
||||
$dashboard_user = $this->environment_variables()->where('key', 'SERVICE_USER_ADMIN')->first();
|
||||
$dashboard_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_ADMIN')->first();
|
||||
@@ -463,7 +601,7 @@ class Service extends BaseModel
|
||||
]);
|
||||
}
|
||||
$fields->put('Supabase', $data->toArray());
|
||||
case str($image)?->contains('minio'):
|
||||
case $image->contains('minio'):
|
||||
$data = collect([]);
|
||||
$console_url = $this->environment_variables()->where('key', 'MINIO_BROWSER_REDIRECT_URL')->first();
|
||||
$s3_api_url = $this->environment_variables()->where('key', 'MINIO_SERVER_URL')->first();
|
||||
@@ -516,7 +654,7 @@ class Service extends BaseModel
|
||||
|
||||
$fields->put('MinIO', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('weblate'):
|
||||
case $image->contains('weblate'):
|
||||
$data = collect([]);
|
||||
$admin_email = $this->environment_variables()->where('key', 'WEBLATE_ADMIN_EMAIL')->first();
|
||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_WEBLATE')->first();
|
||||
@@ -542,7 +680,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('Weblate', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('meilisearch'):
|
||||
case $image->contains('meilisearch'):
|
||||
$data = collect([]);
|
||||
$SERVICE_PASSWORD_MEILISEARCH = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_MEILISEARCH')->first();
|
||||
if ($SERVICE_PASSWORD_MEILISEARCH) {
|
||||
@@ -556,7 +694,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('Meilisearch', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('ghost'):
|
||||
case $image->contains('ghost'):
|
||||
$data = collect([]);
|
||||
$MAIL_OPTIONS_AUTH_PASS = $this->environment_variables()->where('key', 'MAIL_OPTIONS_AUTH_PASS')->first();
|
||||
$MAIL_OPTIONS_AUTH_USER = $this->environment_variables()->where('key', 'MAIL_OPTIONS_AUTH_USER')->first();
|
||||
@@ -616,45 +754,8 @@ class Service extends BaseModel
|
||||
|
||||
$fields->put('Ghost', $data->toArray());
|
||||
break;
|
||||
default:
|
||||
$data = collect([]);
|
||||
$admin_user = $this->environment_variables()->where('key', 'SERVICE_USER_ADMIN')->first();
|
||||
// Chaskiq
|
||||
$admin_email = $this->environment_variables()->where('key', 'ADMIN_EMAIL')->first();
|
||||
|
||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_ADMIN')->first();
|
||||
if ($admin_user) {
|
||||
$data = $data->merge([
|
||||
'User' => [
|
||||
'key' => 'SERVICE_USER_ADMIN',
|
||||
'value' => data_get($admin_user, 'value', 'admin'),
|
||||
'readonly' => true,
|
||||
'rules' => 'required',
|
||||
],
|
||||
]);
|
||||
}
|
||||
if ($admin_password) {
|
||||
$data = $data->merge([
|
||||
'Password' => [
|
||||
'key' => 'SERVICE_PASSWORD_ADMIN',
|
||||
'value' => data_get($admin_password, 'value'),
|
||||
'rules' => 'required',
|
||||
'isPassword' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
if ($admin_email) {
|
||||
$data = $data->merge([
|
||||
'Email' => [
|
||||
'key' => 'ADMIN_EMAIL',
|
||||
'value' => data_get($admin_email, 'value'),
|
||||
'rules' => 'required|email',
|
||||
],
|
||||
]);
|
||||
}
|
||||
$fields->put('Admin', $data->toArray());
|
||||
break;
|
||||
case str($image)?->contains('vaultwarden'):
|
||||
case $image->contains('vaultwarden'):
|
||||
$data = collect([]);
|
||||
|
||||
$DATABASE_URL = $this->environment_variables()->where('key', 'DATABASE_URL')->first();
|
||||
@@ -720,7 +821,7 @@ class Service extends BaseModel
|
||||
|
||||
$fields->put('Vaultwarden', $data);
|
||||
break;
|
||||
case str($image)->contains('gitlab/gitlab'):
|
||||
case $image->contains('gitlab/gitlab'):
|
||||
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_GITLAB')->first();
|
||||
$data = collect([]);
|
||||
if ($password) {
|
||||
@@ -744,7 +845,7 @@ class Service extends BaseModel
|
||||
|
||||
$fields->put('GitLab', $data->toArray());
|
||||
break;
|
||||
case str($image)->contains('code-server'):
|
||||
case $image->contains('code-server'):
|
||||
$data = collect([]);
|
||||
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_64_PASSWORDCODESERVER')->first();
|
||||
if ($password) {
|
||||
@@ -770,7 +871,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('Code Server', $data->toArray());
|
||||
break;
|
||||
case str($image)->contains('elestio/strapi'):
|
||||
case $image->contains('elestio/strapi'):
|
||||
$data = collect([]);
|
||||
$license = $this->environment_variables()->where('key', 'STRAPI_LICENSE')->first();
|
||||
if ($license) {
|
||||
@@ -793,16 +894,55 @@ class Service extends BaseModel
|
||||
|
||||
$fields->put('Strapi', $data->toArray());
|
||||
break;
|
||||
default:
|
||||
$data = collect([]);
|
||||
$admin_user = $this->environment_variables()->where('key', 'SERVICE_USER_ADMIN')->first();
|
||||
// Chaskiq
|
||||
$admin_email = $this->environment_variables()->where('key', 'ADMIN_EMAIL')->first();
|
||||
|
||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_ADMIN')->first();
|
||||
if ($admin_user) {
|
||||
$data = $data->merge([
|
||||
'User' => [
|
||||
'key' => 'SERVICE_USER_ADMIN',
|
||||
'value' => data_get($admin_user, 'value', 'admin'),
|
||||
'readonly' => true,
|
||||
'rules' => 'required',
|
||||
],
|
||||
]);
|
||||
}
|
||||
if ($admin_password) {
|
||||
$data = $data->merge([
|
||||
'Password' => [
|
||||
'key' => 'SERVICE_PASSWORD_ADMIN',
|
||||
'value' => data_get($admin_password, 'value'),
|
||||
'rules' => 'required',
|
||||
'isPassword' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
if ($admin_email) {
|
||||
$data = $data->merge([
|
||||
'Email' => [
|
||||
'key' => 'ADMIN_EMAIL',
|
||||
'value' => data_get($admin_email, 'value'),
|
||||
'rules' => 'required|email',
|
||||
],
|
||||
]);
|
||||
}
|
||||
$fields->put('Admin', $data->toArray());
|
||||
break;
|
||||
}
|
||||
}
|
||||
$databases = $this->databases()->get();
|
||||
ray($databases);
|
||||
|
||||
foreach ($databases as $database) {
|
||||
$image = str($database->image)->before(':')->value();
|
||||
$image = str($database->image)->before(':');
|
||||
if ($image->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
switch ($image) {
|
||||
case str($image)->contains('postgres'):
|
||||
case $image->contains('postgres'):
|
||||
$userVariables = ['SERVICE_USER_POSTGRES', 'SERVICE_USER_POSTGRESQL'];
|
||||
$passwordVariables = ['SERVICE_PASSWORD_POSTGRES', 'SERVICE_PASSWORD_POSTGRESQL'];
|
||||
$dbNameVariables = ['POSTGRESQL_DATABASE', 'POSTGRES_DB'];
|
||||
@@ -840,7 +980,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('PostgreSQL', $data->toArray());
|
||||
break;
|
||||
case str($image)->contains('mysql'):
|
||||
case $image->contains('mysql'):
|
||||
$userVariables = ['SERVICE_USER_MYSQL', 'SERVICE_USER_WORDPRESS', 'MYSQL_USER'];
|
||||
$passwordVariables = ['SERVICE_PASSWORD_MYSQL', 'SERVICE_PASSWORD_WORDPRESS', 'MYSQL_PASSWORD'];
|
||||
$rootPasswordVariables = ['SERVICE_PASSWORD_MYSQLROOT', 'SERVICE_PASSWORD_ROOT'];
|
||||
@@ -890,7 +1030,7 @@ class Service extends BaseModel
|
||||
}
|
||||
$fields->put('MySQL', $data->toArray());
|
||||
break;
|
||||
case str($image)->contains('mariadb'):
|
||||
case $image->contains('mariadb'):
|
||||
$userVariables = ['SERVICE_USER_MARIADB', 'SERVICE_USER_WORDPRESS', '_APP_DB_USER', 'SERVICE_USER_MYSQL', 'MYSQL_USER'];
|
||||
$passwordVariables = ['SERVICE_PASSWORD_MARIADB', 'SERVICE_PASSWORD_WORDPRESS', '_APP_DB_PASS', 'MYSQL_PASSWORD'];
|
||||
$rootPasswordVariables = ['SERVICE_PASSWORD_MARIADBROOT', 'SERVICE_PASSWORD_ROOT', '_APP_DB_ROOT_PASS', 'MYSQL_ROOT_PASSWORD'];
|
||||
@@ -1077,12 +1217,12 @@ class Service extends BaseModel
|
||||
public function environment_variables(): HasMany
|
||||
{
|
||||
|
||||
return $this->hasMany(EnvironmentVariable::class)->orderByRaw("key LIKE 'SERVICE%' DESC, value ASC");
|
||||
return $this->hasMany(EnvironmentVariable::class)->orderByRaw("LOWER(key) LIKE LOWER('SERVICE%') DESC, LOWER(key) ASC");
|
||||
}
|
||||
|
||||
public function environment_variables_preview(): HasMany
|
||||
{
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->orderBy('key', 'asc');
|
||||
return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->orderByRaw("LOWER(key) LIKE LOWER('SERVICE%') DESC, LOWER(key) ASC");
|
||||
}
|
||||
|
||||
public function workdir()
|
||||
|
||||
@@ -112,4 +112,9 @@ class ServiceApplication extends BaseModel
|
||||
{
|
||||
getFilesystemVolumesFromServer($this, $isInit);
|
||||
}
|
||||
|
||||
public function isBackupSolutionAvailable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,6 +120,7 @@ class ServiceDatabase extends BaseModel
|
||||
{
|
||||
return str($this->databaseType())->contains('mysql') ||
|
||||
str($this->databaseType())->contains('postgres') ||
|
||||
str($this->databaseType())->contains('postgis') ||
|
||||
str($this->databaseType())->contains('mariadb') ||
|
||||
str($this->databaseType())->contains('mongodb');
|
||||
}
|
||||
|
||||
@@ -20,12 +20,16 @@ const RESTART_MODE = 'unless-stopped';
|
||||
const DATABASE_DOCKER_IMAGES = [
|
||||
'bitnami/mariadb',
|
||||
'bitnami/mongodb',
|
||||
'bitnami/mysql',
|
||||
'bitnami/postgresql',
|
||||
'bitnami/redis',
|
||||
'mysql',
|
||||
'bitnami/mysql',
|
||||
'mysql/mysql-server',
|
||||
'mariadb',
|
||||
'postgis/postgis',
|
||||
'postgres',
|
||||
'bitnami/postgresql',
|
||||
'supabase/postgres',
|
||||
'elestio/postgres',
|
||||
'mongo',
|
||||
'redis',
|
||||
'memcached',
|
||||
@@ -33,8 +37,6 @@ const DATABASE_DOCKER_IMAGES = [
|
||||
'neo4j',
|
||||
'influxdb',
|
||||
'clickhouse/clickhouse-server',
|
||||
'supabase/postgres',
|
||||
'elestio/postgres',
|
||||
];
|
||||
const SPECIFIC_SERVICES = [
|
||||
'quay.io/minio/minio',
|
||||
|
||||
@@ -325,38 +325,16 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$labels->push('traefik.http.middlewares.gzip.compress=true');
|
||||
$labels->push('traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https');
|
||||
|
||||
$basic_auth = false;
|
||||
$basic_auth_middleware = null;
|
||||
$redirect = false;
|
||||
$redirect_middleware = null;
|
||||
$middlewares_from_labels = collect([]);
|
||||
|
||||
if ($serviceLabels) {
|
||||
$basic_auth = $serviceLabels->contains(function ($value) {
|
||||
return str_contains($value, 'basicauth');
|
||||
});
|
||||
if ($basic_auth) {
|
||||
$basic_auth_middleware = $serviceLabels
|
||||
->map(function ($item) {
|
||||
if (preg_match('/traefik\.http\.middlewares\.(.*?)\.basicauth\.users/', $item, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
})
|
||||
->filter()
|
||||
->first();
|
||||
}
|
||||
$redirect = $serviceLabels->contains(function ($value) {
|
||||
return str_contains($value, 'redirectregex');
|
||||
});
|
||||
if ($redirect) {
|
||||
$redirect_middleware = $serviceLabels
|
||||
->map(function ($item) {
|
||||
if (preg_match('/traefik\.http\.middlewares\.(.*?)\.redirectregex\.regex/', $item, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
})
|
||||
->filter()
|
||||
->first();
|
||||
}
|
||||
$middlewares_from_labels = $serviceLabels->map(function ($item) {
|
||||
if (preg_match('/traefik\.http\.middlewares\.(.*?)(\.|$)/', $item, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
return null;
|
||||
})->filter()
|
||||
->unique();
|
||||
}
|
||||
foreach ($domains as $loop => $domain) {
|
||||
try {
|
||||
@@ -404,20 +382,15 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$labels->push("traefik.http.services.{$https_label}.loadbalancer.server.port=$port");
|
||||
}
|
||||
if ($path !== '/') {
|
||||
// Middleware handling
|
||||
$middlewares = collect([]);
|
||||
if ($is_stripprefix_enabled && ! str($image)->contains('ghost')) {
|
||||
if ($is_stripprefix_enabled && !str($image)->contains('ghost')) {
|
||||
$labels->push("traefik.http.middlewares.{$https_label}-stripprefix.stripprefix.prefixes={$path}");
|
||||
$middlewares->push("{$https_label}-stripprefix");
|
||||
}
|
||||
if ($is_gzip_enabled) {
|
||||
$middlewares->push('gzip');
|
||||
}
|
||||
if ($basic_auth && $basic_auth_middleware) {
|
||||
$middlewares->push($basic_auth_middleware);
|
||||
}
|
||||
if ($redirect && $redirect_middleware) {
|
||||
$middlewares->push($redirect_middleware);
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
}
|
||||
@@ -425,10 +398,13 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$labels = $labels->merge($redirect_to_non_www);
|
||||
$middlewares->push($to_non_www_name);
|
||||
}
|
||||
if ($redirect_direction === 'www' && ! str($host)->startsWith('www.')) {
|
||||
if ($redirect_direction === 'www' && !str($host)->startsWith('www.')) {
|
||||
$labels = $labels->merge($redirect_to_www);
|
||||
$middlewares->push($to_www_name);
|
||||
}
|
||||
$middlewares_from_labels->each(function ($middleware_name) use ($middlewares) {
|
||||
$middlewares->push($middleware_name);
|
||||
});
|
||||
if ($middlewares->isNotEmpty()) {
|
||||
$middlewares = $middlewares->join(',');
|
||||
$labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}");
|
||||
@@ -437,13 +413,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$middlewares = collect([]);
|
||||
if ($is_gzip_enabled) {
|
||||
$middlewares->push('gzip');
|
||||
}
|
||||
if ($basic_auth && $basic_auth_middleware) {
|
||||
$middlewares->push($basic_auth_middleware);
|
||||
}
|
||||
if ($redirect && $redirect_middleware) {
|
||||
$middlewares->push($redirect_middleware);
|
||||
}
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
}
|
||||
@@ -455,6 +425,9 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$labels = $labels->merge($redirect_to_www);
|
||||
$middlewares->push($to_www_name);
|
||||
}
|
||||
$middlewares_from_labels->each(function ($middleware_name) use ($middlewares) {
|
||||
$middlewares->push($middleware_name);
|
||||
});
|
||||
if ($middlewares->isNotEmpty()) {
|
||||
$middlewares = $middlewares->join(',');
|
||||
$labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}");
|
||||
@@ -490,12 +463,6 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
if ($is_gzip_enabled) {
|
||||
$middlewares->push('gzip');
|
||||
}
|
||||
if ($basic_auth && $basic_auth_middleware) {
|
||||
$middlewares->push($basic_auth_middleware);
|
||||
}
|
||||
if ($redirect && $redirect_middleware) {
|
||||
$middlewares->push($redirect_middleware);
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
}
|
||||
@@ -507,6 +474,9 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$labels = $labels->merge($redirect_to_www);
|
||||
$middlewares->push($to_www_name);
|
||||
}
|
||||
$middlewares_from_labels->each(function ($middleware_name) use ($middlewares) {
|
||||
$middlewares->push($middleware_name);
|
||||
});
|
||||
if ($middlewares->isNotEmpty()) {
|
||||
$middlewares = $middlewares->join(',');
|
||||
$labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}");
|
||||
@@ -516,12 +486,6 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
if ($is_gzip_enabled) {
|
||||
$middlewares->push('gzip');
|
||||
}
|
||||
if ($basic_auth && $basic_auth_middleware) {
|
||||
$middlewares->push($basic_auth_middleware);
|
||||
}
|
||||
if ($redirect && $redirect_middleware) {
|
||||
$middlewares->push($redirect_middleware);
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
}
|
||||
@@ -533,6 +497,9 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$labels = $labels->merge($redirect_to_www);
|
||||
$middlewares->push($to_www_name);
|
||||
}
|
||||
$middlewares_from_labels->each(function ($middleware_name) use ($middlewares) {
|
||||
$middlewares->push($middleware_name);
|
||||
});
|
||||
if ($middlewares->isNotEmpty()) {
|
||||
$middlewares = $middlewares->join(',');
|
||||
$labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}");
|
||||
|
||||
@@ -522,6 +522,11 @@ function sslip(Server $server)
|
||||
|
||||
function get_service_templates(bool $force = false): Collection
|
||||
{
|
||||
if (isDev()) {
|
||||
$services = File::get(base_path('templates/service-templates.json'));
|
||||
|
||||
return collect(json_decode($services))->sortKeys();
|
||||
}
|
||||
if ($force) {
|
||||
try {
|
||||
$response = Http::retry(3, 1000)->get(config('constants.services.official'));
|
||||
@@ -828,6 +833,31 @@ function convertToArray($collection)
|
||||
return $collection;
|
||||
}
|
||||
|
||||
function parseCommandFromMagicEnvVariable(Str|string $key): Stringable
|
||||
{
|
||||
$value = str($key);
|
||||
$count = substr_count($value->value(), '_');
|
||||
if ($count === 2) {
|
||||
if ($value->startsWith('SERVICE_FQDN') || $value->startsWith('SERVICE_URL')) {
|
||||
// SERVICE_FQDN_UMAMI
|
||||
$command = $value->after('SERVICE_')->beforeLast('_');
|
||||
} else {
|
||||
// SERVICE_BASE64_UMAMI
|
||||
$command = $value->after('SERVICE_')->beforeLast('_');
|
||||
}
|
||||
}
|
||||
if ($count === 3) {
|
||||
if ($value->startsWith('SERVICE_FQDN') || $value->startsWith('SERVICE_URL')) {
|
||||
// SERVICE_FQDN_UMAMI_1000
|
||||
$command = $value->after('SERVICE_')->before('_');
|
||||
} else {
|
||||
// SERVICE_BASE64_64_UMAMI
|
||||
$command = $value->after('SERVICE_')->beforeLast('_');
|
||||
}
|
||||
}
|
||||
|
||||
return str($command);
|
||||
}
|
||||
function parseEnvVariable(Str|string $value)
|
||||
{
|
||||
$value = str($value);
|
||||
@@ -859,6 +889,7 @@ function parseEnvVariable(Str|string $value)
|
||||
} else {
|
||||
// SERVICE_BASE64_64_UMAMI
|
||||
$command = $value->after('SERVICE_')->beforeLast('_');
|
||||
ray($command);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3117,7 +3148,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
||||
foreach ($magicEnvironments as $key => $value) {
|
||||
$key = str($key);
|
||||
$value = replaceVariables($value);
|
||||
$command = $key->after('SERVICE_')->before('_');
|
||||
$command = parseCommandFromMagicEnvVariable($key);
|
||||
$found = $resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->first();
|
||||
if ($found) {
|
||||
continue;
|
||||
@@ -3676,6 +3707,18 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
||||
});
|
||||
}
|
||||
$serviceLabels = $labels->merge($defaultLabels);
|
||||
if ($serviceLabels->count() > 0) {
|
||||
if ($isApplication) {
|
||||
$isContainerLabelEscapeEnabled = data_get($resource, 'settings.is_container_label_escape_enabled');
|
||||
} else {
|
||||
$isContainerLabelEscapeEnabled = data_get($resource, 'is_container_label_escape_enabled');
|
||||
}
|
||||
if ($isContainerLabelEscapeEnabled) {
|
||||
$serviceLabels = $serviceLabels->map(function ($value, $key) {
|
||||
return escapeDollarSign($value);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
|
||||
if ($isApplication) {
|
||||
$shouldGenerateLabelsExactly = $resource->destination->server->settings->generate_exact_labels;
|
||||
|
||||
@@ -7,7 +7,7 @@ return [
|
||||
|
||||
// The release version of your application
|
||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||
'release' => '4.0.0-beta.351',
|
||||
'release' => '4.0.0-beta.357',
|
||||
// When left empty or `null` the Laravel environment will be used
|
||||
'environment' => config('app.env'),
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
return '4.0.0-beta.351';
|
||||
return '4.0.0-beta.357';
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"coolify": {
|
||||
"v4": {
|
||||
"version": "4.0.0-beta.350"
|
||||
"version": "4.0.0-beta.354"
|
||||
},
|
||||
"nightly": {
|
||||
"version": "4.0.0-beta.351"
|
||||
"version": "4.0.0-beta.355"
|
||||
},
|
||||
"helper": {
|
||||
"version": "1.0.1"
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"realtime": {
|
||||
"version": "1.0.3"
|
||||
|
||||
9
package-lock.json
generated
@@ -10,7 +10,7 @@
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"alpinejs": "3.14.0",
|
||||
"cookie": "^0.6.0",
|
||||
"cookie": "^0.7.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"ioredis": "5.4.1",
|
||||
"node-pty": "^1.0.0",
|
||||
@@ -960,10 +960,9 @@
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
||||
"license": "MIT",
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.0.tgz",
|
||||
"integrity": "sha512-qCf+V4dtlNhSRXGAZatc1TasyFO6GjohcOul807YOb5ik3+kQSnb4d7iajeCL8QHaJ4uZEjCgiCJerKXwdRVlQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"alpinejs": "3.14.0",
|
||||
"cookie": "^0.6.0",
|
||||
"cookie": "^0.7.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"ioredis": "5.4.1",
|
||||
"node-pty": "^1.0.0",
|
||||
|
||||
166
public/svgs/anythingllm.svg
Normal file
@@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0.00 0.00 245.00 245.00">
|
||||
<path stroke="#919393" stroke-width="2.00" fill="none" stroke-linecap="butt" vector-effect="non-scaling-stroke" d="
|
||||
M 187.03 159.00
|
||||
L 161.49 159.00
|
||||
A 1.24 1.24 0.0 0 1 160.48 158.48
|
||||
Q 153.96 149.33 147.89 140.81
|
||||
C 145.78 137.86 141.80 138.01 139.49 140.67
|
||||
C 136.43 144.17 133.65 147.56 136.44 151.42
|
||||
Q 142.22 159.39 148.22 167.98
|
||||
Q 152.74 174.47 160.49 174.57
|
||||
Q 173.94 174.73 188.79 174.60
|
||||
C 196.64 174.52 203.24 168.72 203.23 160.63
|
||||
Q 203.16 123.84 203.20 83.74
|
||||
C 203.21 78.41 199.97 73.56 195.17 71.35
|
||||
Q 191.90 69.85 186.23 69.92
|
||||
Q 173.94 70.08 161.37 69.94
|
||||
C 156.39 69.89 152.10 71.63 149.08 75.49
|
||||
Q 117.03 116.46 84.45 158.09
|
||||
A 2.37 2.35 -70.9 0 1 82.59 159.00
|
||||
L 57.21 159.00
|
||||
Q 56.65 159.00 56.65 158.45
|
||||
L 56.66 85.95
|
||||
Q 56.66 85.31 57.30 85.31
|
||||
L 83.00 85.31
|
||||
A 0.80 0.79 71.0 0 1 83.63 85.62
|
||||
Q 90.51 94.60 97.61 104.71
|
||||
C 99.47 107.36 103.07 108.21 105.48 105.83
|
||||
Q 107.60 103.72 109.70 100.67
|
||||
C 110.60 99.36 110.38 97.79 110.28 96.30
|
||||
Q 110.23 95.62 109.82 95.07
|
||||
Q 103.03 85.94 96.91 77.34
|
||||
C 93.63 72.73 89.66 69.98 84.18 70.00
|
||||
Q 71.60 70.05 56.56 69.96
|
||||
C 50.37 69.93 45.44 72.61 42.63 78.14
|
||||
Q 41.19 80.99 41.25 87.27
|
||||
Q 41.55 120.87 41.27 158.11
|
||||
Q 41.23 162.77 42.32 165.57
|
||||
Q 44.32 170.75 49.37 173.22
|
||||
Q 52.63 174.81 60.03 174.72
|
||||
Q 72.58 174.56 82.84 174.65
|
||||
Q 91.13 174.73 95.47 169.18
|
||||
Q 127.35 128.40 160.51 86.00
|
||||
A 1.81 1.80 18.9 0 1 161.93 85.31
|
||||
L 187.42 85.31
|
||||
A 0.40 0.40 0.0 0 1 187.82 85.71
|
||||
L 187.82 158.21
|
||||
Q 187.82 159.00 187.03 159.00"
|
||||
/>
|
||||
<path fill="#222627" d="
|
||||
M 46.00 0.00
|
||||
L 198.80 0.00
|
||||
Q 221.03 2.81 233.86 19.40
|
||||
Q 244.84 33.61 244.80 52.00
|
||||
Q 244.65 120.20 244.83 188.95
|
||||
Q 244.86 199.26 243.39 205.30
|
||||
Q 241.12 214.72 235.86 222.46
|
||||
C 234.56 224.37 232.98 226.08 231.56 227.86
|
||||
Q 229.92 229.91 227.88 231.54
|
||||
C 226.00 233.04 224.26 234.66 222.24 236.01
|
||||
Q 214.15 241.39 204.78 243.49
|
||||
Q 198.73 244.86 188.67 244.83
|
||||
Q 119.30 244.65 52.55 244.80
|
||||
Q 32.84 244.84 18.81 233.38
|
||||
Q 2.64 220.18 0.00 198.69
|
||||
L 0.00 45.76
|
||||
Q 1.42 35.66 4.33 29.79
|
||||
Q 17.17 3.86 46.00 0.00
|
||||
Z
|
||||
M 187.03 159.00
|
||||
L 161.49 159.00
|
||||
A 1.24 1.24 0.0 0 1 160.48 158.48
|
||||
Q 153.96 149.33 147.89 140.81
|
||||
C 145.78 137.86 141.80 138.01 139.49 140.67
|
||||
C 136.43 144.17 133.65 147.56 136.44 151.42
|
||||
Q 142.22 159.39 148.22 167.98
|
||||
Q 152.74 174.47 160.49 174.57
|
||||
Q 173.94 174.73 188.79 174.60
|
||||
C 196.64 174.52 203.24 168.72 203.23 160.63
|
||||
Q 203.16 123.84 203.20 83.74
|
||||
C 203.21 78.41 199.97 73.56 195.17 71.35
|
||||
Q 191.90 69.85 186.23 69.92
|
||||
Q 173.94 70.08 161.37 69.94
|
||||
C 156.39 69.89 152.10 71.63 149.08 75.49
|
||||
Q 117.03 116.46 84.45 158.09
|
||||
A 2.37 2.35 -70.9 0 1 82.59 159.00
|
||||
L 57.21 159.00
|
||||
Q 56.65 159.00 56.65 158.45
|
||||
L 56.66 85.95
|
||||
Q 56.66 85.31 57.30 85.31
|
||||
L 83.00 85.31
|
||||
A 0.80 0.79 71.0 0 1 83.63 85.62
|
||||
Q 90.51 94.60 97.61 104.71
|
||||
C 99.47 107.36 103.07 108.21 105.48 105.83
|
||||
Q 107.60 103.72 109.70 100.67
|
||||
C 110.60 99.36 110.38 97.79 110.28 96.30
|
||||
Q 110.23 95.62 109.82 95.07
|
||||
Q 103.03 85.94 96.91 77.34
|
||||
C 93.63 72.73 89.66 69.98 84.18 70.00
|
||||
Q 71.60 70.05 56.56 69.96
|
||||
C 50.37 69.93 45.44 72.61 42.63 78.14
|
||||
Q 41.19 80.99 41.25 87.27
|
||||
Q 41.55 120.87 41.27 158.11
|
||||
Q 41.23 162.77 42.32 165.57
|
||||
Q 44.32 170.75 49.37 173.22
|
||||
Q 52.63 174.81 60.03 174.72
|
||||
Q 72.58 174.56 82.84 174.65
|
||||
Q 91.13 174.73 95.47 169.18
|
||||
Q 127.35 128.40 160.51 86.00
|
||||
A 1.81 1.80 18.9 0 1 161.93 85.31
|
||||
L 187.42 85.31
|
||||
A 0.40 0.40 0.0 0 1 187.82 85.71
|
||||
L 187.82 158.21
|
||||
Q 187.82 159.00 187.03 159.00
|
||||
Z"
|
||||
/>
|
||||
<path fill="#ffffff" d="
|
||||
M 187.82 158.21
|
||||
L 187.82 85.71
|
||||
A 0.40 0.40 0.0 0 0 187.42 85.31
|
||||
L 161.93 85.31
|
||||
A 1.81 1.80 18.9 0 0 160.51 86.00
|
||||
Q 127.35 128.40 95.47 169.18
|
||||
Q 91.13 174.73 82.84 174.65
|
||||
Q 72.58 174.56 60.03 174.72
|
||||
Q 52.63 174.81 49.37 173.22
|
||||
Q 44.32 170.75 42.32 165.57
|
||||
Q 41.23 162.77 41.27 158.11
|
||||
Q 41.55 120.87 41.25 87.27
|
||||
Q 41.19 80.99 42.63 78.14
|
||||
C 45.44 72.61 50.37 69.93 56.56 69.96
|
||||
Q 71.60 70.05 84.18 70.00
|
||||
C 89.66 69.98 93.63 72.73 96.91 77.34
|
||||
Q 103.03 85.94 109.82 95.07
|
||||
Q 110.23 95.62 110.28 96.30
|
||||
C 110.38 97.79 110.60 99.36 109.70 100.67
|
||||
Q 107.60 103.72 105.48 105.83
|
||||
C 103.07 108.21 99.47 107.36 97.61 104.71
|
||||
Q 90.51 94.60 83.63 85.62
|
||||
A 0.80 0.79 71.0 0 0 83.00 85.31
|
||||
L 57.30 85.31
|
||||
Q 56.66 85.31 56.66 85.95
|
||||
L 56.65 158.45
|
||||
Q 56.65 159.00 57.21 159.00
|
||||
L 82.59 159.00
|
||||
A 2.37 2.35 -70.9 0 0 84.45 158.09
|
||||
Q 117.03 116.46 149.08 75.49
|
||||
C 152.10 71.63 156.39 69.89 161.37 69.94
|
||||
Q 173.94 70.08 186.23 69.92
|
||||
Q 191.90 69.85 195.17 71.35
|
||||
C 199.97 73.56 203.21 78.41 203.20 83.74
|
||||
Q 203.16 123.84 203.23 160.63
|
||||
C 203.24 168.72 196.64 174.52 188.79 174.60
|
||||
Q 173.94 174.73 160.49 174.57
|
||||
Q 152.74 174.47 148.22 167.98
|
||||
Q 142.22 159.39 136.44 151.42
|
||||
C 133.65 147.56 136.43 144.17 139.49 140.67
|
||||
C 141.80 138.01 145.78 137.86 147.89 140.81
|
||||
Q 153.96 149.33 160.48 158.48
|
||||
A 1.24 1.24 0.0 0 0 161.49 159.00
|
||||
L 187.03 159.00
|
||||
Q 187.82 159.00 187.82 158.21
|
||||
Z"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
BIN
public/svgs/argilla.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
1
public/svgs/clickhouse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="215" height="90" viewBox="0 0 100 43" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_378_10860)"><rect x="2.70837" y="2.875" width="2.24992" height="20.2493" rx="0.236664" fill="currentColor" /><rect x="7.2085" y="2.875" width="2.24992" height="20.2493" rx="0.236664" fill="currentColor" /><rect x="11.7086" y="2.875" width="2.24992" height="20.2493" rx="0.236664" fill="currentColor" /><rect x="16.2076" y="2.875" width="2.24992" height="20.2493" rx="0.236664" fill="currentColor" /><rect x="20.7087" y="10.7502" width="2.24992" height="4.49985" rx="0.236664" fill="currentColor" /></g></svg>
|
||||
|
After Width: | Height: | Size: 642 B |
BIN
public/svgs/coolify.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
public/svgs/getoutline.jpeg
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
11
public/svgs/homarr.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?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">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="484px" height="329px" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g><path style="opacity:0.947" fill="#f95251" d="M 157.5,-0.5 C 158.833,-0.5 160.167,-0.5 161.5,-0.5C 200.102,3.59921 222.268,24.9325 228,63.5C 228.667,88.5 228.667,113.5 228,138.5C 222.962,132.265 216.629,130.265 209,132.5C 208.667,109.167 208.333,85.8333 208,62.5C 202.332,36.3319 186.165,21.9986 159.5,19.5C 141.783,20.273 127.949,27.9397 118,42.5C 112.924,38.3791 107.757,34.3791 102.5,30.5C 115.97,11.5969 134.303,1.26361 157.5,-0.5 Z"/></g>
|
||||
<g><path style="opacity:0.947" fill="#f95251" d="M 321.5,-0.5 C 322.833,-0.5 324.167,-0.5 325.5,-0.5C 348.697,1.26361 367.03,11.5969 380.5,30.5C 375.243,34.3791 370.076,38.3791 365,42.5C 349.005,21.3908 328.505,15.2242 303.5,24C 287.107,31.7273 277.607,44.5606 275,62.5C 274.667,85.8333 274.333,109.167 274,132.5C 266.371,130.265 260.038,132.265 255,138.5C 254.333,113.5 254.333,88.5 255,63.5C 260.732,24.9325 282.898,3.59921 321.5,-0.5 Z"/></g>
|
||||
<g><path style="opacity:0.984" fill="#f95251" d="M -0.5,139.5 C -0.5,137.167 -0.5,134.833 -0.5,132.5C 19.5,132.5 39.5,132.5 59.5,132.5C 51.7127,98.1844 43.3793,64.0177 34.5,30C 83.3876,36.5512 118.554,62.0512 140,106.5C 159.513,155.397 153.846,201.064 123,243.5C 114.899,253.77 105.399,262.437 94.5,269.5C 90.7735,258.059 87.6068,246.392 85,234.5C 39.0428,218.384 10.5428,186.717 -0.5,139.5 Z"/></g>
|
||||
<g><path style="opacity:0.984" fill="#f95251" d="M 483.5,132.5 C 483.5,134.833 483.5,137.167 483.5,139.5C 472.457,186.717 443.957,218.384 398,234.5C 395.393,246.392 392.226,258.059 388.5,269.5C 351.514,243.037 332.514,206.871 331.5,161C 333.865,105.236 359.865,64.9024 409.5,40C 421.97,34.3953 434.97,31.0619 448.5,30C 439.621,64.0177 431.287,98.1844 423.5,132.5C 443.5,132.5 463.5,132.5 483.5,132.5 Z"/></g>
|
||||
<g><path style="opacity:0.95" fill="#f95251" d="M 211.5,170.5 C 225.127,170.958 231.627,177.958 231,191.5C 226.507,203.825 218.007,207.659 205.5,203C 197.535,196.871 195.369,189.037 199,179.5C 201.917,174.637 206.083,171.637 211.5,170.5 Z"/></g>
|
||||
<g><path style="opacity:0.949" fill="#f95251" d="M 265.5,170.5 C 280.848,170.68 287.348,178.347 285,193.5C 279.06,204.76 270.227,207.593 258.5,202C 249.176,192.625 249.176,183.292 258.5,174C 260.925,172.787 263.259,171.621 265.5,170.5 Z"/></g>
|
||||
<g><path style="opacity:0.987" fill="#f95251" d="M 388.5,328.5 C 386.5,328.5 384.5,328.5 382.5,328.5C 285.992,327.966 189.325,326.966 92.5,325.5C 120.96,261.579 170.294,227.913 240.5,224.5C 299.804,226.887 345.304,252.887 377,302.5C 381.676,310.846 385.509,319.513 388.5,328.5 Z"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
BIN
public/svgs/infisical.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
6
public/svgs/it-tools.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?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">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="512px" height="512px" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g><path style="opacity:0.995" fill="#18a057" d="M 230.5,-0.5 C 247.5,-0.5 264.5,-0.5 281.5,-0.5C 290.12,3.28885 296.287,9.62218 300,18.5C 299.871,28.5889 300.704,38.4222 302.5,48C 326.717,53.6219 349.217,63.1219 370,76.5C 376.469,71.0323 382.636,65.199 388.5,59C 398.925,52.0844 409.591,51.7511 420.5,58C 432,68.1667 442.833,79 453,90.5C 459,100.5 459,110.5 453,120.5C 447.017,127.317 440.851,133.984 434.5,140.5C 447.998,161.821 457.498,184.821 463,209.5C 474.144,210.648 485.31,211.815 496.5,213C 503.496,216.822 508.496,222.322 511.5,229.5C 511.5,246.5 511.5,263.5 511.5,280.5C 508.841,288.664 503.508,294.497 495.5,298C 484.573,299.444 473.573,300.277 462.5,300.5C 457.369,325.4 448.036,348.566 434.5,370C 441.693,377.526 448.526,385.359 455,393.5C 458.667,402.825 458.001,411.825 453,420.5C 443.167,430.333 433.333,440.167 423.5,450C 414.895,457.565 405.229,459.232 394.5,455C 386.322,448.153 378.155,441.32 370,434.5C 348.501,447.828 325.334,457.161 300.5,462.5C 301.01,473.958 300.177,485.291 298,496.5C 294.006,504.342 287.839,509.342 279.5,511.5C 263.167,511.5 246.833,511.5 230.5,511.5C 222.336,508.841 216.503,503.508 213,495.5C 212,484.833 211,474.167 210,463.5C 198.505,459.749 187.005,455.915 175.5,452C 173.842,451.275 173.342,450.108 174,448.5C 192.195,429.971 210.695,411.805 229.5,394C 293.836,401.915 343.336,378.748 378,324.5C 408.025,263.569 400.691,207.569 356,156.5C 315.267,118.147 267.767,106.314 213.5,121C 164.374,138.458 132.874,172.291 119,222.5C 117.485,228.075 116.485,233.742 116,239.5C 115.261,253.906 115.594,268.239 117,282.5C 98.8333,300.667 80.6667,318.833 62.5,337C 61.552,337.483 60.552,337.649 59.5,337.5C 54.8294,325.486 51.1627,313.153 48.5,300.5C 37.4331,300.188 26.4331,299.355 15.5,298C 7.189,293.843 1.85567,287.343 -0.5,278.5C -0.5,262.833 -0.5,247.167 -0.5,231.5C 2.22646,223.578 7.22646,217.411 14.5,213C 25.7307,211.098 37.0641,210.265 48.5,210.5C 53.718,185.511 63.0513,162.178 76.5,140.5C 71.2189,133.716 65.3855,127.383 59,121.5C 51.8558,110.353 52.1892,99.353 60,88.5C 69.8333,78.6667 79.6667,68.8333 89.5,59C 98.3002,53.1199 107.633,52.1199 117.5,56C 125.629,62.4604 133.463,69.2938 141,76.5C 162.028,62.9274 184.861,53.4274 209.5,48C 210.93,37.2282 212.097,26.3949 213,15.5C 216.503,7.49214 222.336,2.15881 230.5,-0.5 Z"/></g>
|
||||
<g><path style="opacity:0.99" fill="#1d1d1d" d="M 52.5,511.5 C 46.5,511.5 40.5,511.5 34.5,511.5C 16.5,506.167 4.83333,494.5 -0.5,476.5C -0.5,470.167 -0.5,463.833 -0.5,457.5C 1.14258,451.876 3.64258,446.542 7,441.5C 55.9723,391.528 105.306,341.861 155,292.5C 141.187,245.876 152.02,206.042 187.5,173C 216.657,150.235 248.991,143.902 284.5,154C 289.202,158.922 290.702,164.755 289,171.5C 275,186.167 261,200.833 247,215.5C 234.564,236.922 238.73,254.422 259.5,268C 272.178,272.999 284.178,271.666 295.5,264C 309.596,248.899 324.596,234.899 340.5,222C 353.68,220.169 360.513,226.003 361,239.5C 365.554,290.573 345.387,328.073 300.5,352C 273.591,363.046 246.258,364.379 218.5,356C 169.472,405.361 120.139,454.361 70.5,503C 64.8398,506.712 58.8398,509.545 52.5,511.5 Z"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
BIN
public/svgs/labelstudio.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
public/svgs/langfuse.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
1
public/svgs/litellm.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#939598" d="M0 34h36v2H0z"/><path fill="#D1D3D4" d="M3 35h33V6H21c-4 0-5 2-5 2l-4 6S0 19 0 24c0 4 6 6 6 6z"/><path fill="#231F20" d="m14 35 2-3h20v3z"/><path fill="#3B88C3" d="M0 23.999c0 4 6 6 6 6V17.125C3 19 0 21.499 0 23.999M6 30v-.001z"/><path fill="#269" d="m6 30-3 5h33v-5z"/><path fill="#3B88C3" d="m20 30 4-6h12v6z"/><path fill="#55ACEE" d="M26 8H16l-4 6h-.001 10.843c.477 0 1.108-.448 1.412-1l2.197-4c.303-.552.102-1-.451-1"/><path fill="#3B88C3" d="m25.902 10 .549-1c.303-.552.102-1-.451-1H16l-1.333 2z"/></svg>
|
||||
|
After Width: | Height: | Size: 593 B |
8
public/svgs/nitropage.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect transform="matrix(1 0 -.16885 .98564 0 0)" x="2.6887" y="1.2563" width="14.457" height="14.667" fill="#581c87" style="paint-order:stroke fill markers"/>
|
||||
<text x="0.74027044" y="12.170821" display="none" fill="#ffffff" font-family="'Liberation Sans'" font-size="10.583px" font-weight="bold" letter-spacing="-.66146px" stroke-width="4.2333" word-spacing="0px" xml:space="preserve"><tspan x="0.74027044" y="12.170821" fill="#ffffff" font-family="'Jost*'" font-size="10.583px" font-style="italic" font-weight="900" stroke-width="4.2333" style="paint-order:stroke fill markers">NP</tspan></text>
|
||||
<g fill="#fff" stroke-width="4.2333" aria-label="NP">
|
||||
<path d="m7.1008 4.7625-0.59266 3.3655-4.0322-3.7147-1.3229 7.7576h2.1907l0.58208-3.3655 4.0428 3.7147 1.3229-7.7576z" style="paint-order:stroke fill markers"/>
|
||||
<path d="m10.027 4.7625-1.27 7.4083h2.2966l0.39158-2.3283h0.62442c1.9156-0.021167 3.2385-0.89958 3.3867-2.54 0.14817-1.6192-0.79375-2.5188-2.6564-2.54zm2.5717 1.8415c0.48683 0.010583 0.75141 0.26458 0.67733 0.68791-0.08467 0.45508-0.508 0.6985-1.016 0.6985h-0.49742l0.24342-1.3864z" style="paint-order:stroke fill markers"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
14
public/svgs/ollama.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<?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">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="4096px" height="4096px" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g><path style="opacity:0.999" fill="#fefefe" d="M 1984.5,-0.5 C 2026.5,-0.5 2068.5,-0.5 2110.5,-0.5C 2537.4,15.5079 2922.4,149.008 3265.5,400C 3560.04,620.244 3781.2,898.744 3929,1235.5C 4031.4,1474.76 4086.9,1724.43 4095.5,1984.5C 4095.5,2026.5 4095.5,2068.5 4095.5,2110.5C 4079.61,2533.7 3948.11,2916.03 3701,3257.5C 3593.06,3404.12 3467.89,3534.62 3325.5,3649C 3314.27,3657.74 3302.94,3666.24 3291.5,3674.5C 3294.9,3533.77 3270.4,3398.11 3218,3267.5C 3213.27,3256.38 3208.27,3245.38 3203,3234.5C 3199.86,3228.11 3198.2,3221.44 3198,3214.5C 3233.37,3166.09 3260.04,3113.09 3278,3055.5C 3315.81,2931.9 3329.15,2805.57 3318,2676.5C 3312.19,2588.11 3293.86,2502.44 3263,2419.5C 3248.74,2385.4 3232.58,2352.23 3214.5,2320C 3228.7,2298.44 3242.54,2276.6 3256,2254.5C 3306.49,2163.1 3334.16,2065.1 3339,1960.5C 3347.09,1770.12 3293.75,1599.45 3179,1448.5C 3152.35,1414.84 3123.18,1383.34 3091.5,1354C 3073.96,1338.79 3056.13,1323.96 3038,1309.5C 3037.33,1303.83 3037.33,1298.17 3038,1292.5C 3071.33,1118.01 3070.66,943.681 3036,769.5C 3022.49,704.637 3000.82,642.637 2971,583.5C 2948.49,539.65 2918.65,501.484 2881.5,469C 2825.8,423.008 2762.8,409.008 2692.5,427C 2651.4,440.793 2615.9,463.293 2586,494.5C 2546.73,537.991 2515.73,586.991 2493,641.5C 2466.37,705.666 2447.04,771.999 2435,840.5C 2428.17,878.941 2423.17,917.608 2420,956.5C 2419.88,958.573 2418.88,959.907 2417,960.5C 2399.1,950.801 2381.27,940.967 2363.5,931C 2153.62,824.176 1943.62,823.842 1733.5,930C 1715.06,940.301 1696.56,950.467 1678,960.5C 1676.35,960.18 1675.35,959.18 1675,957.5C 1667.31,849.014 1643.31,744.347 1603,643.5C 1581.9,592.477 1553.57,546.144 1518,504.5C 1488.61,471.396 1453.44,446.562 1412.5,430C 1388.07,422.647 1363.07,419.147 1337.5,419.5C 1322.44,419.049 1307.78,421.215 1293.5,426C 1244.84,441.668 1204.68,469.502 1173,509.5C 1141.62,549.221 1116.62,592.887 1098,640.5C 1066.87,721.373 1047.53,805.04 1040,891.5C 1026.67,1023.93 1032.01,1155.6 1056,1286.5C 1057.33,1293.8 1058,1301.14 1058,1308.5C 887.035,1442.34 787.369,1617.67 759,1834.5C 747.069,1944.53 758.735,2051.86 794,2156.5C 807.02,2192.21 823.02,2226.54 842,2259.5C 854.715,2279.77 867.548,2299.93 880.5,2320C 836.781,2396.64 806.948,2478.47 791,2565.5C 783.711,2603.19 779.045,2641.19 777,2679.5C 776.333,2731.83 776.333,2784.17 777,2836.5C 782.248,2934.22 803.581,3028.22 841,3118.5C 856.12,3152.76 874.787,3184.76 897,3214.5C 897.611,3218.68 896.944,3222.68 895,3226.5C 830.268,3368.77 799.768,3518.1 803.5,3674.5C 556.783,3485.22 362.616,3252.55 221,2976.5C 83.5748,2704.13 9.74149,2415.47 -0.5,2110.5C -0.5,2068.5 -0.5,2026.5 -0.5,1984.5C 15.5079,1557.6 149.008,1172.6 400,829.5C 620.244,534.963 898.744,313.796 1235.5,166C 1474.76,63.6006 1724.43,8.10056 1984.5,-0.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#000000" d="M 3291.5,3674.5 C 3219.32,3730.61 3143.32,3781.28 3063.5,3826.5C 3086.34,3778.48 3098.17,3727.82 3099,3674.5C 3102.6,3547.82 3078.26,3426.82 3026,3311.5C 3012.26,3283.68 2998.26,3256.01 2984,3228.5C 2983.33,3211.83 2983.33,3195.17 2984,3178.5C 2986.77,3167.3 2991.43,3156.97 2998,3147.5C 3011.32,3131.52 3025.32,3116.18 3040,3101.5C 3055.7,3082.12 3068.37,3060.78 3078,3037.5C 3102.95,2974.82 3118.62,2909.82 3125,2842.5C 3135.67,2731.91 3124.67,2623.58 3092,2517.5C 3079.64,2478.12 3061.97,2441.45 3039,2407.5C 3031.38,2397.54 3023.38,2387.88 3015,2378.5C 2984.39,2332.41 2986.72,2288.07 3022,2245.5C 3066.42,2200.01 3099.09,2147.01 3120,2086.5C 3154.85,1979.03 3156.52,1871.03 3125,1762.5C 3089.97,1643.55 3024.14,1545.72 2927.5,1469C 2862.72,1419.8 2789.72,1390.13 2708.5,1380C 2686.83,1378.03 2665.16,1378.03 2643.5,1380C 2623.56,1383.05 2603.56,1385.55 2583.5,1387.5C 2544.15,1385.92 2515.31,1367.92 2497,1333.5C 2488.47,1313.24 2478.81,1293.57 2468,1274.5C 2451.43,1251.93 2434.1,1229.93 2416,1208.5C 2343.7,1135.91 2257.86,1085.74 2158.5,1058C 2140.99,1053.57 2123.33,1049.9 2105.5,1047C 2033.1,1038.03 1962.77,1046.03 1894.5,1071C 1825.56,1096.11 1763.56,1132.45 1708.5,1180C 1668.06,1216.42 1635.23,1258.58 1610,1306.5C 1603.43,1325.64 1593.77,1342.98 1581,1358.5C 1561.48,1377.23 1538.15,1386.57 1511,1386.5C 1493.39,1385.7 1475.89,1383.87 1458.5,1381C 1393.37,1374.82 1330.71,1384.49 1270.5,1410C 1181.85,1448.98 1109.68,1508.15 1054,1587.5C 957.404,1727.48 927.071,1880.82 963,2047.5C 983.321,2126.03 1021.65,2194.03 1078,2251.5C 1102.43,2283.23 1107.43,2317.89 1093,2355.5C 1089.44,2363.62 1085.11,2371.29 1080,2378.5C 1052.63,2408.91 1031.3,2443.25 1016,2481.5C 996.087,2532.48 982.42,2585.15 975,2639.5C 958.127,2755.12 965.46,2869.12 997,2981.5C 1005.9,3012.21 1017.9,3041.54 1033,3069.5C 1039.84,3080.51 1047.17,3091.18 1055,3101.5C 1069.68,3116.18 1083.68,3131.52 1097,3147.5C 1103.4,3157.04 1108.07,3167.37 1111,3178.5C 1111.67,3195.17 1111.67,3211.83 1111,3228.5C 1085.66,3274.84 1063.33,3322.51 1044,3371.5C 1005.13,3479.61 989.794,3590.94 998,3705.5C 1001.44,3737.36 1008.44,3768.36 1019,3798.5C 1022.7,3808.23 1027.2,3817.56 1032.5,3826.5C 952.208,3781.54 875.874,3730.87 803.5,3674.5C 799.768,3518.1 830.268,3368.77 895,3226.5C 896.944,3222.68 897.611,3218.68 897,3214.5C 874.787,3184.76 856.12,3152.76 841,3118.5C 803.581,3028.22 782.248,2934.22 777,2836.5C 776.333,2784.17 776.333,2731.83 777,2679.5C 779.045,2641.19 783.711,2603.19 791,2565.5C 806.948,2478.47 836.781,2396.64 880.5,2320C 867.548,2299.93 854.715,2279.77 842,2259.5C 823.02,2226.54 807.02,2192.21 794,2156.5C 758.735,2051.86 747.069,1944.53 759,1834.5C 787.369,1617.67 887.035,1442.34 1058,1308.5C 1058,1301.14 1057.33,1293.8 1056,1286.5C 1032.01,1155.6 1026.67,1023.93 1040,891.5C 1047.53,805.04 1066.87,721.373 1098,640.5C 1116.62,592.887 1141.62,549.221 1173,509.5C 1204.68,469.502 1244.84,441.668 1293.5,426C 1307.78,421.215 1322.44,419.049 1337.5,419.5C 1363.07,419.147 1388.07,422.647 1412.5,430C 1453.44,446.562 1488.61,471.396 1518,504.5C 1553.57,546.144 1581.9,592.477 1603,643.5C 1643.31,744.347 1667.31,849.014 1675,957.5C 1675.35,959.18 1676.35,960.18 1678,960.5C 1696.56,950.467 1715.06,940.301 1733.5,930C 1943.62,823.842 2153.62,824.176 2363.5,931C 2381.27,940.967 2399.1,950.801 2417,960.5C 2418.88,959.907 2419.88,958.573 2420,956.5C 2423.17,917.608 2428.17,878.941 2435,840.5C 2447.04,771.999 2466.37,705.666 2493,641.5C 2515.73,586.991 2546.73,537.991 2586,494.5C 2615.9,463.293 2651.4,440.793 2692.5,427C 2762.8,409.008 2825.8,423.008 2881.5,469C 2918.65,501.484 2948.49,539.65 2971,583.5C 3000.82,642.637 3022.49,704.637 3036,769.5C 3070.66,943.681 3071.33,1118.01 3038,1292.5C 3037.33,1298.17 3037.33,1303.83 3038,1309.5C 3056.13,1323.96 3073.96,1338.79 3091.5,1354C 3123.18,1383.34 3152.35,1414.84 3179,1448.5C 3293.75,1599.45 3347.09,1770.12 3339,1960.5C 3334.16,2065.1 3306.49,2163.1 3256,2254.5C 3242.54,2276.6 3228.7,2298.44 3214.5,2320C 3232.58,2352.23 3248.74,2385.4 3263,2419.5C 3293.86,2502.44 3312.19,2588.11 3318,2676.5C 3329.15,2805.57 3315.81,2931.9 3278,3055.5C 3260.04,3113.09 3233.37,3166.09 3198,3214.5C 3198.2,3221.44 3199.86,3228.11 3203,3234.5C 3208.27,3245.38 3213.27,3256.38 3218,3267.5C 3270.4,3398.11 3294.9,3533.77 3291.5,3674.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefefe" d="M 1343.5,613.5 C 1345.86,613.337 1348.19,613.503 1350.5,614C 1363.25,622.08 1374.08,632.247 1383,644.5C 1406.08,678.657 1424.41,715.323 1438,754.5C 1469.67,849.867 1486.01,947.867 1487,1048.5C 1487.67,1077.83 1487.67,1107.17 1487,1136.5C 1475.83,1153 1464.67,1169.5 1453.5,1186C 1407.83,1184.32 1362.5,1187.32 1317.5,1195C 1293.64,1199.88 1269.98,1205.55 1246.5,1212C 1244.5,1212.67 1242.5,1212.67 1240.5,1212C 1237.69,1200.67 1235.52,1189.17 1234,1177.5C 1220.98,1067.87 1222.98,958.541 1240,849.5C 1250.18,786.973 1269.18,727.306 1297,670.5C 1306.8,651.693 1319.3,634.86 1334.5,620C 1337.57,617.812 1340.57,615.645 1343.5,613.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefefe" d="M 2743.5,613.5 C 2746.98,613.184 2750.31,613.684 2753.5,615C 2767.13,624.964 2778.3,637.13 2787,651.5C 2807.31,685.784 2822.97,722.118 2834,760.5C 2858.32,848.257 2870.16,937.757 2869.5,1029C 2869.08,1081 2865.91,1132.83 2860,1184.5C 2858.99,1193.9 2857.16,1203.06 2854.5,1212C 2852.5,1212.67 2850.5,1212.67 2848.5,1212C 2813.95,1202.49 2778.95,1195.16 2743.5,1190C 2709.57,1187.05 2675.57,1185.71 2641.5,1186C 2630.33,1169.5 2619.17,1153 2608,1136.5C 2606.33,1076.74 2607.99,1017.07 2613,957.5C 2620.37,882.341 2637.04,809.341 2663,738.5C 2676.24,703.018 2693.9,670.018 2716,639.5C 2724.1,629.559 2733.27,620.893 2743.5,613.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefefe" d="M 3063.5,3826.5 C 2768.17,3994.26 2450.5,4083.93 2110.5,4095.5C 2068.5,4095.5 2026.5,4095.5 1984.5,4095.5C 1663.69,4084.63 1361.69,4003.8 1078.5,3853C 1062.94,3844.39 1047.61,3835.56 1032.5,3826.5C 1027.2,3817.56 1022.7,3808.23 1019,3798.5C 1008.44,3768.36 1001.44,3737.36 998,3705.5C 989.794,3590.94 1005.13,3479.61 1044,3371.5C 1063.33,3322.51 1085.66,3274.84 1111,3228.5C 1111.67,3211.83 1111.67,3195.17 1111,3178.5C 1108.07,3167.37 1103.4,3157.04 1097,3147.5C 1083.68,3131.52 1069.68,3116.18 1055,3101.5C 1047.17,3091.18 1039.84,3080.51 1033,3069.5C 1017.9,3041.54 1005.9,3012.21 997,2981.5C 965.46,2869.12 958.127,2755.12 975,2639.5C 982.42,2585.15 996.087,2532.48 1016,2481.5C 1031.3,2443.25 1052.63,2408.91 1080,2378.5C 1085.11,2371.29 1089.44,2363.62 1093,2355.5C 1107.43,2317.89 1102.43,2283.23 1078,2251.5C 1021.65,2194.03 983.321,2126.03 963,2047.5C 927.071,1880.82 957.404,1727.48 1054,1587.5C 1109.68,1508.15 1181.85,1448.98 1270.5,1410C 1330.71,1384.49 1393.37,1374.82 1458.5,1381C 1475.89,1383.87 1493.39,1385.7 1511,1386.5C 1538.15,1386.57 1561.48,1377.23 1581,1358.5C 1593.77,1342.98 1603.43,1325.64 1610,1306.5C 1635.23,1258.58 1668.06,1216.42 1708.5,1180C 1763.56,1132.45 1825.56,1096.11 1894.5,1071C 1962.77,1046.03 2033.1,1038.03 2105.5,1047C 2123.33,1049.9 2140.99,1053.57 2158.5,1058C 2257.86,1085.74 2343.7,1135.91 2416,1208.5C 2434.1,1229.93 2451.43,1251.93 2468,1274.5C 2478.81,1293.57 2488.47,1313.24 2497,1333.5C 2515.31,1367.92 2544.15,1385.92 2583.5,1387.5C 2603.56,1385.55 2623.56,1383.05 2643.5,1380C 2665.16,1378.03 2686.83,1378.03 2708.5,1380C 2789.72,1390.13 2862.72,1419.8 2927.5,1469C 3024.14,1545.72 3089.97,1643.55 3125,1762.5C 3156.52,1871.03 3154.85,1979.03 3120,2086.5C 3099.09,2147.01 3066.42,2200.01 3022,2245.5C 2986.72,2288.07 2984.39,2332.41 3015,2378.5C 3023.38,2387.88 3031.38,2397.54 3039,2407.5C 3061.97,2441.45 3079.64,2478.12 3092,2517.5C 3124.67,2623.58 3135.67,2731.91 3125,2842.5C 3118.62,2909.82 3102.95,2974.82 3078,3037.5C 3068.37,3060.78 3055.7,3082.12 3040,3101.5C 3025.32,3116.18 3011.32,3131.52 2998,3147.5C 2991.43,3156.97 2986.77,3167.3 2984,3178.5C 2983.33,3195.17 2983.33,3211.83 2984,3228.5C 2998.26,3256.01 3012.26,3283.68 3026,3311.5C 3078.26,3426.82 3102.6,3547.82 3099,3674.5C 3098.17,3727.82 3086.34,3778.48 3063.5,3826.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#000000" d="M 2012.5,1851.5 C 2112.37,1846.89 2208.04,1864.39 2299.5,1904C 2385.62,1942.45 2455.79,2000.28 2510,2077.5C 2542.75,2125.73 2563.75,2178.73 2573,2236.5C 2586.91,2380.14 2536.41,2494.97 2421.5,2581C 2340.82,2637.34 2251.15,2668.01 2152.5,2673C 2079.17,2674.97 2005.83,2674.97 1932.5,2673C 1826.08,2665.77 1731.75,2628.77 1649.5,2562C 1545.11,2470.64 1503.61,2356.14 1525,2218.5C 1543.42,2138.98 1581.08,2070.31 1638,2012.5C 1724.73,1929.05 1827.89,1877.89 1947.5,1859C 1969.31,1856.53 1990.98,1854.03 2012.5,1851.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#000000" d="M 1379.5,1875.5 C 1434.55,1872.44 1476.05,1894.44 1504,1941.5C 1507.73,1949.96 1511.73,1958.29 1516,1966.5C 1522.92,2031.46 1501.09,2084.29 1450.5,2125C 1425.26,2142.77 1397.26,2149.44 1366.5,2145C 1313.36,2136.83 1277.86,2107.33 1260,2056.5C 1249.49,1997.03 1266.32,1946.86 1310.5,1906C 1330.89,1889.8 1353.89,1879.64 1379.5,1875.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#000000" d="M 2687.5,1875.5 C 2742.89,1873.11 2785.39,1895.11 2815,1941.5C 2832.9,1972.49 2840.57,2005.82 2838,2041.5C 2828.41,2090.75 2799.91,2123.59 2752.5,2140C 2699.54,2155.81 2655.04,2142.98 2619,2101.5C 2597.87,2076.91 2584.54,2048.58 2579,2016.5C 2578.33,1999.83 2578.33,1983.17 2579,1966.5C 2593.13,1927.71 2618.96,1899.87 2656.5,1883C 2666.74,1879.52 2677.07,1877.02 2687.5,1875.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefefe" d="M 2018.5,1983.5 C 2118.82,1978 2211.82,2001.16 2297.5,2053C 2340.25,2081.75 2376.41,2117.25 2406,2159.5C 2433.84,2203.86 2446.84,2252.19 2445,2304.5C 2439.12,2354.58 2419.45,2398.25 2386,2435.5C 2362.54,2461.31 2335.37,2482.15 2304.5,2498C 2251.11,2526.6 2194.11,2541.6 2133.5,2543C 2075.5,2543.67 2017.5,2543.67 1959.5,2543C 1884.97,2540.6 1816.97,2518.6 1755.5,2477C 1725.83,2455.33 1701,2429.16 1681,2398.5C 1637.86,2320.42 1639.19,2243.09 1685,2166.5C 1733.44,2091.82 1799.94,2039.99 1884.5,2011C 1927.96,1995.22 1972.62,1986.05 2018.5,1983.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#000000" d="M 1964.5,2160.5 C 1974.84,2160.33 1985.17,2160.5 1995.5,2161C 1999.17,2162 2002.83,2163 2006.5,2164C 2019.36,2170.6 2032.03,2177.43 2044.5,2184.5C 2051.61,2180.57 2058.61,2176.4 2065.5,2172C 2084.44,2160.58 2104.77,2157.25 2126.5,2162C 2154.24,2173.76 2165.74,2194.6 2161,2224.5C 2159.39,2229.33 2157.39,2234 2155,2238.5C 2141.4,2256.86 2124.57,2271.36 2104.5,2282C 2095.83,2289.2 2093,2298.36 2096,2309.5C 2097.52,2320.59 2099.52,2331.59 2102,2342.5C 2102.67,2352.17 2102.67,2361.83 2102,2371.5C 2097.45,2391.05 2085.28,2402.88 2065.5,2407C 2048.08,2407.98 2030.75,2407.31 2013.5,2405C 1996.6,2395.27 1986.6,2380.77 1983.5,2361.5C 1986.88,2342.54 1990.05,2323.54 1993,2304.5C 1994.81,2296.58 1992.98,2289.75 1987.5,2284C 1971.14,2274.9 1956.31,2263.73 1943,2250.5C 1918.23,2221.25 1920.06,2193.75 1948.5,2168C 1953.54,2164.64 1958.88,2162.14 1964.5,2160.5 Z"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
1
public/svgs/postgresql.svg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/svgs/prefect.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
public/svgs/qdrant.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
56
public/svgs/searxng.svg
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 92 92"
|
||||
height="92mm"
|
||||
width="92mm">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(-40.921303,-17.416526)"
|
||||
id="layer1">
|
||||
<circle
|
||||
r="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:12;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
cy="92"
|
||||
cx="75"
|
||||
id="path3713" />
|
||||
<circle
|
||||
r="30"
|
||||
cy="53.902557"
|
||||
cx="75.921303"
|
||||
id="path834"
|
||||
style="fill:none;fill-opacity:1;stroke:#3050ff;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 67.514849,37.91524 a 18,18 0 0 1 21.051475,3.312407 18,18 0 0 1 3.137312,21.078282"
|
||||
id="path852"
|
||||
style="fill:none;fill-opacity:1;stroke:#3050ff;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
transform="rotate(-46.234709)"
|
||||
ry="1.8669105e-13"
|
||||
y="122.08995"
|
||||
x="3.7063529"
|
||||
height="39.963303"
|
||||
width="18.846331"
|
||||
id="rect912"
|
||||
style="opacity:1;fill:#3050ff;fill-opacity:1;stroke:none;stroke-width:8;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
5
public/svgs/tolgee.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="100%" height="100%" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
style="fill:#EC407A;fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="M97.16,7.27a16.94,16.94,0,0,0-1.9,24.47,16.36,16.36,0,0,0,5,3.83,3.23,3.23,0,0,1-2.9,5.77,23.14,23.14,0,0,1-11.41-13C73.83,31.1,63.46,37.09,52.82,46.51c-27.44,24.3-34.35,61.74-16.38,85.26-4.57,5.79-8,12.22-8.9,18.69a20.88,20.88,0,0,0,5.62,18c9.18,9.61,21.42,7.13,31.26,5.14,6.58-1.34,12.8-2.6,16.5-.23,3.22,2.07,3.47,3.87,3.61,4.45,2.1,9.32-5.79,13.89-7.67,16.27a1.48,1.48,0,0,0,1.13,2.4c3.48,0,9-1.18,12.34-4.08s7.16-7.9,5.89-16.32c-.08-.5-.18-1-.32-1.58-.86-3.35-3.1-7.57-8.61-11.09-7.72-4.95-17-3.07-25.22-1.41-9.76,2-16,2.85-20.37-1.71a9.13,9.13,0,0,1-2.46-8.19c.54-3.77,2.65-7.89,5.62-11.86,21.71,16.89,56.87,13.47,82.67-9.39a75.34,75.34,0,0,0,20.81-28.09A23.14,23.14,0,0,1,134.8,89a3.23,3.23,0,0,1,6.08-2.19,16.37,16.37,0,0,0,3.2,5.39,16.85,16.85,0,1,0,11.48-28,3.23,3.23,0,0,1-.51-6.44,23.41,23.41,0,0,1,12.88,2.69c2.6-14.08,3.34-31.41-2.06-37.51-4.08-4.61-20.62-8-35.18-7.76A23.48,23.48,0,0,1,130.8,25a3.23,3.23,0,0,1-6.33-1.28A16.94,16.94,0,0,0,97.16,7.27Zm63.25,21a5.29,5.29,0,0,1-.57,6.19c-1.29,1.14-2.72-.51-4.1-2.06s-3.1-3.42-1.81-4.56A5.74,5.74,0,0,1,160.41,28.27Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
BIN
public/svgs/unstructured.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/svgs/weaviate.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
@@ -151,9 +151,9 @@
|
||||
@endif
|
||||
@endif
|
||||
<template x-teleport="body">
|
||||
<div x-show="modalOpen" @click.away="modalOpen = false; resetModal()"
|
||||
<div x-show="modalOpen"
|
||||
class="fixed top-0 lg:pt-10 left-0 z-[99] flex items-start justify-center w-screen h-screen" x-cloak>
|
||||
<div x-show="modalOpen" @click="modalOpen = false; resetModal()"
|
||||
<div x-show="modalOpen"
|
||||
class="absolute inset-0 w-full h-full bg-black bg-opacity-20 backdrop-blur-sm"></div>
|
||||
<div x-show="modalOpen" x-trap.inert.noscroll="modalOpen" x-transition:enter="ease-out duration-100"
|
||||
x-transition:enter-start="opacity-0 -translate-y-2 sm:scale-95"
|
||||
@@ -272,7 +272,7 @@
|
||||
class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Your Password
|
||||
</label>
|
||||
<form action="return false">
|
||||
<form @submit.prevent="return false" @keydown.enter.prevent>
|
||||
<input type="password" id="password-confirm" x-model="password" class="w-full input"
|
||||
placeholder="Enter your password">
|
||||
</form>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
'transition-all duration-150 box-without-bg dark:bg-coolgray-100 bg-white group',
|
||||
'hover:border-l-coollabs cursor-pointer' => !$upgrade,
|
||||
'hover:border-l-red-500 cursor-not-allowed' => $upgrade,
|
||||
]) @if (!$upgrade) wire:click={{ $wire }} @endif>
|
||||
])>
|
||||
<div class="flex items-center">
|
||||
{{ $logo }}
|
||||
<div class="flex flex-col pl-2 ">
|
||||
@@ -20,11 +20,6 @@
|
||||
</div>
|
||||
@isset($documentation)
|
||||
<div class="flex-1"></div>
|
||||
<div class="flex items-center px-2 " title="Read the documentation.">
|
||||
<a class="p-2 rounded hover:bg-coolgray-200 hover:no-underline group-hover:dark:text-white text-neutral-600"
|
||||
onclick="event.stopPropagation()" href="{{ $documentation }}" target="_blank">
|
||||
Docs
|
||||
</a>
|
||||
</div>
|
||||
{{ $documentation }}
|
||||
@endisset
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<livewire:server.proxy.status :server="$server" />
|
||||
@endif
|
||||
</div>
|
||||
<div class="subtitle">{{ data_get($server, 'name') }}.</div>
|
||||
<div class="subtitle">{{ data_get($server, 'name') }}</div>
|
||||
<div class="navbar-main">
|
||||
<nav class="flex items-center gap-6 overflow-x-scroll sm:overflow-x-hidden scrollbar min-h-10 whitespace-nowrap">
|
||||
<a class="{{ request()->routeIs('server.show') ? 'dark:text-white' : '' }}"
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
'status' => 'Restarting',
|
||||
'lastDeploymentInfo' => null,
|
||||
'lastDeploymentLink' => null,
|
||||
'noLoading' => false,
|
||||
])
|
||||
<div class="flex items-center">
|
||||
<x-loading wire:loading.delay.longer />
|
||||
@if (!$noLoading)
|
||||
<x-loading wire:loading.delay.longer />
|
||||
@endif
|
||||
<span wire:loading.remove.delay.longer class="flex items-center">
|
||||
<div class="badge badge-warning "></div>
|
||||
<div class="pl-2 pr-1 text-xs font-bold tracking-wider dark:text-warning" @if($lastDeploymentInfo) title="{{$lastDeploymentInfo}}" @endif>
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
'status' => 'Running',
|
||||
'lastDeploymentInfo' => null,
|
||||
'lastDeploymentLink' => null,
|
||||
'noLoading' => false,
|
||||
])
|
||||
<div class="flex items-center">
|
||||
<x-loading wire:loading.delay.longer />
|
||||
@if (!$noLoading)
|
||||
<x-loading wire:loading.delay.longer />
|
||||
@endif
|
||||
<span wire:loading.remove.delay.longer class="flex items-center">
|
||||
<div class="badge badge-success "></div>
|
||||
<div class="pl-2 pr-1 text-xs font-bold tracking-wider text-success" @if($lastDeploymentInfo) title="{{$lastDeploymentInfo}}" @endif>
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
@props([
|
||||
'status' => 'Stopped',
|
||||
'noLoading' => false,
|
||||
])
|
||||
<div class="flex items-center">
|
||||
<x-loading wire:loading.delay.longer />
|
||||
@if (!$noLoading)
|
||||
<x-loading wire:loading.delay.longer />
|
||||
@endif
|
||||
<span wire:loading.remove.delay.longer class="flex items-center">
|
||||
<div class="badge badge-error "></div>
|
||||
<div class="pl-2 pr-1 text-xs font-bold tracking-wider text-error">{{ str($status)->before(':')->headline() }}</div>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div class="grid grid-cols-1 gap-2 xl:grid-cols-2">
|
||||
@foreach ($projects as $project)
|
||||
<div class="gap-2 border border-transparent cursor-pointer box group"
|
||||
onclick="gotoProject('{{ $project->uuid }}','{{ $project->default_environment() }}')">
|
||||
onclick="gotoProject('{{ $project->uuid }}','{{ $project->default_environment }}')">
|
||||
<div class="flex flex-1 mx-6">
|
||||
<div class="flex flex-col justify-center flex-1">
|
||||
<div class="box-title">{{ $project->name }}</div>
|
||||
@@ -33,7 +33,7 @@
|
||||
</div>
|
||||
<div class="flex items-center justify-center gap-2 text-xs font-bold">
|
||||
<a class="hover:underline"
|
||||
href="{{ route('project.resource.create', ['project_uuid' => $project->uuid, 'environment_name' => data_get($project, 'default_environment()', 'production')]) }}">
|
||||
href="{{ route('project.resource.create', ['project_uuid' => $project->uuid, 'environment_name' => data_get($project, 'default_environment', 'production')]) }}">
|
||||
<span class="p-2 font-bold">+ Add Resource</span>
|
||||
</a>
|
||||
<a class="hover:underline"
|
||||
@@ -122,7 +122,7 @@
|
||||
@if (count($deployments_per_server) > 0)
|
||||
<x-loading />
|
||||
@endif
|
||||
<x-modal-confirmation
|
||||
<x-modal-confirmation
|
||||
title="Confirm Cleanup Queues?"
|
||||
buttonTitle="Cleanup Queues"
|
||||
isErrorButton
|
||||
|
||||
@@ -1,37 +1,38 @@
|
||||
<div>
|
||||
<div class="flex flex-col gap-2">
|
||||
@forelse($database->scheduledBackups as $backup)
|
||||
@if ($type == 'database')
|
||||
<a class="box"
|
||||
href="{{ route('project.database.backup.execution', [...$parameters, 'backup_uuid' => $backup->uuid]) }}">
|
||||
<div class="flex flex-col">
|
||||
<div>Frequency: {{ $backup->frequency }}</div>
|
||||
<div>Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}</div>
|
||||
<div>Number of backups to keep (locally): {{ $backup->number_of_backups_locally }}</div>
|
||||
</div>
|
||||
</a>
|
||||
@else
|
||||
<div class="box" wire:click="setSelectedBackup('{{ data_get($backup, 'id') }}')">
|
||||
<div @class([ 'border-coollabs'=>
|
||||
data_get($backup, 'id') === data_get($selectedBackup, 'id'),
|
||||
'flex flex-col border-l-2 border-transparent',
|
||||
])>
|
||||
<div>Frequency: {{ $backup->frequency }}</div>
|
||||
<div>Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}</div>
|
||||
<div>Number of backups to keep (locally): {{ $backup->number_of_backups_locally }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@if ($type == 'database')
|
||||
<a class="box"
|
||||
href="{{ route('project.database.backup.execution', [...$parameters, 'backup_uuid' => $backup->uuid]) }}">
|
||||
<div class="flex flex-col">
|
||||
<div>Frequency: {{ $backup->frequency }}</div>
|
||||
<div>Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}</div>
|
||||
<div>Number of backups to keep (locally): {{ $backup->number_of_backups_locally }}</div>
|
||||
</div>
|
||||
</a>
|
||||
@else
|
||||
<div class="box" wire:click="setSelectedBackup('{{ data_get($backup, 'id') }}')">
|
||||
<div @class([
|
||||
'border-coollabs' =>
|
||||
data_get($backup, 'id') === data_get($selectedBackup, 'id'),
|
||||
'flex flex-col border-l-2 border-transparent',
|
||||
])>
|
||||
<div>Frequency: {{ $backup->frequency }}</div>
|
||||
<div>Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}</div>
|
||||
<div>Number of backups to keep (locally): {{ $backup->number_of_backups_locally }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@empty
|
||||
<div>No scheduled backups configured.</div>
|
||||
<div>No scheduled backups configured.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
@if ($type === 'service-database' && $selectedBackup)
|
||||
<div class="pt-10">
|
||||
<livewire:project.database.backup-edit wire:key="{{ $selectedBackup->id }}" :backup="$selectedBackup"
|
||||
:s3s="$s3s" :status="data_get($database, 'status')" />
|
||||
<h3 class="py-4">Executions</h3>
|
||||
<livewire:project.database.backup-executions wire:key="{{ $selectedBackup->id }}" :backup="$selectedBackup" :database="$database" />
|
||||
</div>
|
||||
<div class="pt-10">
|
||||
<livewire:project.database.backup-edit wire:key="{{ $selectedBackup->id }}" :backup="$selectedBackup"
|
||||
:s3s="$s3s" :status="data_get($database, 'status')" />
|
||||
<livewire:project.database.backup-executions wire:key="{{ $selectedBackup->uuid }}" :backup="$selectedBackup"
|
||||
:database="$database" />
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -9,35 +9,59 @@
|
||||
</x-modal-input>
|
||||
</div>
|
||||
<div class="subtitle">All your projects are here.</div>
|
||||
<div class="grid gap-2 lg:grid-cols-2">
|
||||
@forelse ($projects as $project)
|
||||
<div class="box group" onclick="gotoProject('{{ $project->uuid }}', '{{ $project->default_environment() }}')">
|
||||
<div class="flex flex-col justify-center flex-1 mx-6">
|
||||
<div class="box-title">{{ $project->name }}</div>
|
||||
<div class="box-description ">
|
||||
{{ $project->description }}</div>
|
||||
<div x-data="searchComponent()">
|
||||
<x-forms.input placeholder="Search for name, description..." x-model="search" id="null" />
|
||||
<div class="grid grid-cols-2 gap-4 pt-4">
|
||||
<template x-if="allFilteredItems.length === 0">
|
||||
<div>No project found with the search term "<span x-text="search"></span>".</div>
|
||||
</template>
|
||||
|
||||
<template x-for="item in allFilteredItems" :key="item.uuid">
|
||||
<div class="box group" @click="gotoProject(item)">
|
||||
<div class="flex flex-col justify-center flex-1 mx-6">
|
||||
<div class="box-title" x-text="item.name"></div>
|
||||
<div class="box-description ">
|
||||
<div x-text="item.description"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-center gap-2 pt-4 pb-2 mr-4 text-xs lg:py-0 lg:justify-normal">
|
||||
<a class="mx-4 font-bold hover:underline"
|
||||
href="{{ route('project.edit', ['project_uuid' => data_get($project, 'uuid')]) }}">
|
||||
Settings
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div>
|
||||
<div>No project found.</div>
|
||||
</div>
|
||||
@endforelse
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function gotoProject(uuid, environment) {
|
||||
if (environment) {
|
||||
window.location.href = '/project/' + uuid + '/' + environment;
|
||||
} else {
|
||||
window.location.href = '/project/' + uuid;
|
||||
function sortFn(a, b) {
|
||||
return a.name.localeCompare(b.name)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
function searchComponent() {
|
||||
return {
|
||||
search: '',
|
||||
projects: @js($projects),
|
||||
filterAndSort(items) {
|
||||
if (this.search === '') {
|
||||
return Object.values(items).sort(sortFn);
|
||||
}
|
||||
const searchLower = this.search.toLowerCase();
|
||||
return Object.values(items).filter(item => {
|
||||
return (item.name?.toLowerCase().includes(searchLower) ||
|
||||
item.description?.toLowerCase().includes(searchLower))
|
||||
}).sort(sortFn);
|
||||
},
|
||||
get allFilteredItems() {
|
||||
return [
|
||||
this.projects,
|
||||
].flatMap((items) => this.filterAndSort(items));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function gotoProject(item) {
|
||||
if (item.default_environment) {
|
||||
window.location.href = '/project/' + item.uuid + '/' + item.default_environment;
|
||||
} else {
|
||||
window.location.href = '/project/' + item.uuid;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
<div x-data="searchComponent()">
|
||||
<x-forms.input placeholder="Search for name, fqdn..." x-model="search" id="null" />
|
||||
<div class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3">
|
||||
<template x-if="allFilteredItems.length === 0">
|
||||
<div>No resource found with the search term "<span x-text="search"></span>".</div>
|
||||
</template>
|
||||
|
||||
<template x-for="item in allFilteredItems" :key="item.uuid">
|
||||
<span>
|
||||
<a class="h-24 box group" :href="item.hrefLink">
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<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 = ''"
|
||||
href="#">General</a>
|
||||
@if ($serviceDatabase->isBackupSolutionAvailable())
|
||||
@if ($serviceDatabase?->isBackupSolutionAvailable())
|
||||
<a :class="activeTab === 'backups' && 'menu-item-active'" class="menu-item"
|
||||
@click.prevent="activeTab = 'backups'; window.location.hash = 'backups'" href="#">Backups</a>
|
||||
@endif
|
||||
|
||||
@@ -56,13 +56,13 @@
|
||||
@else
|
||||
<form wire:submit.prevent='submit' class="flex flex-col gap-2">
|
||||
<x-forms.textarea rows="10" class="whitespace-pre-wrap" id="variables" wire:model="variables" label="Production Environment Variables"></x-forms.textarea>
|
||||
|
||||
|
||||
@if ($showPreview)
|
||||
<x-forms.textarea rows="10" class="whitespace-pre-wrap" label="Preview Deployments Environment Variables"
|
||||
id="variablesPreview" wire:model="variablesPreview"></x-forms.textarea>
|
||||
@endif
|
||||
|
||||
|
||||
<x-forms.button type="submit" class="btn btn-primary">Save All Environment Variables</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<div x-init="$wire.checkProxy()" class="flex gap-2">
|
||||
@if (data_get($server, 'proxy.status') === 'running')
|
||||
<x-status.running status="Proxy Running" />
|
||||
<x-status.running status="Proxy Running" noLoading />
|
||||
@elseif (data_get($server, 'proxy.status') === 'restarting')
|
||||
<x-status.restarting status="Proxy Restarting" />
|
||||
<x-status.restarting status="Proxy Restarting" noLoading />
|
||||
@elseif (data_get($server, 'proxy.force_stop'))
|
||||
<x-status.stopped status="Proxy Stopped" />
|
||||
<x-status.stopped status="Proxy Stopped" noLoading />
|
||||
@elseif (data_get($server, 'proxy.status') === 'exited')
|
||||
<x-status.stopped status="Proxy Exited" />
|
||||
<x-status.stopped status="Proxy Exited" noLoading />
|
||||
@else
|
||||
<x-status.stopped status="Proxy Not Running" />
|
||||
<x-status.stopped status="Proxy Not Running" noLoading />
|
||||
@endif
|
||||
<x-forms.button wire:click='checkProxy(true)'>Refresh</x-forms.button>
|
||||
</div>
|
||||
|
||||
@@ -20,18 +20,14 @@
|
||||
<div class="w-[500px]">
|
||||
<x-forms.input readonly label="Deploy Webhook URL" id="webhook" />
|
||||
</div>
|
||||
<x-modal-confirmation
|
||||
title="Redeploy all resources with this tag?"
|
||||
isHighlighted
|
||||
buttonTitle="Redeploy All"
|
||||
submitAction="redeploy_all"
|
||||
:actions="['All resources with this tag will be redeployed.', 'During redeploy resources will be temporarily unavailable.']"
|
||||
confirmationText="{{ $oneTag->name }}"
|
||||
confirmationLabel="Please confirm the execution of the actions by entering the Tag Name below"
|
||||
shortConfirmationLabel="Tag Name"
|
||||
:confirmWithPassword="false"
|
||||
step2ButtonText="Redeploy All"
|
||||
/>
|
||||
<x-modal-confirmation title="Redeploy all resources with this tag?" isHighlighted
|
||||
buttonTitle="Redeploy All" submitAction="redeploy_all" :actions="[
|
||||
'All resources with this tag will be redeployed.',
|
||||
'During redeploy resources will be temporarily unavailable.',
|
||||
]"
|
||||
confirmationText="{{ $tag }}"
|
||||
confirmationLabel="Please confirm the execution of the actions by entering the Tag Name below"
|
||||
shortConfirmationLabel="Tag Name" :confirmWithPassword="false" step2ButtonText="Redeploy All" />
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-2 pt-4 lg:grid-cols-2 xl:grid-cols-3">
|
||||
@foreach ($applications as $application)
|
||||
|
||||
@@ -24,18 +24,13 @@
|
||||
<div class="w-[500px]">
|
||||
<x-forms.input readonly label="Deploy Webhook URL" id="webhook" />
|
||||
</div>
|
||||
<x-modal-confirmation
|
||||
title="Redeploy all resources with this tag?"
|
||||
isHighlighted
|
||||
buttonTitle="Redeploy All"
|
||||
submitAction="redeploy_all"
|
||||
:actions="['All resources with this tag will be redeployed.', 'During redeploy resources will be temporarily unavailable.']"
|
||||
confirmationText="{{ $oneTag->name }}"
|
||||
confirmationLabel="Please confirm the execution of the actions by entering the Tag Name below"
|
||||
shortConfirmationLabel="Tag Name"
|
||||
:confirmWithPassword="false"
|
||||
step2ButtonText="Redeploy All"
|
||||
/>
|
||||
<x-modal-confirmation title="Redeploy all resources with this tag?" isHighlighted buttonTitle="Redeploy All"
|
||||
submitAction="redeploy_all" :actions="[
|
||||
'All resources with this tag will be redeployed.',
|
||||
'During redeploy resources will be temporarily unavailable.',
|
||||
]" confirmationText="{{ $tag }}"
|
||||
confirmationLabel="Please confirm the execution of the actions by entering the Tag Name below"
|
||||
shortConfirmationLabel="Tag Name" :confirmWithPassword="false" step2ButtonText="Redeploy All" />
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-2 pt-4 lg:grid-cols-2 xl:grid-cols-3">
|
||||
@foreach ($applications as $application)
|
||||
|
||||
32
templates/compose/anythingllm.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
# documentation: https://docs.anythingllm.com/installation-docker/overview
|
||||
# slogan: AnythingLLM is the easiest to use, all-in-one AI application that can do RAG, AI Agents, and much more with no code or infrastructure headaches.
|
||||
# tags: lowcode, nocode, ai, llm, openai, anthropic, machine-learning, rag, agents, chatbot, api, team, bot
|
||||
# logo: svgs/anythingllm.svg
|
||||
# port: 3001
|
||||
|
||||
services:
|
||||
anything-llm:
|
||||
image: mintplexlabs/anythingllm
|
||||
environment:
|
||||
- SERVICE_FQDN_ANYTHINGLLM_3001
|
||||
- STORAGE_DIR=/app/server/storage
|
||||
- DISABLE_TELEMETRY=${DISABLE_TELEMETRY:-true}
|
||||
- PASSWORDLOWERCASE=${PASSWORDLOWERCASE:-1}
|
||||
- PASSWORDMAXCHAR=${PASSWORDMAXCHAR:-250}
|
||||
- PASSWORDMINCHAR=${PASSWORDMINCHAR:-6}
|
||||
- PASSWORDNUMERIC=${PASSWORDNUMERIC:-1}
|
||||
- PASSWORDREQUIREMENTS=${PASSWORDREQUIREMENTS:-1}
|
||||
- PASSWORDSYMBOL=${PASSWORDSYMBOL:-1}
|
||||
- PASSWORDUPPERCASE=${PASSWORDUPPERCASE:-1}
|
||||
- SIG_KEY=${SERVICE_PASSWORD_SIGKEY}
|
||||
- SIG_SALT=${SERVICE_PASSWORD_SIGSALT}
|
||||
- JWT_SECRET=${SERVICE_PASSWORD_JWTSECRET}
|
||||
- AUTH_TOKEN=${SERVICE_PASSWORD_AUTHTOKEN}
|
||||
- SERVER_PORT=${SERVER_PORT:-3001}
|
||||
cap_add:
|
||||
- SYS_ADMIN
|
||||
volumes:
|
||||
- "anythingllm-storage:/app/server/storage"
|
||||
- "anythingllm-hot:/app/collector/hotdir"
|
||||
- "anythingllm-outputs:/app/collector/outputs"
|
||||
user: "${UID:-1000}:${GID:-1000}"
|
||||
126
templates/compose/argilla.yaml
Normal file
@@ -0,0 +1,126 @@
|
||||
# documentation: https://docs.argilla.io/latest/
|
||||
# slogan: Argilla is a collaboration tool for AI engineers and domain experts who need to build high-quality datasets for their projects.
|
||||
# tags: workflow, orchestration, data-pipeline, python, argilla, ai, elasticsearch, datasets, data, machine-learning, data-science, nlp
|
||||
# logo: svgs/argilla.png
|
||||
# port: 6900
|
||||
|
||||
services:
|
||||
argilla:
|
||||
image: "argilla/argilla-server:v2.2.0"
|
||||
environment:
|
||||
- SERVICE_FQDN_ARGILLA_6900
|
||||
- ARGILLA_HOME_PATH=/var/lib/argilla
|
||||
- ARGILLA_ELASTICSEARCH=http://elasticsearch:9200
|
||||
- ARGILLA_DATABASE_URL=postgresql+asyncpg://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB}
|
||||
- ARGILLA_REDIS_URL=redis://redis:6379/0
|
||||
- ARGILLA_AUTH_SECRET_KEY=${SERVICE_PASSWORD_AUTHSECRET}
|
||||
- ARGILLA_ENABLE_TELEMETRY=${ARGILLA_ENABLE_TELEMETRY:-0}
|
||||
- HF_HUB_DISABLE_TELEMETRY=${HF_HUB_DISABLE_TELEMETRY:-1}
|
||||
- REINDEX_DATASETS=${REINDEX_DATASETS:-1}
|
||||
- DEFAULT_USER_ENABLED=${DEFAULT_USER_ENABLED:-true}
|
||||
- USERNAME=${ARGILLA_USERNAME:-argilla}
|
||||
- PASSWORD=${SERVICE_PASSWORD_ARGILLA}
|
||||
- API_KEY=${SERVICE_PASSWORD_APIKEY}
|
||||
- DEFAULT_USER_PASSWORD=${SERVICE_PASSWORD_ARGILLA}
|
||||
- DEFAULT_USER_API_KEY=${SERVICE_PASSWORD_APIKEY}
|
||||
- WORKSPACE=${WORKSPACE:-default}
|
||||
depends_on:
|
||||
elasticsearch:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- "argilla-data:/var/lib/argilla"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- 'python -c "import requests as r;r.get(\"http://localhost:6900/api/_status\").raise_for_status()"'
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
worker:
|
||||
image: "argilla/argilla-server:v2.2.0"
|
||||
environment:
|
||||
- ARGILLA_HOME_PATH=/var/lib/argilla
|
||||
- ARGILLA_ELASTICSEARCH=http://elasticsearch:9200
|
||||
- ARGILLA_DATABASE_URL=postgresql+asyncpg://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB}
|
||||
- ARGILLA_REDIS_URL=redis://redis:6379/0
|
||||
- ARGILLA_AUTH_SECRET_KEY=${SERVICE_PASSWORD_AUTHSECRET}
|
||||
- ARGILLA_ENABLE_TELEMETRY=${ARGILLA_ENABLE_TELEMETRY:-0}
|
||||
- HF_HUB_DISABLE_TELEMETRY=${HF_HUB_DISABLE_TELEMETRY:-1}
|
||||
- REINDEX_DATASETS=${REINDEX_DATASETS:-1}
|
||||
- DEFAULT_USER_ENABLED=${DEFAULT_USER_ENABLED:-true}
|
||||
- USERNAME=${ARGILLA_USERNAME:-argilla}
|
||||
- PASSWORD=${SERVICE_PASSWORD_ARGILLA}
|
||||
- API_KEY=${SERVICE_PASSWORD_APIKEY}
|
||||
- DEFAULT_USER_PASSWORD=${SERVICE_PASSWORD_ARGILLA}
|
||||
- DEFAULT_USER_API_KEY=${SERVICE_PASSWORD_APIKEY}
|
||||
- BACKGROUND_NUM_WORKERS=${BACKGROUND_NUM_WORKERS:-1}
|
||||
- WORKSPACE=${WORKSPACE:-default}
|
||||
depends_on:
|
||||
elasticsearch:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- "argilla-data:/var/lib/argilla"
|
||||
command: "sh -c 'python -m argilla_server worker --num-workers $${BACKGROUND_NUM_WORKERS}'"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- pwd
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
postgres:
|
||||
image: "postgres:14"
|
||||
environment:
|
||||
- POSTGRES_USER=${SERVICE_USER_POSTGRES}
|
||||
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
||||
- POSTGRES_DB=${POSTGRES_DB:-argilla}
|
||||
volumes:
|
||||
- "pg-data:/var/lib/postgresql/data"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
redis:
|
||||
image: "redis:7"
|
||||
volumes:
|
||||
- "redis-data:/data"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- "redis-cli -h localhost -p 6379 ping"
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
elasticsearch:
|
||||
image: "docker.elastic.co/elasticsearch/elasticsearch:8.12.2"
|
||||
environment:
|
||||
- node.name=${NODE_NAME:-elasticsearch}
|
||||
- cluster.name=${CLUSTER_NAME:-es-argilla-local}
|
||||
- discovery.type=${DISCOVERY_TYPE:-single-node}
|
||||
- "ES_JAVA_OPTS=${ES_JAVA_OPTS:-\"-Xms512m -Xmx512m\"}"
|
||||
- cluster.routing.allocation.disk.threshold_enabled=${CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED:-false}
|
||||
- xpack.security.enabled=${XPACK_SECURITY_ENABLED:-false}
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
volumes:
|
||||
- "elasticsearch-data:/usr/share/elasticsearch/data/"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- "curl --silent --fail http://elasticsearch:9200"
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
@@ -15,19 +15,19 @@ services:
|
||||
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
|
||||
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
|
||||
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
|
||||
- FORCE_SSL=false
|
||||
- ENABLE_ACCOUNT_SIGNUP=false
|
||||
- FORCE_SSL=${FORCE_SSL:-false}
|
||||
- ENABLE_ACCOUNT_SIGNUP=${ENABLE_ACCOUNT_SIGNUP:-false}
|
||||
- REDIS_URL=redis://default@redis:6379
|
||||
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
|
||||
- REDIS_OPENSSL_VERIFY_MODE=none
|
||||
- POSTGRES_DATABASE=chatwoot
|
||||
- POSTGRES_HOST=postgres
|
||||
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
|
||||
- REDIS_OPENSSL_VERIFY_MODE=${REDIS_OPENSSL_VERIFY_MODE:-none}
|
||||
- POSTGRES_DATABASE=${POSTGRES_DB:-chatwoot}
|
||||
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
|
||||
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- RAILS_MAX_THREADS=5
|
||||
- NODE_ENV=production
|
||||
- RAILS_ENV=production
|
||||
- INSTALLATION_ENV=docker
|
||||
- RAILS_MAX_THREADS=${RAILS_MAX_THREADS:-5}
|
||||
- NODE_ENV=${NODE_ENV:-production}
|
||||
- RAILS_ENV=${RAILS_ENV:-production}
|
||||
- INSTALLATION_ENV=${INSTALLATION_ENV:-docker}
|
||||
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
|
||||
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
|
||||
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
|
||||
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
|
||||
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
|
||||
- ACTIVE_STORAGE_SERVICE=local
|
||||
- ACTIVE_STORAGE_SERVICE=${ACTIVE_STORAGE_SERVICE:-local}
|
||||
entrypoint: docker/entrypoints/rails.sh
|
||||
command: sh -c "bundle exec rails db:chatwoot_prepare && bundle exec rails s -p 3000 -b 0.0.0.0"
|
||||
volumes:
|
||||
@@ -56,19 +56,19 @@ services:
|
||||
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
|
||||
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
|
||||
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
|
||||
- FORCE_SSL=false
|
||||
- ENABLE_ACCOUNT_SIGNUP=false
|
||||
- FORCE_SSL=${FORCE_SSL:-false}
|
||||
- ENABLE_ACCOUNT_SIGNUP=${ENABLE_ACCOUNT_SIGNUP:-false}
|
||||
- REDIS_URL=redis://default@redis:6379
|
||||
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
|
||||
- REDIS_OPENSSL_VERIFY_MODE=none
|
||||
- POSTGRES_DATABASE=chatwoot
|
||||
- POSTGRES_HOST=postgres
|
||||
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
|
||||
- REDIS_OPENSSL_VERIFY_MODE=${REDIS_OPENSSL_VERIFY_MODE:-none}
|
||||
- POSTGRES_DATABASE=${POSTGRES_DB:-chatwoot}
|
||||
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
|
||||
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- RAILS_MAX_THREADS=5
|
||||
- NODE_ENV=production
|
||||
- RAILS_ENV=production
|
||||
- INSTALLATION_ENV=docker
|
||||
- RAILS_MAX_THREADS=${RAILS_MAX_THREADS:-5}
|
||||
- NODE_ENV=${NODE_ENV:-production}
|
||||
- RAILS_ENV=${RAILS_ENV:-production}
|
||||
- INSTALLATION_ENV=${INSTALLATION_ENV:-docker}
|
||||
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
|
||||
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
|
||||
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
|
||||
@@ -77,7 +77,7 @@ services:
|
||||
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
|
||||
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
|
||||
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
|
||||
- ACTIVE_STORAGE_SERVICE=local
|
||||
- ACTIVE_STORAGE_SERVICE=${ACTIVE_STORAGE_SERVICE:-local}
|
||||
command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml']
|
||||
volumes:
|
||||
- sidekiq-data:/app/storage
|
||||
@@ -93,11 +93,11 @@ services:
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_DB=chatwoot
|
||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES_USER
|
||||
- POSTGRES_DB=${POSTGRES_DB:-chatwoot}
|
||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $SERVICE_USER_POSTGRES_USER -d chatwoot -h 127.0.0.1"]
|
||||
test: ["CMD-SHELL", "pg_isready -U $SERVICE_USER_POSTGRES -d chatwoot -h 127.0.0.1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
|
||||
services:
|
||||
directus:
|
||||
image: directus/directus:10
|
||||
image: directus/directus:11
|
||||
volumes:
|
||||
- directus-uploads:/directus/uploads
|
||||
- directus-extensions:/directus/extensions
|
||||
- directus-templates:/directus/templates
|
||||
environment:
|
||||
- SERVICE_FQDN_DIRECTUS_8055
|
||||
- KEY=$SERVICE_BASE64_64_KEY
|
||||
@@ -37,6 +38,7 @@ services:
|
||||
condition: service_healthy
|
||||
postgresql:
|
||||
image: postgis/postgis:16-3.4-alpine
|
||||
platform: linux/amd64
|
||||
volumes:
|
||||
- directus-postgresql-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
|
||||
services:
|
||||
directus:
|
||||
image: directus/directus:10
|
||||
image: directus/directus:11
|
||||
volumes:
|
||||
- directus-uploads:/directus/uploads
|
||||
- directus-database:/directus/database
|
||||
- directus-uploads:/directus/uploads
|
||||
- directus-extensions:/directus/extensions
|
||||
- directus-templates:/directus/templates
|
||||
environment:
|
||||
- SERVICE_FQDN_DIRECTUS_8055
|
||||
- KEY=$SERVICE_BASE64_64_KEY
|
||||
|
||||
87
templates/compose/getoutline.yaml
Normal file
@@ -0,0 +1,87 @@
|
||||
# documentation: https://docs.getoutline.com/s/hosting/doc/hosting-outline-nipGaCRBDu
|
||||
# slogan: Your team’s knowledge base
|
||||
# tags: knowledge base, documentation
|
||||
# logo: svgs/getoutline.jpeg
|
||||
# port: 3000
|
||||
|
||||
services:
|
||||
outline:
|
||||
image: docker.getoutline.com/outlinewiki/outline:latest
|
||||
volumes:
|
||||
- storage-data:/var/lib/outline/data
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- SERVICE_FQDN_OUTLINE_3000
|
||||
- NODE_ENV=production
|
||||
- SECRET_KEY=${SERVICE_BASE64_OUTLINE}
|
||||
- UTILS_SECRET=${SERVICE_PASSWORD_64_OUTLINE}
|
||||
- DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_64_POSTGRES}@postgres:5432/${POSTGRES_DATABASE:-outline}
|
||||
- REDIS_URL=redis://:${SERVICE_PASSWORD_64_REDIS}@redis:6379
|
||||
- URL=${SERVICE_FQDN_OUTLINE_3000}
|
||||
- PORT=${OUTLINE_PORT:-3000}
|
||||
- FILE_STORAGE=${FILE_STORAGE:-local}
|
||||
- FILE_STORAGE_LOCAL_ROOT_DIR=${FILE_STORAGE_LOCAL_ROOT_DIR:-/var/lib/outline/data}
|
||||
- FILE_STORAGE_UPLOAD_MAX_SIZE=${FILE_STORAGE_UPLOAD_MAX_SIZE:-2000}
|
||||
- FILE_STORAGE_IMPORT_MAX_SIZE=${FILE_STORAGE_IMPORT_MAX_SIZE:-100}
|
||||
- FILE_STORAGE_WORKSPACE_IMPORT_MAX_SIZE=${FILE_STORAGE_WORKSPACE_IMPORT_MAX_SIZE}
|
||||
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
|
||||
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
|
||||
- AWS_REGION=${AWS_REGION}
|
||||
- AWS_S3_ACCELERATE_URL=${AWS_S3_ACCELERATE_URL}
|
||||
- AWS_S3_UPLOAD_BUCKET_URL=${AWS_S3_UPLOAD_BUCKET_URL}
|
||||
- AWS_S3_UPLOAD_BUCKET_NAME=${AWS_S3_UPLOAD_BUCKET_NAME}
|
||||
- AWS_S3_FORCE_PATH_STYLE=${AWS_S3_FORCE_PATH_STYLE:-true}
|
||||
- AWS_S3_ACL=${AWS_S3_ACL:-private}
|
||||
- SLACK_CLIENT_ID=${SLACK_CLIENT_ID}
|
||||
- SLACK_CLIENT_SECRET=${SLACK_CLIENT_SECRET}
|
||||
- GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
|
||||
- GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
|
||||
- AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
|
||||
- AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
|
||||
- AZURE_RESOURCE_APP_ID=${AZURE_RESOURCE_APP_ID}
|
||||
- OIDC_CLIENT_ID=${OIDC_CLIENT_ID}
|
||||
- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
|
||||
- OIDC_AUTH_URI=${OIDC_AUTH_URI}
|
||||
- OIDC_TOKEN_URI=${OIDC_TOKEN_URI}
|
||||
- OIDC_USERINFO_URI=${OIDC_USERINFO_URI}
|
||||
- OIDC_LOGOUT_URI=${OIDC_LOGOUT_URI}
|
||||
- OIDC_USERNAME_CLAIM=${OIDC_USERNAME_CLAIM}
|
||||
- OIDC_DISPLAY_NAME=${OIDC_DISPLAY_NAME}
|
||||
- OIDC_SCOPES=${OIDC_SCOPES}
|
||||
- GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}
|
||||
- GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}
|
||||
- GITHUB_APP_NAME=${GITHUB_APP_NAME}
|
||||
- GITHUB_APP_ID=${GITHUB_APP_ID}
|
||||
- GITHUB_APP_PRIVATE_KEY=${GITHUB_APP_PRIVATE_KEY}
|
||||
- PGSSLMODE=${PGSSLMODE:-disable}
|
||||
healthcheck:
|
||||
disable: true
|
||||
|
||||
redis:
|
||||
image: redis:alpine
|
||||
environment:
|
||||
- REDIS_PASSWORD=${SERVICE_PASSWORD_64_REDIS}
|
||||
command: ["redis-server", "--requirepass", "${SERVICE_PASSWORD_64_REDIS}"]
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "-a", "${SERVICE_PASSWORD_64_REDIS}", "PING"]
|
||||
interval: 10s
|
||||
timeout: 30s
|
||||
retries: 3
|
||||
|
||||
postgres:
|
||||
image: postgres:12-alpine
|
||||
volumes:
|
||||
- database-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_USER=${SERVICE_USER_POSTGRES}
|
||||
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_64_POSTGRES}
|
||||
- POSTGRES_DB=${POSTGRES_DATABASE:-outline}
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "${SERVICE_USER_POSTGRES}", "-d", "${POSTGRES_DATABASE:-outline}"]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
21
templates/compose/homarr.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
# documentation: https://homarr.dev
|
||||
# slogan: Homarr is a self-hosted homepage for your services.
|
||||
# tags: homarr,self-hosted,homepage
|
||||
# logo: svgs/homarr.svg
|
||||
# port: 7575
|
||||
|
||||
services:
|
||||
homarr:
|
||||
image: ghcr.io/ajnart/homarr:latest
|
||||
environment:
|
||||
- SERVICE_FQDN_HOMARR_7575
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./homarr/configs:/app/data/configs
|
||||
- ./homarr/icons:/app/public/icons
|
||||
- ./homarr/data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:7575"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
69
templates/compose/infisical.yaml
Normal file
@@ -0,0 +1,69 @@
|
||||
# documentation: https://infisical.com/docs/documentation/getting-started/introduction
|
||||
# slogan: Infisical is the open source secret management platform that developers use to centralize their application configuration and secrets like API keys and database credentials.
|
||||
# tags: security, environment, secrets, infisical, database, configuration, secret, api, keys, auth, encryption
|
||||
# logo: svgs/infisical.png
|
||||
# port: 8080
|
||||
|
||||
|
||||
services:
|
||||
backend:
|
||||
image: "infisical/infisical:latest-postgres"
|
||||
environment:
|
||||
- SERVICE_FQDN_BACKEND_8080
|
||||
- SITE_URL=${SERVICE_FQDN_BACKEND_8080}
|
||||
- NODE_ENV=${NODE_ENV:-production}
|
||||
- ENCRYPTION_KEY=${SERVICE_PASSWORD_ENCRYPTIONKEY}
|
||||
- AUTH_SECRET=${SERVICE_REALBASE64_64_AUTHSECRET}
|
||||
- DB_CONNECTION_URI=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@db:5432/${POSTGRES_DB}
|
||||
- REDIS_URL=redis://redis:6379
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- "wget --no-verbose --tries=1 --spider http://127.0.0.1:8080/api/status || exit 1"
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
db-migration:
|
||||
condition: service_completed_successfully
|
||||
redis:
|
||||
image: "redis:7"
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
environment:
|
||||
- ALLOW_EMPTY_PASSWORD=${ALLOW_EMPTY_PASSWORD:-yes}
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- "redis-cli -h localhost -p 6379 ping"
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
db:
|
||||
image: "postgres:14-alpine"
|
||||
volumes:
|
||||
- pg_data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_USER=${SERVICE_USER_POSTGRES}
|
||||
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
||||
- POSTGRES_DB=${POSTGRES_DB:-infisical}
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
db-migration:
|
||||
exclude_from_hc: true
|
||||
image: "infisical/infisical:latest-postgres"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
command: "npm run migration:latest"
|
||||
restart: on-failure
|
||||
environment:
|
||||
- POSTGRES_USER=${SERVICE_USER_POSTGRES}
|
||||
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
||||
- POSTGRES_DB=${POSTGRES_DB:-infisical}
|
||||
- DB_CONNECTION_URI=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@db:5432/${POSTGRES_DB:-infisical}
|
||||
- REDIS_URL=redis://redis:6379
|
||||
@@ -1,35 +1,83 @@
|
||||
# ignore: true
|
||||
# documentation: https://invoiceninja.github.io/selfhost.html
|
||||
# slogan: The leading open-source invoicing platform
|
||||
# tags: invoicing, billing, accounting, finance, self-hosted
|
||||
# port: 9000
|
||||
|
||||
services:
|
||||
invoice-ninja:
|
||||
image: invoiceninja/invoiceninja:5
|
||||
environment:
|
||||
- SERVICE_FQDN_INVOICENINJA
|
||||
- APP_ENV=production
|
||||
- APP_ENV=${APP_ENV:-production}
|
||||
- APP_URL=${SERVICE_FQDN_INVOICENINJA}
|
||||
- APP_KEY=${SERVICE_BASE64_INVOICENINJA}
|
||||
- APP_DEBUG=false
|
||||
- REQUIRE_HTTPS=false
|
||||
- PHANTOMJS_PDF_GENERATION=false
|
||||
- PDF_GENERATOR=snappdf
|
||||
- TRUSTED_PROXIES=*
|
||||
- QUEUE_CONNECTION=database
|
||||
- DB_HOST=mysql
|
||||
- DB_PORT=3306
|
||||
- DB_DATABASE=${MYSQL_DATABASE:-invoice_ninja}
|
||||
- DB_USERNAME=${SERVICE_USER_MYSQL}
|
||||
- DB_PASSWORD=${SERVICE_PASSWORD_MYSQL}
|
||||
- APP_KEY=base64:${SERVICE_REALBASE64_INVOICENINJA}
|
||||
- APP_DEBUG=${APP_DEBUG:-false}
|
||||
- REQUIRE_HTTPS=${REQUIRE_HTTPS:-false}
|
||||
- PHANTOMJS_PDF_GENERATION=${PHANTOMJS_PDF_GENERATION:-false}
|
||||
- PDF_GENERATOR=${PDF_GENERATOR:-snappdf}
|
||||
- TRUSTED_PROXIES=${TRUSTED_PROXIES:-*}
|
||||
- QUEUE_CONNECTION=${QUEUE_CONNECTION:-database}
|
||||
- IN_USER_EMAIL=${IN_USER_EMAIL:-admin@example.com}
|
||||
- IN_PASSWORD=${SERVICE_PASSWORD_INVOICENINJAUSER}
|
||||
- DB_HOST=${DB_HOST:-mariadb}
|
||||
- DB_PORT=${DB_PORT:-3306}
|
||||
- DB_DATABASE=${DB_DATABASE:-invoiceninja}
|
||||
- DB_USERNAME=$SERVICE_USER_MARIADB
|
||||
- DB_PASSWORD=$SERVICE_PASSWORD_MARIADB
|
||||
healthcheck:
|
||||
test: ['CMD', 'curl', '-f', 'http://127.0.0.1:9000']
|
||||
test: ['CMD', 'echo', 'ok']
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
volumes:
|
||||
- invoice-ninja-public:/var/www/app/public
|
||||
- invoice-ninja-storage:/var/www/app/storage
|
||||
- type: bind
|
||||
source: ./supervisord.conf
|
||||
target: /etc/supervisord.conf
|
||||
content: |
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
pidfile=/tmp/supervisord.pid
|
||||
logfile=/dev/null ; nodaemon will cause logs to go to stdout
|
||||
logfile_maxbytes=0
|
||||
loglevel=info
|
||||
|
||||
[program:php-fpm]
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
command=php artisan serve --host 0.0.0.0 --port 9000
|
||||
|
||||
[program:scheduler]
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
command=php artisan schedule:work
|
||||
|
||||
[program:queue-worker]
|
||||
process_name=%(program_name)s_%(process_num)02d
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
numprocs=2
|
||||
command=php artisan queue:work --sleep=3 --tries=1 --memory=256 --timeout=3600
|
||||
|
||||
[eventlistener:shutdown]
|
||||
command=shutdown.sh
|
||||
events=PROCESS_STATE_STOPPED, PROCESS_STATE_EXITED, PROCESS_STATE_FATAL
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
- type: bind
|
||||
source: ./php.ini
|
||||
target: /usr/local/etc/php/php.ini
|
||||
@@ -51,7 +99,6 @@ services:
|
||||
; opcache.jit=1205
|
||||
; opcache.memory_consumption=1024M
|
||||
|
||||
|
||||
post_max_size = 60M
|
||||
upload_max_filesize = 50M
|
||||
memory_limit=512M
|
||||
@@ -78,28 +125,19 @@ services:
|
||||
post_max_size = 60M
|
||||
upload_max_filesize = 50M
|
||||
depends_on:
|
||||
mysql:
|
||||
mariadb:
|
||||
condition: service_healthy
|
||||
mysql:
|
||||
image: mariadb:lts
|
||||
mariadb:
|
||||
image: mariadb:11
|
||||
volumes:
|
||||
- mariadb-data:/var/lib/mysql
|
||||
environment:
|
||||
- MYSQL_USER=${SERVICE_USER_MYSQL}
|
||||
- MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL}
|
||||
- MYSQL_DATABASE=${MYSQL_DATABASE:-invoice_ninja}
|
||||
- MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}
|
||||
- MYSQL_ROOT_PASSWORD=$SERVICE_PASSWORD_MARIADBROOT
|
||||
- MYSQL_DATABASE=${DB_DATABASE:-invoiceninja}
|
||||
- MYSQL_USER=$SERVICE_USER_MARIADB
|
||||
- MYSQL_PASSWORD=$SERVICE_PASSWORD_MARIADB
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"mysqladmin",
|
||||
"ping",
|
||||
"-h",
|
||||
"127.0.0.1",
|
||||
"-uroot",
|
||||
"-p${SERVICE_PASSWORD_MYSQLROOT}",
|
||||
]
|
||||
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
volumes:
|
||||
- invoice-ninja-mysql-data:/var/lib/mysql
|
||||
|
||||
18
templates/compose/it-tools.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# documentation: https://github.com/corentinth/it-tools
|
||||
# slogan: IT Tools is a self-hosted solution for managing various IT tasks.
|
||||
# tags: it-tools,management,self-hosted
|
||||
# logo: svgs/it-tools.svg
|
||||
# port: 80
|
||||
|
||||
services:
|
||||
it-tools:
|
||||
image: corentinth/it-tools:latest
|
||||
environment:
|
||||
- SERVICE_FQDN_ITTOOLS_80
|
||||
volumes:
|
||||
- it-tools-data:/app/data
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
47
templates/compose/labelstudio.yaml
Normal file
@@ -0,0 +1,47 @@
|
||||
# documentation: https://labelstud.io/guide/
|
||||
# slogan: Label Studio is a multi-type data labeling and annotation tool with standardized output format
|
||||
# tags: workflow, orchestration, data-pipeline, python, labelstudio, ai, elasticsearch, datasets, data, machine-learning, data-science, nlp, images, vision
|
||||
# logo: svgs/labelstudio.png
|
||||
# port: 8080
|
||||
|
||||
services:
|
||||
labelstudio:
|
||||
image: heartexlabs/label-studio:latest
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- SERVICE_FQDN_LABELSTUDIO_8080
|
||||
- DJANGO_DB=${DJANGO_DB:-default}
|
||||
- POSTGRE_NAME=${POSTGRES_DB:-labelstudio}
|
||||
- POSTGRE_USER=${SERVICE_USER_POSTGRES}
|
||||
- POSTGRE_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
||||
- POSTGRE_PORT=5432
|
||||
- POSTGRE_HOST=postgres
|
||||
- LABEL_STUDIO_HOST=${SERVICE_FQDN_LABELSTUDIO}
|
||||
- SSRF_PROTECTION_ENABLED=${SSRF_PROTECTION_ENABLED:-true}
|
||||
- LABEL_STUDIO_DISABLE_SIGNUP_WITHOUT_LINK=${LABEL_STUDIO_DISABLE_SIGNUP_WITHOUT_LINK:-true}
|
||||
- DATA_UPLOAD_MAX_NUMBER_FILES=${DATA_UPLOAD_MAX_NUMBER_FILES:-10000}
|
||||
- LABEL_STUDIO_USERNAME=${LABEL_STUDIO_USERNAME:-admin@example.com}
|
||||
- LABEL_STUDIO_PASSWORD=${SERVICE_PASSWORD_LABELSTUDIO}
|
||||
- LABEL_STUDIO_DISABLE_SIGNUP_WITHOUT_LINK=${LABEL_STUDIO_DISABLE_SIGNUP_WITHOUT_LINK:-true}
|
||||
volumes:
|
||||
- labelstudio-data:/label-studio/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
- POSTGRES_USER=${SERVICE_USER_POSTGRES}
|
||||
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
||||
- POSTGRES_DB=${POSTGRES_DB:-labelstudio}
|
||||
volumes:
|
||||
- pg-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
55
templates/compose/langfuse.yaml
Normal file
@@ -0,0 +1,55 @@
|
||||
# documentation: https://langfuse.com/docs
|
||||
# slogan: Langfuse is an open-source LLM engineering platform that helps teams collaboratively debug, analyze, and iterate on their LLM applications.
|
||||
# tags: ai, qdrant, weaviate, langchain, openai, gpt, llm, lmops, langfuse, llmops, tracing, observation, metrics
|
||||
# logo: svgs/langfuse.png
|
||||
# port: 3000
|
||||
|
||||
services:
|
||||
langfuse:
|
||||
image: langfuse/langfuse:2
|
||||
environment:
|
||||
- SERVICE_FQDN_LANGFUSE_3000
|
||||
- DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-langfuse}
|
||||
- DIRECT_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-langfuse}
|
||||
- SALT=$SERVICE_PASSWORD_SALT
|
||||
- AUTH_DISABLE_SIGNUP=${AUTH_DISABLE_SIGNUP:-false}
|
||||
- NEXTAUTH_URL=$SERVICE_FQDN_LANGFUSE_3000
|
||||
- NEXTAUTH_SECRET=${SERVICE_BASE64_64_NEXTAUTHSECRET}
|
||||
- TELEMETRY_ENABLED=${TELEMETRY_ENABLED:-false}
|
||||
- LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES=${LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES:-false}
|
||||
- HOSTNAME=${HOSTNAME:-0.0.0.0}
|
||||
- LANGFUSE_INIT_USER_NAME=${LANGFUSE_INIT_USER_NAME:-Admin}
|
||||
- LANGFUSE_INIT_USER_EMAIL=${LANGFUSE_INIT_USER_EMAIL:-admin@example.com}
|
||||
- LANGFUSE_INIT_USER_PASSWORD=${SERVICE_PASSWORD_LANGFUSE}
|
||||
- LANGFUSE_INIT_ORG_ID=${LANGFUSE_INIT_ORG_ID:-my-org}
|
||||
- LANGFUSE_INIT_ORG_NAME=${LANGFUSE_INIT_ORG_NAME:-My Org}
|
||||
- LANGFUSE_INIT_PROJECT_ID=${LANGFUSE_INIT_PROJECT_ID:-my-project}
|
||||
- LANGFUSE_INIT_PROJECT_NAME=${LANGFUSE_INIT_PROJECT_NAME:-My Project}
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- wget
|
||||
- "-q"
|
||||
- "--spider"
|
||||
- "http://127.0.0.1:3000/api/public/health"
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
image: "postgres:16-alpine"
|
||||
environment:
|
||||
- POSTGRES_DB=${POSTGRES_DB:-langfuse}
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||
volumes:
|
||||
- "pg-data:/var/lib/postgresql/data"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
167
templates/compose/litellm.yaml
Normal file
@@ -0,0 +1,167 @@
|
||||
# documentation: https://docs.litellm.ai
|
||||
# slogan: Call all LLM APIs using the OpenAI format. Use Bedrock, Azure, OpenAI, Cohere, Anthropic, Ollama, Sagemaker, HuggingFace, Replicate, Groq (100+ LLMs)
|
||||
# tags: ai, qdrant, weaviate, langchain, openai, gpt, llm, lmops, anthropic, cohere, ollama, sagemaker, huggingface, replicate, groq
|
||||
# logo: svgs/litellm.svg
|
||||
# port: 4000
|
||||
|
||||
services:
|
||||
litellm:
|
||||
image: "ghcr.io/berriai/litellm-database:main-stable"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- SERVICE_FQDN_LITELLM_4000
|
||||
- LITELLM_LOG=${LITELLM_LOG:-ERROR}
|
||||
- LITELLM_MODE=${LITELLM_MODE:-PRODUCTION}
|
||||
- LITELLM_MASTER_KEY=${SERVICE_PASSWORD_MASTERKEY}
|
||||
- UI_USERNAME=${SERVICE_USER_UI}
|
||||
- UI_PASSWORD=${SERVICE_PASSWORD_UI}
|
||||
- DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-litellm}
|
||||
- REDIS_HOST=${REDIS_HOST:-redis}
|
||||
- REDIS_PORT=${REDIS_PORT:-6379}
|
||||
- POSTGRES_USER=${SERVICE_USER_POSTGRES}
|
||||
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
||||
- POSTGRES_DB=${POSTGRES_DB:-litellm}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- OPENAI_API_BASE=${OPENAI_API_BASE}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- ANTHROPIC_API_BASE=${ANTHROPIC_API_BASE}
|
||||
- VOYAGE_API_KEY=${VOYAGE_API_KEY}
|
||||
- VOYAGE_API_BASE=${VOYAGE_API_BASE}
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ./litellm-config.yaml
|
||||
target: /app/config.yaml
|
||||
content: |
|
||||
general_settings:
|
||||
proxy_batch_write_at: 60
|
||||
|
||||
router_settings:
|
||||
redis_host: os.environ/REDIS_HOST
|
||||
redis_port: os.environ/REDIS_PORT
|
||||
redis_password: os.environ/REDIS_PASSWORD
|
||||
enable_pre_call_check: true
|
||||
|
||||
litellm_settings:
|
||||
set_verbose: false
|
||||
json_logs: true
|
||||
log_raw_request_response: true
|
||||
# turn_off_message_logging: false
|
||||
# redact_user_api_key_info: false
|
||||
service_callback: ["prometheus_system"]
|
||||
drop_params: true
|
||||
# max_budget: 100
|
||||
# budget_duration: 30d
|
||||
num_retries: 3
|
||||
request_timeout: 600
|
||||
telemetry: false
|
||||
cache: true
|
||||
cache_params:
|
||||
type: redis
|
||||
host: os.environ/REDIS_HOST
|
||||
port: os.environ/REDIS_PORT
|
||||
password: os.environ/REDIS_PASSWORD
|
||||
namespace: "litellm_cache"
|
||||
ttl: 600
|
||||
success_callback:
|
||||
# - "langfuse"
|
||||
- "prometheus"
|
||||
failure_callback:
|
||||
# - "langfuse"
|
||||
- "prometheus"
|
||||
model_list:
|
||||
# OpenAI
|
||||
- model_name: gpt-4
|
||||
litellm_params:
|
||||
model: openai/gpt-4
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
api_base: os.environ/OPENAI_API_BASE
|
||||
- model_name: gpt-4o
|
||||
litellm_params:
|
||||
model: openai/gpt-4o
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
api_base: os.environ/OPENAI_API_BASE
|
||||
- model_name: gpt-4o-mini
|
||||
litellm_params:
|
||||
model: openai/gpt-4o-mini
|
||||
api_key: os.environ/OPENAI_API_KEY
|
||||
api_base: os.environ/OPENAI_API_BASE
|
||||
# Anthropic
|
||||
- model_name: claude-3-haiku
|
||||
litellm_params:
|
||||
model: claude-3-haiku-20240307
|
||||
api_key: "os.environ/ANTHROPIC_API_KEY"
|
||||
api_base: "os.environ/ANTHROPIC_API_BASE"
|
||||
- model_name: claude-3.5-sonnet
|
||||
litellm_params:
|
||||
model: claude-3-5-sonnet-20240620
|
||||
api_key: "os.environ/ANTHROPIC_API_KEY"
|
||||
api_base: "os.environ/ANTHROPIC_API_BASE"
|
||||
# VoyageAI
|
||||
- model_name: voyage-law-2
|
||||
model_info:
|
||||
output_vector_size: 1024
|
||||
litellm_params:
|
||||
model: voyage/voyage-law-2
|
||||
api_key: "os.environ/VOYAGE_API_KEY"
|
||||
api_base: "os.environ/VOYAGE_API_BASE"
|
||||
# rpm: 300
|
||||
# tpm: 1000000
|
||||
- model_name: voyage-multilingual-2
|
||||
model_info:
|
||||
mode: embedding
|
||||
max_tokens: 32000
|
||||
max_input_tokens: 32000
|
||||
output_vector_size: 1024
|
||||
litellm_params:
|
||||
model: voyage/voyage-multilingual-2
|
||||
api_key: "os.environ/VOYAGE_API_KEY"
|
||||
api_base: "os.environ/VOYAGE_API_BASE"
|
||||
input_cost_per_token: 0.00000012
|
||||
output_cost_per_token: 0
|
||||
# rpm: 300
|
||||
# tpm: 1000000
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- python
|
||||
- "-c"
|
||||
- "import requests as r;r.get('http://127.0.0.1:4000/health/liveliness').raise_for_status()"
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
command:
|
||||
- "--config"
|
||||
- /app/config.yaml
|
||||
- "--port"
|
||||
- "4000"
|
||||
- "--num_workers"
|
||||
- "8"
|
||||
postgres:
|
||||
image: "postgres:16-alpine"
|
||||
environment:
|
||||
- POSTGRES_DB=${POSTGRES_DB:-litellm}
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||
volumes:
|
||||
- "pg-data:/var/lib/postgresql/data"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
command: redis-server --appendonly yes
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
37
templates/compose/nitropage-with-postgresql.yaml
Normal file
@@ -0,0 +1,37 @@
|
||||
# documentation: https://nitropage.com
|
||||
# slogan: Nitropage is an extensible visual website builder, offering a growing collection of versatile building blocks, focal-point image cropping and sovereign font management.
|
||||
# tags: nitropage, builder, editor, wysiwyg, cms, content, management
|
||||
# logo: svgs/nitropage.svg
|
||||
# port: 3000
|
||||
|
||||
services:
|
||||
nitropage:
|
||||
image: codeberg.org/nitropage/nitropage
|
||||
environment:
|
||||
- SERVICE_FQDN_NITROPAGE_3000
|
||||
- NP_AUTH_SALT=${SERVICE_BASE64_SALT}
|
||||
- NP_AUTH_PASSWORD=${SERVICE_PASSWORD_64_SESSION}
|
||||
- DATABASE_URL=postgresql://${SERVICE_USER_POSTGRESQL}:${SERVICE_PASSWORD_POSTGRESQL}@postgresql:5432/${POSTGRESQL_DATABASE:-nitropage}
|
||||
volumes:
|
||||
- nitropage-data:/app/.data
|
||||
depends_on:
|
||||
postgresql:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000/admin"]
|
||||
interval: 2s
|
||||
timeout: 10s
|
||||
retries: 15
|
||||
postgresql:
|
||||
image: postgres:16-alpine
|
||||
volumes:
|
||||
- nitropage-postgresql-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_USER=${SERVICE_USER_POSTGRESQL}
|
||||
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
|
||||
- POSTGRES_DB=${POSTGRESQL_DATABASE:-nitropage}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
21
templates/compose/nitropage.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
# documentation: https://nitropage.com
|
||||
# slogan: Nitropage is an extensible visual website builder, offering a growing collection of versatile building blocks, focal-point image cropping and sovereign font management.
|
||||
# tags: nitropage, builder, editor, wysiwyg, cms, content, management
|
||||
# logo: svgs/nitropage.svg
|
||||
# port: 3000
|
||||
|
||||
services:
|
||||
nitropage:
|
||||
image: codeberg.org/nitropage/nitropage:sqlite
|
||||
environment:
|
||||
- SERVICE_FQDN_NITROPAGE_3000
|
||||
- NP_AUTH_SALT=${SERVICE_BASE64_SALT}
|
||||
- NP_AUTH_PASSWORD=${SERVICE_PASSWORD_64_SESSION}
|
||||
- DATABASE_URL=file:../../.data/dev.db
|
||||
volumes:
|
||||
- nitropage-data:/app/.data
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000/admin"]
|
||||
interval: 2s
|
||||
timeout: 10s
|
||||
retries: 15
|
||||
34
templates/compose/ollama-with-open-webui.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
# documentation: https://docs.openwebui.com
|
||||
# slogan: Ollama with Open Web UI integrates AI model deployment with a user-friendly interface.
|
||||
# tags: ollama,ai,models,deployment,open-web-ui,integration
|
||||
# logo: svgs/ollama.svg
|
||||
|
||||
services:
|
||||
ollama-api:
|
||||
image: "ollama/ollama:latest"
|
||||
volumes:
|
||||
- "ollama:/root/.ollama"
|
||||
healthcheck:
|
||||
test: ["CMD", "ollama", "list"]
|
||||
interval: 5s
|
||||
timeout: 30s
|
||||
retries: 10
|
||||
|
||||
open-webui:
|
||||
image: "ghcr.io/open-webui/open-webui:main"
|
||||
volumes:
|
||||
- "open-webui:/app/backend/data"
|
||||
depends_on:
|
||||
- ollama-api
|
||||
environment:
|
||||
- SERVICE_FQDN_OLLAMA_8080
|
||||
- OLLAMA_BASE_URL=http://ollama-api:11434
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- curl
|
||||
- "-f"
|
||||
- "http://127.0.0.1:8080"
|
||||
interval: 5s
|
||||
timeout: 30s
|
||||
retries: 10
|
||||
79
templates/compose/prefect.yaml
Normal file
@@ -0,0 +1,79 @@
|
||||
# documentation: https://www.prefect.io/
|
||||
# slogan: Prefect is an orchestration and observability platform that empowers developers to build and scale workflows quickly.
|
||||
# tags: workflow, orchestration, data-pipeline, python, automation, data-processing, data-integration, etl
|
||||
# logo: svgs/prefect.png
|
||||
# port: 4200
|
||||
|
||||
services:
|
||||
prefect:
|
||||
image: "prefecthq/prefect:3-latest"
|
||||
depends_on:
|
||||
postgresql:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- SERVICE_FQDN_PREFECT_4200
|
||||
- PREFECT_API_DATABASE_CONNECTION_URL=postgresql+asyncpg://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql:5432/${POSTGRES_DB:-prefect}
|
||||
- PREFECT_API_KEY=${SERVICE_PASSWORD_APIKEY}
|
||||
- PREFECT_EXPERIMENTAL_WARN=${PREFECT_EXPERIMENTAL_WARN:-false}
|
||||
- PREFECT_EXPERIMENTAL_ENABLE_SCHEDULE_CONCURRENCY=${PREFECT_EXPERIMENTAL_ENABLE_SCHEDULE_CONCURRENCY:-false}
|
||||
- PREFECT_RUNNER_SERVER_ENABLE=${PREFECT_RUNNER_SERVER_ENABLE:-false}
|
||||
- PREFECT_DEFAULT_WORK_POOL_NAME=${DEFAULT_POOL_NAME:-default}
|
||||
command:
|
||||
- prefect
|
||||
- server
|
||||
- start
|
||||
- "--host"
|
||||
- 0.0.0.0
|
||||
- "--port"
|
||||
- "4200"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- python
|
||||
- "-c"
|
||||
- "import requests as r;r.get('http://127.0.0.1:4200/api/health').raise_for_status()"
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
postgresql:
|
||||
image: "postgres:16-alpine"
|
||||
volumes:
|
||||
- "pg-data:/var/lib/postgresql/data"
|
||||
environment:
|
||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- POSTGRES_DB=${POSTGRES_DB:-prefect}
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
agent:
|
||||
image: "prefecthq/prefect:3-python3.12"
|
||||
depends_on:
|
||||
prefect:
|
||||
condition: service_healthy
|
||||
entrypoint:
|
||||
- /opt/prefect/entrypoint.sh
|
||||
- prefect
|
||||
- worker
|
||||
- start
|
||||
- --pool=${DEFAULT_POOL_NAME}
|
||||
- --with-healthcheck
|
||||
- --name=${DEFAULT_WORKER_NAME}
|
||||
- --limit=${DEFAULT_POOL_LIMIT}
|
||||
environment:
|
||||
- PREFECT_API_URL=http://prefect:4200/api
|
||||
- PREFECT_API_KEY=${SERVICE_PASSWORD_APIKEY}
|
||||
- DEFAULT_POOL_NAME=${DEFAULT_POOL_NAME:-default}
|
||||
- DEFAULT_POOL_LIMIT=${DEFAULT_POOL_LIMIT:-1}
|
||||
- DEFAULT_WORKER_NAME=${DEFAULT_WORKER_NAME:-worker1}
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- pwd
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
21
templates/compose/qdrant.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
# documentation: https://qdrant.tech/documentation/
|
||||
# slogan: Qdrant is a vector similarity search engine that provides a production-ready service with a convenient API to store, search, and manage points (i.e. vectors) with an additional payload.
|
||||
# tags: ai, vector-database, semantic-search, machine-learning, bm25, embeddings, llm
|
||||
# logo: svgs/qdrant.png
|
||||
# port: 6333
|
||||
|
||||
services:
|
||||
qdrant:
|
||||
image: "qdrant/qdrant:latest"
|
||||
environment:
|
||||
- SERVICE_FQDN_QDRANT_6333
|
||||
- QDRANT__SERVICE__API_KEY=${SERVICE_PASSWORD_QDRANTAPIKEY}
|
||||
volumes:
|
||||
- "qdrant-storage:/qdrant/storage"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- bash -c ':> /dev/tcp/127.0.0.1/6333' || exit 1
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
@@ -16,6 +16,6 @@ services:
|
||||
- ${PORT}:5672
|
||||
healthcheck:
|
||||
test: rabbitmq-diagnostics -q ping
|
||||
interval: 30s
|
||||
interval: 5s
|
||||
timeout: 30s
|
||||
retries: 3
|
||||
retries: 10
|
||||
|
||||
72
templates/compose/searxng.yaml
Normal file
@@ -0,0 +1,72 @@
|
||||
# documentation: https://docs.searxng.org
|
||||
# slogan: SearXNG is a free internet metasearch engine which aggregates results from more than 70 search services.
|
||||
# tags: search, google, engine, images, documents, rss, proxy, news, web, api
|
||||
# logo: svgs/searxng.svg
|
||||
# port: 8080
|
||||
|
||||
services:
|
||||
searxng:
|
||||
image: searxng/searxng
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- SERVICE_FQDN_SEARXNG_8080
|
||||
- INSTANCE_NAME=${INSTANCE_NAME:-coolify}
|
||||
- BASE_URL=${SERVICE_FQDN_SEARXNG_8080}
|
||||
- SEARXNG_URL=${SERVICE_FQDN_SEARXNG_8080}
|
||||
- SEARXNG_BIND_ADDRESS=${SEARXNG_BIND_ADDRESS:-0.0.0.0}
|
||||
- SEARXNG_SECRET=${SERVICE_PASSWORD_SEARXNGSECRET}
|
||||
- SEARXNG_REDIS_URL=redis://redis:6379/0
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- wget
|
||||
- "-q"
|
||||
- "--spider"
|
||||
- "http://127.0.0.1:8080/healthz"
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ./settings.yml
|
||||
target: /etc/searxng/settings.yml
|
||||
content: |
|
||||
# see https://docs.searxng.org/admin/settings/settings.html#settings-use-default-settings
|
||||
use_default_settings: true
|
||||
server:
|
||||
limiter: false
|
||||
image_proxy: true
|
||||
search:
|
||||
formats:
|
||||
- html
|
||||
- csv
|
||||
- json
|
||||
- rss
|
||||
ui:
|
||||
static_use_hash: true
|
||||
- type: bind
|
||||
source: ./limiter.toml
|
||||
target: /etc/searxng/limiter.toml
|
||||
content: |
|
||||
# This configuration file updates the default configuration file
|
||||
# See https://github.com/searxng/searxng/blob/master/searx/botdetection/limiter.toml
|
||||
|
||||
[botdetection.ip_limit]
|
||||
# activate link_token method in the ip_limit method
|
||||
link_token = true
|
||||
|
||||
redis:
|
||||
image: "redis:7"
|
||||
restart: always
|
||||
volumes:
|
||||
- "redis-data:/data"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- redis-cli
|
||||
- ping
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
21
templates/compose/unstructured.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
# documentation: https://github.com/Unstructured-IO/unstructured-api?tab=readme-ov-file#--general-pre-processing-pipeline-for-documents
|
||||
# slogan: Unstructured provides a platform and tools to ingest and process unstructured documents for Retrieval Augmented Generation (RAG) and model fine-tuning.
|
||||
# tags: workflow, orchestration, data-pipeline, python, data, machine-learning, data-science, nlp, unstructured, ocr, data-extraction
|
||||
# logo: svgs/unstructured.png
|
||||
# port: 8000
|
||||
|
||||
services:
|
||||
unstructured:
|
||||
image: "downloads.unstructured.io/unstructured-io/unstructured-api:latest"
|
||||
environment:
|
||||
- SERVICE_FQDN_UNSTRUCTURED_8000
|
||||
- "UNSTRUCTURED_API_KEY=${SERVICE_PASSWORD_APIKEY}"
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- wget
|
||||
- "-qO-"
|
||||
- "http://0.0.0.0:8000/healthcheck"
|
||||
interval: 5s
|
||||
timeout: 30s
|
||||
retries: 10
|
||||
45
templates/compose/weaviate.yaml
Normal file
@@ -0,0 +1,45 @@
|
||||
# documentation: https://weaviate.io/developers/weaviate
|
||||
# slogan: Weaviate is an open-source vector database that stores both objects and vectors, allowing for combining vector search with structured filtering.
|
||||
# tags: ai, vector-database, semantic-search, machine-learning, bm25, embeddings, llm
|
||||
# logo: svgs/weaviate.png
|
||||
# port: 8080
|
||||
|
||||
|
||||
services:
|
||||
weaviate:
|
||||
image: "cr.weaviate.io/semitechnologies/weaviate:1.26.4"
|
||||
volumes:
|
||||
- "weaviate-data:/var/lib/weaviate"
|
||||
command:
|
||||
- "--host"
|
||||
- 0.0.0.0
|
||||
- "--port"
|
||||
- "8080"
|
||||
- "--scheme"
|
||||
- http
|
||||
environment:
|
||||
- SERVICE_FQDN_WEAVIATE_8080
|
||||
- DISABLE_TELEMETRY=${DISABLE_TELEMETRY:-true}
|
||||
- QUERY_DEFAULTS_LIMIT=${QUERY_DEFAULTS_LIMIT:-1000}
|
||||
- LOG_LEVEL=${LOG_LEVEL:-info}
|
||||
- GOMEMLIMIT=${GOMEMLIMIT:-1024MiB}
|
||||
- GOMAXPROCS=${GOMAXPROCS:-2}
|
||||
- AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=${AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED:-false}
|
||||
- AUTHORIZATION_ADMINLIST_USERS=${AUTHORIZATION_ADMINLIST_USERS:-admin@example.com}
|
||||
- AUTHENTICATION_APIKEY_USERS=${AUTHENTICATION_APIKEY_USERS:-admin@example.com}
|
||||
- AUTHENTICATION_APIKEY_ENABLED=${AUTHENTICATION_APIKEY_ENABLED:-true}
|
||||
- AUTHENTICATION_APIKEY_ALLOWED_KEYS=${SERVICE_PASSWORD_APIKEYS}
|
||||
- PERSISTENCE_DATA_PATH=/var/lib/weaviate
|
||||
- DEFAULT_VECTORIZER_MODULE=${DEFAULT_VECTORIZER_MODULE:-none}
|
||||
- ENABLE_MODULES=${ENABLE_MODULES:-text2vec-openai,generative-openai,qna-openai}
|
||||
- CLUSTER_HOSTNAME=${CLUSTER_HOSTNAME:-node1}
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- wget
|
||||
- "-q"
|
||||
- "--spider"
|
||||
- "http://localhost:8080/v1/.well-known/ready"
|
||||
interval: 5s
|
||||
timeout: 30s
|
||||
retries: 10
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"coolify": {
|
||||
"v4": {
|
||||
"version": "4.0.0-beta.351"
|
||||
"version": "4.0.0-beta.357"
|
||||
},
|
||||
"nightly": {
|
||||
"version": "4.0.0-beta.352"
|
||||
"version": "4.0.0-beta.358"
|
||||
},
|
||||
"helper": {
|
||||
"version": "1.0.1"
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"realtime": {
|
||||
"version": "1.0.3"
|
||||
|
||||