feat(core): wip version of coolify.json
This commit is contained in:
@@ -442,6 +442,7 @@ class General extends Component
|
|||||||
{
|
{
|
||||||
$config = GenerateConfig::run($this->application, true);
|
$config = GenerateConfig::run($this->application, true);
|
||||||
$fileName = str($this->application->name)->slug()->append('_config.json');
|
$fileName = str($this->application->name)->slug()->append('_config.json');
|
||||||
|
dd($config);
|
||||||
|
|
||||||
return response()->streamDownload(function () use ($config) {
|
return response()->streamDownload(function () use ($config) {
|
||||||
echo $config;
|
echo $config;
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Enums\ApplicationDeploymentStatus;
|
use App\Enums\ApplicationDeploymentStatus;
|
||||||
|
use App\Services\ConfigurationGenerator;
|
||||||
|
use App\Traits\HasConfiguration;
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
@@ -105,7 +107,7 @@ use Visus\Cuid2\Cuid2;
|
|||||||
|
|
||||||
class Application extends BaseModel
|
class Application extends BaseModel
|
||||||
{
|
{
|
||||||
use HasFactory, SoftDeletes;
|
use HasConfiguration, HasFactory, SoftDeletes;
|
||||||
|
|
||||||
private static $parserVersion = '4';
|
private static $parserVersion = '4';
|
||||||
|
|
||||||
@@ -1640,35 +1642,28 @@ class Application extends BaseModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getLimits(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'limits_memory' => $this->limits_memory,
|
||||||
|
'limits_memory_swap' => $this->limits_memory_swap,
|
||||||
|
'limits_memory_swappiness' => $this->limits_memory_swappiness,
|
||||||
|
'limits_memory_reservation' => $this->limits_memory_reservation,
|
||||||
|
'limits_cpus' => $this->limits_cpus,
|
||||||
|
'limits_cpuset' => $this->limits_cpuset,
|
||||||
|
'limits_cpu_shares' => $this->limits_cpu_shares,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function generateConfig($is_json = false)
|
public function generateConfig($is_json = false)
|
||||||
{
|
{
|
||||||
$config = collect([]);
|
$generator = new ConfigurationGenerator($this);
|
||||||
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) {
|
if ($is_json) {
|
||||||
return json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
return $generator->toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $config;
|
return $generator->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setConfig($config)
|
public function setConfig($config)
|
||||||
|
194
app/Services/ConfigurationGenerator.php
Normal file
194
app/Services/ConfigurationGenerator.php
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Models\Application;
|
||||||
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
|
||||||
|
class ConfigurationGenerator
|
||||||
|
{
|
||||||
|
protected array $config = [];
|
||||||
|
|
||||||
|
public function __construct(protected Application $resource)
|
||||||
|
{
|
||||||
|
$this->generateConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function generateConfig(): void
|
||||||
|
{
|
||||||
|
if ($this->resource instanceof Application) {
|
||||||
|
$this->config = [
|
||||||
|
'id' => $this->resource->id,
|
||||||
|
'name' => $this->resource->name,
|
||||||
|
'uuid' => $this->resource->uuid,
|
||||||
|
'description' => $this->resource->description,
|
||||||
|
'coolify_details' => [
|
||||||
|
'project_uuid' => $this->resource->project()->uuid,
|
||||||
|
'environment_uuid' => $this->resource->environment->uuid,
|
||||||
|
|
||||||
|
'destination_type' => $this->resource->destination_type,
|
||||||
|
'destination_id' => $this->resource->destination_id,
|
||||||
|
'source_type' => $this->resource->source_type,
|
||||||
|
'source_id' => $this->resource->source_id,
|
||||||
|
'private_key_id' => $this->resource->private_key_id,
|
||||||
|
],
|
||||||
|
|
||||||
|
'post_deployment_command' => $this->resource->post_deployment_command,
|
||||||
|
'post_deployment_command_container' => $this->resource->post_deployment_command_container,
|
||||||
|
'pre_deployment_command' => $this->resource->pre_deployment_command,
|
||||||
|
'pre_deployment_command_container' => $this->resource->pre_deployment_command_container,
|
||||||
|
'build' => [
|
||||||
|
'type' => $this->resource->build_pack,
|
||||||
|
'static_image' => $this->resource->static_image,
|
||||||
|
'base_directory' => $this->resource->base_directory,
|
||||||
|
'publish_directory' => $this->resource->publish_directory,
|
||||||
|
'dockerfile' => $this->resource->dockerfile,
|
||||||
|
'dockerfile_location' => $this->resource->dockerfile_location,
|
||||||
|
'dockerfile_target_build' => $this->resource->dockerfile_target_build,
|
||||||
|
'custom_docker_run_options' => $this->resource->custom_docker_options,
|
||||||
|
'compose_parsing_version' => $this->resource->compose_parsing_version,
|
||||||
|
'docker_compose' => $this->resource->docker_compose,
|
||||||
|
'docker_compose_location' => $this->resource->docker_compose_location,
|
||||||
|
'docker_compose_raw' => $this->resource->docker_compose_raw,
|
||||||
|
'docker_compose_domains' => $this->resource->docker_compose_domains,
|
||||||
|
'docker_compose_custom_start_command' => $this->resource->docker_compose_custom_start_command,
|
||||||
|
'docker_compose_custom_build_command' => $this->resource->docker_compose_custom_build_command,
|
||||||
|
'install_command' => $this->resource->install_command,
|
||||||
|
'build_command' => $this->resource->build_command,
|
||||||
|
'start_command' => $this->resource->start_command,
|
||||||
|
'watch_paths' => $this->resource->watch_paths,
|
||||||
|
],
|
||||||
|
'source' => [
|
||||||
|
'git_repository' => $this->resource->git_repository,
|
||||||
|
'git_branch' => $this->resource->git_branch,
|
||||||
|
'git_commit_sha' => $this->resource->git_commit_sha,
|
||||||
|
'repository_project_id' => $this->resource->repository_project_id,
|
||||||
|
],
|
||||||
|
'docker_registry_image' => $this->getDockerRegistryImage(),
|
||||||
|
'domains' => [
|
||||||
|
'fqdn' => $this->resource->fqdn,
|
||||||
|
'ports_exposes' => $this->resource->ports_exposes,
|
||||||
|
'ports_mappings' => $this->resource->ports_mappings,
|
||||||
|
'redirect' => $this->resource->redirect,
|
||||||
|
'custom_nginx_configuration' => $this->resource->custom_nginx_configuration,
|
||||||
|
],
|
||||||
|
'environment_variables' => [
|
||||||
|
'production' => $this->getEnvironmentVariables(),
|
||||||
|
'preview' => $this->getPreviewEnvironmentVariables(),
|
||||||
|
],
|
||||||
|
'settings' => $this->getApplicationSettings(),
|
||||||
|
'preview' => $this->getPreview(),
|
||||||
|
'limits' => $this->resource->getLimits(),
|
||||||
|
'health_check' => [
|
||||||
|
'health_check_path' => $this->resource->health_check_path,
|
||||||
|
'health_check_port' => $this->resource->health_check_port,
|
||||||
|
'health_check_host' => $this->resource->health_check_host,
|
||||||
|
'health_check_method' => $this->resource->health_check_method,
|
||||||
|
'health_check_return_code' => $this->resource->health_check_return_code,
|
||||||
|
'health_check_scheme' => $this->resource->health_check_scheme,
|
||||||
|
'health_check_response_text' => $this->resource->health_check_response_text,
|
||||||
|
'health_check_interval' => $this->resource->health_check_interval,
|
||||||
|
'health_check_timeout' => $this->resource->health_check_timeout,
|
||||||
|
'health_check_retries' => $this->resource->health_check_retries,
|
||||||
|
'health_check_start_period' => $this->resource->health_check_start_period,
|
||||||
|
'health_check_enabled' => $this->resource->health_check_enabled,
|
||||||
|
],
|
||||||
|
'webhooks_secrets' => [
|
||||||
|
'manual_webhook_secret_github' => $this->resource->manual_webhook_secret_github,
|
||||||
|
'manual_webhook_secret_gitlab' => $this->resource->manual_webhook_secret_gitlab,
|
||||||
|
'manual_webhook_secret_bitbucket' => $this->resource->manual_webhook_secret_bitbucket,
|
||||||
|
'manual_webhook_secret_gitea' => $this->resource->manual_webhook_secret_gitea,
|
||||||
|
],
|
||||||
|
'swarm' => [
|
||||||
|
'swarm_replicas' => $this->resource->swarm_replicas,
|
||||||
|
'swarm_placement_constraints' => $this->resource->swarm_placement_constraints,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPreview(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'preview_url_template' => $this->resource->preview_url_template,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDockerRegistryImage(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'image' => $this->resource->docker_registry_image_name,
|
||||||
|
'tag' => $this->resource->docker_registry_image_tag,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getEnvironmentVariables(): array
|
||||||
|
{
|
||||||
|
$variables = collect([]);
|
||||||
|
foreach ($this->resource->environment_variables as $env) {
|
||||||
|
$variables->push([
|
||||||
|
'key' => $env->key,
|
||||||
|
'value' => $env->value,
|
||||||
|
'is_build_time' => $env->is_build_time,
|
||||||
|
'is_preview' => $env->is_preview,
|
||||||
|
'is_multiline' => $env->is_multiline,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $variables->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPreviewEnvironmentVariables(): array
|
||||||
|
{
|
||||||
|
$variables = collect([]);
|
||||||
|
foreach ($this->resource->environment_variables_preview as $env) {
|
||||||
|
$variables->push([
|
||||||
|
'key' => $env->key,
|
||||||
|
'value' => $env->value,
|
||||||
|
'is_build_time' => $env->is_build_time,
|
||||||
|
'is_preview' => $env->is_preview,
|
||||||
|
'is_multiline' => $env->is_multiline,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $variables->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getApplicationSettings(): array
|
||||||
|
{
|
||||||
|
$removedKeys = ['id', 'application_id', 'created_at', 'updated_at'];
|
||||||
|
$settings = $this->resource->settings->attributesToArray();
|
||||||
|
$settings = collect($settings)->filter(function ($value, $key) use ($removedKeys) {
|
||||||
|
return ! in_array($key, $removedKeys);
|
||||||
|
})->sortBy(function ($value, $key) {
|
||||||
|
return $key;
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
return $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveJson(string $path): void
|
||||||
|
{
|
||||||
|
file_put_contents($path, json_encode($this->config, JSON_PRETTY_PRINT));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveYaml(string $path): void
|
||||||
|
{
|
||||||
|
file_put_contents($path, Yaml::dump($this->config, 6, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return $this->config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toJson(): string
|
||||||
|
{
|
||||||
|
return json_encode($this->config, JSON_PRETTY_PRINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toYaml(): string
|
||||||
|
{
|
||||||
|
return Yaml::dump($this->config, 6, 2);
|
||||||
|
}
|
||||||
|
}
|
42
app/Traits/HasConfiguration.php
Normal file
42
app/Traits/HasConfiguration.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Traits;
|
||||||
|
|
||||||
|
use App\Services\ConfigurationGenerator;
|
||||||
|
|
||||||
|
trait HasConfiguration
|
||||||
|
{
|
||||||
|
public function generateConfigurationFiles(): void
|
||||||
|
{
|
||||||
|
$generator = new ConfigurationGenerator($this);
|
||||||
|
|
||||||
|
$configDir = base_configuration_dir()."/{$this->uuid}";
|
||||||
|
if (! is_dir($configDir)) {
|
||||||
|
mkdir($configDir, 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$generator->saveJson($configDir.'/coolify.json');
|
||||||
|
$generator->saveYaml($configDir.'/coolify.yaml');
|
||||||
|
|
||||||
|
// Generate a README file with basic information
|
||||||
|
file_put_contents(
|
||||||
|
$configDir.'/README.md',
|
||||||
|
generate_readme_file($this->name, now()->toIso8601String())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfigurationAsJson(): string
|
||||||
|
{
|
||||||
|
return (new ConfigurationGenerator($this))->toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfigurationAsYaml(): string
|
||||||
|
{
|
||||||
|
return (new ConfigurationGenerator($this))->toYaml();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfigurationAsArray(): array
|
||||||
|
{
|
||||||
|
return (new ConfigurationGenerator($this))->toArray();
|
||||||
|
}
|
||||||
|
}
|
@@ -5,13 +5,14 @@
|
|||||||
<x-forms.button type="submit">
|
<x-forms.button type="submit">
|
||||||
Save
|
Save
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
{{--
|
|
||||||
<x-forms.button wire:click="downloadConfig">
|
{{-- <x-forms.button wire:click="downloadConfig">
|
||||||
Download Config
|
Download Config
|
||||||
<x-modal-input buttonTitle="Upload Config" title="Upload Config" :closeOutside="false">
|
</x-forms.button> --}}
|
||||||
|
{{-- <x-modal-input buttonTitle="Upload Config" title="Upload Config" :closeOutside="false">
|
||||||
<livewire:project.shared.upload-config :applicationId="$application->id" />
|
<livewire:project.shared.upload-config :applicationId="$application->id" />
|
||||||
</x-modal-input>
|
</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">
|
||||||
|
Reference in New Issue
Block a user