feat(application): make ports_exposes optional for portless apps
This commit is contained in:
parent
ad95d65aca
commit
9c8e5645b4
6 changed files with 60 additions and 25 deletions
|
|
@ -144,7 +144,7 @@ public function applications(Request $request)
|
|||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'object',
|
||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'git_repository', 'git_branch', 'build_pack', 'ports_exposes'],
|
||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'git_repository', 'git_branch', 'build_pack'],
|
||||
properties: [
|
||||
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
||||
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
||||
|
|
@ -309,7 +309,7 @@ public function create_public_application(Request $request)
|
|||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'object',
|
||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'github_app_uuid', 'git_repository', 'git_branch', 'build_pack', 'ports_exposes'],
|
||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'github_app_uuid', 'git_repository', 'git_branch', 'build_pack'],
|
||||
properties: [
|
||||
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
||||
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
||||
|
|
@ -474,7 +474,7 @@ public function create_private_gh_app_application(Request $request)
|
|||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'object',
|
||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'private_key_uuid', 'git_repository', 'git_branch', 'build_pack', 'ports_exposes'],
|
||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'private_key_uuid', 'git_repository', 'git_branch', 'build_pack'],
|
||||
properties: [
|
||||
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
||||
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
||||
|
|
@ -776,7 +776,7 @@ public function create_dockerfile_application(Request $request)
|
|||
mediaType: 'application/json',
|
||||
schema: new OA\Schema(
|
||||
type: 'object',
|
||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'docker_registry_image_name', 'ports_exposes'],
|
||||
required: ['project_uuid', 'server_uuid', 'environment_name', 'environment_uuid', 'docker_registry_image_name'],
|
||||
properties: [
|
||||
'project_uuid' => ['type' => 'string', 'description' => 'The project UUID.'],
|
||||
'server_uuid' => ['type' => 'string', 'description' => 'The server UUID.'],
|
||||
|
|
@ -1114,7 +1114,7 @@ private function create_application(Request $request, $type)
|
|||
'git_repository' => ['string', 'required', new ValidGitRepositoryUrl],
|
||||
'git_branch' => ['string', 'required', new ValidGitBranch],
|
||||
'build_pack' => ['required', Rule::enum(BuildPackTypes::class)],
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|nullable',
|
||||
'docker_compose_domains' => 'array|nullable',
|
||||
'docker_compose_domains.*' => 'array:name,domain',
|
||||
'docker_compose_domains.*.name' => 'string|required',
|
||||
|
|
@ -1307,7 +1307,7 @@ private function create_application(Request $request, $type)
|
|||
'git_repository' => 'string|required',
|
||||
'git_branch' => ['string', 'required', new ValidGitBranch],
|
||||
'build_pack' => ['required', Rule::enum(BuildPackTypes::class)],
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|nullable',
|
||||
'github_app_uuid' => 'string|required',
|
||||
'watch_paths' => 'string|nullable',
|
||||
'docker_compose_domains' => 'array|nullable',
|
||||
|
|
@ -1534,7 +1534,7 @@ private function create_application(Request $request, $type)
|
|||
'git_repository' => ['string', 'required', new ValidGitRepositoryUrl],
|
||||
'git_branch' => ['string', 'required', new ValidGitBranch],
|
||||
'build_pack' => ['required', Rule::enum(BuildPackTypes::class)],
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|nullable',
|
||||
'private_key_uuid' => 'string|required',
|
||||
'watch_paths' => 'string|nullable',
|
||||
'docker_compose_domains' => 'array|nullable',
|
||||
|
|
@ -1835,7 +1835,7 @@ private function create_application(Request $request, $type)
|
|||
$validationRules = [
|
||||
'docker_registry_image_name' => 'string|required',
|
||||
'docker_registry_image_tag' => 'string',
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required',
|
||||
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|nullable',
|
||||
];
|
||||
$validationRules = array_merge(sharedDataApplications(), $validationRules);
|
||||
$validator = customApiValidator($request->all(), $validationRules);
|
||||
|
|
|
|||
|
|
@ -1282,7 +1282,7 @@ private function generate_runtime_environment_variables()
|
|||
|
||||
// Add PORT if not exists, use the first port as default
|
||||
if ($this->build_pack !== 'dockercompose') {
|
||||
if ($this->application->environment_variables->where('key', 'PORT')->isEmpty()) {
|
||||
if ($this->application->environment_variables->where('key', 'PORT')->isEmpty() && ! empty($ports)) {
|
||||
$envs->push("PORT={$ports[0]}");
|
||||
}
|
||||
}
|
||||
|
|
@ -2585,7 +2585,7 @@ private function generate_compose_file()
|
|||
'image' => $this->production_image_name,
|
||||
'container_name' => $this->container_name,
|
||||
'restart' => RESTART_MODE,
|
||||
'expose' => $ports,
|
||||
...(!empty($ports) ? ['expose' => $ports] : []),
|
||||
'networks' => [
|
||||
$this->destination->network => [
|
||||
'aliases' => array_merge(
|
||||
|
|
@ -2617,16 +2617,19 @@ private function generate_compose_file()
|
|||
// If custom_healthcheck_found is true, the Dockerfile's HEALTHCHECK will be used
|
||||
// If healthcheck is disabled, no healthcheck will be added
|
||||
if (! $this->application->custom_healthcheck_found && ! $this->application->isHealthcheckDisabled()) {
|
||||
$docker_compose['services'][$this->container_name]['healthcheck'] = [
|
||||
'test' => [
|
||||
'CMD-SHELL',
|
||||
$this->generate_healthcheck_commands(),
|
||||
],
|
||||
'interval' => $this->application->health_check_interval.'s',
|
||||
'timeout' => $this->application->health_check_timeout.'s',
|
||||
'retries' => $this->application->health_check_retries,
|
||||
'start_period' => $this->application->health_check_start_period.'s',
|
||||
];
|
||||
$healthcheck_command = $this->generate_healthcheck_commands();
|
||||
if ($healthcheck_command !== null) {
|
||||
$docker_compose['services'][$this->container_name]['healthcheck'] = [
|
||||
'test' => [
|
||||
'CMD-SHELL',
|
||||
$healthcheck_command,
|
||||
],
|
||||
'interval' => $this->application->health_check_interval.'s',
|
||||
'timeout' => $this->application->health_check_timeout.'s',
|
||||
'retries' => $this->application->health_check_retries,
|
||||
'start_period' => $this->application->health_check_start_period.'s',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (! is_null($this->application->limits_cpuset)) {
|
||||
|
|
@ -2836,7 +2839,11 @@ private function generate_healthcheck_commands()
|
|||
|
||||
// HTTP type healthcheck (default)
|
||||
if (! $this->application->health_check_port) {
|
||||
$health_check_port = (int) $this->application->ports_exposes_array[0];
|
||||
if (! empty($this->application->ports_exposes_array)) {
|
||||
$health_check_port = (int) $this->application->ports_exposes_array[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
$health_check_port = (int) $this->application->health_check_port;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ protected function rules(): array
|
|||
'staticImage' => 'required',
|
||||
'baseDirectory' => array_merge(['required'], array_slice(ValidationPatterns::directoryPathRules(), 1)),
|
||||
'publishDirectory' => ValidationPatterns::directoryPathRules(),
|
||||
'portsExposes' => 'required',
|
||||
'portsExposes' => 'nullable',
|
||||
'portsMappings' => 'nullable',
|
||||
'customNetworkAliases' => 'nullable',
|
||||
'dockerfile' => 'nullable',
|
||||
|
|
@ -208,7 +208,6 @@ protected function messages(): array
|
|||
'buildPack.required' => 'The Build Pack field is required.',
|
||||
'staticImage.required' => 'The Static Image field is required.',
|
||||
'baseDirectory.required' => 'The Base Directory field is required.',
|
||||
'portsExposes.required' => 'The Exposed Ports field is required.',
|
||||
'isStatic.required' => 'The Static setting is required.',
|
||||
'isStatic.boolean' => 'The Static setting must be true or false.',
|
||||
'isSpa.required' => 'The SPA setting is required.',
|
||||
|
|
|
|||
|
|
@ -2147,7 +2147,7 @@ public function setConfig($config)
|
|||
'config.build_pack' => 'required|string',
|
||||
'config.base_directory' => 'required|string',
|
||||
'config.publish_directory' => 'required|string',
|
||||
'config.ports_exposes' => 'required|string',
|
||||
'config.ports_exposes' => 'nullable|string',
|
||||
'config.settings.is_static' => 'required|boolean',
|
||||
]);
|
||||
if ($deepValidator->fails()) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('applications', function (Blueprint $table) {
|
||||
$table->string('ports_exposes')->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('applications', function (Blueprint $table) {
|
||||
$table->string('ports_exposes')->nullable(false)->default('')->change();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -492,6 +492,13 @@ class="flex items-start gap-2 p-4 mb-4 text-sm rounded-lg bg-blue-50 dark:bg-blu
|
|||
</div>
|
||||
@endif
|
||||
@endif
|
||||
@if (empty($portsExposes) || $portsExposes === '0')
|
||||
<x-callout type="info" title="No ports exposed" class="mb-4">
|
||||
This application does not expose any ports and will not be reachable through the proxy or your domains.
|
||||
This behavior is normal for background workers, bots, or scheduled tasks.
|
||||
If your application needs to handle HTTP traffic, please specify the port(s) it listens on.
|
||||
</x-callout>
|
||||
@endif
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
@if ($isStatic || $buildPack === 'static')
|
||||
<x-forms.input id="portsExposes" label="Ports Exposes" readonly
|
||||
|
|
@ -502,7 +509,7 @@ class="flex items-start gap-2 p-4 mb-4 text-sm rounded-lg bg-blue-50 dark:bg-blu
|
|||
helper="Readonly labels are disabled. You can set the ports manually in the labels section."
|
||||
x-bind:disabled="!canUpdate" />
|
||||
@else
|
||||
<x-forms.input placeholder="3000,3001" id="portsExposes" label="Ports Exposes" required
|
||||
<x-forms.input placeholder="3000,3001" id="portsExposes" label="Ports Exposes"
|
||||
helper="A comma separated list of ports your application uses. The first port will be used as default healthcheck port if nothing defined in the Healthcheck menu. Be sure to set this correctly."
|
||||
x-bind:disabled="!canUpdate" />
|
||||
@endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue