From ce3cae3ff9bf3f1580427df21c7883b7f19e4e0f Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 12 Jan 2026 21:42:20 +0100 Subject: [PATCH] fix(api): applications post and patch endpoints - remove `docker_compose_raw` from post and patch endpoints, as the compose file is sourced from git and should not be manually settable via the api - improve the documentation for `docker_compose_domains` (URLs) - enhanced array validation for `docker_compose_domains` by validating each array field and verifying which fields are allowed - set a custom array validation error message, as the default message is not really clear - show an error if the user attempts to set `domains` when the build pack is `dockercompose` - validate that the `domains` in `docker_compose_domains` are proper URLs and include a valid scheme (`http` or `https`) --- .../Api/ApplicationsController.php | 364 ++++++++++++------ bootstrap/helpers/api.php | 2 +- 2 files changed, 254 insertions(+), 112 deletions(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index a08143022..099b3d124 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -19,6 +19,7 @@ use App\Rules\ValidGitRepositoryUrl; use App\Services\DockerImageParser; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; use OpenApi\Attributes as OA; use Spatie\Url\Url; @@ -198,10 +199,19 @@ public function applications(Request $request) 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], - 'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], - 'docker_compose_domains' => ['type' => 'array', 'description' => 'The Docker Compose domains.'], + 'docker_compose_domains' => [ + 'type' => 'array', + 'description' => 'Array of URLs to be applied to containers of a dockercompose application.', + 'items' => new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The service name as defined in docker-compose.'], + 'domain' => ['type' => 'string', 'description' => 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")'], + ], + ), + ], 'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'], 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'is_http_basic_auth_enabled' => ['type' => 'boolean', 'description' => 'HTTP Basic Authentication enabled.'], @@ -350,10 +360,19 @@ public function create_public_application(Request $request) 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], - 'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], - 'docker_compose_domains' => ['type' => 'array', 'description' => 'The Docker Compose domains.'], + 'docker_compose_domains' => [ + 'type' => 'array', + 'description' => 'Array of URLs to be applied to containers of a dockercompose application.', + 'items' => new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The service name as defined in docker-compose.'], + 'domain' => ['type' => 'string', 'description' => 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")'], + ], + ), + ], 'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'], 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'is_http_basic_auth_enabled' => ['type' => 'boolean', 'description' => 'HTTP Basic Authentication enabled.'], @@ -502,10 +521,19 @@ public function create_private_gh_app_application(Request $request) 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], - 'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], - 'docker_compose_domains' => ['type' => 'array', 'description' => 'The Docker Compose domains.'], + 'docker_compose_domains' => [ + 'type' => 'array', + 'description' => 'Array of URLs to be applied to containers of a dockercompose application.', + 'items' => new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The service name as defined in docker-compose.'], + 'domain' => ['type' => 'string', 'description' => 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")'], + ], + ), + ], 'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'], 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'is_http_basic_auth_enabled' => ['type' => 'boolean', 'description' => 'HTTP Basic Authentication enabled.'], @@ -1056,8 +1084,10 @@ private function create_application(Request $request, $type) 'build_pack' => ['required', Rule::enum(BuildPackTypes::class)], 'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required', 'docker_compose_location' => 'string', - 'docker_compose_raw' => 'string|nullable', 'docker_compose_domains' => 'array|nullable', + 'docker_compose_domains.*' => 'array:name,domain', + 'docker_compose_domains.*.name' => 'string|required', + 'docker_compose_domains.*.domain' => 'string|nullable', ]; // ports_exposes is not required for dockercompose if ($request->build_pack === 'dockercompose') { @@ -1065,13 +1095,26 @@ private function create_application(Request $request, $type) $request->offsetSet('ports_exposes', '80'); } $validationRules = array_merge(sharedDataApplications(), $validationRules); - $validator = customApiValidator($request->all(), $validationRules); + $validationMessages = [ + 'docker_compose_domains.*.array' => 'An item in the docker_compose_domains array has invalid fields. Only a name and domain field are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); if ($validator->fails()) { return response()->json([ 'message' => 'Validation failed.', 'errors' => $validator->errors(), ], 422); } + // For dockercompose applications, domains (fqdn) field should not be used + // Only docker_compose_domains should be used to set domains for individual services + if ($request->build_pack === 'dockercompose' && $request->has('domains')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'domains' => 'The domains field cannot be used for dockercompose applications. Use docker_compose_domains instead to set domains for individual services.', + ], + ], 422); + } if (! $request->has('name')) { $request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch)); } @@ -1087,11 +1130,42 @@ private function create_application(Request $request, $type) $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { $dockerComposeDomains = collect($request->docker_compose_domains); - if ($dockerComposeDomains->count() > 0) { - $dockerComposeDomains->each(function ($domain, $key) use ($dockerComposeDomainsJson) { - $dockerComposeDomainsJson->put(data_get($domain, 'name'), ['domain' => data_get($domain, 'domain')]); - }); + $domainErrors = []; + + foreach ($dockerComposeDomains as $index => $item) { + $domainValue = data_get($item, 'domain'); + if (filled($domainValue)) { + $urls = str($domainValue)->replaceStart(',', '')->replaceEnd(',', '')->trim(); + str($urls)->explode(',')->each(function ($url) use (&$domainErrors) { + $url = trim($url); + if (empty($url)) { + return; + } + if (! filter_var($url, FILTER_VALIDATE_URL)) { + $domainErrors[] = "Invalid URL: {$url}"; + + return; + } + $scheme = parse_url($url, PHP_URL_SCHEME) ?? ''; + if (! in_array(strtolower($scheme), ['http', 'https'])) { + $domainErrors[] = "Invalid URL scheme: {$scheme} for URL: {$url}. Only http and https are supported."; + } + }); + } } + + if (! empty($domainErrors)) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_domains' => $domainErrors, + ], + ], 422); + } + + $dockerComposeDomains->each(function ($domain) use ($dockerComposeDomainsJson) { + $dockerComposeDomainsJson->put(data_get($domain, 'name'), ['domain' => data_get($domain, 'domain')]); + }); $request->offsetUnset('docker_compose_domains'); } if ($dockerComposeDomainsJson->count() > 0) { @@ -1170,17 +1244,32 @@ private function create_application(Request $request, $type) 'github_app_uuid' => 'string|required', 'watch_paths' => 'string|nullable', 'docker_compose_location' => 'string', - 'docker_compose_raw' => 'string|nullable', + 'docker_compose_domains' => 'array|nullable', + 'docker_compose_domains.*' => 'array:name,domain', + 'docker_compose_domains.*.name' => 'string|required', + 'docker_compose_domains.*.domain' => 'string|nullable', ]; $validationRules = array_merge(sharedDataApplications(), $validationRules); - - $validator = customApiValidator($request->all(), $validationRules); + $validationMessages = [ + 'docker_compose_domains.*.array' => 'An item in the docker_compose_domains array has invalid fields. Only a name and domain field are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); if ($validator->fails()) { return response()->json([ 'message' => 'Validation failed.', 'errors' => $validator->errors(), ], 422); } + // For dockercompose applications, domains (fqdn) field should not be used + // Only docker_compose_domains should be used to set domains for individual services + if ($request->build_pack === 'dockercompose' && $request->has('domains')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'domains' => 'The domains field cannot be used for dockercompose applications. Use docker_compose_domains instead to set domains for individual services.', + ], + ], 422); + } if (! $request->has('name')) { $request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch)); @@ -1229,43 +1318,43 @@ private function create_application(Request $request, $type) $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { - if (! $request->has('docker_compose_raw')) { + $dockerComposeDomains = collect($request->docker_compose_domains); + $domainErrors = []; + + foreach ($dockerComposeDomains as $index => $item) { + $domainValue = data_get($item, 'domain'); + if (filled($domainValue)) { + $urls = str($domainValue)->replaceStart(',', '')->replaceEnd(',', '')->trim(); + str($urls)->explode(',')->each(function ($url) use (&$domainErrors) { + $url = trim($url); + if (empty($url)) { + return; + } + if (! filter_var($url, FILTER_VALIDATE_URL)) { + $domainErrors[] = "Invalid URL: {$url}"; + + return; + } + $scheme = parse_url($url, PHP_URL_SCHEME) ?? ''; + if (! in_array(strtolower($scheme), ['http', 'https'])) { + $domainErrors[] = "Invalid URL scheme: {$scheme} for URL: {$url}. Only http and https are supported."; + } + }); + } + } + + if (! empty($domainErrors)) { return response()->json([ 'message' => 'Validation failed.', 'errors' => [ - 'docker_compose_raw' => 'The base64 encoded docker_compose_raw is required.', + 'docker_compose_domains' => $domainErrors, ], ], 422); } - if (! isBase64Encoded($request->docker_compose_raw)) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - if (mb_detect_encoding($dockerComposeRaw, 'ASCII', true) === false) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $yaml = Yaml::parse($dockerComposeRaw); - $services = data_get($yaml, 'services'); - $dockerComposeDomains = collect($request->docker_compose_domains); - if ($dockerComposeDomains->count() > 0) { - $dockerComposeDomains->each(function ($domain, $key) use ($services, $dockerComposeDomainsJson) { - $name = data_get($domain, 'name'); - if (data_get($services, $name)) { - $dockerComposeDomainsJson->put($name, ['domain' => data_get($domain, 'domain')]); - } - }); - } + $dockerComposeDomains->each(function ($domain) use ($dockerComposeDomainsJson) { + $dockerComposeDomainsJson->put(data_get($domain, 'name'), ['domain' => data_get($domain, 'domain')]); + }); $request->offsetUnset('docker_compose_domains'); } if ($dockerComposeDomainsJson->count() > 0) { @@ -1335,11 +1424,17 @@ private function create_application(Request $request, $type) 'private_key_uuid' => 'string|required', 'watch_paths' => 'string|nullable', 'docker_compose_location' => 'string', - 'docker_compose_raw' => 'string|nullable', + 'docker_compose_domains' => 'array|nullable', + 'docker_compose_domains.*' => 'array:name,domain', + 'docker_compose_domains.*.name' => 'string|required', + 'docker_compose_domains.*.domain' => 'string|nullable', ]; $validationRules = array_merge(sharedDataApplications(), $validationRules); - $validator = customApiValidator($request->all(), $validationRules); + $validationMessages = [ + 'docker_compose_domains.*.array' => 'An item in the docker_compose_domains array has invalid fields. Only a name and domain field are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); if ($validator->fails()) { return response()->json([ @@ -1347,6 +1442,16 @@ private function create_application(Request $request, $type) 'errors' => $validator->errors(), ], 422); } + // For dockercompose applications, domains (fqdn) field should not be used + // Only docker_compose_domains should be used to set domains for individual services + if ($request->build_pack === 'dockercompose' && $request->has('domains')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'domains' => 'The domains field cannot be used for dockercompose applications. Use docker_compose_domains instead to set domains for individual services.', + ], + ], 422); + } if (! $request->has('name')) { $request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch)); } @@ -1370,44 +1475,43 @@ private function create_application(Request $request, $type) $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { - if (! $request->has('docker_compose_raw')) { + $dockerComposeDomains = collect($request->docker_compose_domains); + $domainErrors = []; + + foreach ($dockerComposeDomains as $index => $item) { + $domainValue = data_get($item, 'domain'); + if (filled($domainValue)) { + $urls = str($domainValue)->replaceStart(',', '')->replaceEnd(',', '')->trim(); + str($urls)->explode(',')->each(function ($url) use (&$domainErrors) { + $url = trim($url); + if (empty($url)) { + return; + } + if (! filter_var($url, FILTER_VALIDATE_URL)) { + $domainErrors[] = "Invalid URL: {$url}"; + + return; + } + $scheme = parse_url($url, PHP_URL_SCHEME) ?? ''; + if (! in_array(strtolower($scheme), ['http', 'https'])) { + $domainErrors[] = "Invalid URL scheme: {$scheme} for URL: {$url}. Only http and https are supported."; + } + }); + } + } + + if (! empty($domainErrors)) { return response()->json([ 'message' => 'Validation failed.', 'errors' => [ - 'docker_compose_raw' => 'The base64 encoded docker_compose_raw is required.', + 'docker_compose_domains' => $domainErrors, ], ], 422); } - if (! isBase64Encoded($request->docker_compose_raw)) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - if (mb_detect_encoding($dockerComposeRaw, 'ASCII', true) === false) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - $yaml = Yaml::parse($dockerComposeRaw); - $services = data_get($yaml, 'services'); - $dockerComposeDomains = collect($request->docker_compose_domains); - if ($dockerComposeDomains->count() > 0) { - $dockerComposeDomains->each(function ($domain, $key) use ($services, $dockerComposeDomainsJson) { - $name = data_get($domain, 'name'); - if (data_get($services, $name)) { - $dockerComposeDomainsJson->put($name, ['domain' => data_get($domain, 'domain')]); - } - }); - } + $dockerComposeDomains->each(function ($domain) use ($dockerComposeDomainsJson) { + $dockerComposeDomainsJson->put(data_get($domain, 'name'), ['domain' => data_get($domain, 'domain')]); + }); $request->offsetUnset('docker_compose_domains'); } if ($dockerComposeDomainsJson->count() > 0) { @@ -2090,10 +2194,19 @@ public function delete_by_uuid(Request $request) 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], - 'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], - 'docker_compose_domains' => ['type' => 'array', 'description' => 'The Docker Compose domains.'], + 'docker_compose_domains' => [ + 'type' => 'array', + 'description' => 'Array of URLs to be applied to containers of a dockercompose application.', + 'items' => new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The service name as defined in docker-compose.'], + 'domain' => ['type' => 'string', 'description' => 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")'], + ], + ), + ], 'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'], 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'connect_to_docker_network' => ['type' => 'boolean', 'description' => 'The flag to connect the service to the predefined Docker network.'], @@ -2192,8 +2305,10 @@ public function update_by_uuid(Request $request) 'static_image' => 'string', 'watch_paths' => 'string|nullable', 'docker_compose_location' => 'string', - 'docker_compose_raw' => 'string|nullable', 'docker_compose_domains' => 'array|nullable', + 'docker_compose_domains.*' => 'array:name,domain', + 'docker_compose_domains.*.name' => 'string|required', + 'docker_compose_domains.*.domain' => 'string|nullable', 'docker_compose_custom_start_command' => 'string|nullable', 'docker_compose_custom_build_command' => 'string|nullable', 'custom_nginx_configuration' => 'string|nullable', @@ -2202,7 +2317,10 @@ public function update_by_uuid(Request $request) 'http_basic_auth_password' => 'string', ]; $validationRules = array_merge(sharedDataApplications(), $validationRules); - $validator = customApiValidator($request->all(), $validationRules); + $validationMessages = [ + 'docker_compose_domains.*.array' => 'An item in the docker_compose_domains array has invalid fields. Only a name and domain field are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); // Validate ports_exposes if ($request->has('ports_exposes')) { @@ -2278,6 +2396,17 @@ public function update_by_uuid(Request $request) $application->save(); } + // For dockercompose applications, domains (fqdn) field should not be used + // Only docker_compose_domains should be used to set domains for individual services + if ($application->build_pack === 'dockercompose' && $request->has('domains')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'domains' => 'The domains field cannot be used for dockercompose applications. Use docker_compose_domains instead to set domains for individual services.', + ], + ], 422); + } + $domains = $request->domains; $requestHasDomains = $request->has('domains'); if ($requestHasDomains && $server->isProxyShouldRun()) { @@ -2321,44 +2450,57 @@ public function update_by_uuid(Request $request) $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { - if (! $request->has('docker_compose_raw')) { + if (empty($application->docker_compose_raw)) { return response()->json([ 'message' => 'Validation failed.', 'errors' => [ - 'docker_compose_raw' => 'The base64 encoded docker_compose_raw is required.', + 'docker_compose_domains' => 'Cannot set docker_compose_domains without docker_compose_raw. Reload the compose file from the git repository first.', ], ], 422); } - if (! isBase64Encoded($request->docker_compose_raw)) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - if (mb_detect_encoding($dockerComposeRaw, 'ASCII', true) === false) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - $yaml = Yaml::parse($dockerComposeRaw); - $services = data_get($yaml, 'services'); $dockerComposeDomains = collect($request->docker_compose_domains); - if ($dockerComposeDomains->count() > 0) { - $dockerComposeDomains->each(function ($domain, $key) use ($services, $dockerComposeDomainsJson) { - $name = data_get($domain, 'name'); - if (data_get($services, $name)) { - $dockerComposeDomainsJson->put($name, ['domain' => data_get($domain, 'domain')]); - } - }); + $domainErrors = []; + + foreach ($dockerComposeDomains as $item) { + $domainValue = data_get($item, 'domain'); + if (filled($domainValue)) { + $urls = str($domainValue)->replaceStart(',', '')->replaceEnd(',', '')->trim(); + str($urls)->explode(',')->each(function ($url) use (&$domainErrors) { + $url = trim($url); + if (empty($url)) { + return; + } + if (! filter_var($url, FILTER_VALIDATE_URL)) { + $domainErrors[] = "Invalid URL: {$url}"; + + return; + } + $scheme = parse_url($url, PHP_URL_SCHEME) ?? ''; + if (! in_array(strtolower($scheme), ['http', 'https'])) { + $domainErrors[] = "Invalid URL scheme: {$scheme} for URL: {$url}. Only http and https are supported."; + } + }); + } } + + if (! empty($domainErrors)) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_domains' => $domainErrors, + ], + ], 422); + } + + $yaml = Yaml::parse($application->docker_compose_raw); + $services = data_get($yaml, 'services', []); + $dockerComposeDomains->each(function ($domain) use ($services, $dockerComposeDomainsJson) { + $name = data_get($domain, 'name'); + if ($name && is_array($services) && isset($services[$name])) { + $dockerComposeDomainsJson->put($name, ['domain' => data_get($domain, 'domain')]); + } + }); $request->offsetUnset('docker_compose_domains'); } $instantDeploy = $request->instant_deploy; diff --git a/bootstrap/helpers/api.php b/bootstrap/helpers/api.php index d9d6f40d8..55cff42d0 100644 --- a/bootstrap/helpers/api.php +++ b/bootstrap/helpers/api.php @@ -131,7 +131,6 @@ function sharedDataApplications() 'manual_webhook_secret_gitea' => 'string|nullable', 'docker_compose_location' => 'string', 'docker_compose' => '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', @@ -181,4 +180,5 @@ function removeUnnecessaryFieldsFromRequest(Request $request) $request->offsetUnset('force_domain_override'); $request->offsetUnset('autogenerate_domain'); $request->offsetUnset('is_container_label_escape_enabled'); + $request->offsetUnset('docker_compose_raw'); }