Compare commits
235 Commits
v4.0.0-bet
...
next
| Author | SHA1 | Date | |
|---|---|---|---|
| 9e5551c4dd | |||
|
|
789fc1348d | ||
|
|
fd15c7b49e | ||
|
|
7872818f9e | ||
|
|
1b79f78fda | ||
|
|
e6ff801559 | ||
|
|
8b7c34d5e6 | ||
|
|
e6566d8be3 | ||
|
|
290c287f7e | ||
|
|
1de50227c3 | ||
|
|
d69164bc43 | ||
|
|
0e2889b857 | ||
|
|
df9b2ebb1f | ||
|
|
91a1fdcb9a | ||
|
|
10ca408b37 | ||
|
|
1d4dd405b8 | ||
|
|
482016be1d | ||
|
|
c5e6d04a95 | ||
|
|
ce352eb590 | ||
|
|
3e5b0d920c | ||
|
|
dc75e5dc6e | ||
|
|
34e7805ef4 | ||
|
|
dee9123694 | ||
|
|
b02720aac8 | ||
|
|
3000579bcd | ||
|
|
be03e0c587 | ||
|
|
f0e6892d77 | ||
|
|
44f2d521a2 | ||
|
|
ef821b2c2d | ||
|
|
d031911ada | ||
|
|
ab8bb8dc4e | ||
|
|
1c6d47f2fc | ||
|
|
742df4f5df | ||
|
|
2522ecf832 | ||
|
|
8d2fef558f | ||
|
|
a979beb3a6 | ||
|
|
0143b9bb26 | ||
|
|
ce9d4308d4 | ||
|
|
57a96c2579 | ||
|
|
4e9bafd6df | ||
|
|
15b5cbf68f | ||
|
|
bfe9a17f4b | ||
|
|
ec3916bb7e | ||
|
|
974b4b92c1 | ||
|
|
e16ccb2bcd | ||
|
|
a361a864dd | ||
|
|
1bed6bf696 | ||
|
|
5c65eb281d | ||
|
|
0cd2ca6e79 | ||
|
|
7cb9cb0a44 | ||
|
|
2b9b2af8fe | ||
|
|
b8f211eced | ||
|
|
1034d9c315 | ||
|
|
37bc2643a5 | ||
|
|
052fcd2520 | ||
|
|
df152e9fbd | ||
|
|
8af41b533c | ||
|
|
17b852ce1d | ||
|
|
f4c88d3600 | ||
|
|
9c2b24b9d0 | ||
|
|
4e6bf6bb8d | ||
|
|
74571d99a1 | ||
|
|
4bcfe1c0b8 | ||
|
|
b25ef93a8e | ||
|
|
e6db0b9798 | ||
|
|
2805681a30 | ||
|
|
22dc06f1f2 | ||
|
|
30b1d076d2 | ||
|
|
c486281816 | ||
|
|
71d28492b8 | ||
|
|
1914b505ed | ||
|
|
8c78e9adf0 | ||
|
|
e1168bebe0 | ||
|
|
bb8a276aa9 | ||
|
|
8d543d40cc | ||
|
|
f5ca820be8 | ||
|
|
09d1ca79b9 | ||
|
|
5fcd432c76 | ||
|
|
837796debf | ||
|
|
16817993fa | ||
|
|
2b818285b8 | ||
|
|
5c83b573b6 | ||
|
|
46f226c3f7 | ||
|
|
7aa60adc98 | ||
|
|
a2cfa1423d | ||
|
|
cdedf3b25c | ||
|
|
63f329d123 | ||
|
|
0b084060ee | ||
|
|
2c895927f6 | ||
|
|
db8c59eaaf | ||
|
|
b31cfd1604 | ||
|
|
8c503bc7fc | ||
|
|
c4ee91930d | ||
|
|
8fd103cc77 | ||
|
|
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 | ||
|
|
6d6d6bfc87 | ||
|
|
7665a1787f | ||
|
|
846e45134e | ||
|
|
a8d8df7d8b | ||
|
|
283fe47f5c | ||
|
|
88367d8af1 | ||
|
|
506f733632 | ||
|
|
9f2e7851f7 | ||
|
|
8269e9d29d | ||
|
|
8803cae54c | ||
|
|
c1930e3dfc | ||
|
|
c717b6859b | ||
|
|
4624a381b1 | ||
|
|
6928b0a2c8 | ||
|
|
2da6f66e85 | ||
|
|
a1124a885d | ||
|
|
9448d0f0d2 | ||
|
|
e446354d97 | ||
|
|
c8aa09359f | ||
|
|
128d732438 | ||
|
|
3b97bb1341 | ||
|
|
a4c8f83d17 | ||
|
|
0ca9885ddf | ||
|
|
acd6eedf40 | ||
|
|
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 | ||
|
|
b324303505 | ||
|
|
6aa7cfc479 | ||
|
|
2cf0f4facc | ||
|
|
a6e50ce24e | ||
|
|
3a352e832b | ||
|
|
1b8365d559 | ||
|
|
0494f9a7e5 | ||
|
|
c402d7f543 | ||
|
|
565cb54dba | ||
|
|
14c8023197 | ||
|
|
44ceb097f3 | ||
|
|
eb5765979f | ||
|
|
611e80c987 | ||
|
|
7645047d75 | ||
|
|
82f96fe677 | ||
|
|
48e4ebdb5d | ||
|
|
028c41b011 | ||
|
|
d53c1f99d6 | ||
|
|
918d8e783a | ||
|
|
464769881f | ||
|
|
c1eb01fac5 | ||
|
|
1e46b63041 | ||
|
|
0f7a199d81 | ||
|
|
2f356b16b6 | ||
|
|
a6f457f2f3 | ||
|
|
71bb1f5e17 | ||
|
|
ce926afdaa | ||
|
|
b8cdb40ce5 | ||
|
|
7f59efd27c | ||
|
|
4f23d3880d | ||
|
|
b4175658e9 | ||
|
|
f080a4bf30 | ||
|
|
58dcf769e4 | ||
|
|
319457020c | ||
|
|
20acb4363b | ||
|
|
a219942987 | ||
|
|
22a58eea8f | ||
|
|
868bbaf5a9 | ||
|
|
18ae29ba99 | ||
|
|
380f2f4029 | ||
|
|
c3e80fbc18 | ||
|
|
6b178f8b2e | ||
|
|
e7d45ac876 | ||
|
|
48886cac84 | ||
|
|
633c8253ec | ||
|
|
fa253b981a | ||
|
|
45b4d1b25b | ||
|
|
e1a585c194 | ||
|
|
631b7096c9 | ||
|
|
cdb146f03c | ||
|
|
ea81d8ecfe | ||
|
|
793f91e7fb | ||
|
|
807304c50b | ||
|
|
204aaf5dfa | ||
|
|
c1612a9e88 | ||
|
|
3847076392 | ||
|
|
ac887eefd6 | ||
|
|
2637afcfb2 | ||
|
|
7d1f760c53 | ||
|
|
5262676596 |
@@ -22,3 +22,4 @@ yarn-error.log
|
|||||||
/_data
|
/_data
|
||||||
.rnd
|
.rnd
|
||||||
/.ssh
|
/.ssh
|
||||||
|
.ignition.json
|
||||||
|
|||||||
1
.github/workflows/coolify-helper.yml
vendored
@@ -98,3 +98,4 @@ jobs:
|
|||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }}
|
webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }}
|
||||||
|
|
||||||
|
|||||||
1
.gitignore
vendored
@@ -32,3 +32,4 @@ _ide_helper_models.php
|
|||||||
.rnd
|
.rnd
|
||||||
/.ssh
|
/.ssh
|
||||||
scripts/load-test/*
|
scripts/load-test/*
|
||||||
|
.ignition.json
|
||||||
|
|||||||
17
app/Actions/Application/GenerateConfig.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Application;
|
||||||
|
|
||||||
|
use App\Models\Application;
|
||||||
|
use Lorisleiva\Actions\Concerns\AsAction;
|
||||||
|
|
||||||
|
class GenerateConfig
|
||||||
|
{
|
||||||
|
use AsAction;
|
||||||
|
|
||||||
|
public function handle(Application $application, bool $is_json = false)
|
||||||
|
{
|
||||||
|
ray()->clearAll();
|
||||||
|
return $application->generateConfig(is_json: $is_json);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ class CheckConfiguration
|
|||||||
];
|
];
|
||||||
$proxy_configuration = instant_remote_process($payload, $server, false);
|
$proxy_configuration = instant_remote_process($payload, $server, false);
|
||||||
if ($reset || ! $proxy_configuration || is_null($proxy_configuration)) {
|
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)) {
|
if (! $proxy_configuration || is_null($proxy_configuration)) {
|
||||||
throw new \Exception('Could not generate proxy configuration');
|
throw new \Exception('Could not generate proxy configuration');
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class StartProxy
|
|||||||
}
|
}
|
||||||
SaveConfiguration::run($server, $configuration);
|
SaveConfiguration::run($server, $configuration);
|
||||||
$docker_compose_yml_base64 = base64_encode($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();
|
$server->save();
|
||||||
if ($server->isSwarm()) {
|
if ($server->isSwarm()) {
|
||||||
$commands = $commands->merge([
|
$commands = $commands->merge([
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ class ServicesGenerate extends Command
|
|||||||
$serviceTemplatesJson[$name] = $parsed;
|
$serviceTemplatesJson[$name] = $parsed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$serviceTemplatesJson = json_encode($serviceTemplatesJson);
|
$serviceTemplatesJson = json_encode($serviceTemplatesJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||||
file_put_contents(base_path('templates/service-templates.json'), $serviceTemplatesJson);
|
file_put_contents(base_path('templates/service-templates.json'), $serviceTemplatesJson.PHP_EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function process_file($file)
|
private function process_file($file)
|
||||||
@@ -78,7 +78,7 @@ class ServicesGenerate extends Command
|
|||||||
if ($logo->count() > 0) {
|
if ($logo->count() > 0) {
|
||||||
$logo = str($logo[0])->after('# logo:')->trim()->value();
|
$logo = str($logo[0])->after('# logo:')->trim()->value();
|
||||||
} else {
|
} else {
|
||||||
$logo = 'svgs/unknown.svg';
|
$logo = 'svgs/coolify.png';
|
||||||
}
|
}
|
||||||
$minversion = collect(preg_grep('/^# minversion:/', explode("\n", $content)))->values();
|
$minversion = collect(preg_grep('/^# minversion:/', explode("\n", $content)))->values();
|
||||||
if ($minversion->count() > 0) {
|
if ($minversion->count() > 0) {
|
||||||
|
|||||||
8
app/Enums/StaticImageTypes.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum StaticImageTypes: string
|
||||||
|
{
|
||||||
|
case NGINX_ALPINE = 'nginx:alpine';
|
||||||
|
}
|
||||||
@@ -132,6 +132,7 @@ class ApplicationsController extends Controller
|
|||||||
'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'],
|
'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'],
|
||||||
'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'],
|
'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'],
|
||||||
'is_static' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is static.'],
|
'is_static' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is static.'],
|
||||||
|
'static_image' => ['type' => 'string', 'enum' => ['nginx:alpine'], 'description' => 'The static image.'],
|
||||||
'install_command' => ['type' => 'string', 'description' => 'The install command.'],
|
'install_command' => ['type' => 'string', 'description' => 'The install command.'],
|
||||||
'build_command' => ['type' => 'string', 'description' => 'The build command.'],
|
'build_command' => ['type' => 'string', 'description' => 'The build command.'],
|
||||||
'start_command' => ['type' => 'string', 'description' => 'The start command.'],
|
'start_command' => ['type' => 'string', 'description' => 'The start command.'],
|
||||||
@@ -236,6 +237,7 @@ class ApplicationsController extends Controller
|
|||||||
'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'],
|
'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'],
|
||||||
'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'],
|
'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'],
|
||||||
'is_static' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is static.'],
|
'is_static' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is static.'],
|
||||||
|
'static_image' => ['type' => 'string', 'enum' => ['nginx:alpine'], 'description' => 'The static image.'],
|
||||||
'install_command' => ['type' => 'string', 'description' => 'The install command.'],
|
'install_command' => ['type' => 'string', 'description' => 'The install command.'],
|
||||||
'build_command' => ['type' => 'string', 'description' => 'The build command.'],
|
'build_command' => ['type' => 'string', 'description' => 'The build command.'],
|
||||||
'start_command' => ['type' => 'string', 'description' => 'The start command.'],
|
'start_command' => ['type' => 'string', 'description' => 'The start command.'],
|
||||||
@@ -339,6 +341,7 @@ class ApplicationsController extends Controller
|
|||||||
'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'],
|
'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'],
|
||||||
'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'],
|
'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'],
|
||||||
'is_static' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is static.'],
|
'is_static' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is static.'],
|
||||||
|
'static_image' => ['type' => 'string', 'enum' => ['nginx:alpine'], 'description' => 'The static image.'],
|
||||||
'install_command' => ['type' => 'string', 'description' => 'The install command.'],
|
'install_command' => ['type' => 'string', 'description' => 'The install command.'],
|
||||||
'build_command' => ['type' => 'string', 'description' => 'The build command.'],
|
'build_command' => ['type' => 'string', 'description' => 'The build command.'],
|
||||||
'start_command' => ['type' => 'string', 'description' => 'The start command.'],
|
'start_command' => ['type' => 'string', 'description' => 'The start command.'],
|
||||||
@@ -633,7 +636,7 @@ class ApplicationsController extends Controller
|
|||||||
|
|
||||||
private function create_application(Request $request, $type)
|
private function create_application(Request $request, $type)
|
||||||
{
|
{
|
||||||
$allowedFields = ['project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server'];
|
$allowedFields = ['project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image'];
|
||||||
$teamId = getTeamIdFromToken();
|
$teamId = getTeamIdFromToken();
|
||||||
if (is_null($teamId)) {
|
if (is_null($teamId)) {
|
||||||
return invalidTokenResponse();
|
return invalidTokenResponse();
|
||||||
@@ -672,6 +675,7 @@ class ApplicationsController extends Controller
|
|||||||
$instantDeploy = $request->instant_deploy;
|
$instantDeploy = $request->instant_deploy;
|
||||||
$githubAppUuid = $request->github_app_uuid;
|
$githubAppUuid = $request->github_app_uuid;
|
||||||
$useBuildServer = $request->use_build_server;
|
$useBuildServer = $request->use_build_server;
|
||||||
|
$isStatic = $request->is_static;
|
||||||
|
|
||||||
$project = Project::whereTeamId($teamId)->whereUuid($request->project_uuid)->first();
|
$project = Project::whereTeamId($teamId)->whereUuid($request->project_uuid)->first();
|
||||||
if (! $project) {
|
if (! $project) {
|
||||||
@@ -700,8 +704,7 @@ class ApplicationsController extends Controller
|
|||||||
if ($request->build_pack === 'dockercompose') {
|
if ($request->build_pack === 'dockercompose') {
|
||||||
$request->offsetSet('ports_exposes', '80');
|
$request->offsetSet('ports_exposes', '80');
|
||||||
}
|
}
|
||||||
$validator = customApiValidator($request->all(), [
|
$validationRules = [
|
||||||
sharedDataApplications(),
|
|
||||||
'git_repository' => 'string|required',
|
'git_repository' => 'string|required',
|
||||||
'git_branch' => 'string|required',
|
'git_branch' => 'string|required',
|
||||||
'build_pack' => ['required', Rule::enum(BuildPackTypes::class)],
|
'build_pack' => ['required', Rule::enum(BuildPackTypes::class)],
|
||||||
@@ -709,19 +712,21 @@ class ApplicationsController extends Controller
|
|||||||
'docker_compose_location' => 'string',
|
'docker_compose_location' => 'string',
|
||||||
'docker_compose_raw' => 'string|nullable',
|
'docker_compose_raw' => 'string|nullable',
|
||||||
'docker_compose_domains' => 'array|nullable',
|
'docker_compose_domains' => 'array|nullable',
|
||||||
'docker_compose_custom_start_command' => 'string|nullable',
|
];
|
||||||
'docker_compose_custom_build_command' => 'string|nullable',
|
$validationRules = array_merge($validationRules, sharedDataApplications());
|
||||||
]);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Validation failed.',
|
'message' => 'Validation failed.',
|
||||||
'errors' => $validator->errors(),
|
'errors' => $validator->errors(),
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
$return = $this->validateDataApplications($request, $server);
|
$return = $this->validateDataApplications($request, $server);
|
||||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$application = new Application;
|
$application = new Application;
|
||||||
removeUnnecessaryFieldsFromRequest($request);
|
removeUnnecessaryFieldsFromRequest($request);
|
||||||
|
|
||||||
@@ -744,11 +749,15 @@ class ApplicationsController extends Controller
|
|||||||
$application->destination_id = $destination->id;
|
$application->destination_id = $destination->id;
|
||||||
$application->destination_type = $destination->getMorphClass();
|
$application->destination_type = $destination->getMorphClass();
|
||||||
$application->environment_id = $environment->id;
|
$application->environment_id = $environment->id;
|
||||||
|
$application->save();
|
||||||
|
if (isset($isStatic)) {
|
||||||
|
$application->settings->is_static = $isStatic;
|
||||||
|
$application->settings->save();
|
||||||
|
}
|
||||||
if (isset($useBuildServer)) {
|
if (isset($useBuildServer)) {
|
||||||
$application->settings->is_build_server_enabled = $useBuildServer;
|
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
}
|
}
|
||||||
$application->save();
|
|
||||||
$application->refresh();
|
$application->refresh();
|
||||||
if (! $application->settings->is_container_label_readonly_enabled) {
|
if (! $application->settings->is_container_label_readonly_enabled) {
|
||||||
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
||||||
@@ -782,8 +791,7 @@ class ApplicationsController extends Controller
|
|||||||
if ($request->build_pack === 'dockercompose') {
|
if ($request->build_pack === 'dockercompose') {
|
||||||
$request->offsetSet('ports_exposes', '80');
|
$request->offsetSet('ports_exposes', '80');
|
||||||
}
|
}
|
||||||
$validator = customApiValidator($request->all(), [
|
$validationRules = [
|
||||||
sharedDataApplications(),
|
|
||||||
'git_repository' => 'string|required',
|
'git_repository' => 'string|required',
|
||||||
'git_branch' => 'string|required',
|
'git_branch' => 'string|required',
|
||||||
'build_pack' => ['required', Rule::enum(BuildPackTypes::class)],
|
'build_pack' => ['required', Rule::enum(BuildPackTypes::class)],
|
||||||
@@ -792,10 +800,10 @@ class ApplicationsController extends Controller
|
|||||||
'watch_paths' => 'string|nullable',
|
'watch_paths' => 'string|nullable',
|
||||||
'docker_compose_location' => 'string',
|
'docker_compose_location' => 'string',
|
||||||
'docker_compose_raw' => 'string|nullable',
|
'docker_compose_raw' => 'string|nullable',
|
||||||
'docker_compose_domains' => 'array|nullable',
|
];
|
||||||
'docker_compose_custom_start_command' => 'string|nullable',
|
$validationRules = array_merge($validationRules, sharedDataApplications());
|
||||||
'docker_compose_custom_build_command' => 'string|nullable',
|
|
||||||
]);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Validation failed.',
|
'message' => 'Validation failed.',
|
||||||
@@ -882,8 +890,8 @@ class ApplicationsController extends Controller
|
|||||||
if ($request->build_pack === 'dockercompose') {
|
if ($request->build_pack === 'dockercompose') {
|
||||||
$request->offsetSet('ports_exposes', '80');
|
$request->offsetSet('ports_exposes', '80');
|
||||||
}
|
}
|
||||||
$validator = customApiValidator($request->all(), [
|
|
||||||
sharedDataApplications(),
|
$validationRules = [
|
||||||
'git_repository' => 'string|required',
|
'git_repository' => 'string|required',
|
||||||
'git_branch' => 'string|required',
|
'git_branch' => 'string|required',
|
||||||
'build_pack' => ['required', Rule::enum(BuildPackTypes::class)],
|
'build_pack' => ['required', Rule::enum(BuildPackTypes::class)],
|
||||||
@@ -892,10 +900,10 @@ class ApplicationsController extends Controller
|
|||||||
'watch_paths' => 'string|nullable',
|
'watch_paths' => 'string|nullable',
|
||||||
'docker_compose_location' => 'string',
|
'docker_compose_location' => 'string',
|
||||||
'docker_compose_raw' => 'string|nullable',
|
'docker_compose_raw' => 'string|nullable',
|
||||||
'docker_compose_domains' => 'array|nullable',
|
];
|
||||||
'docker_compose_custom_start_command' => 'string|nullable',
|
|
||||||
'docker_compose_custom_build_command' => 'string|nullable',
|
$validationRules = array_merge($validationRules, sharedDataApplications());
|
||||||
]);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -975,10 +983,13 @@ class ApplicationsController extends Controller
|
|||||||
if (! $request->has('name')) {
|
if (! $request->has('name')) {
|
||||||
$request->offsetSet('name', 'dockerfile-'.new Cuid2);
|
$request->offsetSet('name', 'dockerfile-'.new Cuid2);
|
||||||
}
|
}
|
||||||
$validator = customApiValidator($request->all(), [
|
|
||||||
sharedDataApplications(),
|
$validationRules = [
|
||||||
'dockerfile' => 'string|required',
|
'dockerfile' => 'string|required',
|
||||||
]);
|
];
|
||||||
|
$validationRules = array_merge($validationRules, sharedDataApplications());
|
||||||
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Validation failed.',
|
'message' => 'Validation failed.',
|
||||||
@@ -1057,12 +1068,14 @@ class ApplicationsController extends Controller
|
|||||||
if (! $request->has('name')) {
|
if (! $request->has('name')) {
|
||||||
$request->offsetSet('name', 'docker-image-'.new Cuid2);
|
$request->offsetSet('name', 'docker-image-'.new Cuid2);
|
||||||
}
|
}
|
||||||
$validator = customApiValidator($request->all(), [
|
$validationRules = [
|
||||||
sharedDataApplications(),
|
|
||||||
'docker_registry_image_name' => 'string|required',
|
'docker_registry_image_name' => 'string|required',
|
||||||
'docker_registry_image_tag' => 'string',
|
'docker_registry_image_tag' => 'string',
|
||||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
||||||
]);
|
];
|
||||||
|
$validationRules = array_merge($validationRules, sharedDataApplications());
|
||||||
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Validation failed.',
|
'message' => 'Validation failed.',
|
||||||
@@ -1135,10 +1148,12 @@ class ApplicationsController extends Controller
|
|||||||
if (! $request->has('name')) {
|
if (! $request->has('name')) {
|
||||||
$request->offsetSet('name', 'service'.new Cuid2);
|
$request->offsetSet('name', 'service'.new Cuid2);
|
||||||
}
|
}
|
||||||
$validator = customApiValidator($request->all(), [
|
$validationRules = [
|
||||||
sharedDataApplications(),
|
|
||||||
'docker_compose_raw' => 'string|required',
|
'docker_compose_raw' => 'string|required',
|
||||||
]);
|
];
|
||||||
|
$validationRules = array_merge($validationRules, sharedDataApplications());
|
||||||
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Validation failed.',
|
'message' => 'Validation failed.',
|
||||||
@@ -1488,8 +1503,7 @@ class ApplicationsController extends Controller
|
|||||||
$server = $application->destination->server;
|
$server = $application->destination->server;
|
||||||
$allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server'];
|
$allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server'];
|
||||||
|
|
||||||
$validator = customApiValidator($request->all(), [
|
$validationRules = [
|
||||||
sharedDataApplications(),
|
|
||||||
'name' => 'string|max:255',
|
'name' => 'string|max:255',
|
||||||
'description' => 'string|nullable',
|
'description' => 'string|nullable',
|
||||||
'static_image' => 'string',
|
'static_image' => 'string',
|
||||||
@@ -1499,7 +1513,9 @@ class ApplicationsController extends Controller
|
|||||||
'docker_compose_domains' => 'array|nullable',
|
'docker_compose_domains' => 'array|nullable',
|
||||||
'docker_compose_custom_start_command' => 'string|nullable',
|
'docker_compose_custom_start_command' => 'string|nullable',
|
||||||
'docker_compose_custom_build_command' => 'string|nullable',
|
'docker_compose_custom_build_command' => 'string|nullable',
|
||||||
]);
|
];
|
||||||
|
$validationRules = array_merge($validationRules, sharedDataApplications());
|
||||||
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
|
|
||||||
// Validate ports_exposes
|
// Validate ports_exposes
|
||||||
if ($request->has('ports_exposes')) {
|
if ($request->has('ports_exposes')) {
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ class Help extends Component
|
|||||||
send_user_an_email($mail, auth()->user()?->email, 'hi@coollabs.io');
|
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->dispatch('success', 'Feedback sent.', 'We will get in touch with you as soon as possible.');
|
||||||
|
$this->reset('description', 'subject');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Livewire\Project\Application;
|
namespace App\Livewire\Project\Application;
|
||||||
|
|
||||||
|
use App\Actions\Application\GenerateConfig;
|
||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
@@ -243,12 +244,19 @@ class General extends Component
|
|||||||
|
|
||||||
public function updatedApplicationFqdn()
|
public function updatedApplicationFqdn()
|
||||||
{
|
{
|
||||||
$this->application->fqdn = str($this->application->fqdn)->replaceEnd(',', '')->trim();
|
try {
|
||||||
$this->application->fqdn = str($this->application->fqdn)->replaceStart(',', '')->trim();
|
$this->application->fqdn = str($this->application->fqdn)->replaceEnd(',', '')->trim();
|
||||||
$this->application->fqdn = str($this->application->fqdn)->trim()->explode(',')->map(function ($domain) {
|
$this->application->fqdn = str($this->application->fqdn)->replaceStart(',', '')->trim();
|
||||||
return str($domain)->trim()->lower();
|
$this->application->fqdn = str($this->application->fqdn)->trim()->explode(',')->map(function ($domain) {
|
||||||
});
|
return str($domain)->trim()->lower();
|
||||||
$this->application->fqdn = $this->application->fqdn->unique()->implode(',');
|
});
|
||||||
|
$this->application->fqdn = $this->application->fqdn->unique()->implode(',');
|
||||||
|
$this->application->save();
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
$originalFqdn = $this->application->getOriginal('fqdn');
|
||||||
|
$this->application->fqdn = $originalFqdn;
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
$this->resetDefaultLabels();
|
$this->resetDefaultLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,18 +295,22 @@ class General extends Component
|
|||||||
|
|
||||||
public function resetDefaultLabels()
|
public function resetDefaultLabels()
|
||||||
{
|
{
|
||||||
if ($this->application->settings->is_container_label_readonly_enabled) {
|
try {
|
||||||
return;
|
if ($this->application->settings->is_container_label_readonly_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->customLabels = str(implode('|coolify|', generateLabelsApplication($this->application)))->replace('|coolify|', "\n");
|
||||||
|
$this->ports_exposes = $this->application->ports_exposes;
|
||||||
|
$this->is_container_label_escape_enabled = $this->application->settings->is_container_label_escape_enabled;
|
||||||
|
$this->application->custom_labels = base64_encode($this->customLabels);
|
||||||
|
$this->application->save();
|
||||||
|
if ($this->application->build_pack === 'dockercompose') {
|
||||||
|
$this->loadComposeFile();
|
||||||
|
}
|
||||||
|
$this->dispatch('configurationChanged');
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
$this->customLabels = str(implode('|coolify|', generateLabelsApplication($this->application)))->replace('|coolify|', "\n");
|
|
||||||
$this->ports_exposes = $this->application->ports_exposes;
|
|
||||||
$this->is_container_label_escape_enabled = $this->application->settings->is_container_label_escape_enabled;
|
|
||||||
$this->application->custom_labels = base64_encode($this->customLabels);
|
|
||||||
$this->application->save();
|
|
||||||
if ($this->application->build_pack === 'dockercompose') {
|
|
||||||
$this->loadComposeFile();
|
|
||||||
}
|
|
||||||
$this->dispatch('configurationChanged');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkFqdns($showToaster = true)
|
public function checkFqdns($showToaster = true)
|
||||||
@@ -413,4 +425,16 @@ class General extends Component
|
|||||||
$this->dispatch('configurationChanged');
|
$this->dispatch('configurationChanged');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public function downloadConfig()
|
||||||
|
{
|
||||||
|
$config = GenerateConfig::run($this->application, true);
|
||||||
|
$fileName = str($this->application->name)->slug()->append('_config.json');
|
||||||
|
|
||||||
|
return response()->streamDownload(function () use ($config) {
|
||||||
|
echo $config;
|
||||||
|
}, $fileName, [
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'Content-Disposition' => 'attachment; filename=' . $fileName,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,12 @@ class PublicGitRepository extends Component
|
|||||||
|
|
||||||
public bool $isStatic = false;
|
public bool $isStatic = false;
|
||||||
|
|
||||||
|
public bool $checkCoolifyConfig = true;
|
||||||
|
|
||||||
public ?string $publish_directory = null;
|
public ?string $publish_directory = null;
|
||||||
|
|
||||||
// In case of docker compose
|
// In case of docker compose
|
||||||
public ?string $base_directory = null;
|
public string $base_directory = '/';
|
||||||
|
|
||||||
public ?string $docker_compose_location = '/docker-compose.yaml';
|
public ?string $docker_compose_location = '/docker-compose.yaml';
|
||||||
// End of docker compose
|
// End of docker compose
|
||||||
@@ -97,6 +99,7 @@ class PublicGitRepository extends Component
|
|||||||
$this->base_directory = '/'.$this->base_directory;
|
$this->base_directory = '/'.$this->base_directory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updatedDockerComposeLocation()
|
public function updatedDockerComposeLocation()
|
||||||
@@ -275,6 +278,7 @@ class PublicGitRepository extends Component
|
|||||||
'destination_id' => $destination->id,
|
'destination_id' => $destination->id,
|
||||||
'destination_type' => $destination_class,
|
'destination_type' => $destination_class,
|
||||||
'build_pack' => $this->build_pack,
|
'build_pack' => $this->build_pack,
|
||||||
|
'base_directory' => $this->base_directory,
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
$application_init = [
|
$application_init = [
|
||||||
@@ -289,6 +293,7 @@ class PublicGitRepository extends Component
|
|||||||
'source_id' => $this->git_source->id,
|
'source_id' => $this->git_source->id,
|
||||||
'source_type' => $this->git_source->getMorphClass(),
|
'source_type' => $this->git_source->getMorphClass(),
|
||||||
'build_pack' => $this->build_pack,
|
'build_pack' => $this->build_pack,
|
||||||
|
'base_directory' => $this->base_directory,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,11 +308,15 @@ class PublicGitRepository extends Component
|
|||||||
|
|
||||||
$application->settings->is_static = $this->isStatic;
|
$application->settings->is_static = $this->isStatic;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
|
|
||||||
$fqdn = generateFqdn($destination->server, $application->uuid);
|
$fqdn = generateFqdn($destination->server, $application->uuid);
|
||||||
$application->fqdn = $fqdn;
|
$application->fqdn = $fqdn;
|
||||||
$application->save();
|
$application->save();
|
||||||
|
if ($this->checkCoolifyConfig) {
|
||||||
|
// $config = loadConfigFromGit($this->repository_url, $this->git_branch, $this->base_directory, $this->query['server_id'], auth()->user()->currentTeam()->id);
|
||||||
|
// if ($config) {
|
||||||
|
// $application->setConfig($config);
|
||||||
|
// }
|
||||||
|
}
|
||||||
return redirect()->route('project.application.configuration', [
|
return redirect()->route('project.application.configuration', [
|
||||||
'application_uuid' => $application->uuid,
|
'application_uuid' => $application->uuid,
|
||||||
'environment_name' => $environment->name,
|
'environment_name' => $environment->name,
|
||||||
|
|||||||
@@ -23,13 +23,17 @@ class EditDomain extends Component
|
|||||||
|
|
||||||
public function updatedApplicationFqdn()
|
public function updatedApplicationFqdn()
|
||||||
{
|
{
|
||||||
$this->application->fqdn = str($this->application->fqdn)->replaceEnd(',', '')->trim();
|
try {
|
||||||
$this->application->fqdn = str($this->application->fqdn)->replaceStart(',', '')->trim();
|
$this->application->fqdn = str($this->application->fqdn)->replaceEnd(',', '')->trim();
|
||||||
$this->application->fqdn = str($this->application->fqdn)->trim()->explode(',')->map(function ($domain) {
|
$this->application->fqdn = str($this->application->fqdn)->replaceStart(',', '')->trim();
|
||||||
return str($domain)->trim()->lower();
|
$this->application->fqdn = str($this->application->fqdn)->trim()->explode(',')->map(function ($domain) {
|
||||||
});
|
return str($domain)->trim()->lower();
|
||||||
$this->application->fqdn = $this->application->fqdn->unique()->implode(',');
|
});
|
||||||
$this->application->save();
|
$this->application->fqdn = $this->application->fqdn->unique()->implode(',');
|
||||||
|
$this->application->save();
|
||||||
|
} catch(\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function submit()
|
public function submit()
|
||||||
|
|||||||
@@ -48,14 +48,6 @@ class Add extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
$this->validate();
|
$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', [
|
$this->dispatch('saveKey', [
|
||||||
'key' => $this->key,
|
'key' => $this->key,
|
||||||
'value' => $this->value,
|
'value' => $this->value,
|
||||||
|
|||||||
@@ -53,30 +53,16 @@ class All extends Component
|
|||||||
|
|
||||||
public function sortEnvironmentVariables()
|
public function sortEnvironmentVariables()
|
||||||
{
|
{
|
||||||
if ($this->resource->type() === 'application') {
|
if (! data_get($this->resource, 'settings.is_env_sorting_enabled')) {
|
||||||
$this->resource->load(['environment_variables', 'environment_variables_preview']);
|
if ($this->resource->environment_variables) {
|
||||||
} else {
|
$this->resource->environment_variables = $this->resource->environment_variables->sortBy('order')->values();
|
||||||
$this->resource->load(['environment_variables']);
|
}
|
||||||
|
|
||||||
|
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();
|
$this->getDevView();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +107,8 @@ class All extends Component
|
|||||||
$this->sortEnvironmentVariables();
|
$this->sortEnvironmentVariables();
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
|
} finally {
|
||||||
|
$this->refreshEnvs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
41
app/Livewire/Project/Shared/UploadConfig.php
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Project\Shared;
|
||||||
|
|
||||||
|
use App\Models\Application;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class UploadConfig extends Component
|
||||||
|
{
|
||||||
|
public $config;
|
||||||
|
public $applicationId;
|
||||||
|
public function mount() {
|
||||||
|
if (isDev()) {
|
||||||
|
$this->config = '{
|
||||||
|
"build_pack": "nixpacks",
|
||||||
|
"base_directory": "/nodejs",
|
||||||
|
"publish_directory": "/",
|
||||||
|
"ports_exposes": "3000",
|
||||||
|
"settings": {
|
||||||
|
"is_static": false
|
||||||
|
}
|
||||||
|
}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function uploadConfig()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$application = Application::findOrFail($this->applicationId);
|
||||||
|
$application->setConfig($this->config);
|
||||||
|
$this->dispatch('success', 'Application settings updated');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->dispatch('error', $e->getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.project.shared.upload-config');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
use Illuminate\Process\InvokedProcess;
|
use Illuminate\Process\InvokedProcess;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Process;
|
use Illuminate\Support\Facades\Process;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
@@ -1427,4 +1428,67 @@ class Application extends BaseModel
|
|||||||
return $parsedCollection->toArray();
|
return $parsedCollection->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function generateConfig($is_json = false)
|
||||||
|
{
|
||||||
|
$config = collect([]);
|
||||||
|
if ($this->build_pack = 'nixpacks') {
|
||||||
|
$config = collect([
|
||||||
|
'build_pack' => 'nixpacks',
|
||||||
|
'docker_registry_image_name' => $this->docker_registry_image_name,
|
||||||
|
'docker_registry_image_tag' => $this->docker_registry_image_tag,
|
||||||
|
'install_command' => $this->install_command,
|
||||||
|
'build_command' => $this->build_command,
|
||||||
|
'start_command' => $this->start_command,
|
||||||
|
'base_directory' => $this->base_directory,
|
||||||
|
'publish_directory' => $this->publish_directory,
|
||||||
|
'custom_docker_run_options' => $this->custom_docker_run_options,
|
||||||
|
'ports_exposes' => $this->ports_exposes,
|
||||||
|
'ports_mappings' => $this->ports_mapping,
|
||||||
|
'settings' => collect([
|
||||||
|
'is_static' => $this->settings->is_static,
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$config = $config->filter(function ($value) {
|
||||||
|
return str($value)->isNotEmpty();
|
||||||
|
});
|
||||||
|
if ($is_json) {
|
||||||
|
return json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
public function setConfig($config) {
|
||||||
|
|
||||||
|
$config = $config;
|
||||||
|
$validator = Validator::make(['config' => $config], [
|
||||||
|
'config' => 'required|json',
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new \Exception('Invalid JSON format');
|
||||||
|
}
|
||||||
|
$config = json_decode($config, true);
|
||||||
|
|
||||||
|
$deepValidator = Validator::make(['config' => $config], [
|
||||||
|
'config.build_pack' => 'required|string',
|
||||||
|
'config.base_directory' => 'required|string',
|
||||||
|
'config.publish_directory' => 'required|string',
|
||||||
|
'config.ports_exposes' => 'required|string',
|
||||||
|
'config.settings.is_static' => 'required|boolean',
|
||||||
|
]);
|
||||||
|
if ($deepValidator->fails()) {
|
||||||
|
throw new \Exception('Invalid data');
|
||||||
|
}
|
||||||
|
$config = $deepValidator->validated()['config'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$settings = data_get($config, 'settings', []);
|
||||||
|
data_forget($config, 'settings');
|
||||||
|
$this->update($config);
|
||||||
|
$this->settings()->update($settings);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new \Exception('Failed to update application settings');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ class Project extends BaseModel
|
|||||||
{
|
{
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
|
protected $appends = ['default_environment'];
|
||||||
|
|
||||||
public static function ownedByCurrentTeam()
|
public static function ownedByCurrentTeam()
|
||||||
{
|
{
|
||||||
return Project::whereTeamId(currentTeam()->id)->orderBy('name');
|
return Project::whereTeamId(currentTeam()->id)->orderByRaw('LOWER(name)');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function booted()
|
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());
|
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();
|
$default = $this->environments()->where('name', 'production')->first();
|
||||||
if ($default) {
|
if ($default) {
|
||||||
|
|||||||
@@ -39,13 +39,19 @@ class ScheduledDatabaseBackup extends BaseModel
|
|||||||
public function server()
|
public function server()
|
||||||
{
|
{
|
||||||
if ($this->database) {
|
if ($this->database) {
|
||||||
if ($this->database->destination && $this->database->destination->server) {
|
if ($this->database instanceof ServiceDatabase) {
|
||||||
$server = $this->database->destination->server;
|
$destination = data_get($this->database->service, 'destination');
|
||||||
|
$server = data_get($destination, 'server');
|
||||||
|
} else {
|
||||||
|
$destination = data_get($this->database, 'destination');
|
||||||
|
$server = data_get($destination, 'server');
|
||||||
|
}
|
||||||
|
if ($server) {
|
||||||
return $server;
|
return $server;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -448,11 +448,19 @@ $schema://$host {
|
|||||||
// Should move everything except /caddy and /nginx to /traefik
|
// Should move everything except /caddy and /nginx to /traefik
|
||||||
// The code needs to be modified as well, so maybe it does not worth it
|
// The code needs to be modified as well, so maybe it does not worth it
|
||||||
if ($proxyType === ProxyTypes::TRAEFIK->value) {
|
if ($proxyType === ProxyTypes::TRAEFIK->value) {
|
||||||
$proxy_path = $proxy_path;
|
// Do nothing
|
||||||
} elseif ($proxyType === ProxyTypes::CADDY->value) {
|
} 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) {
|
} 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;
|
return $proxy_path;
|
||||||
|
|||||||
@@ -283,9 +283,147 @@ class Service extends BaseModel
|
|||||||
$fields = collect([]);
|
$fields = collect([]);
|
||||||
$applications = $this->applications()->get();
|
$applications = $this->applications()->get();
|
||||||
foreach ($applications as $application) {
|
foreach ($applications as $application) {
|
||||||
$image = str($application->image)->before(':')->value();
|
$image = str($application->image)->before(':');
|
||||||
|
if ($image->isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
switch ($image) {
|
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' => data_get($email, 'key'),
|
||||||
|
'value' => data_get($email, 'value'),
|
||||||
|
'rules' => 'required|email',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_INVOICENINJAUSER')->first();
|
||||||
|
$data = $data->merge([
|
||||||
|
'Password' => [
|
||||||
|
'key' => data_get($password, 'key'),
|
||||||
|
'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([]);
|
$data = collect([]);
|
||||||
$host_port = $this->environment_variables()->where('key', 'PORT')->first();
|
$host_port = $this->environment_variables()->where('key', 'PORT')->first();
|
||||||
$username = $this->environment_variables()->where('key', 'SERVICE_USER_RABBITMQ')->first();
|
$username = $this->environment_variables()->where('key', 'SERVICE_USER_RABBITMQ')->first();
|
||||||
@@ -320,7 +458,7 @@ class Service extends BaseModel
|
|||||||
}
|
}
|
||||||
$fields->put('RabbitMQ', $data->toArray());
|
$fields->put('RabbitMQ', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)?->contains('tolgee'):
|
case $image->contains('tolgee'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_TOLGEE')->first();
|
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_TOLGEE')->first();
|
||||||
$data = $data->merge([
|
$data = $data->merge([
|
||||||
@@ -343,7 +481,7 @@ class Service extends BaseModel
|
|||||||
}
|
}
|
||||||
$fields->put('Tolgee', $data->toArray());
|
$fields->put('Tolgee', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)?->contains('logto'):
|
case $image->contains('logto'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$logto_endpoint = $this->environment_variables()->where('key', 'LOGTO_ENDPOINT')->first();
|
$logto_endpoint = $this->environment_variables()->where('key', 'LOGTO_ENDPOINT')->first();
|
||||||
$logto_admin_endpoint = $this->environment_variables()->where('key', 'LOGTO_ADMIN_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());
|
$fields->put('Logto', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)?->contains('unleash-server'):
|
case $image->contains('unleash-server'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_UNLEASH')->first();
|
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_UNLEASH')->first();
|
||||||
$data = $data->merge([
|
$data = $data->merge([
|
||||||
@@ -390,7 +528,7 @@ class Service extends BaseModel
|
|||||||
}
|
}
|
||||||
$fields->put('Unleash', $data->toArray());
|
$fields->put('Unleash', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)?->contains('grafana'):
|
case $image->contains('grafana'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_GRAFANA')->first();
|
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_GRAFANA')->first();
|
||||||
$data = $data->merge([
|
$data = $data->merge([
|
||||||
@@ -413,7 +551,7 @@ class Service extends BaseModel
|
|||||||
}
|
}
|
||||||
$fields->put('Grafana', $data->toArray());
|
$fields->put('Grafana', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)?->contains('directus'):
|
case $image->contains('directus'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$admin_email = $this->environment_variables()->where('key', 'ADMIN_EMAIL')->first();
|
$admin_email = $this->environment_variables()->where('key', 'ADMIN_EMAIL')->first();
|
||||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_ADMIN')->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());
|
$fields->put('Directus', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)?->contains('kong'):
|
case $image->contains('kong'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$dashboard_user = $this->environment_variables()->where('key', 'SERVICE_USER_ADMIN')->first();
|
$dashboard_user = $this->environment_variables()->where('key', 'SERVICE_USER_ADMIN')->first();
|
||||||
$dashboard_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_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());
|
$fields->put('Supabase', $data->toArray());
|
||||||
case str($image)?->contains('minio'):
|
case $image->contains('minio'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$console_url = $this->environment_variables()->where('key', 'MINIO_BROWSER_REDIRECT_URL')->first();
|
$console_url = $this->environment_variables()->where('key', 'MINIO_BROWSER_REDIRECT_URL')->first();
|
||||||
$s3_api_url = $this->environment_variables()->where('key', 'MINIO_SERVER_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());
|
$fields->put('MinIO', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)?->contains('weblate'):
|
case $image->contains('weblate'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$admin_email = $this->environment_variables()->where('key', 'WEBLATE_ADMIN_EMAIL')->first();
|
$admin_email = $this->environment_variables()->where('key', 'WEBLATE_ADMIN_EMAIL')->first();
|
||||||
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_WEBLATE')->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());
|
$fields->put('Weblate', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)?->contains('meilisearch'):
|
case $image->contains('meilisearch'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$SERVICE_PASSWORD_MEILISEARCH = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_MEILISEARCH')->first();
|
$SERVICE_PASSWORD_MEILISEARCH = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_MEILISEARCH')->first();
|
||||||
if ($SERVICE_PASSWORD_MEILISEARCH) {
|
if ($SERVICE_PASSWORD_MEILISEARCH) {
|
||||||
@@ -556,7 +694,7 @@ class Service extends BaseModel
|
|||||||
}
|
}
|
||||||
$fields->put('Meilisearch', $data->toArray());
|
$fields->put('Meilisearch', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)?->contains('ghost'):
|
case $image->contains('ghost'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$MAIL_OPTIONS_AUTH_PASS = $this->environment_variables()->where('key', 'MAIL_OPTIONS_AUTH_PASS')->first();
|
$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();
|
$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());
|
$fields->put('Ghost', $data->toArray());
|
||||||
break;
|
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();
|
case $image->contains('vaultwarden'):
|
||||||
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'):
|
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
|
|
||||||
$DATABASE_URL = $this->environment_variables()->where('key', 'DATABASE_URL')->first();
|
$DATABASE_URL = $this->environment_variables()->where('key', 'DATABASE_URL')->first();
|
||||||
@@ -720,7 +821,7 @@ class Service extends BaseModel
|
|||||||
|
|
||||||
$fields->put('Vaultwarden', $data);
|
$fields->put('Vaultwarden', $data);
|
||||||
break;
|
break;
|
||||||
case str($image)->contains('gitlab/gitlab'):
|
case $image->contains('gitlab/gitlab'):
|
||||||
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_GITLAB')->first();
|
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_GITLAB')->first();
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
if ($password) {
|
if ($password) {
|
||||||
@@ -744,7 +845,7 @@ class Service extends BaseModel
|
|||||||
|
|
||||||
$fields->put('GitLab', $data->toArray());
|
$fields->put('GitLab', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)->contains('code-server'):
|
case $image->contains('code-server'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_64_PASSWORDCODESERVER')->first();
|
$password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_64_PASSWORDCODESERVER')->first();
|
||||||
if ($password) {
|
if ($password) {
|
||||||
@@ -770,7 +871,7 @@ class Service extends BaseModel
|
|||||||
}
|
}
|
||||||
$fields->put('Code Server', $data->toArray());
|
$fields->put('Code Server', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)->contains('elestio/strapi'):
|
case $image->contains('elestio/strapi'):
|
||||||
$data = collect([]);
|
$data = collect([]);
|
||||||
$license = $this->environment_variables()->where('key', 'STRAPI_LICENSE')->first();
|
$license = $this->environment_variables()->where('key', 'STRAPI_LICENSE')->first();
|
||||||
if ($license) {
|
if ($license) {
|
||||||
@@ -793,15 +894,55 @@ class Service extends BaseModel
|
|||||||
|
|
||||||
$fields->put('Strapi', $data->toArray());
|
$fields->put('Strapi', $data->toArray());
|
||||||
break;
|
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();
|
$databases = $this->databases()->get();
|
||||||
|
|
||||||
foreach ($databases as $database) {
|
foreach ($databases as $database) {
|
||||||
$image = str($database->image)->before(':')->value();
|
$image = str($database->image)->before(':');
|
||||||
|
if ($image->isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
switch ($image) {
|
switch ($image) {
|
||||||
case str($image)->contains('postgres'):
|
case $image->contains('postgres'):
|
||||||
$userVariables = ['SERVICE_USER_POSTGRES', 'SERVICE_USER_POSTGRESQL'];
|
$userVariables = ['SERVICE_USER_POSTGRES', 'SERVICE_USER_POSTGRESQL'];
|
||||||
$passwordVariables = ['SERVICE_PASSWORD_POSTGRES', 'SERVICE_PASSWORD_POSTGRESQL'];
|
$passwordVariables = ['SERVICE_PASSWORD_POSTGRES', 'SERVICE_PASSWORD_POSTGRESQL'];
|
||||||
$dbNameVariables = ['POSTGRESQL_DATABASE', 'POSTGRES_DB'];
|
$dbNameVariables = ['POSTGRESQL_DATABASE', 'POSTGRES_DB'];
|
||||||
@@ -839,10 +980,10 @@ class Service extends BaseModel
|
|||||||
}
|
}
|
||||||
$fields->put('PostgreSQL', $data->toArray());
|
$fields->put('PostgreSQL', $data->toArray());
|
||||||
break;
|
break;
|
||||||
case str($image)->contains('mysql'):
|
case $image->contains('mysql'):
|
||||||
$userVariables = ['SERVICE_USER_MYSQL', 'SERVICE_USER_WORDPRESS', 'MYSQL_USER'];
|
$userVariables = ['SERVICE_USER_MYSQL', 'SERVICE_USER_WORDPRESS', 'MYSQL_USER'];
|
||||||
$passwordVariables = ['SERVICE_PASSWORD_MYSQL', 'SERVICE_PASSWORD_WORDPRESS', 'MYSQL_PASSWORD'];
|
$passwordVariables = ['SERVICE_PASSWORD_MYSQL', 'SERVICE_PASSWORD_WORDPRESS', 'MYSQL_PASSWORD','SERVICE_PASSWORD_64_MYSQL'];
|
||||||
$rootPasswordVariables = ['SERVICE_PASSWORD_MYSQLROOT', 'SERVICE_PASSWORD_ROOT'];
|
$rootPasswordVariables = ['SERVICE_PASSWORD_MYSQLROOT', 'SERVICE_PASSWORD_ROOT','SERVICE_PASSWORD_64_MYSQLROOT'];
|
||||||
$dbNameVariables = ['MYSQL_DATABASE'];
|
$dbNameVariables = ['MYSQL_DATABASE'];
|
||||||
$mysql_user = $this->environment_variables()->whereIn('key', $userVariables)->first();
|
$mysql_user = $this->environment_variables()->whereIn('key', $userVariables)->first();
|
||||||
$mysql_password = $this->environment_variables()->whereIn('key', $passwordVariables)->first();
|
$mysql_password = $this->environment_variables()->whereIn('key', $passwordVariables)->first();
|
||||||
@@ -889,7 +1030,7 @@ class Service extends BaseModel
|
|||||||
}
|
}
|
||||||
$fields->put('MySQL', $data->toArray());
|
$fields->put('MySQL', $data->toArray());
|
||||||
break;
|
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'];
|
$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'];
|
$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'];
|
$rootPasswordVariables = ['SERVICE_PASSWORD_MARIADBROOT', 'SERVICE_PASSWORD_ROOT', '_APP_DB_ROOT_PASS', 'MYSQL_ROOT_PASSWORD'];
|
||||||
@@ -1076,12 +1217,12 @@ class Service extends BaseModel
|
|||||||
public function environment_variables(): HasMany
|
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
|
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()
|
public function workdir()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use App\Enums\BuildPackTypes;
|
use App\Enums\BuildPackTypes;
|
||||||
use App\Enums\RedirectTypes;
|
use App\Enums\RedirectTypes;
|
||||||
|
use App\Enums\StaticImageTypes;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@@ -89,6 +90,7 @@ function sharedDataApplications()
|
|||||||
'git_branch' => 'string',
|
'git_branch' => 'string',
|
||||||
'build_pack' => Rule::enum(BuildPackTypes::class),
|
'build_pack' => Rule::enum(BuildPackTypes::class),
|
||||||
'is_static' => 'boolean',
|
'is_static' => 'boolean',
|
||||||
|
'static_image' => Rule::enum(StaticImageTypes::class),
|
||||||
'domains' => 'string',
|
'domains' => 'string',
|
||||||
'redirect' => Rule::enum(RedirectTypes::class),
|
'redirect' => Rule::enum(RedirectTypes::class),
|
||||||
'git_commit_sha' => 'string',
|
'git_commit_sha' => 'string',
|
||||||
@@ -176,4 +178,5 @@ function removeUnnecessaryFieldsFromRequest(Request $request)
|
|||||||
$request->offsetUnset('github_app_uuid');
|
$request->offsetUnset('github_app_uuid');
|
||||||
$request->offsetUnset('private_key_uuid');
|
$request->offsetUnset('private_key_uuid');
|
||||||
$request->offsetUnset('use_build_server');
|
$request->offsetUnset('use_build_server');
|
||||||
|
$request->offsetUnset('is_static');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ const DATABASE_DOCKER_IMAGES = [
|
|||||||
];
|
];
|
||||||
const SPECIFIC_SERVICES = [
|
const SPECIFIC_SERVICES = [
|
||||||
'quay.io/minio/minio',
|
'quay.io/minio/minio',
|
||||||
|
'minio/minio',
|
||||||
'svhd/logto',
|
'svhd/logto',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -332,8 +332,12 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
|||||||
if (preg_match('/traefik\.http\.middlewares\.(.*?)(\.|$)/', $item, $matches)) {
|
if (preg_match('/traefik\.http\.middlewares\.(.*?)(\.|$)/', $item, $matches)) {
|
||||||
return $matches[1];
|
return $matches[1];
|
||||||
}
|
}
|
||||||
|
if (preg_match('/coolify\.traefik\.middlewares=(.*)/', $item, $matches)) {
|
||||||
|
return explode(',', $matches[1]);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
})->filter()
|
})->flatten()
|
||||||
|
->filter()
|
||||||
->unique();
|
->unique();
|
||||||
}
|
}
|
||||||
foreach ($domains as $loop => $domain) {
|
foreach ($domains as $loop => $domain) {
|
||||||
|
|||||||
@@ -522,6 +522,11 @@ function sslip(Server $server)
|
|||||||
|
|
||||||
function get_service_templates(bool $force = false): Collection
|
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) {
|
if ($force) {
|
||||||
try {
|
try {
|
||||||
$response = Http::retry(3, 1000)->get(config('constants.services.official'));
|
$response = Http::retry(3, 1000)->get(config('constants.services.official'));
|
||||||
@@ -1169,10 +1174,10 @@ function check_domain_usage(ServiceApplication|Application|null $resource = null
|
|||||||
if ($domains->contains($naked_domain)) {
|
if ($domains->contains($naked_domain)) {
|
||||||
if (data_get($resource, 'uuid')) {
|
if (data_get($resource, 'uuid')) {
|
||||||
if ($resource->uuid !== $app->uuid) {
|
if ($resource->uuid !== $app->uuid) {
|
||||||
throw new \RuntimeException("Domain $naked_domain is already in use by another resource called: <br><br>{$app->name}.");
|
throw new \RuntimeException("Domain $naked_domain is already in use by another resource: <br><br>Link: <a class='underline' target='_blank' href='{$app->link()}'>{$app->name}</a>");
|
||||||
}
|
}
|
||||||
} elseif ($domain) {
|
} elseif ($domain) {
|
||||||
throw new \RuntimeException("Domain $naked_domain is already in use by another resource called: <br><br>{$app->name}.");
|
throw new \RuntimeException("Domain $naked_domain is already in use by another resource: <br><br>Link: <a class='underline' target='_blank' href='{$app->link()}'>{$app->name}</a>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1188,10 +1193,10 @@ function check_domain_usage(ServiceApplication|Application|null $resource = null
|
|||||||
if ($domains->contains($naked_domain)) {
|
if ($domains->contains($naked_domain)) {
|
||||||
if (data_get($resource, 'uuid')) {
|
if (data_get($resource, 'uuid')) {
|
||||||
if ($resource->uuid !== $app->uuid) {
|
if ($resource->uuid !== $app->uuid) {
|
||||||
throw new \RuntimeException("Domain $naked_domain is already in use by another resource called: <br><br>{$app->name}.");
|
throw new \RuntimeException("Domain $naked_domain is already in use by another resource: <br><br>Link: <a class='underline' target='_blank' href='{$app->service->link()}'>{$app->service->name}</a>");
|
||||||
}
|
}
|
||||||
} elseif ($domain) {
|
} elseif ($domain) {
|
||||||
throw new \RuntimeException("Domain $naked_domain is already in use by another resource called: <br><br>{$app->name}.");
|
throw new \RuntimeException("Domain $naked_domain is already in use by another resource: <br><br>Link: <a class='underline' target='_blank' href='{$app->service->link()}'>{$app->service->name}</a>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3176,6 +3181,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
|||||||
} elseif ($isService) {
|
} elseif ($isService) {
|
||||||
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
|
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
|
||||||
}
|
}
|
||||||
|
$fqdn = str($fqdn)->replace('http://', '')->replace('https://', '');
|
||||||
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
|
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
|
||||||
'key' => $key->value(),
|
'key' => $key->value(),
|
||||||
$nameOfId => $resource->id,
|
$nameOfId => $resource->id,
|
||||||
@@ -3976,3 +3982,31 @@ function instanceSettings()
|
|||||||
{
|
{
|
||||||
return InstanceSettings::get();
|
return InstanceSettings::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadConfigFromGit(string $repository, string $branch, string $base_directory, int $server_id, int $team_id) {
|
||||||
|
|
||||||
|
$server = Server::find($server_id)->where('team_id', $team_id)->first();
|
||||||
|
if (!$server) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$uuid = new Cuid2();
|
||||||
|
$cloneCommand = "git clone --no-checkout -b $branch $repository .";
|
||||||
|
$workdir = rtrim($base_directory, '/');
|
||||||
|
$fileList = collect([".$workdir/coolify.json"]);
|
||||||
|
$commands = collect([
|
||||||
|
"rm -rf /tmp/{$uuid}",
|
||||||
|
"mkdir -p /tmp/{$uuid}",
|
||||||
|
"cd /tmp/{$uuid}",
|
||||||
|
$cloneCommand,
|
||||||
|
'git sparse-checkout init --cone',
|
||||||
|
"git sparse-checkout set {$fileList->implode(' ')}",
|
||||||
|
'git read-tree -mu HEAD',
|
||||||
|
"cat .$workdir/coolify.json",
|
||||||
|
'rm -rf /tmp/{$uuid}',
|
||||||
|
]);
|
||||||
|
try {
|
||||||
|
return instant_remote_process($commands, $server);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ return [
|
|||||||
|
|
||||||
// The release version of your application
|
// The release version of your application
|
||||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||||
'release' => '4.0.0-beta.355',
|
'release' => '4.0.0-beta.358',
|
||||||
|
|
||||||
// When left empty or `null` the Laravel environment will be used
|
// When left empty or `null` the Laravel environment will be used
|
||||||
'environment' => config('app.env'),
|
'environment' => config('app.env'),
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return '4.0.0-beta.355';
|
return '4.0.0-beta.358';
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('service_applications', function (Blueprint $table) {
|
||||||
|
$table->dropUnique(['fqdn']);
|
||||||
|
});
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->dropUnique(['fqdn']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('service_applications', function (Blueprint $table) {
|
||||||
|
$table->unique('fqdn');
|
||||||
|
});
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->unique('fqdn');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"auth.register": "S'enregistrer",
|
"auth.register": "S'enregistrer",
|
||||||
"auth.registration_disabled": "L'enregistrement est désactivé. Merci de contacter l'administateur.",
|
"auth.registration_disabled": "L'enregistrement est désactivé. Merci de contacter l'administateur.",
|
||||||
"auth.reset_password": "Réinitialiser le mot de passe",
|
"auth.reset_password": "Réinitialiser le mot de passe",
|
||||||
"auth.failed": "Aucune correspondance n'a été trouvé pour les informations d'identification renseignées.",
|
"auth.failed": "Aucune correspondance n'a été trouvée pour les informations d'identification renseignées.",
|
||||||
"auth.failed.callback": "Erreur lors du processus de retour de la plateforme de connexion.",
|
"auth.failed.callback": "Erreur lors du processus de retour de la plateforme de connexion.",
|
||||||
"auth.failed.password": "Le mot de passe renseigné est incorrect.",
|
"auth.failed.password": "Le mot de passe renseigné est incorrect.",
|
||||||
"auth.failed.email": "Aucun utilisateur avec cette adresse email n'a été trouvé.",
|
"auth.failed.email": "Aucun utilisateur avec cette adresse email n'a été trouvé.",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"version": "4.0.0-beta.355"
|
"version": "4.0.0-beta.355"
|
||||||
},
|
},
|
||||||
"helper": {
|
"helper": {
|
||||||
"version": "1.0.1"
|
"version": "1.0.2"
|
||||||
},
|
},
|
||||||
"realtime": {
|
"realtime": {
|
||||||
"version": "1.0.3"
|
"version": "1.0.3"
|
||||||
|
|||||||
9
package-lock.json
generated
@@ -10,7 +10,7 @@
|
|||||||
"@xterm/addon-fit": "^0.10.0",
|
"@xterm/addon-fit": "^0.10.0",
|
||||||
"@xterm/xterm": "^5.5.0",
|
"@xterm/xterm": "^5.5.0",
|
||||||
"alpinejs": "3.14.0",
|
"alpinejs": "3.14.0",
|
||||||
"cookie": "^0.6.0",
|
"cookie": "^0.7.0",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"ioredis": "5.4.1",
|
"ioredis": "5.4.1",
|
||||||
"node-pty": "^1.0.0",
|
"node-pty": "^1.0.0",
|
||||||
@@ -960,10 +960,9 @@
|
|||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||||
},
|
},
|
||||||
"node_modules/cookie": {
|
"node_modules/cookie": {
|
||||||
"version": "0.6.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.0.tgz",
|
||||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
"integrity": "sha512-qCf+V4dtlNhSRXGAZatc1TasyFO6GjohcOul807YOb5ik3+kQSnb4d7iajeCL8QHaJ4uZEjCgiCJerKXwdRVlQ==",
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"@xterm/addon-fit": "^0.10.0",
|
"@xterm/addon-fit": "^0.10.0",
|
||||||
"@xterm/xterm": "^5.5.0",
|
"@xterm/xterm": "^5.5.0",
|
||||||
"alpinejs": "3.14.0",
|
"alpinejs": "3.14.0",
|
||||||
"cookie": "^0.6.0",
|
"cookie": "^0.7.0",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"ioredis": "5.4.1",
|
"ioredis": "5.4.1",
|
||||||
"node-pty": "^1.0.0",
|
"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 |
25
public/svgs/audiobookshelf.svg
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<svg version="1.1" id="prefix__Layer_1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 1235.7 1235.4"
|
||||||
|
xml:space="preserve">
|
||||||
|
<style>
|
||||||
|
.prefix__st0 {
|
||||||
|
fill: #fff
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g id="prefix__Layer_2_1_">
|
||||||
|
<g id="prefix__Layer_2-2">
|
||||||
|
<g id="prefix__Layer_4">
|
||||||
|
<circle class="prefix__st0" cx="618.6" cy="618.6" r="618.6" id="prefix__Layer_5" />
|
||||||
|
<linearGradient id="prefix__SVGID_1_" gradientUnits="userSpaceOnUse" x1="617.37" y1="1257.3" x2="617.37"
|
||||||
|
y2="61.44" gradientTransform="matrix(1 0 0 -1 0 1278)">
|
||||||
|
<stop offset=".32" stop-color="#cd9d49" />
|
||||||
|
<stop offset=".99" stop-color="#875d27" />
|
||||||
|
</linearGradient>
|
||||||
|
<circle cx="617.4" cy="618.6" r="597.9" fill="url(#prefix__SVGID_1_)" />
|
||||||
|
</g>
|
||||||
|
<path class="prefix__st0"
|
||||||
|
d="M1005.6 574.1c-4.8-4-12.4-10-22.6-17v-79.2c0-201.9-163.7-365.6-365.6-365.6-201.9 0-365.6 163.7-365.6 365.6v79.2c-10.2 7-17.7 13-22.6 17-4.1 3.4-6.5 8.5-6.5 13.9v94.9c0 5.4 2.4 10.5 6.5 14 11.3 9.4 37.2 29.1 77.5 49.3v9.2c0 24.9 16 45 35.8 45 19.8 0 35.8-20.2 35.8-45V527.8c0-24.9-16-45-35.8-45-19 0-34.5 18.5-35.8 41.9h-.1v-46.9c0-171.6 139.1-310.7 310.7-310.7C789 167.2 928 306.3 928 477.9v46.9c-1.3-23.4-16.8-41.9-35.8-41.9-19.8 0-35.8 20.2-35.8 45v227.6c0 24.9 16 45 35.8 45 19.8 0 35.8-20.2 35.8-45v-9.2c40.3-20.2 66.2-39.9 77.5-49.3 4.2-3.5 6.5-8.6 6.5-14v-95c.1-5.4-2.3-10.5-6.4-13.9z" />
|
||||||
|
<path class="prefix__st0"
|
||||||
|
d="M489.9 969.7c23.9 0 43.3-19.4 43.3-43.3V441.6c0-23.9-19.4-43.3-43.3-43.3h-44.7c-23.9 0-43.3 19.4-43.3 43.3v484.8c0 23.9 19.4 43.3 43.3 43.3h44.7zm-71.7-455.1h98.7v10.3h-98.7v-10.3zM639.7 969.7c23.9 0 43.3-19.4 43.3-43.3V441.6c0-23.9-19.4-43.3-43.3-43.3H595c-23.9 0-43.3 19.4-43.3 43.3v484.8c0 23.9 19.4 43.3 43.3 43.3h44.7zM568 514.6h98.7v10.3H568v-10.3zM789.6 969.7c23.9 0 43.3-19.4 43.3-43.3V441.6c0-23.9-19.4-43.3-43.3-43.3h-44.7c-23.9 0-43.3 19.4-43.3 43.3v484.8c0 23.9 19.4 43.3 43.3 43.3h44.7zm-71.7-455.1h98.7v10.3h-98.7v-10.3zM327.1 984.7h580.5c18 0 32.6 14.6 32.6 32.6s-14.6 32.6-32.6 32.6H327.1c-18 0-32.6-14.6-32.6-32.6s14.6-32.6 32.6-32.6z" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
BIN
public/svgs/azimutt.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/svgs/bookstack.png
Normal file
|
After Width: | Height: | Size: 5.6 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 |
10
public/svgs/dozzle.svg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?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="256px" height="256px" 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:1" fill="#222222" d="M -0.5,-0.5 C 84.8333,-0.5 170.167,-0.5 255.5,-0.5C 255.5,84.8333 255.5,170.167 255.5,255.5C 170.167,255.5 84.8333,255.5 -0.5,255.5C -0.5,170.167 -0.5,84.8333 -0.5,-0.5 Z"/></g>
|
||||||
|
<g><path style="opacity:1" fill="#fbda56" d="M 161.5,179.5 C 160.957,179.56 160.624,179.893 160.5,180.5C 184.157,181.5 207.824,181.833 231.5,181.5C 231.5,186.833 231.5,192.167 231.5,197.5C 199.167,197.5 166.833,197.5 134.5,197.5C 134.813,194.753 134.48,192.086 133.5,189.5C 132.893,189.624 132.56,189.957 132.5,190.5C 115.506,204.774 95.8393,210.94 73.5,209C 58.1984,207.118 42.8651,205.618 27.5,204.5C 32.8364,149.128 38.5031,93.795 44.5,38.5C 59.7916,40.3257 75.1249,41.8257 90.5,43C 113.794,44.8067 132.127,55.14 145.5,74C 173.165,74.5 200.831,74.6666 228.5,74.5C 228.91,80.6208 228.41,86.6208 227,92.5C 205.158,121.53 183.324,150.53 161.5,179.5 Z"/></g>
|
||||||
|
<g><path style="opacity:1" fill="#222222" d="M 64.5,58.5 C 74.4468,59.9949 84.4468,61.1616 94.5,62C 117.983,67.1515 131.483,81.6515 135,105.5C 135.624,124.968 132.958,143.968 127,162.5C 119.558,178.614 107.058,187.781 89.5,190C 76.8083,190.293 64.1416,189.793 51.5,188.5C 56.0225,145.186 60.3558,101.852 64.5,58.5 Z"/></g>
|
||||||
|
<g><path style="opacity:1" fill="#252422" d="M 153.5,93.5 C 169.328,92.3386 185.328,92.1719 201.5,93C 185,114.833 168.5,136.667 152,158.5C 155.973,140.11 157.307,121.443 156,102.5C 155.34,99.322 154.507,96.322 153.5,93.5 Z"/></g>
|
||||||
|
<g><path style="opacity:1" fill="#6d6133" d="M 161.5,179.5 C 185.167,180.167 208.833,180.833 232.5,181.5C 232.167,181.5 231.833,181.5 231.5,181.5C 207.824,181.833 184.157,181.5 160.5,180.5C 160.624,179.893 160.957,179.56 161.5,179.5 Z"/></g>
|
||||||
|
<g><path style="opacity:1" fill="#d6ba4d" d="M 231.5,181.5 C 231.833,181.5 232.167,181.5 232.5,181.5C 232.5,187.167 232.5,192.833 232.5,198.5C 199.5,198.5 166.5,198.5 133.5,198.5C 133.806,195.615 133.473,192.948 132.5,190.5C 132.56,189.957 132.893,189.624 133.5,189.5C 134.48,192.086 134.813,194.753 134.5,197.5C 166.833,197.5 199.167,197.5 231.5,197.5C 231.5,192.167 231.5,186.833 231.5,181.5 Z"/></g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
BIN
public/svgs/easyappointments.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
1
public/svgs/forgejo.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" width="32" height="32"><style>circle,path{fill:none;stroke:#000;stroke-width:15}path{stroke-width:25}.orange{stroke:#f60}.red{stroke:#d40000}</style><g transform="translate(6 6)"><path d="M58 168V70a50 50 0 0 1 50-50h20" class="orange"/><path d="M58 168v-30a50 50 0 0 1 50-50h20" class="red"/><circle cx="142" cy="20" r="18" class="orange"/><circle cx="142" cy="88" r="18" class="red"/><circle cx="58" cy="180" r="18" class="red"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 503 B |
BIN
public/svgs/getoutline.jpeg
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
public/svgs/infisical.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
public/svgs/joplin.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
55
public/svgs/keycloak.svg
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<svg viewBox="0 0 128 128" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip-path">
|
||||||
|
<path class="cls-1" d="M.02-.02H128v127.98H.02z" />
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-path-3">
|
||||||
|
<path class="cls-1" d="M428 245.69h-9.77a.42.42 0 0 1-.33-.17l-.76-1-2.14-2.82-5.68-7.7-3.18-4.28a.41.41 0 0 0-.63 0l-3.33 3.71-.38.43a.4.4 0 0 0-.1.27v11.16a.41.41 0 0 1-.41.41h-8.42a.41.41 0 0 1-.41-.41v-40.55a.4.4 0 0 1 .41-.41h8.42a.41.41 0 0 1 .41.41v15.53a.4.4 0 0 0 .7.28l4.65-5L414 208l3.24-3.52a.41.41 0 0 1 .3-.13h10.34a.4.4 0 0 1 .41.42.46.46 0 0 1-.1.25l-4.66 5.17-7.74 8.61-3.23 3.58a.4.4 0 0 0 0 .5l4 5.63 3.66 5.16.45.63 2.77 3.88 2.89 4.06 2 2.82a.41.41 0 0 1-.33.63zm-38.72-.57a.41.41 0 0 1-.37.57h-8.94a.4.4 0 0 1-.37-.25l-.18-.4-3.46-8a.4.4 0 0 0-.37-.25h-16.8a.41.41 0 0 0-.38.25l-.52 1.2-3.12 7.25a.41.41 0 0 1-.36.23h-8.94a.41.41 0 0 1-.37-.57l.62-1.44 4.22-9.76.15-.34.18-.41.08-.2 1.4-3.25 10.84-25.09a.41.41 0 0 1 .37-.25h8.4a.4.4 0 0 1 .37.25l5.64 13 2.79 6.44 3.12 7.21 5.9 13.66zm-17.16-17-.59-1.38-2-4.63-2-4.57a.41.41 0 0 0-.75 0l-3.51 8.11-1.07 2.48a.4.4 0 0 0 .37.56h9.13a.4.4 0 0 0 .37-.61zm-26.51 4.66a17.7 17.7 0 0 1-.83 1.84 20.76 20.76 0 0 1-4 5.37 22.08 22.08 0 0 1-2.26 1.94 21 21 0 0 1-11.68 4.14h-1.51a21.6 21.6 0 0 1-12.1-3.42 22 22 0 0 1-3.34-2.7c-.41-.41-.81-.82-1.18-1.24a20.43 20.43 0 0 1-5.1-14 23.47 23.47 0 0 1 .27-3.6l-.19-.28.3-.45a20.05 20.05 0 0 1 5.89-10.91A22 22 0 0 1 313 207a20.33 20.33 0 0 1 7.39-3.09 23.77 23.77 0 0 1 4.92-.49 21.25 21.25 0 0 1 15.45 6.13 20.25 20.25 0 0 1 6.17 12.94c.07.74.1 1.51.1 2.28a21.76 21.76 0 0 1-1.47 7.97zm-8-8a13.54 13.54 0 0 0-3.18-9 5.22 5.22 0 0 0-.36-.43 11.34 11.34 0 0 0-8.73-3.9 12.49 12.49 0 0 0-2.67.28 11.4 11.4 0 0 0-6.06 3.62 13.44 13.44 0 0 0-3.55 9.12v.32a13.41 13.41 0 0 0 3.56 9.41 11.78 11.78 0 0 0 1.07 1 11.35 11.35 0 0 0 2.33 1.6 12.09 12.09 0 0 0 10.81-.09 11.76 11.76 0 0 0 2.87-2.18l.36-.38a13.42 13.42 0 0 0 2-2.83 13.84 13.84 0 0 0 1.53-6.55zm-34.51 12.69h-16.85a.4.4 0 0 1-.41-.4v-32.33a.4.4 0 0 0-.23-.36.35.35 0 0 0-.17 0H277a.4.4 0 0 0-.41.41v40.55a.41.41 0 0 0 .41.41h26a.41.41 0 0 0 .41-.41v-7.42a.41.41 0 0 0-.34-.46zm-45.76-34c-.67-.05-1.34-.08-2-.08a21.24 21.24 0 0 0-15.42 6.15 22.18 22.18 0 0 0-2.08 2.35 20.67 20.67 0 0 0-4.22 13 22.27 22.27 0 0 0 1.35 7.89 19.26 19.26 0 0 0 2.08 4.05 20.42 20.42 0 0 0 2.74 3.28 20.93 20.93 0 0 0 4.13 3.14c.37.21.75.42 1.13.61.38.19.56.27.85.39a23.61 23.61 0 0 0 9.6 1.88 21.39 21.39 0 0 0 3.07-.22c.64-.09 1.27-.21 1.9-.36a21.44 21.44 0 0 0 9.63-5.32c.58-.54 1.16-1.12 1.73-1.74a.41.41 0 0 0 0-.56l-5.34-5.49a.39.39 0 0 0-.36-.12.44.44 0 0 0-.24.14 13.55 13.55 0 0 1-10.84 5 12.05 12.05 0 0 1-4.18-.71 11.73 11.73 0 0 1-4.28-2.79 11.29 11.29 0 0 1-2.7-4.3 14.68 14.68 0 0 1-.79-5 12 12 0 0 1 3.21-8.7l.49-.47a12.68 12.68 0 0 1 8.91-3.4 13.35 13.35 0 0 1 10.59 5.08.4.4 0 0 0 .61 0l5.19-5.89a.42.42 0 0 0 0-.55 21.73 21.73 0 0 0-14.78-7.27zm-23.34 4.2 1.57-2.74a.4.4 0 0 0-.35-.61h-9.07a.41.41 0 0 0-.35.2l-8.22 14.15-.44.32-.33.25a.42.42 0 0 1-.17-.16l-.14-.23-.21-.35-8.12-14a.41.41 0 0 0-.35-.2h-9.07a.41.41 0 0 0-.35.61l3.93 6.88 7.12 12.44 2.87 5a.41.41 0 0 1 .06.2v15.82a.41.41 0 0 0 .41.41h8.42a.41.41 0 0 0 .41-.41v-15.79a.41.41 0 0 1 .06-.2l2-3.55 7.7-13.46 1.57-2.74 1-1.83zm-38.85 29.85H174.7a.41.41 0 0 1-.41-.41v-7.77a.41.41 0 0 1 .41-.41h17.71a.41.41 0 0 0 .41-.41v-7.06a.41.41 0 0 0-.41-.41H174.7a.41.41 0 0 1-.41-.41V213a.41.41 0 0 1 .41-.41h19.78a.41.41 0 0 0 .41-.41v-7.41a.41.41 0 0 0-.41-.41h-29a.4.4 0 0 0-.41.41v40.55a.41.41 0 0 0 .41.41h29.66a.41.41 0 0 0 .41-.41v-7.36a.41.41 0 0 0-.42-.44zm-34.82 7-3.84-5.38-3.93-5.52-.14-.21q-5.38-7.57-7.54-10.58a.4.4 0 0 1 0-.5l3.69-4.09 3-3.37 2.92-3.24 6-6.66a.4.4 0 0 0-.3-.67h-10.31a.41.41 0 0 0-.3.13l-6.4 7-8.4 9.13a.4.4 0 0 1-.7-.28v-15.55a.4.4 0 0 0-.41-.4h-8.42a.4.4 0 0 0-.41.41v40.55a.41.41 0 0 0 .41.41h8.42a.41.41 0 0 0 .41-.41v-11.16a.4.4 0 0 1 .1-.27l1.75-2 2-2.17a.41.41 0 0 1 .63 0l5.84 7.85 4.19 5.65 1.68 2.27a.4.4 0 0 0 .32.17h9.78a.41.41 0 0 0 .33-.65zM120 204.28H33.93a.78.78 0 0 0-.66.37l-.43.74-5.27 9.13-5.82 10.09a.76.76 0 0 0 0 .76l1.25 2.21 10.25 17.76a.77.77 0 0 0 .67.39H120a.85.85 0 0 0 .85-.85v-39.74a.86.86 0 0 0-.85-.86Z" id="path1576" />
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-gradient" x1="20.71" y1="225.61" x2="430.83" y2="225.61" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#e6e6e6" id="stop1579" />
|
||||||
|
<stop offset="1" stop-color="#595959" id="stop1581" />
|
||||||
|
</linearGradient>
|
||||||
|
<style id="style2007">.cls-1{fill:none}</style>
|
||||||
|
</defs>
|
||||||
|
<g id="g2460" transform="translate(.714 .07)">
|
||||||
|
<path d="M105.69 41.25a.76.76 0 0 1-.66-.38l-11.51-20a.78.78 0 0 0-.67-.38h-47a.76.76 0 0 0-.66.38l-12 20.71 4.625 6.774c-.134.236-1.199 4.644-1.065 4.88L33.19 82.29l12 20.73a.76.76 0 0 0 .66.38h47a.78.78 0 0 0 .67-.38l11.52-20a.76.76 0 0 1 .66-.38H120a.86.86 0 0 0 .86-.86V42.11a.86.86 0 0 0-.86-.86z" id="path1588" style="fill:#4d4d4d;clip-path:url(#clip-path)" clip-path="url(#clip-path)" transform="matrix(1.2527 0 0 1.2527 -23.058 -13.67)" />
|
||||||
|
<g clip-path="url(#clip-path-3)" id="g1592" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#4d4d4d">
|
||||||
|
<path id="rect1590" style="display:inline;fill:url(#linear-gradient)" d="M20.71 197.91h99.111v52.823H20.71z" />
|
||||||
|
</g>
|
||||||
|
<path d="m21.876 61.343-16.122 5.85-1.591-2.743a.952.952 0 0 1 0-.952l7.29-12.64z" id="path1594" style="fill:#e1e1e1;stroke-width:1.2527" />
|
||||||
|
<path class="cls-62" id="polygon1794" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#c8c8c8" d="M120.89 225.43v9.83l-8.48-8.62z" />
|
||||||
|
<path class="cls-61" d="m117.757 66.016 10.623 10.798v12.039a1.065 1.065 0 0 1-1.064 1.065H114.95z" id="path1798" style="fill:#c2c2c2;stroke-width:1.2527" />
|
||||||
|
<path class="cls-63" id="polygon1802" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#c7c7c7" d="m112.41 226.64-2.24 19.08H98.31l-3.59-8.66z" />
|
||||||
|
<path class="cls-64" id="polygon1804" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#cecece" d="M120.89 216.31v9.12l-8.48 1.21z" />
|
||||||
|
<path class="cls-65" d="M128.38 39.083v13.993l-10.622 12.927-8.03-27.997h17.538a1.077 1.077 0 0 1 1.114 1.077z" id="path1808" style="fill:#d3d3d3;stroke-width:1.2527" />
|
||||||
|
<path class="cls-58" id="polygon1812" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#c6c6c6" d="M98.31 245.72h-6.26l-1.62-2.33 4.29-6.33z" />
|
||||||
|
<path class="cls-66" id="polygon1814" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#d5d5d5" d="m112.41 226.64-23.47-9.93 12.34-12.43h4.73z" />
|
||||||
|
<path class="cls-67" d="m88.357 53.577 7.24 25.492 22.16-13.066Z" id="path1816" style="fill:#d0d0d0;stroke-width:1.2527" />
|
||||||
|
<path class="cls-50" id="polygon1818" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#bfbfbf" d="m90.36 245.72.07-2.33 1.62 2.33z" />
|
||||||
|
<path class="cls-68" id="polygon1820" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#d9d9d9" d="m101.28 204.28-12.34 12.43-2.23-11.12 4.77-1.31z" />
|
||||||
|
<path class="cls-69" d="m88.357 53.577-35.69 8.23 37.581 25.192Z" id="path1822" style="fill:#d4d4d4;stroke-width:1.2527" />
|
||||||
|
<path class="cls-67" d="m88.357 53.577 1.866 33.422 5.362-7.93z" id="path1824" style="fill:#d0d0d0;stroke-width:1.2527" />
|
||||||
|
<path class="cls-68" d="m85.563 39.647-32.896 22.16 35.69-8.23Z" id="path1826" style="fill:#d9d9d9;stroke-width:1.2527" />
|
||||||
|
<path class="cls-70" id="polygon1828" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#d8d8d8" d="M60.45 223.28 48.1 245.72h-7.03l-5.2-22.81z" />
|
||||||
|
<path class="cls-71" d="M36.82 38.006 21.877 61.343 18.118 39.41l.538-.927a.977.977 0 0 1 .827-.464h17.338z" id="path1830" style="fill:#e2e2e2;stroke-width:1.2527" />
|
||||||
|
<path class="cls-70" d="M28.39 89.918h-8.944a.965.965 0 0 1-.84-.489L5.754 67.194l16.122-5.85Z" id="path1832" style="fill:#d8d8d8;stroke-width:1.2527" />
|
||||||
|
<path class="cls-72" id="polygon1834" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#e4e4e4" d="m27.56 214.53 5.27-9.13 3.04 17.51z" />
|
||||||
|
<path class="cls-73" id="polygon1836" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#dedede" d="m86.71 205.59-7.91-1.31H52.67l7.78 19z" />
|
||||||
|
<path class="cls-73" id="polygon1838" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#dedede" d="m60.45 223.28-7.78-19H47.8l-11.93 18.63z" />
|
||||||
|
<path class="cls-74" id="polygon1840" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#c5c5c5" d="M84.72 245.72H90.36l.07-2.33z" />
|
||||||
|
<path class="cls-67" id="polygon1842" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#d0d0d0" d="M73.47 245.72h11.25l5.71-2.33-29.98-20.11 5.4 22.44z" />
|
||||||
|
<path class="cls-75" id="polygon1844" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#d1d1d1" d="m65.85 245.72-5.4-22.44-12.35 22.44h17.15z" />
|
||||||
|
<path class="cls-78" id="polygon1856" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#ddd" d="m86.79 204.28-.08 1.31 4.77-1.31H89.3z" />
|
||||||
|
<path class="cls-79" id="polygon1858" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#e3e3e3" d="m86.71 205.59-.73-1.31H78.8z" />
|
||||||
|
<path class="cls-71" id="polygon1860" transform="matrix(1.2527 0 0 1.2527 -23.058 -217.896)" style="fill:#e2e2e2" d="m86.71 205.59.08-1.31h-.81z" />
|
||||||
|
<path class="cls-80" d="M58.58 38.457 44.074 63.573a.84.84 0 0 0-.1.414H33.851L53.757 29.5a.79.79 0 0 1 .3.288l4.51 7.842a.864.864 0 0 1 .013.827z" id="path1862" style="fill:#00b8e3;stroke-width:1.2527" />
|
||||||
|
<path class="cls-81" d="m58.567 90.394-4.51 7.804a.877.877 0 0 1-.3.288L33.84 63.962h10.122a.777.777 0 0 0 .1.388l14.481 25.054a.852.852 0 0 1 .025.99z" id="path1864" style="fill:#33c6e9;stroke-width:1.2527" />
|
||||||
|
<path class="cls-82" d="M53.757 29.5 33.852 63.962l-5.011 8.656-4.76-8.268a.777.777 0 0 1-.1-.388.84.84 0 0 1 .1-.414l4.835-8.355 14.67-25.38a.852.852 0 0 1 .738-.438h9.032a.89.89 0 0 1 .401.125z" id="path1866" style="fill:#008aaa;stroke-width:1.2527" />
|
||||||
|
<path class="cls-80" d="M53.757 98.486a.89.89 0 0 1-.426.113h-9.007a.852.852 0 0 1-.739-.439L30.181 74.948l-1.328-2.305 5.011-8.656Z" id="path1868" style="fill:#00b8e3;stroke-width:1.2527" />
|
||||||
|
<path class="cls-82" d="M93.793 63.962 73.875 98.46a.927.927 0 0 1-.3-.288l-4.51-7.817a.864.864 0 0 1 0-.802l14.481-25.129a.84.84 0 0 0 .126-.438h10.121Z" id="path1870" style="fill:#008aaa;stroke-width:1.2527" />
|
||||||
|
<path class="cls-80" d="M103.64 63.962a.84.84 0 0 1-.126.438L84.01 98.223a.852.852 0 0 1-.727.4h-8.982a.927.927 0 0 1-.438-.112l19.93-34.55 5.011-8.643 4.735 8.218a.84.84 0 0 1 .1.426z" id="path1872" style="fill:#00b8e3;stroke-width:1.2527" />
|
||||||
|
<path class="cls-80" d="M93.793 63.962H83.66a.84.84 0 0 0-.125-.426L69.053 38.482a.852.852 0 0 1 0-.865l4.51-7.817a.927.927 0 0 1 .3-.288z" id="path1874" style="fill:#00b8e3;stroke-width:1.2527" />
|
||||||
|
<path class="cls-81" d="m98.78 55.33-5.012 8.644L73.85 29.487a.927.927 0 0 1 .439-.112h9.007a.852.852 0 0 1 .726.4z" id="path1876" style="fill:#33c6e9;stroke-width:1.2527" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 11 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/libreoffice.svg
Normal file
|
After Width: | Height: | Size: 10 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 |
6
public/svgs/mattermost.svg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="256" height="256" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
||||||
|
<g>
|
||||||
|
<path d="M6.79123171,86.9648684 C25.2351716,32.4823178 76.783459,-1.43234143 131.421839,0.0464773399 L131.421839,0.0464773399 L113.909757,20.739032 C81.4957329,26.5997669 53.5072568,48.7337413 42.5072761,81.2287969 C26.140539,129.576353 53.572705,182.545803 103.779303,199.543648 C153.985902,216.538377 207.952658,191.12264 224.319395,142.7782 C235.283535,110.390667 226.589826,75.9306053 204.563374,51.5978814 L204.563374,51.5978814 L203.21701,24.4290666 C247.371203,56.4768925 267.622761,114.633895 249.208429,169.029181 C226.546194,235.970273 153.909545,271.865521 86.9684532,249.204844 C20.0273609,226.542609 -15.8694453,153.905961 6.79123171,86.9648684 Z M165.185344,11.9237762 C165.839826,11.6401671 166.594039,11.5793938 167.321762,11.8256038 C168.035459,12.0671391 168.585536,12.5580009 168.936152,13.1595015 L168.936152,13.1595015 L169.007833,13.2763734 L169.071723,13.4103864 C169.240019,13.7313945 169.383381,14.0991514 169.450388,14.5510559 C169.582343,15.4417519 169.641535,17.5358595 169.665634,19.6808502 L169.671365,20.2662434 C169.677102,20.9486534 169.679633,21.6256073 169.680171,22.2599793 L169.680173,22.7924325 C169.678741,24.5267431 169.663874,25.8268542 169.663874,25.8268542 L169.663874,25.8268542 L170.167202,44.7600977 L170.910507,66.6151379 L171.837691,104.59538 C171.837691,104.59538 171.83785,104.602367 171.838064,104.616156 L171.838772,104.677745 C171.838883,104.691349 171.838983,104.706608 171.839058,104.723498 L171.839105,104.844231 C171.832023,107.013302 171.387173,122.892918 160.122454,133.928662 C148.009853,145.795053 133.131285,144.708923 123.451177,141.433394 C113.771069,138.154749 101.293828,129.979951 98.8800345,113.195592 C96.8283098,98.9302108 104.41287,86.9390787 106.734401,83.6627102 L106.889339,83.4459953 C107.205256,83.0081712 107.389865,82.7777388 107.389865,82.7777388 L107.389865,82.7777388 L131.197445,53.1717559 L145.064682,36.2627333 L156.965355,21.5275276 C156.965355,21.5275276 158.715313,19.1834331 160.51647,16.874806 L160.876881,16.4142586 C161.477025,15.6498178 162.070275,14.9069442 162.593713,14.2737698 L162.898895,13.907734 C163.342593,13.3805415 163.71955,12.9564826 163.983901,12.6998055 C164.292443,12.4006135 164.608776,12.205827 164.918876,12.0546727 L164.918876,12.0546727 L165.146386,11.9393591 Z" fill="#0058CC" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
17
public/svgs/mautic.svg
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="349.779px" height="349.779px" viewBox="0 0 349.779 349.779" enable-background="new 0 0 349.779 349.779"
|
||||||
|
xml:space="preserve">
|
||||||
|
<path fill="#FFFFFF" d="M174.89,349.779C78.612,349.779,0,271.462,0,174.89S78.612,0,174.89,0c23.26,0,45.931,4.417,67.129,13.543
|
||||||
|
c5.889,2.65,8.833,9.422,6.478,15.605c-2.649,5.888-9.421,8.833-15.604,6.477c-18.549-7.655-37.98-11.482-58.002-11.482
|
||||||
|
c-83.323,0-151.041,67.718-151.041,151.041S91.567,326.225,174.89,326.225c83.323,0,151.041-67.718,151.041-151.041
|
||||||
|
c0-17.96-2.944-35.332-9.127-51.819c-2.355-6.183,0.883-12.955,7.066-15.31c6.183-2.355,12.954,0.883,15.31,7.066
|
||||||
|
c7.066,19.138,10.6,39.453,10.6,60.063C349.779,271.167,271.462,349.779,174.89,349.779"/>
|
||||||
|
<g>
|
||||||
|
<polygon fill="#FDB933" points="251.44,156.93 224.354,185.194 239.369,248.496 273.522,248.496 "/>
|
||||||
|
</g>
|
||||||
|
<polygon fill="#FDB933" points="240.253,73.312 249.674,82.734 174.89,161.935 110.999,96.277 74.196,248.496 108.35,248.496
|
||||||
|
128.665,163.996 174.89,214.343 273.817,106.583 283.239,116.299 292.66,63.007 "/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
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 |
51
public/svgs/onedev.svg
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="200 200 630 630"
|
||||||
|
height="200"
|
||||||
|
width="200"
|
||||||
|
version="1.1">
|
||||||
|
<g
|
||||||
|
transform="matrix(1.969278,0,0,1.969278,522.1972,523.64867)">
|
||||||
|
<g
|
||||||
|
paint-order="stroke">
|
||||||
|
<g
|
||||||
|
transform="matrix(1.6226969,0,0,-1.6226969,2.4340454,49.894842)">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
d="m 0,0 c 9.013,0 16.323,3.81 16.323,8.503 0,4.697 -7.31,4.663 -16.323,4.663 -9.015,0 -16.323,0.034 -16.323,-4.663 C -16.323,3.81 -9.015,0 0,0"
|
||||||
|
transform="translate(0,-6.5830035)"
|
||||||
|
paint-order="stroke"
|
||||||
|
style="opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="scale(1.6226969,-1.6226969)">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
d="m 0,0 c -10.7,0 -19.375,-8.674 -19.375,-19.375 0,-6.235 2.958,-11.768 7.533,-15.312 -9.205,-22.861 -31.582,-39.042 -57.699,-39.042 -13.013,0 -25.101,4.021 -35.1,10.876 2.549,4.364 4.016,9.436 4.016,14.853 0,16.292 -13.208,29.5 -29.5,29.5 -0.415,0 -0.827,-0.015 -1.238,-0.031 -0.261,2.309 -0.408,4.653 -0.408,7.031 0,10.383 2.57,20.171 7.084,28.784 10.565,22.164 33.744,37.56 60.658,37.56 24.747,0 46.31,-13.023 57.838,-32.347 -1.504,-1.553 -2.434,-3.665 -2.434,-5.997 0,-4.764 3.861,-8.625 8.625,-8.625 4.764,0 8.625,3.861 8.625,8.625 0,4.088 -2.848,7.504 -6.665,8.393 -1.01,1.971 -2.089,3.902 -3.251,5.776 3.102,3.499 5.018,8.066 5.018,13.106 0,10.953 -8.882,19.832 -19.834,19.832 -5.277,0 -10.033,-2.094 -13.581,-5.459 -11.75,6.755 -25.354,10.625 -39.853,10.625 -14.169,0 -27.485,-3.705 -39.051,-10.175 -3.497,3.109 -8.082,5.009 -13.128,5.009 -10.956,0 -19.834,-8.879 -19.834,-19.832 0,-4.643 1.598,-8.91 4.273,-12.285 -7.92,-12.438 -12.533,-27.18 -12.533,-42.99 0,-4.618 0.413,-9.14 1.166,-13.547 -6.693,-5.408 -10.977,-13.679 -10.977,-22.953 0,-16.292 13.208,-29.5 29.5,-29.5 4.15,0 8.097,0.86 11.68,2.407 13.551,-10.446 30.509,-16.68 48.904,-16.68 35.091,0 64.955,22.649 75.833,54.088 7.607,2.615 13.083,9.816 13.083,18.31 C 19.375,-8.674 10.7,0 0,0"
|
||||||
|
transform="translate(70.125,11.5)"
|
||||||
|
paint-order="stroke"
|
||||||
|
style="opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="matrix(1.6226969,0,0,-1.6226969,-41.533257,-8.9250313)">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
d="m 0,0 c 3.561,1.848 7.952,0.457 9.8,-3.105 0.127,-0.246 0.205,-0.503 0.304,-0.759 1.367,9.134 -1.382,17.072 -7.088,18.88 -6.791,2.152 -15.166,-5.181 -18.713,-16.372 -3.546,-11.195 -0.915,-22.012 5.873,-24.161 6.137,-1.944 13.562,3.878 17.552,13.287 -0.323,-0.247 -0.661,-0.482 -1.032,-0.674 -3.564,-1.85 -7.951,-0.463 -9.801,3.102 C -4.953,-6.239 -3.564,-1.85 0,0"
|
||||||
|
transform="translate(3.4126028,5.2498778)"
|
||||||
|
paint-order="stroke"
|
||||||
|
style="opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="matrix(1.6226969,0,0,-1.6226969,46.400783,-8.9251198)">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
d="M 0,0 C 6.789,2.148 9.42,12.966 5.873,24.16 2.326,35.352 -6.049,42.685 -12.84,40.532 c -5.705,-1.807 -8.455,-9.746 -7.088,-18.88 0.1,0.256 0.178,0.514 0.305,0.759 1.848,3.563 6.238,4.953 9.799,3.106 3.564,-1.85 4.953,-6.24 3.105,-9.802 -1.849,-3.566 -6.236,-4.952 -9.801,-3.103 -0.371,0.193 -0.709,0.428 -1.031,0.674 C -13.563,3.878 -6.137,-1.944 0,0"
|
||||||
|
transform="translate(6.411045,-20.266777)"
|
||||||
|
paint-order="stroke"
|
||||||
|
style="opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.8 KiB |
BIN
public/svgs/organizr.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
12
public/svgs/paperless.svg
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 27.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 1000 1000" style="enable-background:new 0 0 1000 1000;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<path class="st0" d="M299,891.7c-4.2-19.8-12.5-59.6-13.6-59.6c-176.7-105.7-155.8-288.7-97.3-393.4
|
||||||
|
c12.5,131.8,245.8,222.8,109.8,383.9c-1.1,2,6.2,27.2,12.5,50.2c27.2-46,68-101.4,65.8-106.7C208.9,358.2,731.9,326.9,840.6,73.7
|
||||||
|
c49.1,244.8-25.1,623.5-445.5,719.7c-2,1.1-76.3,131.8-79.5,132.9c0-2-31.4-1.1-27.2-11.5C290.7,908.4,294.8,900.1,299,891.7
|
||||||
|
L299,891.7z M293.8,793.4c53.3-61.8-9.4-167.4-47.1-201.9C310.5,701.3,306.3,765.1,293.8,793.4L293.8,793.4z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 869 B |
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 |
BIN
public/svgs/soketi.jpeg
Normal file
|
After Width: | Height: | Size: 18 KiB |
17
public/svgs/supertokens.svg
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="44.869" height="40.302" viewBox="0 0 44.869 40.302">
|
||||||
|
<g id="Group_10325" data-name="Group 10325" transform="translate(0.516)">
|
||||||
|
<path id="Exclusion_1" data-name="Exclusion 1" d="M18.621,36.98c-.1,0-.2,0-.305-.008a7.383,7.383,0,0,1-3.67-1.338c-.308-.207-.615-.429-.912-.644l-.027-.019a16.427,16.427,0,0,0-1.965-1.286,7.348,7.348,0,0,0-3.4-.847l-.165,0a5.86,5.86,0,0,0-1.338.135A1.959,1.959,0,0,0,5.934,34.7a3.214,3.214,0,0,0,.3,1.18,3.066,3.066,0,0,1,.274.709h0c-.034,0-.122-.108-.289-.313-.665-.82-2.428-2.995-4.791-3.458A1.76,1.76,0,0,1,.306,30.1C6.2,21.434,6.931,18.338,9.672,6.822l.238-1q.261-1.1.55-2.3A1.773,1.773,0,0,1,11.5,2.3L14.818.918a1.759,1.759,0,0,1,.676-.135,1.8,1.8,0,0,1,.275.021A14.322,14.322,0,0,1,20.989,0h2.3a14.32,14.32,0,0,1,5.219.8,1.77,1.77,0,0,0-1.017.539l-10,.758h0l-.7-.757A1.773,1.773,0,0,0,15.77.805a5.9,5.9,0,0,0-1.814,1.1c-1.308,1.2-1.972,3.351-1.972,6.406V20.836c0,3.056.664,5.213,1.972,6.408,1.377,1.262,3.743,1.9,7.033,1.9h2.3c3.29,0,5.656-.64,7.033-1.9,1.308-1.2,1.972-3.354,1.972-6.408V8.31c0-3.053-.664-5.208-1.972-6.406A5.912,5.912,0,0,0,28.508.8a1.825,1.825,0,0,1,.274-.021,1.749,1.749,0,0,1,.675.135L32.779,2.3a1.773,1.773,0,0,1,1.036,1.223c.613,2.556,1.133,4.837,1.511,6.5,2.1,9.24,2.891,12.7,8.2,20.511a1.759,1.759,0,0,1-1.115,2.718A8.073,8.073,0,0,0,37.9,36.443c-.108.139-.155.2-.168.2a2.225,2.225,0,0,1,.195-.49l.118-.273a3.243,3.243,0,0,0,.293-1.18,1.9,1.9,0,0,0-.657-1.524,10.157,10.157,0,0,0-2.225-.28q-.118,0-.237,0a3.506,3.506,0,0,0-2.887,1.172,5,5,0,0,0-.3.455l-.013.022a4.346,4.346,0,0,1-.365.543,1.328,1.328,0,0,1-1.083.532A4.472,4.472,0,0,1,28.737,35c-.242-.122-.44-.222-.632-.3a5.773,5.773,0,0,0-2.236-.523,3.7,3.7,0,0,0-.643.055,7.689,7.689,0,0,0-2.771,1.336c-.194.126-.386.252-.579.374A6.007,6.007,0,0,1,18.621,36.98Z" transform="translate(0 2.822)" fill="#f93" stroke="rgba(0,0,0,0)" stroke-width="1"/>
|
||||||
|
<g id="Group_4056" data-name="Group 4056" transform="translate(5.914 22.19)">
|
||||||
|
<path id="Path_14227" data-name="Path 14227" d="M698.042,466.44l.162-2.728,2.46-.713,1.006,3.181A4.743,4.743,0,0,0,698.042,466.44Z" transform="translate(-680.16 -451.111)" fill="#db902e"/>
|
||||||
|
<path id="Path_14229" data-name="Path 14229" d="M660.956,448.452c0,.064,0,1.019.007,1.1-1.971-.35-3.581.3-3.53,1.77h-.017V450.9c-.081-2.846,1.322-5.229,2.111-7.863.647-2.175.943-8.8,1.467-6.608a14.459,14.459,0,0,1-.037,5.614,23.229,23.229,0,0,0,0,3.2Z" transform="translate(-657.412 -435.988)" fill="#db902e"/>
|
||||||
|
<path id="Path_14231" data-name="Path 14231" d="M722.715,448.452c0,.064,0,1.019-.007,1.1,1.724.09,3.581.3,3.53,1.77h.017V450.9c.081-2.846-1.322-5.229-2.11-7.863-.647-2.175-.943-8.8-1.467-6.608a14.438,14.438,0,0,0,.038,5.614,23.287,23.287,0,0,1,0,3.2Z" transform="translate(-693.804 -435.988)" fill="#db902e"/>
|
||||||
|
</g>
|
||||||
|
<g id="Group_1803" data-name="Group 1803" transform="translate(9.16)">
|
||||||
|
<path id="Path_14233" data-name="Path 14233" d="M678.914,391.217c3.483,0,4.746.813,5.128,1.162.671.615,1.056,2.193,1.056,4.328v12.525c0,2.135-.385,3.712-1.057,4.328-.381.349-1.643,1.161-5.127,1.161h-2.3c-3.483,0-4.746-.812-5.129-1.163-.671-.614-1.055-2.191-1.055-4.326V396.707c0-2.135.385-3.713,1.056-4.328.382-.349,1.645-1.162,5.128-1.162h2.3m0-5.644h-2.3q-6.052,0-8.94,2.644t-2.888,8.49v12.525q0,5.846,2.888,8.49t8.94,2.644h2.3q6.054,0,8.94-2.644t2.888-8.49V396.707q0-5.846-2.888-8.49t-8.94-2.644Z" transform="translate(-664.788 -385.573)" fill="#1a1a1a"/>
|
||||||
|
</g>
|
||||||
|
<g id="Group_1804" data-name="Group 1804" transform="translate(19.692 15.337)">
|
||||||
|
<ellipse id="Ellipse_669" data-name="Ellipse 669" cx="2.445" cy="2.445" rx="2.445" ry="2.445" transform="translate(0 0)" fill="#1a1a1a"/>
|
||||||
|
<path id="Path_14234" data-name="Path 14234" d="M693.3,432.955h-2.286a.517.517,0,0,1-.514-.566l.47-4.836a.516.516,0,0,1,.514-.466h1.344a.516.516,0,0,1,.514.466l.47,4.836A.517.517,0,0,1,693.3,432.955Z" transform="translate(-689.717 -424.151)" fill="#1a1a1a"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.9 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 |
@@ -272,7 +272,7 @@
|
|||||||
class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||||
Your Password
|
Your Password
|
||||||
</label>
|
</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"
|
<input type="password" id="password-confirm" x-model="password" class="w-full input"
|
||||||
placeholder="Enter your password">
|
placeholder="Enter your password">
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
'transition-all duration-150 box-without-bg dark:bg-coolgray-100 bg-white group',
|
'transition-all duration-150 box-without-bg dark:bg-coolgray-100 bg-white group',
|
||||||
'hover:border-l-coollabs cursor-pointer' => !$upgrade,
|
'hover:border-l-coollabs cursor-pointer' => !$upgrade,
|
||||||
'hover:border-l-red-500 cursor-not-allowed' => $upgrade,
|
'hover:border-l-red-500 cursor-not-allowed' => $upgrade,
|
||||||
]) @if (!$upgrade) wire:click={{ $wire }} @endif>
|
])>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
{{ $logo }}
|
{{ $logo }}
|
||||||
<div class="flex flex-col pl-2 ">
|
<div class="flex flex-col pl-2 ">
|
||||||
@@ -20,11 +20,6 @@
|
|||||||
</div>
|
</div>
|
||||||
@isset($documentation)
|
@isset($documentation)
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
<div class="flex items-center px-2 " title="Read the documentation.">
|
{{ $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>
|
|
||||||
@endisset
|
@endisset
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<livewire:server.proxy.status :server="$server" />
|
<livewire:server.proxy.status :server="$server" />
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="subtitle">{{ data_get($server, 'name') }}.</div>
|
<div class="subtitle">{{ data_get($server, 'name') }}</div>
|
||||||
<div class="navbar-main">
|
<div class="navbar-main">
|
||||||
<nav class="flex items-center gap-6 overflow-x-scroll sm:overflow-x-hidden scrollbar min-h-10 whitespace-nowrap">
|
<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' : '' }}"
|
<a class="{{ request()->routeIs('server.show') ? 'dark:text-white' : '' }}"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<div class="grid grid-cols-1 gap-2 xl:grid-cols-2">
|
<div class="grid grid-cols-1 gap-2 xl:grid-cols-2">
|
||||||
@foreach ($projects as $project)
|
@foreach ($projects as $project)
|
||||||
<div class="gap-2 border border-transparent cursor-pointer box group"
|
<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-1 mx-6">
|
||||||
<div class="flex flex-col justify-center flex-1">
|
<div class="flex flex-col justify-center flex-1">
|
||||||
<div class="box-title">{{ $project->name }}</div>
|
<div class="box-title">{{ $project->name }}</div>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-center gap-2 text-xs font-bold">
|
<div class="flex items-center justify-center gap-2 text-xs font-bold">
|
||||||
<a class="hover:underline"
|
<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>
|
<span class="p-2 font-bold">+ Add Resource</span>
|
||||||
</a>
|
</a>
|
||||||
<a class="hover:underline"
|
<a class="hover:underline"
|
||||||
|
|||||||
@@ -5,6 +5,13 @@
|
|||||||
<x-forms.button type="submit">
|
<x-forms.button type="submit">
|
||||||
Save
|
Save
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
|
{{--
|
||||||
|
<x-forms.button wire:click="downloadConfig">
|
||||||
|
Download Config
|
||||||
|
<x-modal-input buttonTitle="Upload Config" title="Upload Config" :closeOutside="false">
|
||||||
|
<livewire:project.shared.upload-config :applicationId="$application->id" />
|
||||||
|
</x-modal-input>
|
||||||
|
--}}
|
||||||
</div>
|
</div>
|
||||||
<div>General configuration for your application.</div>
|
<div>General configuration for your application.</div>
|
||||||
<div class="flex flex-col gap-2 py-4">
|
<div class="flex flex-col gap-2 py-4">
|
||||||
@@ -56,7 +63,7 @@
|
|||||||
@endif
|
@endif
|
||||||
@if ($application->build_pack !== 'dockercompose')
|
@if ($application->build_pack !== 'dockercompose')
|
||||||
<div class="flex items-end gap-2">
|
<div class="flex items-end gap-2">
|
||||||
<x-forms.input placeholder="https://coolify.io" id="application.fqdn" label="Domains"
|
<x-forms.input placeholder="https://coolify.io" wire:model.blur="application.fqdn" label="Domains"
|
||||||
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io,https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. " />
|
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io,https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. " />
|
||||||
<x-forms.button wire:click="getWildcardDomain">Generate Domain
|
<x-forms.button wire:click="getWildcardDomain">Generate Domain
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
|
|||||||
@@ -9,35 +9,59 @@
|
|||||||
</x-modal-input>
|
</x-modal-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="subtitle">All your projects are here.</div>
|
<div class="subtitle">All your projects are here.</div>
|
||||||
<div class="grid gap-2 lg:grid-cols-2">
|
<div x-data="searchComponent()">
|
||||||
@forelse ($projects as $project)
|
<x-forms.input placeholder="Search for name, description..." x-model="search" id="null" />
|
||||||
<div class="box group" onclick="gotoProject('{{ $project->uuid }}', '{{ $project->default_environment() }}')">
|
<div class="grid grid-cols-2 gap-4 pt-4">
|
||||||
<div class="flex flex-col justify-center flex-1 mx-6">
|
<template x-if="allFilteredItems.length === 0">
|
||||||
<div class="box-title">{{ $project->name }}</div>
|
<div>No project found with the search term "<span x-text="search"></span>".</div>
|
||||||
<div class="box-description ">
|
</template>
|
||||||
{{ $project->description }}</div>
|
|
||||||
|
<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>
|
||||||
<div class="flex items-center justify-center gap-2 pt-4 pb-2 mr-4 text-xs lg:py-0 lg:justify-normal">
|
</template>
|
||||||
<a class="mx-4 font-bold hover:underline"
|
</div>
|
||||||
href="{{ route('project.edit', ['project_uuid' => data_get($project, 'uuid')]) }}">
|
|
||||||
Settings
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@empty
|
|
||||||
<div>
|
|
||||||
<div>No project found.</div>
|
|
||||||
</div>
|
|
||||||
@endforelse
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function gotoProject(uuid, environment) {
|
function sortFn(a, b) {
|
||||||
if (environment) {
|
return a.name.localeCompare(b.name)
|
||||||
window.location.href = '/project/' + uuid + '/' + environment;
|
|
||||||
} else {
|
|
||||||
window.location.href = '/project/' + uuid;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</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>
|
</div>
|
||||||
|
|||||||
@@ -52,15 +52,21 @@
|
|||||||
helper="It is calculated together with the Base Directory:<br><span class='dark:text-warning'>{{ Str::start($base_directory . $docker_compose_location, '/') }}</span>" />
|
helper="It is calculated together with the Base Directory:<br><span class='dark:text-warning'>{{ Str::start($base_directory . $docker_compose_location, '/') }}</span>" />
|
||||||
Compose file location in your repository:<span
|
Compose file location in your repository:<span
|
||||||
class='dark:text-warning'>{{ Str::start($base_directory . $docker_compose_location, '/') }}</span>
|
class='dark:text-warning'>{{ Str::start($base_directory . $docker_compose_location, '/') }}</span>
|
||||||
|
@else
|
||||||
|
<x-forms.input wire:model="base_directory" label="Base Directory"
|
||||||
|
helper="Directory to use as root. Useful for monorepos." />
|
||||||
@endif
|
@endif
|
||||||
@if ($show_is_static)
|
@if ($show_is_static)
|
||||||
<x-forms.input type="number" id="port" label="Port" :readonly="$isStatic || $build_pack === 'static'"
|
<x-forms.input type="number" id="port" label="Port" :readonly="$isStatic || $build_pack === 'static'"
|
||||||
helper="The port your application listens on." />
|
helper="The port your application listens on." />
|
||||||
<div class="w-52">
|
<div class="w-64">
|
||||||
<x-forms.checkbox instantSave id="isStatic" label="Is it a static site?"
|
<x-forms.checkbox instantSave id="isStatic" label="Is it a static site?"
|
||||||
helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
|
helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
{{-- <div class="w-64">
|
||||||
|
<x-forms.checkbox helper="If your repository contains a coolify.json file, it will be used to configure your application." instantSave id="checkCoolifyConfig" label="Use coolify.json if exists?" />
|
||||||
|
</div> --}}
|
||||||
{{-- @if ($build_pack === 'dockercompose' && isDev())
|
{{-- @if ($build_pack === 'dockercompose' && isDev())
|
||||||
<div class="dark:text-warning">If you choose Docker Compose based deployments, you cannot
|
<div class="dark:text-warning">If you choose Docker Compose based deployments, you cannot
|
||||||
change it afterwards.</div>
|
change it afterwards.</div>
|
||||||
|
|||||||
@@ -50,6 +50,10 @@
|
|||||||
<div x-data="searchComponent()">
|
<div x-data="searchComponent()">
|
||||||
<x-forms.input placeholder="Search for name, fqdn..." x-model="search" id="null" />
|
<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">
|
<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">
|
<template x-for="item in allFilteredItems" :key="item.uuid">
|
||||||
<span>
|
<span>
|
||||||
<a class="h-24 box group" :href="item.hrefLink">
|
<a class="h-24 box group" :href="item.hrefLink">
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<form wire:submit="uploadConfig" class="flex flex-col gap-2 w-full">
|
||||||
|
<x-forms.textarea id="config" monacoEditorLanguage="json" useMonacoEditor />
|
||||||
|
<x-forms.button type="submit">
|
||||||
|
Upload
|
||||||
|
</x-forms.button>
|
||||||
|
</form>
|
||||||
@@ -20,18 +20,14 @@
|
|||||||
<div class="w-[500px]">
|
<div class="w-[500px]">
|
||||||
<x-forms.input readonly label="Deploy Webhook URL" id="webhook" />
|
<x-forms.input readonly label="Deploy Webhook URL" id="webhook" />
|
||||||
</div>
|
</div>
|
||||||
<x-modal-confirmation
|
<x-modal-confirmation title="Redeploy all resources with this tag?" isHighlighted
|
||||||
title="Redeploy all resources with this tag?"
|
buttonTitle="Redeploy All" submitAction="redeploy_all" :actions="[
|
||||||
isHighlighted
|
'All resources with this tag will be redeployed.',
|
||||||
buttonTitle="Redeploy All"
|
'During redeploy resources will be temporarily unavailable.',
|
||||||
submitAction="redeploy_all"
|
]"
|
||||||
:actions="['All resources with this tag will be redeployed.', 'During redeploy resources will be temporarily unavailable.']"
|
confirmationText="{{ $tag }}"
|
||||||
confirmationText="{{ $oneTag->name }}"
|
confirmationLabel="Please confirm the execution of the actions by entering the Tag Name below"
|
||||||
confirmationLabel="Please confirm the execution of the actions by entering the Tag Name below"
|
shortConfirmationLabel="Tag Name" :confirmWithPassword="false" step2ButtonText="Redeploy All" />
|
||||||
shortConfirmationLabel="Tag Name"
|
|
||||||
:confirmWithPassword="false"
|
|
||||||
step2ButtonText="Redeploy All"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-1 gap-2 pt-4 lg:grid-cols-2 xl:grid-cols-3">
|
<div class="grid grid-cols-1 gap-2 pt-4 lg:grid-cols-2 xl:grid-cols-3">
|
||||||
@foreach ($applications as $application)
|
@foreach ($applications as $application)
|
||||||
|
|||||||
@@ -24,18 +24,13 @@
|
|||||||
<div class="w-[500px]">
|
<div class="w-[500px]">
|
||||||
<x-forms.input readonly label="Deploy Webhook URL" id="webhook" />
|
<x-forms.input readonly label="Deploy Webhook URL" id="webhook" />
|
||||||
</div>
|
</div>
|
||||||
<x-modal-confirmation
|
<x-modal-confirmation title="Redeploy all resources with this tag?" isHighlighted buttonTitle="Redeploy All"
|
||||||
title="Redeploy all resources with this tag?"
|
submitAction="redeploy_all" :actions="[
|
||||||
isHighlighted
|
'All resources with this tag will be redeployed.',
|
||||||
buttonTitle="Redeploy All"
|
'During redeploy resources will be temporarily unavailable.',
|
||||||
submitAction="redeploy_all"
|
]" confirmationText="{{ $tag }}"
|
||||||
:actions="['All resources with this tag will be redeployed.', 'During redeploy resources will be temporarily unavailable.']"
|
confirmationLabel="Please confirm the execution of the actions by entering the Tag Name below"
|
||||||
confirmationText="{{ $oneTag->name }}"
|
shortConfirmationLabel="Tag Name" :confirmWithPassword="false" step2ButtonText="Redeploy All" />
|
||||||
confirmationLabel="Please confirm the execution of the actions by entering the Tag Name below"
|
|
||||||
shortConfirmationLabel="Tag Name"
|
|
||||||
:confirmWithPassword="false"
|
|
||||||
step2ButtonText="Redeploy All"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-1 gap-2 pt-4 lg:grid-cols-2 xl:grid-cols-3">
|
<div class="grid grid-cols-1 gap-2 pt-4 lg:grid-cols-2 xl:grid-cols-3">
|
||||||
@foreach ($applications as $application)
|
@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
|
||||||
23
templates/compose/audiobookshelf.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# documentation: https://www.audiobookshelf.org/
|
||||||
|
# slogan: Self-hosted audiobook, ebook, and podcast server
|
||||||
|
# tags: audiobooks, ebooks, podcasts, server, self-hosted
|
||||||
|
# logo: svgs/audiobookshelf.svg
|
||||||
|
# port: 80
|
||||||
|
|
||||||
|
services:
|
||||||
|
audiobookshelf:
|
||||||
|
image: ghcr.io/advplyr/audiobookshelf:latest
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_AUDIOBOOKSHELF_80
|
||||||
|
- TZ=${TIMEZONE:-America/Toronto}
|
||||||
|
volumes:
|
||||||
|
- audiobookshelf-audiobooks:/audiobooks
|
||||||
|
- audiobookshelf-podcasts:/podcasts
|
||||||
|
- audiobookshelf-config:/config
|
||||||
|
- audiobookshelf-metadata:/metadata
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -f http://localhost:80/ping || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 15s
|
||||||
@@ -5,9 +5,8 @@
|
|||||||
# port: 9000
|
# port: 9000
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
authentik-server:
|
authentik-server:
|
||||||
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2024.2.2}
|
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2024.8.0}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: server
|
command: server
|
||||||
environment:
|
environment:
|
||||||
@@ -36,7 +35,7 @@ services:
|
|||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
authentik-worker:
|
authentik-worker:
|
||||||
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2024.2.2}
|
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2024.8.0}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: worker
|
command: worker
|
||||||
environment:
|
environment:
|
||||||
@@ -73,7 +72,7 @@ services:
|
|||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
postgresql:
|
postgresql:
|
||||||
image: docker.io/library/postgres:12-alpine
|
image: docker.io/library/postgres:16-alpine
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
||||||
@@ -85,7 +84,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
|
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
|
||||||
- POSTGRES_USER=${SERVICE_USER_POSTGRESQL}
|
- POSTGRES_USER=${SERVICE_USER_POSTGRESQL}
|
||||||
- POSTGRES_DB=${POSTGRES_DB:-authentik}
|
- POSTGRES_DB=authentik
|
||||||
redis:
|
redis:
|
||||||
image: docker.io/library/redis:alpine
|
image: docker.io/library/redis:alpine
|
||||||
command: --save 60 1 --loglevel warning
|
command: --save 60 1 --loglevel warning
|
||||||
|
|||||||
103
templates/compose/azimutt.yaml
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
# ignore: true
|
||||||
|
# documentation: https://docs.azimutt.app/
|
||||||
|
# slogan: Next-Gen ERD: Design, Explore, Document and Analyze your database.
|
||||||
|
# tags: erd, entity-relationship diagram, database tool, database schema, diagram
|
||||||
|
# logo: svgs/azimutt.png
|
||||||
|
# port: 4000
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:15
|
||||||
|
environment:
|
||||||
|
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||||
|
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||||
|
- POSTGRES_DB=azimutt
|
||||||
|
volumes:
|
||||||
|
- azimutt-postgres-data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
minio:
|
||||||
|
image: minio/minio:latest
|
||||||
|
command: server /data --console-address ":9001"
|
||||||
|
environment:
|
||||||
|
- MINIO_SERVER_URL=$MINIO_SERVER_URL
|
||||||
|
- MINIO_BROWSER_REDIRECT_URL=$MINIO_BROWSER_REDIRECT_URL
|
||||||
|
- MINIO_ROOT_USER=$SERVICE_USER_MINIO
|
||||||
|
- MINIO_ROOT_PASSWORD=$SERVICE_PASSWORD_MINIO
|
||||||
|
volumes:
|
||||||
|
- azimutt-minio-data:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
createbuckets:
|
||||||
|
image: minio/mc:latest
|
||||||
|
restart: no
|
||||||
|
depends_on:
|
||||||
|
minio:
|
||||||
|
condition: service_healthy
|
||||||
|
entrypoint: >
|
||||||
|
/bin/sh -c "
|
||||||
|
/usr/bin/mc config host add myminio http://minio:9000 $SERVICE_USER_MINIO $SERVICE_PASSWORD_MINIO;
|
||||||
|
/usr/bin/mc mb -p myminio/azimutt;
|
||||||
|
/usr/bin/mc policy download myminio/azimutt;
|
||||||
|
exit 0;
|
||||||
|
"
|
||||||
|
|
||||||
|
smtp:
|
||||||
|
image: bytemark/smtp:latest
|
||||||
|
platform: linux/amd64
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_SMTP
|
||||||
|
- RELAY_HOST=$SERVICE_FQDN_SMTP
|
||||||
|
- RELAY_PORT=${RELAY_PORT:-587}
|
||||||
|
- RELAY_USERNAME=$SERVICE_EMAIL_SMTP
|
||||||
|
- RELAY_PASSWORD=$SERVICE_PASSWORD_SMTP
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/25' || exit 1"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 20
|
||||||
|
|
||||||
|
backend:
|
||||||
|
container_name: azimutt-backend
|
||||||
|
platform: linux/amd64
|
||||||
|
image: ghcr.io/azimuttapp/azimutt:main
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
minio:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_AZIMUTT_4000
|
||||||
|
- SENTRY=false
|
||||||
|
- PHX_SERVER=true
|
||||||
|
- PHX_HOST=$SERVICE_URL_AZIMUTT
|
||||||
|
- PORT=${PORT:-4000}
|
||||||
|
- DATABASE_URL=ecto://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgres/azimutt
|
||||||
|
- SECRET_KEY_BASE=$SERVICE_BASE64_64_AZIMUTT
|
||||||
|
- FILE_STORAGE_ADAPTER=${FILE_STORAGE_ADAPTER:-s3}
|
||||||
|
- AUTH_PASSWORD=${AUTH_PASSWORD:-true}
|
||||||
|
- SKIP_ONBOARDING_FUNNEL=${SKIP_ONBOARDING_FUNNEL:-true}
|
||||||
|
- SKIP_EMAIL_CONFIRMATION=${SKIP_EMAIL_CONFIRMATION:-true}
|
||||||
|
- PUBLIC_SITE=${PUBLIC_SITE:-false}
|
||||||
|
- S3_BUCKET=${S3_BUCKET}
|
||||||
|
- S3_HOST=${S3_HOST}
|
||||||
|
- S3_KEY_ID=${S3_KEY_ID}
|
||||||
|
- S3_KEY_SECRET=${S3_KEY_SECRET}
|
||||||
|
- EMAIL_ADAPTER=${EMAIL_ADAPTER:-smtp}
|
||||||
|
- SMTP_RELAY=$SERVICE_FQDN_SMTP
|
||||||
|
- SMTP_USERNAME=$SERVICE_EMAIL_SMTP
|
||||||
|
- SMTP_PASSWORD=$SERVICE_PASSWORD_SMTP
|
||||||
|
- SMTP_PORT=${SMTP_PORT:-587}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/4000' || exit 1"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 20
|
||||||
59
templates/compose/bookstack.yaml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# documentation: https://www.bookstackapp.com/docs/
|
||||||
|
# slogan: BookStack is a simple, self-hosted, easy-to-use platform for organising and storing information
|
||||||
|
# tags: free-and-open-source,mfa,dark-light-themes,searchable,connected,simple-interface,diagramms,notes
|
||||||
|
# logo: svgs/bookstack.png
|
||||||
|
# port: 80
|
||||||
|
|
||||||
|
services:
|
||||||
|
bookstack:
|
||||||
|
image: lscr.io/linuxserver/bookstack:latest
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_BOOKSTACK_80
|
||||||
|
- APP_URL=${SERVICE_FQDN_BOOKSTACK}
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=${TZ:-Europe/Berlin}
|
||||||
|
- DB_HOST=mariadb
|
||||||
|
- DB_PORT=3306
|
||||||
|
- DB_USER=${SERVICE_USER_MYSQL}
|
||||||
|
- DB_PASS=${SERVICE_PASSWORD_MYSQL}
|
||||||
|
- DB_DATABASE=${MYSQL_DATABASE:-bookstackapp}
|
||||||
|
- QUEUE_CONNECTION=${QUEUE_CONNECTION}
|
||||||
|
# You will need to set up an authentication provider as described at https://www.bookstackapp.com/docs/admin/third-party-auth/.
|
||||||
|
- GITHUB_APP_ID=${GITHUB_APP_ID}
|
||||||
|
- GITHUB_APP_SECRET=${GITHUB_APP_SECRET}
|
||||||
|
volumes:
|
||||||
|
- 'bookstack-data:/config'
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD-SHELL
|
||||||
|
- 'wget -qO- http://127.0.0.1:80/'
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
|
depends_on:
|
||||||
|
mariadb:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
mariadb:
|
||||||
|
image: lscr.io/linuxserver/mariadb:latest
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=${TZ:-Europe/Berlin}
|
||||||
|
- MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}
|
||||||
|
- MYSQL_DATABASE=${MYSQL_DATABASE:-bookstack}
|
||||||
|
- MYSQL_USER=${SERVICE_USER_MYSQL}
|
||||||
|
- MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL}
|
||||||
|
volumes:
|
||||||
|
- 'bookstack-mariadb-data:/config'
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- mysqladmin
|
||||||
|
- ping
|
||||||
|
- '-h'
|
||||||
|
- 127.0.0.1
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
@@ -15,19 +15,19 @@ services:
|
|||||||
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
|
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
|
||||||
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
|
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
|
||||||
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
|
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
|
||||||
- FORCE_SSL=false
|
- FORCE_SSL=${FORCE_SSL:-false}
|
||||||
- ENABLE_ACCOUNT_SIGNUP=false
|
- ENABLE_ACCOUNT_SIGNUP=${ENABLE_ACCOUNT_SIGNUP:-false}
|
||||||
- REDIS_URL=redis://default@redis:6379
|
- REDIS_URL=redis://default@redis:6379
|
||||||
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
|
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
|
||||||
- REDIS_OPENSSL_VERIFY_MODE=none
|
- REDIS_OPENSSL_VERIFY_MODE=${REDIS_OPENSSL_VERIFY_MODE:-none}
|
||||||
- POSTGRES_DATABASE=chatwoot
|
- POSTGRES_DATABASE=${POSTGRES_DB:-chatwoot}
|
||||||
- POSTGRES_HOST=postgres
|
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
|
||||||
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
|
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES
|
||||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||||
- RAILS_MAX_THREADS=5
|
- RAILS_MAX_THREADS=${RAILS_MAX_THREADS:-5}
|
||||||
- NODE_ENV=production
|
- NODE_ENV=${NODE_ENV:-production}
|
||||||
- RAILS_ENV=production
|
- RAILS_ENV=${RAILS_ENV:-production}
|
||||||
- INSTALLATION_ENV=docker
|
- INSTALLATION_ENV=${INSTALLATION_ENV:-docker}
|
||||||
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
|
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
|
||||||
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
|
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
|
||||||
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
|
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
|
||||||
@@ -36,7 +36,7 @@ services:
|
|||||||
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
|
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
|
||||||
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
|
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
|
||||||
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
|
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
|
||||||
- ACTIVE_STORAGE_SERVICE=local
|
- ACTIVE_STORAGE_SERVICE=${ACTIVE_STORAGE_SERVICE:-local}
|
||||||
entrypoint: docker/entrypoints/rails.sh
|
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"
|
command: sh -c "bundle exec rails db:chatwoot_prepare && bundle exec rails s -p 3000 -b 0.0.0.0"
|
||||||
volumes:
|
volumes:
|
||||||
@@ -56,19 +56,19 @@ services:
|
|||||||
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
|
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
|
||||||
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
|
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
|
||||||
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
|
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
|
||||||
- FORCE_SSL=false
|
- FORCE_SSL=${FORCE_SSL:-false}
|
||||||
- ENABLE_ACCOUNT_SIGNUP=false
|
- ENABLE_ACCOUNT_SIGNUP=${ENABLE_ACCOUNT_SIGNUP:-false}
|
||||||
- REDIS_URL=redis://default@redis:6379
|
- REDIS_URL=redis://default@redis:6379
|
||||||
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
|
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
|
||||||
- REDIS_OPENSSL_VERIFY_MODE=none
|
- REDIS_OPENSSL_VERIFY_MODE=${REDIS_OPENSSL_VERIFY_MODE:-none}
|
||||||
- POSTGRES_DATABASE=chatwoot
|
- POSTGRES_DATABASE=${POSTGRES_DB:-chatwoot}
|
||||||
- POSTGRES_HOST=postgres
|
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
|
||||||
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
|
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES
|
||||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||||
- RAILS_MAX_THREADS=5
|
- RAILS_MAX_THREADS=${RAILS_MAX_THREADS:-5}
|
||||||
- NODE_ENV=production
|
- NODE_ENV=${NODE_ENV:-production}
|
||||||
- RAILS_ENV=production
|
- RAILS_ENV=${RAILS_ENV:-production}
|
||||||
- INSTALLATION_ENV=docker
|
- INSTALLATION_ENV=${INSTALLATION_ENV:-docker}
|
||||||
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
|
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
|
||||||
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
|
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
|
||||||
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
|
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
|
||||||
@@ -77,7 +77,7 @@ services:
|
|||||||
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
|
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
|
||||||
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
|
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
|
||||||
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
|
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
|
||||||
- ACTIVE_STORAGE_SERVICE=local
|
- ACTIVE_STORAGE_SERVICE=${ACTIVE_STORAGE_SERVICE:-local}
|
||||||
command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml']
|
command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml']
|
||||||
volumes:
|
volumes:
|
||||||
- sidekiq-data:/app/storage
|
- sidekiq-data:/app/storage
|
||||||
@@ -93,11 +93,11 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- postgres-data:/var/lib/postgresql/data
|
- postgres-data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_DB=chatwoot
|
- POSTGRES_DB=${POSTGRES_DB:-chatwoot}
|
||||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES_USER
|
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||||
healthcheck:
|
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
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 5
|
retries: 5
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
directus:
|
directus:
|
||||||
image: directus/directus:10
|
image: directus/directus:11
|
||||||
volumes:
|
volumes:
|
||||||
- directus-uploads:/directus/uploads
|
- directus-uploads:/directus/uploads
|
||||||
- directus-extensions:/directus/extensions
|
- directus-extensions:/directus/extensions
|
||||||
|
- directus-templates:/directus/templates
|
||||||
environment:
|
environment:
|
||||||
- SERVICE_FQDN_DIRECTUS_8055
|
- SERVICE_FQDN_DIRECTUS_8055
|
||||||
- KEY=$SERVICE_BASE64_64_KEY
|
- KEY=$SERVICE_BASE64_64_KEY
|
||||||
@@ -37,6 +38,7 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
postgresql:
|
postgresql:
|
||||||
image: postgis/postgis:16-3.4-alpine
|
image: postgis/postgis:16-3.4-alpine
|
||||||
|
platform: linux/amd64
|
||||||
volumes:
|
volumes:
|
||||||
- directus-postgresql-data:/var/lib/postgresql/data
|
- directus-postgresql-data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
@@ -6,11 +6,12 @@
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
directus:
|
directus:
|
||||||
image: directus/directus:10
|
image: directus/directus:11
|
||||||
volumes:
|
volumes:
|
||||||
- directus-uploads:/directus/uploads
|
|
||||||
- directus-database:/directus/database
|
- directus-database:/directus/database
|
||||||
|
- directus-uploads:/directus/uploads
|
||||||
- directus-extensions:/directus/extensions
|
- directus-extensions:/directus/extensions
|
||||||
|
- directus-templates:/directus/templates
|
||||||
environment:
|
environment:
|
||||||
- SERVICE_FQDN_DIRECTUS_8055
|
- SERVICE_FQDN_DIRECTUS_8055
|
||||||
- KEY=$SERVICE_BASE64_64_KEY
|
- KEY=$SERVICE_BASE64_64_KEY
|
||||||
|
|||||||
32
templates/compose/dozzle-with-auth.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# ignore: true
|
||||||
|
# documentation: https://dozzle.dev/
|
||||||
|
# slogan: Dozzle is a simple and lightweight web UI for Docker logs.
|
||||||
|
# tags: dozzle,docker,logs,web-ui
|
||||||
|
# logo: svgs/dozzle.svg
|
||||||
|
# port: 8080
|
||||||
|
|
||||||
|
services:
|
||||||
|
dozzle:
|
||||||
|
image: amir20/dozzle:latest
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_DOZZLE_8080
|
||||||
|
- DOZZLE_AUTH_PROVIDER=simple
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- type: bind
|
||||||
|
source: /data/users.yml
|
||||||
|
target: /data/users.yml
|
||||||
|
content: |
|
||||||
|
users:
|
||||||
|
# "admin" here is username
|
||||||
|
admin:
|
||||||
|
name: "Admin"
|
||||||
|
# Just sha-256 which can be computed with "echo -n password | shasum -a 256"
|
||||||
|
password: "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"
|
||||||
|
email: me@email.net
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "/dozzle", "healthcheck"]
|
||||||
|
interval: 3s
|
||||||
|
timeout: 30s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
19
templates/compose/dozzle.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# documentation: https://dozzle.dev/guide/getting-started#running-with-docker
|
||||||
|
# slogan: Dozzle is a simple and lightweight web UI for Docker logs.
|
||||||
|
# tags: dozzle,docker,logs,web-ui
|
||||||
|
# logo: svgs/dozzle.svg
|
||||||
|
# port: 8080
|
||||||
|
|
||||||
|
services:
|
||||||
|
dozzle:
|
||||||
|
image: amir20/dozzle:latest
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_DOZZLE_8080
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "/dozzle", "healthcheck"]
|
||||||
|
interval: 3s
|
||||||
|
timeout: 30s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
35
templates/compose/easyappointments.yaml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# documentation: https://easyappointments.org/
|
||||||
|
# slogan: Schedule Anything. Let's start with easy! Get the best free online appointment scheduler on your server, today.
|
||||||
|
# tags: calendar, scheduling, database
|
||||||
|
# logo: svgs/easyappointments.png
|
||||||
|
# port: 80
|
||||||
|
|
||||||
|
services:
|
||||||
|
easyappointments:
|
||||||
|
image: alextselegidis/easyappointments:latest
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_EASYAPPOINTMENTS_80
|
||||||
|
- BASE_URL=${SERVICE_FQDN_EASYAPPOINTMENTS}
|
||||||
|
- DB_HOST=mysql
|
||||||
|
- DB_NAME=easyappointments
|
||||||
|
- DB_USERNAME=root
|
||||||
|
- DB_PASSWORD=${SERVICE_PASSWORD_EASYAPPOINTMENTS}
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://127.0.0.1"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 30
|
||||||
|
mysql:
|
||||||
|
image: mysql:8
|
||||||
|
volumes:
|
||||||
|
- easyappointments-mysql-data:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_EASYAPPOINTMENTS}
|
||||||
|
- MYSQL_DATABASE=easyappointments
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
50
templates/compose/forgejo-with-mariadb.yaml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# documentation: https://forgejo.org/docs
|
||||||
|
# slogan: Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.
|
||||||
|
# tags: version control, collaboration, code, hosting, lightweight, mariadb
|
||||||
|
# logo: svgs/forgejo.svg
|
||||||
|
# port: 3000
|
||||||
|
|
||||||
|
services:
|
||||||
|
forgejo:
|
||||||
|
image: codeberg.org/forgejo/forgejo:8
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_FORGEJO_3000
|
||||||
|
- FORGEJO__server__ROOT_URL=${SERVICE_FQDN_FORGEJO_3000}
|
||||||
|
- FORGEJO__migrations__ALLOWED_DOMAINS=${FORGEJO__migrations__ALLOWED_DOMAINS}
|
||||||
|
- FORGEJO__migrations__ALLOW_LOCALNETWORKS=${FORGEJO__migrations__ALLOW_LOCALNETWORKS-false}
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- FORGEJO__database__DB_TYPE=mysql
|
||||||
|
- FORGEJO__database__HOST=mariadb
|
||||||
|
- FORGEJO__database__NAME=${MYSQL_DATABASE-forgejo}
|
||||||
|
- FORGEJO__database__USER=$SERVICE_USER_MYSQL
|
||||||
|
- FORGEJO__database__PASSWD=$SERVICE_PASSWORD_MYSQL
|
||||||
|
volumes:
|
||||||
|
- forgejo-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- 22222:22
|
||||||
|
depends_on:
|
||||||
|
mariadb:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
|
||||||
|
mariadb:
|
||||||
|
image: mariadb:11
|
||||||
|
volumes:
|
||||||
|
- forgejo-mariadb-data:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
- MYSQL_USER=${SERVICE_USER_MYSQL}
|
||||||
|
- MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL}
|
||||||
|
- MYSQL_DATABASE=${MYSQL_DATABASE}
|
||||||
|
- MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
50
templates/compose/forgejo-with-mysql.yaml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# documentation: https://forgejo.org/docs
|
||||||
|
# slogan: Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.
|
||||||
|
# tags: version control, collaboration, code, hosting, lightweight, mysql
|
||||||
|
# logo: svgs/forgejo.svg
|
||||||
|
# port: 3000
|
||||||
|
|
||||||
|
services:
|
||||||
|
forgejo:
|
||||||
|
image: codeberg.org/forgejo/forgejo:8
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_FORGEJO_3000
|
||||||
|
- FORGEJO__server__ROOT_URL=${SERVICE_FQDN_FORGEJO_3000}
|
||||||
|
- FORGEJO__migrations__ALLOWED_DOMAINS=${FORGEJO__migrations__ALLOWED_DOMAINS}
|
||||||
|
- FORGEJO__migrations__ALLOW_LOCALNETWORKS=${FORGEJO__migrations__ALLOW_LOCALNETWORKS-false}
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- FORGEJO__database__DB_TYPE=mysql
|
||||||
|
- FORGEJO__database__HOST=mysql
|
||||||
|
- FORGEJO__database__NAME=${MYSQL_DATABASE-forgejo}
|
||||||
|
- FORGEJO__database__USER=$SERVICE_USER_MYSQL
|
||||||
|
- FORGEJO__database__PASSWD=$SERVICE_PASSWORD_MYSQL
|
||||||
|
volumes:
|
||||||
|
- forgejo-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- 22222:22
|
||||||
|
depends_on:
|
||||||
|
mysql:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
image: mysql:8
|
||||||
|
volumes:
|
||||||
|
- forgejo-mysql-data:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
- MYSQL_USER=${SERVICE_USER_MYSQL}
|
||||||
|
- MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL}
|
||||||
|
- MYSQL_DATABASE=${MYSQL_DATABASE}
|
||||||
|
- MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
49
templates/compose/forgejo-with-postgresql.yaml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# documentation: https://forgejo.org/docs
|
||||||
|
# slogan: Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.
|
||||||
|
# tags: version control, collaboration, code, hosting, lightweight, postgresql
|
||||||
|
# logo: svgs/forgejo.svg
|
||||||
|
# port: 3000
|
||||||
|
|
||||||
|
services:
|
||||||
|
forgejo:
|
||||||
|
image: codeberg.org/forgejo/forgejo:8
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_FORGEJO_3000
|
||||||
|
- FORGEJO__server__ROOT_URL=${SERVICE_FQDN_FORGEJO_3000}
|
||||||
|
- FORGEJO__migrations__ALLOWED_DOMAINS=${FORGEJO__migrations__ALLOWED_DOMAINS}
|
||||||
|
- FORGEJO__migrations__ALLOW_LOCALNETWORKS=${FORGEJO__migrations__ALLOW_LOCALNETWORKS-false}
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- FORGEJO__database__DB_TYPE=postgres
|
||||||
|
- FORGEJO__database__HOST=postgresql
|
||||||
|
- FORGEJO__database__NAME=${POSTGRESQL_DATABASE-forgejo}
|
||||||
|
- FORGEJO__database__USER=$SERVICE_USER_POSTGRESQL
|
||||||
|
- FORGEJO__database__PASSWD=$SERVICE_PASSWORD_POSTGRESQL
|
||||||
|
volumes:
|
||||||
|
- forgejo-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- 22222:22
|
||||||
|
depends_on:
|
||||||
|
postgresql:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
volumes:
|
||||||
|
- forgejo-postgresql-data:/var/lib/postgresql/data
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=${SERVICE_USER_POSTGRESQL}
|
||||||
|
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
|
||||||
|
- POSTGRES_DB=${POSTGRESQL_DATABASE}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
136
templates/compose/forgejo-with-runner-with-mariadb.yaml
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# documentation: https://forgejo.org/docs
|
||||||
|
# slogan: Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.
|
||||||
|
# tags: version control, collaboration, code, hosting, lightweight, runner, mariadb, actions, cicd, ci
|
||||||
|
# logo: svgs/forgejo.svg
|
||||||
|
# port: 3000
|
||||||
|
|
||||||
|
services:
|
||||||
|
forgejo:
|
||||||
|
image: codeberg.org/forgejo/forgejo:8
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_FORGEJO_3000
|
||||||
|
- FORGEJO__server__ROOT_URL=${SERVICE_FQDN_FORGEJO_3000}
|
||||||
|
- FORGEJO__migrations__ALLOWED_DOMAINS=${FORGEJO__migrations__ALLOWED_DOMAINS}
|
||||||
|
- FORGEJO__migrations__ALLOW_LOCALNETWORKS=${FORGEJO__migrations__ALLOW_LOCALNETWORKS-false}
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- FORGEJO__database__DB_TYPE=mysql
|
||||||
|
- FORGEJO__database__HOST=mariadb
|
||||||
|
- FORGEJO__database__NAME=${MYSQL_DATABASE-forgejo}
|
||||||
|
- FORGEJO__database__USER=$SERVICE_USER_MYSQL
|
||||||
|
- FORGEJO__database__PASSWD=$SERVICE_PASSWORD_MYSQL
|
||||||
|
- RUNNER_SHARED_SECRET=${RUNNER_SHARED_SECRET-0000000000000000000000000000000000000000}
|
||||||
|
- FORGEJO__repository__ENABLE_PUSH_CREATE_USER=true
|
||||||
|
- FORGEJO__repository__DEFAULT_PUSH_CREATE_PRIVATE=false
|
||||||
|
- FORGEJO__repository__DEFAULT_REPO_UNITS=repo.code,repo.actions
|
||||||
|
volumes:
|
||||||
|
- forgejo-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- 22222:22
|
||||||
|
depends_on:
|
||||||
|
mariadb:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
command: >-
|
||||||
|
bash -c '
|
||||||
|
/bin/s6-svscan /etc/s6 &
|
||||||
|
sleep 10 ;
|
||||||
|
su -c "forgejo forgejo-cli actions register --secret ${RUNNER_SHARED_SECRET}" git ;
|
||||||
|
sleep infinity
|
||||||
|
'
|
||||||
|
|
||||||
|
mariadb:
|
||||||
|
image: mariadb:11
|
||||||
|
volumes:
|
||||||
|
- forgejo-mariadb-data:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
- MYSQL_USER=${SERVICE_USER_MYSQL}
|
||||||
|
- MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL}
|
||||||
|
- MYSQL_DATABASE=${MYSQL_DATABASE}
|
||||||
|
- MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
docker-in-docker:
|
||||||
|
image: docker:dind
|
||||||
|
hostname: docker
|
||||||
|
privileged: true
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "pgrep", "dockerd"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 30s
|
||||||
|
retries: 10
|
||||||
|
environment:
|
||||||
|
DOCKER_TLS_CERTDIR: /certs
|
||||||
|
DOCKER_HOST: docker-in-docker
|
||||||
|
volumes:
|
||||||
|
- forgejo-did-certs:/certs
|
||||||
|
|
||||||
|
runner-register:
|
||||||
|
image: code.forgejo.org/forgejo/runner:3.5.0
|
||||||
|
restart: 'no'
|
||||||
|
links:
|
||||||
|
- docker-in-docker
|
||||||
|
- forgejo
|
||||||
|
environment:
|
||||||
|
- DOCKER_HOST=tcp://docker-in-docker:2376
|
||||||
|
- RUNNER_SHARED_SECRET=${RUNNER_SHARED_SECRET}
|
||||||
|
volumes:
|
||||||
|
- forgejo-runner-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
healthcheck:
|
||||||
|
disable: true
|
||||||
|
user: 0:0
|
||||||
|
command: >-
|
||||||
|
bash -ec '
|
||||||
|
while : ; do
|
||||||
|
forgejo-runner create-runner-file --connect --instance http://forgejo:3000 --name runner --secret ${RUNNER_SHARED_SECRET} && break ;
|
||||||
|
sleep 1 ;
|
||||||
|
done ;
|
||||||
|
sed -i -e "s|\"labels\": null|\"labels\": [\"docker:docker://node:20-bookworm\", \"ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04\"]|" .runner ;
|
||||||
|
forgejo-runner generate-config > config.yml ;
|
||||||
|
sed -i -e "s|network: .*|network: host|" config.yml ;
|
||||||
|
sed -i -e "s|^ envs:$$| envs:\n DOCKER_HOST: tcp://docker:2376\n DOCKER_TLS_VERIFY: 1\n DOCKER_CERT_PATH: /certs/client|" config.yml ;
|
||||||
|
sed -i -e "s|^ options:| options: -v /certs/client:/certs/client|" config.yml ;
|
||||||
|
sed -i -e "s| valid_volumes: \[\]$$| valid_volumes:\n - /certs/client|" config.yml ;
|
||||||
|
chown -R 1000:1000 /data ;
|
||||||
|
exit 0
|
||||||
|
'
|
||||||
|
|
||||||
|
runner:
|
||||||
|
image: code.forgejo.org/forgejo/runner:3.5.0
|
||||||
|
links:
|
||||||
|
- docker-in-docker
|
||||||
|
- forgejo
|
||||||
|
depends_on:
|
||||||
|
docker-in-docker:
|
||||||
|
condition: service_started
|
||||||
|
environment:
|
||||||
|
- DOCKER_HOST=tcp://docker:2376
|
||||||
|
- DOCKER_CERT_PATH=/certs/client
|
||||||
|
- DOCKER_TLS_VERIFY=1
|
||||||
|
user: 1000:1000
|
||||||
|
volumes:
|
||||||
|
- forgejo-runner-data:/data
|
||||||
|
- forgejo-did-certs:/certs
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "pgrep", "forgejo-runner"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 30s
|
||||||
|
retries: 10
|
||||||
|
command: >-
|
||||||
|
bash -c '
|
||||||
|
while : ; do test -w .runner && forgejo-runner --config config.yml daemon ; sleep 1 ; done
|
||||||
|
'
|
||||||
136
templates/compose/forgejo-with-runner-with-mysql.yaml
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# documentation: https://forgejo.org/docs
|
||||||
|
# slogan: Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.
|
||||||
|
# tags: version control, collaboration, code, hosting, lightweight, runner, mysql, actions, cicd, ci
|
||||||
|
# logo: svgs/forgejo.svg
|
||||||
|
# port: 3000
|
||||||
|
|
||||||
|
services:
|
||||||
|
forgejo:
|
||||||
|
image: codeberg.org/forgejo/forgejo:8
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_FORGEJO_3000
|
||||||
|
- FORGEJO__server__ROOT_URL=${SERVICE_FQDN_FORGEJO_3000}
|
||||||
|
- FORGEJO__migrations__ALLOWED_DOMAINS=${FORGEJO__migrations__ALLOWED_DOMAINS}
|
||||||
|
- FORGEJO__migrations__ALLOW_LOCALNETWORKS=${FORGEJO__migrations__ALLOW_LOCALNETWORKS-false}
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- FORGEJO__database__DB_TYPE=mysql
|
||||||
|
- FORGEJO__database__HOST=mysql
|
||||||
|
- FORGEJO__database__NAME=${MYSQL_DATABASE-forgejo}
|
||||||
|
- FORGEJO__database__USER=$SERVICE_USER_MYSQL
|
||||||
|
- FORGEJO__database__PASSWD=$SERVICE_PASSWORD_MYSQL
|
||||||
|
- RUNNER_SHARED_SECRET=${RUNNER_SHARED_SECRET-0000000000000000000000000000000000000000}
|
||||||
|
- FORGEJO__repository__ENABLE_PUSH_CREATE_USER=true
|
||||||
|
- FORGEJO__repository__DEFAULT_PUSH_CREATE_PRIVATE=false
|
||||||
|
- FORGEJO__repository__DEFAULT_REPO_UNITS=repo.code,repo.actions
|
||||||
|
volumes:
|
||||||
|
- forgejo-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- 22222:22
|
||||||
|
depends_on:
|
||||||
|
mysql:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
command: >-
|
||||||
|
bash -c '
|
||||||
|
/bin/s6-svscan /etc/s6 &
|
||||||
|
sleep 10 ;
|
||||||
|
su -c "forgejo forgejo-cli actions register --secret ${RUNNER_SHARED_SECRET}" git ;
|
||||||
|
sleep infinity
|
||||||
|
'
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
image: mysql:8
|
||||||
|
volumes:
|
||||||
|
- forgejo-mysql-data:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
- MYSQL_USER=${SERVICE_USER_MYSQL}
|
||||||
|
- MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL}
|
||||||
|
- MYSQL_DATABASE=${MYSQL_DATABASE}
|
||||||
|
- MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
docker-in-docker:
|
||||||
|
image: docker:dind
|
||||||
|
hostname: docker
|
||||||
|
privileged: true
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "pgrep", "dockerd"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 30s
|
||||||
|
retries: 10
|
||||||
|
environment:
|
||||||
|
DOCKER_TLS_CERTDIR: /certs
|
||||||
|
DOCKER_HOST: docker-in-docker
|
||||||
|
volumes:
|
||||||
|
- forgejo-did-certs:/certs
|
||||||
|
|
||||||
|
runner-register:
|
||||||
|
image: code.forgejo.org/forgejo/runner:3.5.0
|
||||||
|
restart: 'no'
|
||||||
|
links:
|
||||||
|
- docker-in-docker
|
||||||
|
- forgejo
|
||||||
|
environment:
|
||||||
|
- DOCKER_HOST=tcp://docker-in-docker:2376
|
||||||
|
- RUNNER_SHARED_SECRET=${RUNNER_SHARED_SECRET}
|
||||||
|
volumes:
|
||||||
|
- forgejo-runner-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
healthcheck:
|
||||||
|
disable: true
|
||||||
|
user: 0:0
|
||||||
|
command: >-
|
||||||
|
bash -ec '
|
||||||
|
while : ; do
|
||||||
|
forgejo-runner create-runner-file --connect --instance http://forgejo:3000 --name runner --secret ${RUNNER_SHARED_SECRET} && break ;
|
||||||
|
sleep 1 ;
|
||||||
|
done ;
|
||||||
|
sed -i -e "s|\"labels\": null|\"labels\": [\"docker:docker://node:20-bookworm\", \"ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04\"]|" .runner ;
|
||||||
|
forgejo-runner generate-config > config.yml ;
|
||||||
|
sed -i -e "s|network: .*|network: host|" config.yml ;
|
||||||
|
sed -i -e "s|^ envs:$$| envs:\n DOCKER_HOST: tcp://docker:2376\n DOCKER_TLS_VERIFY: 1\n DOCKER_CERT_PATH: /certs/client|" config.yml ;
|
||||||
|
sed -i -e "s|^ options:| options: -v /certs/client:/certs/client|" config.yml ;
|
||||||
|
sed -i -e "s| valid_volumes: \[\]$$| valid_volumes:\n - /certs/client|" config.yml ;
|
||||||
|
chown -R 1000:1000 /data ;
|
||||||
|
exit 0
|
||||||
|
'
|
||||||
|
|
||||||
|
runner:
|
||||||
|
image: code.forgejo.org/forgejo/runner:3.5.0
|
||||||
|
links:
|
||||||
|
- docker-in-docker
|
||||||
|
- forgejo
|
||||||
|
depends_on:
|
||||||
|
docker-in-docker:
|
||||||
|
condition: service_started
|
||||||
|
environment:
|
||||||
|
- DOCKER_HOST=tcp://docker:2376
|
||||||
|
- DOCKER_CERT_PATH=/certs/client
|
||||||
|
- DOCKER_TLS_VERIFY=1
|
||||||
|
user: 1000:1000
|
||||||
|
volumes:
|
||||||
|
- forgejo-runner-data:/data
|
||||||
|
- forgejo-did-certs:/certs
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "pgrep", "forgejo-runner"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 30s
|
||||||
|
retries: 10
|
||||||
|
command: >-
|
||||||
|
bash -c '
|
||||||
|
while : ; do test -w .runner && forgejo-runner --config config.yml daemon ; sleep 1 ; done
|
||||||
|
'
|
||||||
135
templates/compose/forgejo-with-runner-with-postgresql.yaml
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
# documentation: https://forgejo.org/docs
|
||||||
|
# slogan: Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.
|
||||||
|
# tags: version control, collaboration, code, hosting, lightweight, runner, postresql, actions, cicd, ci
|
||||||
|
# logo: svgs/forgejo.svg
|
||||||
|
# port: 3000
|
||||||
|
|
||||||
|
services:
|
||||||
|
forgejo:
|
||||||
|
image: codeberg.org/forgejo/forgejo:8
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_FORGEJO_3000
|
||||||
|
- FORGEJO__server__ROOT_URL=${SERVICE_FQDN_FORGEJO_3000}
|
||||||
|
- FORGEJO__migrations__ALLOWED_DOMAINS=${FORGEJO__migrations__ALLOWED_DOMAINS}
|
||||||
|
- FORGEJO__migrations__ALLOW_LOCALNETWORKS=${FORGEJO__migrations__ALLOW_LOCALNETWORKS-false}
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- FORGEJO__database__DB_TYPE=postgres
|
||||||
|
- FORGEJO__database__HOST=postgresql
|
||||||
|
- FORGEJO__database__NAME=${POSTGRESQL_DATABASE-forgejo}
|
||||||
|
- FORGEJO__database__USER=$SERVICE_USER_POSTGRESQL
|
||||||
|
- FORGEJO__database__PASSWD=$SERVICE_PASSWORD_POSTGRESQL
|
||||||
|
- RUNNER_SHARED_SECRET=${RUNNER_SHARED_SECRET-0000000000000000000000000000000000000000}
|
||||||
|
- FORGEJO__repository__ENABLE_PUSH_CREATE_USER=true
|
||||||
|
- FORGEJO__repository__DEFAULT_PUSH_CREATE_PRIVATE=false
|
||||||
|
- FORGEJO__repository__DEFAULT_REPO_UNITS=repo.code,repo.actions
|
||||||
|
volumes:
|
||||||
|
- forgejo-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- 22222:22
|
||||||
|
depends_on:
|
||||||
|
postgresql:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
command: >-
|
||||||
|
bash -c '
|
||||||
|
/bin/s6-svscan /etc/s6 &
|
||||||
|
sleep 10 ;
|
||||||
|
su -c "forgejo forgejo-cli actions register --secret ${RUNNER_SHARED_SECRET}" git ;
|
||||||
|
sleep infinity
|
||||||
|
'
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
volumes:
|
||||||
|
- forgejo-postgresql-data:/var/lib/postgresql/data
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=${SERVICE_USER_POSTGRESQL}
|
||||||
|
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
|
||||||
|
- POSTGRES_DB=${POSTGRESQL_DATABASE}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
docker-in-docker:
|
||||||
|
image: docker:dind
|
||||||
|
hostname: docker
|
||||||
|
privileged: true
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "pgrep", "dockerd"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 30s
|
||||||
|
retries: 10
|
||||||
|
environment:
|
||||||
|
DOCKER_TLS_CERTDIR: /certs
|
||||||
|
DOCKER_HOST: docker-in-docker
|
||||||
|
volumes:
|
||||||
|
- forgejo-did-certs:/certs
|
||||||
|
|
||||||
|
runner-register:
|
||||||
|
image: code.forgejo.org/forgejo/runner:3.5.0
|
||||||
|
restart: 'no'
|
||||||
|
links:
|
||||||
|
- docker-in-docker
|
||||||
|
- forgejo
|
||||||
|
environment:
|
||||||
|
- DOCKER_HOST=tcp://docker-in-docker:2376
|
||||||
|
- RUNNER_SHARED_SECRET=${RUNNER_SHARED_SECRET}
|
||||||
|
volumes:
|
||||||
|
- forgejo-runner-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
healthcheck:
|
||||||
|
disable: true
|
||||||
|
user: 0:0
|
||||||
|
command: >-
|
||||||
|
bash -ec '
|
||||||
|
while : ; do
|
||||||
|
forgejo-runner create-runner-file --connect --instance http://forgejo:3000 --name runner --secret ${RUNNER_SHARED_SECRET} && break ;
|
||||||
|
sleep 1 ;
|
||||||
|
done ;
|
||||||
|
sed -i -e "s|\"labels\": null|\"labels\": [\"docker:docker://node:20-bookworm\", \"ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04\"]|" .runner ;
|
||||||
|
forgejo-runner generate-config > config.yml ;
|
||||||
|
sed -i -e "s|network: .*|network: host|" config.yml ;
|
||||||
|
sed -i -e "s|^ envs:$$| envs:\n DOCKER_HOST: tcp://docker:2376\n DOCKER_TLS_VERIFY: 1\n DOCKER_CERT_PATH: /certs/client|" config.yml ;
|
||||||
|
sed -i -e "s|^ options:| options: -v /certs/client:/certs/client|" config.yml ;
|
||||||
|
sed -i -e "s| valid_volumes: \[\]$$| valid_volumes:\n - /certs/client|" config.yml ;
|
||||||
|
chown -R 1000:1000 /data ;
|
||||||
|
exit 0
|
||||||
|
'
|
||||||
|
|
||||||
|
runner:
|
||||||
|
image: code.forgejo.org/forgejo/runner:3.5.0
|
||||||
|
links:
|
||||||
|
- docker-in-docker
|
||||||
|
- forgejo
|
||||||
|
depends_on:
|
||||||
|
docker-in-docker:
|
||||||
|
condition: service_started
|
||||||
|
environment:
|
||||||
|
- DOCKER_HOST=tcp://docker:2376
|
||||||
|
- DOCKER_CERT_PATH=/certs/client
|
||||||
|
- DOCKER_TLS_VERIFY=1
|
||||||
|
user: 1000:1000
|
||||||
|
volumes:
|
||||||
|
- forgejo-runner-data:/data
|
||||||
|
- forgejo-did-certs:/certs
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "pgrep", "forgejo-runner"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 30s
|
||||||
|
retries: 10
|
||||||
|
command: >-
|
||||||
|
bash -c '
|
||||||
|
while : ; do test -w .runner && forgejo-runner --config config.yml daemon ; sleep 1 ; done
|
||||||
|
'
|
||||||
113
templates/compose/forgejo-with-runner.yaml
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# documentation: https://forgejo.org/docs
|
||||||
|
# slogan: Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.
|
||||||
|
# tags: version control, collaboration, code, hosting, lightweight, runner, actions, cicd, ci
|
||||||
|
# logo: svgs/forgejo.svg
|
||||||
|
# port: 3000
|
||||||
|
|
||||||
|
services:
|
||||||
|
forgejo:
|
||||||
|
image: codeberg.org/forgejo/forgejo:8
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_FORGEJO_3000
|
||||||
|
- FORGEJO__server__ROOT_URL=${SERVICE_FQDN_FORGEJO_3000}
|
||||||
|
- FORGEJO__migrations__ALLOWED_DOMAINS=${FORGEJO__migrations__ALLOWED_DOMAINS}
|
||||||
|
- FORGEJO__migrations__ALLOW_LOCALNETWORKS=${FORGEJO__migrations__ALLOW_LOCALNETWORKS:-false}
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- RUNNER_SHARED_SECRET=${RUNNER_SHARED_SECRET-0000000000000000000000000000000000000000}
|
||||||
|
- FORGEJO__repository__ENABLE_PUSH_CREATE_USER=true
|
||||||
|
- FORGEJO__repository__DEFAULT_PUSH_CREATE_PRIVATE=false
|
||||||
|
- FORGEJO__repository__DEFAULT_REPO_UNITS=repo.code,repo.actions
|
||||||
|
volumes:
|
||||||
|
- forgejo-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- 22222:22
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
command: >-
|
||||||
|
bash -c '
|
||||||
|
/bin/s6-svscan /etc/s6 &
|
||||||
|
sleep 10 ;
|
||||||
|
su -c "forgejo forgejo-cli actions register --secret ${RUNNER_SHARED_SECRET}" git ;
|
||||||
|
sleep infinity
|
||||||
|
'
|
||||||
|
|
||||||
|
docker-in-docker:
|
||||||
|
image: docker:dind
|
||||||
|
hostname: docker
|
||||||
|
privileged: true
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "pgrep", "dockerd"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 30s
|
||||||
|
retries: 10
|
||||||
|
environment:
|
||||||
|
DOCKER_TLS_CERTDIR=/certs
|
||||||
|
DOCKER_HOST=docker-in-docker
|
||||||
|
volumes:
|
||||||
|
- forgejo-did-certs:/certs
|
||||||
|
|
||||||
|
runner-register:
|
||||||
|
image: code.forgejo.org/forgejo/runner:3.5.0
|
||||||
|
restart: 'no'
|
||||||
|
links:
|
||||||
|
- docker-in-docker
|
||||||
|
- forgejo
|
||||||
|
environment:
|
||||||
|
- DOCKER_HOST=tcp://docker-in-docker:2376
|
||||||
|
- RUNNER_SHARED_SECRET=${RUNNER_SHARED_SECRET}
|
||||||
|
volumes:
|
||||||
|
- forgejo-runner-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
healthcheck:
|
||||||
|
disable: true
|
||||||
|
user: 0:0
|
||||||
|
command: >-
|
||||||
|
bash -ec '
|
||||||
|
while : ; do
|
||||||
|
forgejo-runner create-runner-file --connect --instance ${SERVICE_FQDN_FORGEJO}:3000 --name runner --secret ${RUNNER_SHARED_SECRET} && break ;
|
||||||
|
sleep 1 ;
|
||||||
|
done ;
|
||||||
|
sed -i -e "s|\"labels\": null|\"labels\": [\"docker:docker://node:20-bookworm\", \"ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04\"]|" .runner ;
|
||||||
|
forgejo-runner generate-config > config.yml ;
|
||||||
|
sed -i -e "s|network: .*|network: host|" config.yml ;
|
||||||
|
sed -i -e "s|^ envs:$$| envs:\n DOCKER_HOST: tcp://docker:2376\n DOCKER_TLS_VERIFY: 1\n DOCKER_CERT_PATH: /certs/client|" config.yml ;
|
||||||
|
sed -i -e "s|^ options:| options: -v /certs/client:/certs/client|" config.yml ;
|
||||||
|
sed -i -e "s| valid_volumes: \[\]$$| valid_volumes:\n - /certs/client|" config.yml ;
|
||||||
|
chown -R 1000:1000 /data ;
|
||||||
|
exit 0
|
||||||
|
'
|
||||||
|
|
||||||
|
runner:
|
||||||
|
image: code.forgejo.org/forgejo/runner:3.5.0
|
||||||
|
links:
|
||||||
|
- docker-in-docker
|
||||||
|
- forgejo
|
||||||
|
depends_on:
|
||||||
|
docker-in-docker:
|
||||||
|
condition: service_started
|
||||||
|
environment:
|
||||||
|
- DOCKER_HOST=tcp://docker:2376
|
||||||
|
- DOCKER_CERT_PATH=/certs/client
|
||||||
|
- DOCKER_TLS_VERIFY=1
|
||||||
|
user: 1000:1000
|
||||||
|
volumes:
|
||||||
|
- forgejo-runner-data:/data
|
||||||
|
- forgejo-did-certs:/certs
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "pgrep", "forgejo-runner"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 30s
|
||||||
|
retries: 10
|
||||||
|
command: >-
|
||||||
|
bash -c '
|
||||||
|
while : ; do test -w .runner && forgejo-runner --config config.yml daemon ; sleep 1 ; done
|
||||||
|
'
|
||||||
27
templates/compose/forgejo.yaml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# documentation: https://forgejo.org/docs
|
||||||
|
# slogan: Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.
|
||||||
|
# tags: version control, collaboration, code, hosting, lightweight
|
||||||
|
# logo: svgs/forgejo.svg
|
||||||
|
# port: 3000
|
||||||
|
|
||||||
|
services:
|
||||||
|
forgejo:
|
||||||
|
image: codeberg.org/forgejo/forgejo:8
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_FORGEJO_3000
|
||||||
|
- FORGEJO__server__ROOT_URL=${SERVICE_FQDN_FORGEJO_3000}
|
||||||
|
- FORGEJO__migrations__ALLOWED_DOMAINS=${FORGEJO__migrations__ALLOWED_DOMAINS}
|
||||||
|
- FORGEJO__migrations__ALLOW_LOCALNETWORKS=${FORGEJO__migrations__ALLOW_LOCALNETWORKS-false}
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
ports:
|
||||||
|
- 22222:22
|
||||||
|
volumes:
|
||||||
|
- forgejo-data:/data
|
||||||
|
- forgejo-timezone:/etc/timezone:ro
|
||||||
|
- forgejo-localtime:/etc/localtime:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
88
templates/compose/getoutline.yaml
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# 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}
|
||||||
|
- FORCE_HTTPS=${FORCE_HTTPS:-true}
|
||||||
|
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
|
||||||