Add service-specific configuration fields and save
them to the database
This commit is contained in:
parent
95baec99dd
commit
ce0f560c44
@ -7,17 +7,34 @@
|
|||||||
class StackForm extends Component
|
class StackForm extends Component
|
||||||
{
|
{
|
||||||
public $service;
|
public $service;
|
||||||
public $isConfigurationRequired = false;
|
public $fields = [];
|
||||||
protected $listeners = ["saveCompose"];
|
protected $listeners = ["saveCompose"];
|
||||||
protected $rules = [
|
public $rules = [
|
||||||
'service.docker_compose_raw' => 'required',
|
'service.docker_compose_raw' => 'required',
|
||||||
'service.docker_compose' => 'required',
|
'service.docker_compose' => 'required',
|
||||||
'service.name' => 'required',
|
'service.name' => 'required',
|
||||||
'service.description' => 'nullable',
|
'service.description' => 'nullable',
|
||||||
];
|
];
|
||||||
public function mount () {
|
public $validationAttributes = [];
|
||||||
if ($this->service->applications->filter(fn($app) => str($app->image)->contains('minio/minio'))->count() > 0) {
|
public function mount()
|
||||||
$this->isConfigurationRequired = true;
|
{
|
||||||
|
$extraFields = $this->service->extraFields();
|
||||||
|
foreach ($extraFields as $serviceName => $fields) {
|
||||||
|
foreach ($fields as $fieldKey => $field) {
|
||||||
|
$key = data_get($field, 'key');
|
||||||
|
$value = data_get($field, 'value');
|
||||||
|
$rules = data_get($field, 'rules');
|
||||||
|
$isPassword = data_get($field, 'isPassword');
|
||||||
|
$this->fields[$key] = [
|
||||||
|
"serviceName" => $serviceName,
|
||||||
|
"key" => $key,
|
||||||
|
"name" => $fieldKey,
|
||||||
|
"value" => $value,
|
||||||
|
"isPassword" => $isPassword,
|
||||||
|
];
|
||||||
|
$this->rules["fields.$key.value"] = $rules;
|
||||||
|
$this->validationAttributes["fields.$key.value"] = $fieldKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public function saveCompose($raw)
|
public function saveCompose($raw)
|
||||||
@ -32,6 +49,7 @@ public function submit()
|
|||||||
try {
|
try {
|
||||||
$this->validate();
|
$this->validate();
|
||||||
$this->service->save();
|
$this->service->save();
|
||||||
|
$this->service->saveExtraFields($this->fields);
|
||||||
$this->service->parse();
|
$this->service->parse();
|
||||||
$this->service->refresh();
|
$this->service->refresh();
|
||||||
$this->service->saveComposeConfigs();
|
$this->service->saveComposeConfigs();
|
||||||
|
@ -45,7 +45,168 @@ public function type()
|
|||||||
{
|
{
|
||||||
return 'service';
|
return 'service';
|
||||||
}
|
}
|
||||||
|
public function extraFields()
|
||||||
|
{
|
||||||
|
$fields = collect([]);
|
||||||
|
$applications = $this->applications()->get();
|
||||||
|
foreach ($applications as $application) {
|
||||||
|
$image = str($application->image)->before(':')->value();
|
||||||
|
switch ($image) {
|
||||||
|
case str($image)->contains('minio'):
|
||||||
|
$console_url = $this->environment_variables()->where('key', 'MINIO_BROWSER_REDIRECT_URL')->first();
|
||||||
|
$s3_api_url = $this->environment_variables()->where('key', 'MINIO_SERVER_URL')->first();
|
||||||
|
$admin_user = $this->environment_variables()->where('key', 'SERVICE_USER_MINIO')->first();
|
||||||
|
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_MINIO')->first();
|
||||||
|
$fields->put('MinIO', [
|
||||||
|
'Console URL' => [
|
||||||
|
'key' => data_get($console_url, 'key'),
|
||||||
|
'value' => data_get($console_url, 'value'),
|
||||||
|
'rules' => 'required|url',
|
||||||
|
],
|
||||||
|
'S3 API URL' => [
|
||||||
|
'key' => data_get($s3_api_url, 'key'),
|
||||||
|
'value' => data_get($s3_api_url, 'value'),
|
||||||
|
'rules' => 'required|url',
|
||||||
|
],
|
||||||
|
'Admin User' => [
|
||||||
|
'key' => data_get($admin_user, 'key'),
|
||||||
|
'value' => data_get($admin_user, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
],
|
||||||
|
'Admin Password' => [
|
||||||
|
'key' => data_get($admin_password, 'key'),
|
||||||
|
'value' => data_get($admin_password, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
'isPassword' => true,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$databases = $this->databases()->get();
|
||||||
|
|
||||||
|
foreach ($databases as $database) {
|
||||||
|
$image = str($database->image)->before(':')->value();
|
||||||
|
switch ($image) {
|
||||||
|
case str($image)->contains('postgres'):
|
||||||
|
$userVariables = ['SERVICE_USER_POSTGRES', 'SERVICE_USER_POSTGRESQL'];
|
||||||
|
$passwordVariables = ['SERVICE_PASSWORD_POSTGRES', 'SERVICE_PASSWORD_POSTGRESQL'];
|
||||||
|
$dbNameVariables = ['POSTGRESQL_DATABASE', 'POSTGRES_DB'];
|
||||||
|
$postgres_user = $this->environment_variables()->whereIn('key', $userVariables)->first();
|
||||||
|
$postgres_password = $this->environment_variables()->whereIn('key', $passwordVariables)->first();
|
||||||
|
$postgres_db_name = $this->environment_variables()->whereIn('key', $dbNameVariables)->first();
|
||||||
|
$fields->put('PostgreSQL', [
|
||||||
|
'User' => [
|
||||||
|
'key' => data_get($postgres_user, 'key'),
|
||||||
|
'value' => data_get($postgres_user, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
],
|
||||||
|
'Password' => [
|
||||||
|
'key' => data_get($postgres_password, 'key'),
|
||||||
|
'value' => data_get($postgres_password, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
'isPassword' => true,
|
||||||
|
],
|
||||||
|
'Database Name' => [
|
||||||
|
'key' => data_get($postgres_db_name, 'key'),
|
||||||
|
'value' => data_get($postgres_db_name, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
case str($image)->contains('mysql'):
|
||||||
|
$userVariables = ['SERVICE_USER_MYSQL', 'SERVICE_USER_WORDPRESS'];
|
||||||
|
$passwordVariables = ['SERVICE_PASSWORD_MYSQL', 'SERVICE_PASSWORD_WORDPRESS'];
|
||||||
|
$rootPasswordVariables = ['SERVICE_PASSWORD_MYSQLROOT', 'SERVICE_PASSWORD_ROOT'];
|
||||||
|
$dbNameVariables = ['MYSQL_DATABASE'];
|
||||||
|
$mysql_user = $this->environment_variables()->whereIn('key', $userVariables)->first();
|
||||||
|
$mysql_password = $this->environment_variables()->whereIn('key', $passwordVariables)->first();
|
||||||
|
$mysql_root_password = $this->environment_variables()->whereIn('key', $rootPasswordVariables)->first();
|
||||||
|
$mysql_db_name = $this->environment_variables()->whereIn('key', $dbNameVariables)->first();
|
||||||
|
$fields->put('MySQL', [
|
||||||
|
'User' => [
|
||||||
|
'key' => data_get($mysql_user, 'key'),
|
||||||
|
'value' => data_get($mysql_user, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
],
|
||||||
|
'Password' => [
|
||||||
|
'key' => data_get($mysql_password, 'key'),
|
||||||
|
'value' => data_get($mysql_password, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
'isPassword' => true,
|
||||||
|
],
|
||||||
|
'Root Password' => [
|
||||||
|
'key' => data_get($mysql_root_password, 'key'),
|
||||||
|
'value' => data_get($mysql_root_password, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
'isPassword' => true,
|
||||||
|
],
|
||||||
|
'Database Name' => [
|
||||||
|
'key' => data_get($mysql_db_name, 'key'),
|
||||||
|
'value' => data_get($mysql_db_name, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
case str($image)->contains('mariadb'):
|
||||||
|
$userVariables = ['SERVICE_USER_MARIADB', 'SERVICE_USER_WORDPRESS', '_APP_DB_USER'];
|
||||||
|
$passwordVariables = ['SERVICE_PASSWORD_MARIADB', 'SERVICE_PASSWORD_WORDPRESS', '_APP_DB_PASS'];
|
||||||
|
$rootPasswordVariables = ['SERVICE_PASSWORD_MARIADBROOT', 'SERVICE_PASSWORD_ROOT', '_APP_DB_ROOT_PASS'];
|
||||||
|
$dbNameVariables = ['SERVICE_DATABASE_MARIADB', 'SERVICE_DATABASE_WORDPRESS', '_APP_DB_SCHEMA'];
|
||||||
|
$mariadb_user = $this->environment_variables()->whereIn('key', $userVariables)->first();
|
||||||
|
$mariadb_password = $this->environment_variables()->whereIn('key', $passwordVariables)->first();
|
||||||
|
$mariadb_root_password = $this->environment_variables()->whereIn('key', $rootPasswordVariables)->first();
|
||||||
|
$mariadb_db_name = $this->environment_variables()->whereIn('key', $dbNameVariables)->first();
|
||||||
|
$fields->put('MariaDB', [
|
||||||
|
'User' => [
|
||||||
|
'key' => data_get($mariadb_user, 'key'),
|
||||||
|
'value' => data_get($mariadb_user, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
],
|
||||||
|
'Password' => [
|
||||||
|
'key' => data_get($mariadb_password, 'key'),
|
||||||
|
'value' => data_get($mariadb_password, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
'isPassword' => true,
|
||||||
|
],
|
||||||
|
'Root Password' => [
|
||||||
|
'key' => data_get($mariadb_root_password, 'key'),
|
||||||
|
'value' => data_get($mariadb_root_password, 'value'),
|
||||||
|
'rules' => 'required',
|
||||||
|
'isPassword' => true,
|
||||||
|
],
|
||||||
|
'Database Name' => [
|
||||||
|
'key' => data_get($mariadb_db_name, 'key'),
|
||||||
|
'value' => data_get($mariadb_db_name, 'value'),
|
||||||
|
'rules' => data_get($mariadb_db_name, 'value') && 'required',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
public function saveExtraFields($fields)
|
||||||
|
{
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$key = data_get($field, 'key');
|
||||||
|
$value = data_get($field, 'value');
|
||||||
|
$found = $this->environment_variables()->where('key', $key)->first();
|
||||||
|
if ($found) {
|
||||||
|
$found->value = $value;
|
||||||
|
$found->save();
|
||||||
|
} else {
|
||||||
|
$this->environment_variables()->create([
|
||||||
|
'key' => $key,
|
||||||
|
'value' => $value,
|
||||||
|
'is_build_time' => false,
|
||||||
|
'service_id' => $this->id,
|
||||||
|
'is_preview' => false,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public function documentation()
|
public function documentation()
|
||||||
{
|
{
|
||||||
$services = getServiceTemplates();
|
$services = getServiceTemplates();
|
||||||
@ -257,7 +418,7 @@ public function parse(bool $isNew = false): Collection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$networks = collect();
|
$networks = collect();
|
||||||
foreach ($serviceNetworks as $key =>$serviceNetwork) {
|
foreach ($serviceNetworks as $key => $serviceNetwork) {
|
||||||
if (gettype($serviceNetwork) === 'string') {
|
if (gettype($serviceNetwork) === 'string') {
|
||||||
// networks:
|
// networks:
|
||||||
// - appwrite
|
// - appwrite
|
||||||
@ -268,7 +429,7 @@ public function parse(bool $isNew = false): Collection
|
|||||||
// ipv4_address: 192.168.203.254
|
// ipv4_address: 192.168.203.254
|
||||||
// $networks->put($serviceNetwork, null);
|
// $networks->put($serviceNetwork, null);
|
||||||
ray($key);
|
ray($key);
|
||||||
$networks->put($key,$serviceNetwork);
|
$networks->put($key, $serviceNetwork);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($definedNetwork as $key => $network) {
|
foreach ($definedNetwork as $key => $network) {
|
||||||
@ -564,14 +725,20 @@ public function parse(bool $isNew = false): Collection
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add labels to the service
|
// Add labels to the service
|
||||||
|
if (!$isDatabase) {
|
||||||
|
if ($savedService->serviceType()) {
|
||||||
|
$fqdns = generateServiceSpecificFqdns($savedService, forTraefik: true);
|
||||||
|
} else {
|
||||||
$fqdns = collect(data_get($savedService, 'fqdns'));
|
$fqdns = collect(data_get($savedService, 'fqdns'));
|
||||||
|
}
|
||||||
$defaultLabels = defaultLabels($this->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id);
|
$defaultLabels = defaultLabels($this->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id);
|
||||||
$serviceLabels = $serviceLabels->merge($defaultLabels);
|
$serviceLabels = $serviceLabels->merge($defaultLabels);
|
||||||
if (!$isDatabase && $fqdns->count() > 0) {
|
if ($fqdns->count() > 0) {
|
||||||
if ($fqdns) {
|
if ($fqdns) {
|
||||||
$serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($this->uuid, $fqdns, true));
|
$serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($this->uuid, $fqdns, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
data_set($service, 'labels', $serviceLabels->toArray());
|
data_set($service, 'labels', $serviceLabels->toArray());
|
||||||
data_forget($service, 'is_database');
|
data_forget($service, 'is_database');
|
||||||
data_set($service, 'restart', RESTART_MODE);
|
data_set($service, 'restart', RESTART_MODE);
|
||||||
|
@ -22,6 +22,16 @@ public function type()
|
|||||||
{
|
{
|
||||||
return 'service';
|
return 'service';
|
||||||
}
|
}
|
||||||
|
public function serviceType()
|
||||||
|
{
|
||||||
|
$found = str(collect(SPECIFIC_SERVICES)->filter(function ($service) {
|
||||||
|
return str($this->image)->before(':')->value() === $service;
|
||||||
|
})->first());
|
||||||
|
if ($found->isNotEmpty()) {
|
||||||
|
return $found;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
public function service()
|
public function service()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Service::class);
|
return $this->belongsTo(Service::class);
|
||||||
|
@ -29,7 +29,6 @@ public function databaseType()
|
|||||||
return "standalone-$image";
|
return "standalone-$image";
|
||||||
}
|
}
|
||||||
public function getServiceDatabaseUrl() {
|
public function getServiceDatabaseUrl() {
|
||||||
// $type = $this->databaseType();
|
|
||||||
$port = $this->public_port;
|
$port = $this->public_port;
|
||||||
$realIp = $this->service->server->ip;
|
$realIp = $this->service->server->ip;
|
||||||
if ($realIp === 'host.docker.internal' || isDev()) {
|
if ($realIp === 'host.docker.internal' || isDev()) {
|
||||||
|
@ -16,6 +16,11 @@ public function __construct(public Service $service)
|
|||||||
{
|
{
|
||||||
$this->links = collect([]);
|
$this->links = collect([]);
|
||||||
$service->applications()->get()->map(function ($application) {
|
$service->applications()->get()->map(function ($application) {
|
||||||
|
$type = $application->serviceType();
|
||||||
|
if ($type) {
|
||||||
|
$links = generateServiceSpecificFqdns($application, false);
|
||||||
|
$this->links = $this->links->merge($links);
|
||||||
|
} else {
|
||||||
if ($application->fqdn) {
|
if ($application->fqdn) {
|
||||||
$fqdns = collect(Str::of($application->fqdn)->explode(','));
|
$fqdns = collect(Str::of($application->fqdn)->explode(','));
|
||||||
$fqdns->map(function ($fqdn) {
|
$fqdns->map(function ($fqdn) {
|
||||||
@ -30,9 +35,10 @@ public function __construct(public Service $service)
|
|||||||
} else {
|
} else {
|
||||||
$hostPort = $port;
|
$hostPort = $port;
|
||||||
}
|
}
|
||||||
$this->links->push(base_url(withPort:false) . ":{$hostPort}");
|
$this->links->push(base_url(withPort: false) . ":{$hostPort}");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,3 +23,6 @@
|
|||||||
'influxdb',
|
'influxdb',
|
||||||
'clickhouse/clickhouse-server'
|
'clickhouse/clickhouse-server'
|
||||||
];
|
];
|
||||||
|
const SPECIFIC_SERVICES = [
|
||||||
|
'quay.io/minio/minio',
|
||||||
|
];
|
||||||
|
@ -144,6 +144,39 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica
|
|||||||
}
|
}
|
||||||
return $labels;
|
return $labels;
|
||||||
}
|
}
|
||||||
|
function generateServiceSpecificFqdns($service, $forTraefik = false)
|
||||||
|
{
|
||||||
|
$variables = collect($service->service->environment_variables);
|
||||||
|
$type = $service->serviceType();
|
||||||
|
$payload = collect([]);
|
||||||
|
switch ($type) {
|
||||||
|
case $type->contains('minio'):
|
||||||
|
$MINIO_BROWSER_REDIRECT_URL = $variables->where('key', 'MINIO_BROWSER_REDIRECT_URL')->first();
|
||||||
|
if (is_null($MINIO_BROWSER_REDIRECT_URL->value)) {
|
||||||
|
$MINIO_BROWSER_REDIRECT_URL->update([
|
||||||
|
"value" => generateFqdn($service->service->server, 'console-' . $service->uuid)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$MINIO_SERVER_URL = $variables->where('key', 'MINIO_SERVER_URL')->first();
|
||||||
|
if (is_null($MINIO_SERVER_URL->value)) {
|
||||||
|
$MINIO_SERVER_URL->update([
|
||||||
|
"value" => generateFqdn($service->service->server, 'minio-' . $service->uuid)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if ($forTraefik) {
|
||||||
|
$payload = collect([
|
||||||
|
$MINIO_BROWSER_REDIRECT_URL->value . ':9001',
|
||||||
|
$MINIO_SERVER_URL->value . ':9000',
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$payload = collect([
|
||||||
|
$MINIO_BROWSER_REDIRECT_URL->value,
|
||||||
|
$MINIO_SERVER_URL->value,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $payload;
|
||||||
|
}
|
||||||
function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_https_enabled, $onlyPort = null)
|
function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_https_enabled, $onlyPort = null)
|
||||||
{
|
{
|
||||||
$labels = collect([]);
|
$labels = collect([]);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
href="{{ route('project.service', $parameters) }}">
|
href="{{ route('project.service', $parameters) }}">
|
||||||
<button>Configuration</button>
|
<button>Configuration</button>
|
||||||
</a>
|
</a>
|
||||||
<x-services.links :service="$service" />
|
<x-services.links />
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
@if (serviceStatus($service) === 'degraded')
|
@if (serviceStatus($service) === 'degraded')
|
||||||
<button wire:click='deploy' onclick="startService.showModal()"
|
<button wire:click='deploy' onclick="startService.showModal()"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<div class="fixed z-50 top-[4.5rem] left-4" id="vue">
|
<div class="fixed z-50 top-[4.5rem] left-4" id="vue">
|
||||||
<magic-bar></magic-bar>
|
<magic-bar></magic-bar>
|
||||||
</div>
|
</div>
|
||||||
<main class="main max-w-screen-2xl">
|
<main class="pb-10 main max-w-screen-2xl">
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
</main>
|
</main>
|
||||||
@endsection
|
@endsection
|
||||||
|
@ -16,19 +16,21 @@
|
|||||||
<x-forms.input label="Description" id="application.description"></x-forms.input>
|
<x-forms.input label="Description" id="application.description"></x-forms.input>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
|
@if (!$application->serviceType()?->contains(str($application->image)->before(':')))
|
||||||
@if ($application->required_fqdn)
|
@if ($application->required_fqdn)
|
||||||
<x-forms.input required placeholder="https://app.coolify.io" label="Domains"
|
<x-forms.input required placeholder="https://app.coolify.io" label="Domains"
|
||||||
id="application.fqdn" 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.input>
|
id="application.fqdn"
|
||||||
|
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.input>
|
||||||
@else
|
@else
|
||||||
<x-forms.input placeholder="https://app.coolify.io" label="Domains"
|
<x-forms.input placeholder="https://app.coolify.io" label="Domains" id="application.fqdn"
|
||||||
id="application.fqdn" 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.input>
|
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.input>
|
||||||
|
@endif
|
||||||
@endif
|
@endif
|
||||||
<x-forms.input required
|
<x-forms.input required
|
||||||
helper="You can change the image you would like to deploy.<br><br><span class='text-warning'>WARNING. You could corrupt your data. Only do it if you know what you are doing.</span>"
|
helper="You can change the image you would like to deploy.<br><br><span class='text-warning'>WARNING. You could corrupt your data. Only do it if you know what you are doing.</span>"
|
||||||
label="Image" id="application.image"></x-forms.input>
|
label="Image" id="application.image"></x-forms.input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 class="pt-2">Advanced</h3>
|
<h3 class="pt-2">Advanced</h3>
|
||||||
<div class="w-64">
|
<div class="w-64">
|
||||||
<x-forms.checkbox instantSave label="Exclude from service status"
|
<x-forms.checkbox instantSave label="Exclude from service status"
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<div class="w-full pl-8">
|
<div class="w-full pl-8">
|
||||||
<div x-cloak x-show="activeTab === 'service-stack'">
|
<div x-cloak x-show="activeTab === 'service-stack'">
|
||||||
<livewire:project.service.stack-form :service="$service" />
|
<livewire:project.service.stack-form :service="$service" />
|
||||||
<div class="grid grid-cols-1 gap-2 pt-4 xl:grid-cols-3">
|
<div class="grid grid-cols-1 gap-2 pt-4 xl:grid-cols-1">
|
||||||
@foreach ($applications as $application)
|
@foreach ($applications as $application)
|
||||||
<div @class([
|
<div @class([
|
||||||
'border-l border-dashed border-red-500' => Str::of(
|
'border-l border-dashed border-red-500' => Str::of(
|
||||||
@ -58,7 +58,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<div class="text-xs">{{ $application->status }}</div>
|
<div class="text-xs">{{ $application->status }}</div>
|
||||||
</a>
|
</a>
|
||||||
<a class="flex gap-2 p-1 mx-4 font-bold rounded group-hover:text-white hover:no-underline"
|
<a class="flex items-center gap-2 p-1 mx-4 font-bold rounded group-hover:text-white hover:no-underline"
|
||||||
href="{{ route('project.service.logs', [...$parameters, 'service_name' => $application->name]) }}"><span
|
href="{{ route('project.service.logs', [...$parameters, 'service_name' => $application->name]) }}"><span
|
||||||
class="hover:text-warning">Logs</span></a>
|
class="hover:text-warning">Logs</span></a>
|
||||||
</div>
|
</div>
|
||||||
@ -88,7 +88,7 @@ class="hover:text-warning">Logs</span></a>
|
|||||||
@endif
|
@endif
|
||||||
<div class="text-xs">{{ $database->status }}</div>
|
<div class="text-xs">{{ $database->status }}</div>
|
||||||
</a>
|
</a>
|
||||||
<a class="flex gap-2 p-1 mx-4 font-bold rounded hover:no-underline group-hover:text-white"
|
<a class="flex items-center gap-2 p-1 mx-4 font-bold rounded hover:no-underline group-hover:text-white"
|
||||||
href="{{ route('project.service.logs', [...$parameters, 'service_name' => $database->name]) }}"><span
|
href="{{ route('project.service.logs', [...$parameters, 'service_name' => $database->name]) }}"><span
|
||||||
class="hover:text-warning">Logs</span></a>
|
class="hover:text-warning">Logs</span></a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,9 +12,17 @@
|
|||||||
<x-forms.input id="service.name" required label="Service Name" placeholder="My super wordpress site" />
|
<x-forms.input id="service.name" required label="Service Name" placeholder="My super wordpress site" />
|
||||||
<x-forms.input id="service.description" label="Description" />
|
<x-forms.input id="service.description" label="Description" />
|
||||||
</div>
|
</div>
|
||||||
{{-- @if ($isConfigurationRequired)
|
@if ($fields)
|
||||||
<div class="text-warning">This service requires additional confiugration. Please check our <a
|
<div>
|
||||||
href="https://coolify.io/docs" class="text-white underline">documentation</a> for further information.
|
<h3>Service Specific Configuration</h3>
|
||||||
</div>
|
</div>
|
||||||
@endif --}}
|
<div class="grid grid-cols-2 gap-2">
|
||||||
|
@foreach ($fields as $serviceName => $fields)
|
||||||
|
<x-forms.input type="{{ data_get($fields, 'isPassword') ? 'password' : 'text' }}" required
|
||||||
|
helper="Variable name: {{ $serviceName }}"
|
||||||
|
label="{{ data_get($fields, 'serviceName') }} {{ data_get($fields, 'name') }}"
|
||||||
|
id="fields.{{ $serviceName }}.value"></x-forms.input>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</form>
|
</form>
|
||||||
|
Loading…
Reference in New Issue
Block a user