Fix api-v2 CORS at the edge without changing rollout flows (#330)

Add API-only Traefik CORS middleware labels while preserving configured origins and the existing rollout/load-balancer behavior.
This commit is contained in:
Jeppe B
2026-07-29 09:01:08 +02:00
committed by GitHub
parent 710baad28e
commit 448e0e50c2
6 changed files with 228 additions and 18 deletions
@@ -5,6 +5,7 @@ app_require('classes/release_manager_schema_bootstrap.php');
app_require('classes/coolify_api_client.php');
use classes\coolify_api_client;
use classes\cors_policy;
use classes\release_manager;
class ReleaseManagerCoolifyEnvFake extends coolify_api_client
@@ -584,6 +585,9 @@ it('builds explicit Coolify application route labels for release API targets', f
'branch' => 'master',
], [
'coolify_ports_exposes' => '8080',
'runtime_env' => [
'CORS' => 'https://partner.example.test/app',
],
], 'https://api-v2.truckwash.io', 'api-app-uuid', base64_encode('custom.keep=true'));
$labels = explode("\n", base64_decode($payload['custom_labels'], true));
@@ -593,9 +597,29 @@ it('builds explicit Coolify application route labels for release API targets', f
->and($labels)->toContain('custom.keep=true')
->and($labels)->toContain('traefik.http.routers.https-0-api-app-uuid.rule=Host(`api-v2.truckwash.io`) && PathPrefix(`/`)')
->and($labels)->toContain('traefik.http.routers.https-0-api-app-uuid.priority=1001')
->and($labels)->toContain('traefik.http.routers.https-0-api-app-uuid.middlewares=https-0-api-app-uuid-cors,gzip')
->and($labels)->toContain('traefik.http.middlewares.https-0-api-app-uuid-cors.headers.accesscontrolallowcredentials=true')
->and($labels)->toContain(
'traefik.http.middlewares.https-0-api-app-uuid-cors.headers.accesscontrolalloworiginlist='
. implode(',', cors_policy::allowedOrigins('https://partner.example.test/app'))
)
->and($labels)->toContain('traefik.http.routers.https-0-api-app-uuid.tls.certresolver=letsencrypt')
->and($labels)->toContain('traefik.http.routers.https-0-api-app-uuid.tls.domains[0].main=api-v2.truckwash.io')
->and($labels)->toContain('traefik.http.services.https-0-api-app-uuid.loadbalancer.server.port=8080');
$frontendPayload = $payloadMethod->invoke($manager, [
'channel_slug' => 'internal',
'app' => 'frontend',
'repository' => 'copenhagentruckwash/pleno-vue',
'branch' => 'master',
], [
'coolify_ports_exposes' => '80',
], 'https://api-v2.truckwash.io/internal/frontend', 'frontend-app-uuid', '');
$frontendLabels = explode("\n", base64_decode($frontendPayload['custom_labels'], true));
expect($frontendLabels)
->toContain('traefik.http.routers.https-0-frontend-app-uuid.middlewares=https-0-frontend-app-uuid-stripprefix,gzip');
expect(implode("\n", $frontendLabels))->not->toContain('-cors');
});
it('updates existing frontend Coolify applications away from legacy Nixpacks detection', function (): void {
@@ -1560,12 +1584,13 @@ it('requires non-default release channel runtime URLs and preserves load balance
'https://api-v2.truckwash.io/internal/api',
'release-api-internal',
80,
'letsencrypt'
'letsencrypt',
'api'
);
expect($labels)->toContain('traefik.http.routers.https-0-release-api-internal.rule=Host(`api-v2.truckwash.io`) && PathPrefix(`/internal/api`)');
expect($labels)->toContain('traefik.http.routers.https-0-release-api-internal.priority=1013');
expect($labels)->toContain('traefik.http.middlewares.https-0-release-api-internal-stripprefix.stripprefix.prefixes=/internal/api');
expect($labels)->toContain('traefik.http.routers.https-0-release-api-internal.middlewares=https-0-release-api-internal-stripprefix,gzip');
expect($labels)->toContain('traefik.http.routers.https-0-release-api-internal.middlewares=https-0-release-api-internal-cors,https-0-release-api-internal-stripprefix,gzip');
$source = file(app_path('classes/release_manager.php'));
$methodSource = implode('', array_slice(