feat(settings): configure CDN URL for stored images

Add a persisted instance setting for S3 image CDN URLs and use it when building image links. Cache profile avatars and project icons with immutable one-year headers.
This commit is contained in:
Andras Bacsai
2026-09-04 21:15:06 +02:00
parent 9c3fb1da39
commit 3c0e43f482
13 changed files with 82 additions and 16 deletions
@@ -9,7 +9,7 @@
listboxes (API, MCP, telemetry, ) update the snapshot on the server
immediately; without wire:target they briefly flash this bar. --}}
<x-unsaved-bar action="submit"
targets="custom_dns_servers,allowed_ips,webhook_allowed_internal_hosts,webhook_allow_localhost,domain_connect_private_key" />
targets="custom_dns_servers,allowed_ips,webhook_allowed_internal_hosts,webhook_allow_localhost,domain_connect_private_key,image_cdn_url" />
<x-application.settings-section id="access-section" title="Access">
<div class="grid gap-4 lg:grid-cols-2">
@@ -144,9 +144,11 @@
<x-application.settings-section id="avatar-storage-section" title="Image storage"
helper="Choose where compressed profile pictures and project icons are stored. Use S3 for multi-instance or cloud deployments so every application replica can access the same files.">
<div class="max-w-md">
<div class="flex max-w-md flex-col gap-4">
<x-forms.listbox id="avatar_storage" label="Storage destination" onChange="instantSave"
:options="$avatar_storage_options" />
<x-forms.input id="image_cdn_url" label="Image CDN URL"
helper="Optional public CDN URL for profile pictures and project icons stored on S3. Leave empty to use the S3 endpoint." placeholder="https://images.example.com" />
</div>
@if (count($avatar_storage_options) === 1)
<x-callout type="info" title="No usable S3 storage configured" class="mt-4">