filter(fn ($l) => str_contains($l, 'log_append'))->isEmpty())->toBeTrue(); }); it('stamps coolify_app_id and JSON access log on each caddy site when enabled', function () { $labels = fqdnLabelsForCaddy('coolify', 'app-uuid', collect(['https://example.com']), is_traffic_analytics_enabled: true, supports_log_append: true); expect($labels->contains('caddy_0.log_append=coolify_app_id app-uuid'))->toBeTrue(); expect($labels->contains('caddy_0.log.output=file /traffic/access.log'))->toBeTrue(); expect($labels->contains('caddy_0.log.format=json'))->toBeTrue(); }); it('keeps the JSON access log but omits log_append when caddy does not support it', function () { // caddy-docker-proxy 2.8 runs Caddy 2.7.6, which rejects the whole Caddyfile for log_append. $labels = fqdnLabelsForCaddy('coolify', 'app-uuid', collect(['https://example.com']), is_traffic_analytics_enabled: true); expect($labels->filter(fn ($l) => str_contains($l, 'log_append'))->isEmpty())->toBeTrue(); expect($labels->contains('caddy_0.log.output=file /traffic/access.log'))->toBeTrue(); expect($labels->contains('caddy_0.log.format=json'))->toBeTrue(); }); it('emits lumberjack roll directives on each caddy site when enabled', function () { $labels = fqdnLabelsForCaddy('coolify', 'app-uuid', collect(['https://example.com']), is_traffic_analytics_enabled: true); expect($labels->contains('caddy_0.log.output.roll_size=20MiB'))->toBeTrue(); expect($labels->contains('caddy_0.log.output.roll_keep=5'))->toBeTrue(); expect($labels->contains('caddy_0.log.output.roll_keep_for=168h'))->toBeTrue(); }); it('omits lumberjack roll directives when disabled', function () { $labels = fqdnLabelsForCaddy('coolify', 'app-uuid', collect(['https://example.com']), is_traffic_analytics_enabled: false); expect($labels->filter(fn ($l) => str_contains($l, 'roll_'))->isEmpty())->toBeTrue(); }); it('keys a compose service like its Traefik router', function () { $labels = fqdnLabelsForCaddy('coolify', 'app-uuid', collect(['https://example.com']), service_name: 'web.app', is_traffic_analytics_enabled: true, supports_log_append: true); $key = 'app-uuid-'.traefikSafeServiceNameSegment('web.app'); expect($key)->toMatch('/^[A-Za-z0-9-]+$/') ->and($labels->contains("caddy_0.log_append=coolify_app_id {$key}"))->toBeTrue() ->and($labels->contains('caddy_0.log.output=file /traffic/access.log'))->toBeTrue(); }); it('keeps only safe characters in the caddy traffic key', function () { $labels = fqdnLabelsForCaddy('coolify', "app uuid\n{x}", collect(['https://example.com']), is_traffic_analytics_enabled: true, supports_log_append: true); expect($labels->first(fn ($label) => str_contains($label, 'log_append'))) ->toBe('caddy_0.log_append=coolify_app_id app-uuid-x-'); });