Implement multi-container app installation for Immich and Penpot, enhance Docker package scanning, and update Nginx configuration for iframe support

- Added support for installing Immich and Penpot stacks, including necessary Docker images and network configurations.
- Updated DockerPackageScanner to exclude Immich and Penpot related containers from app listings.
- Enhanced Nginx configuration to support iframe embedding for Immich and Penpot applications, improving user experience.
- Modified deployment scripts to ensure proper setup of first-boot container creation services.
This commit is contained in:
Dorian
2026-02-25 18:04:41 +00:00
parent f0ef84e4a5
commit 4cb9ac1faa
12 changed files with 876 additions and 30 deletions

View File

@@ -1,16 +1,35 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
/** BTCPay and Home Assistant set X-Frame-Options and don't support subpath proxy - open in new tab */
/** Apps that set X-Frame-Options and/or don't support subpath proxy - open in new tab for correct display */
function mustOpenInNewTab(url: string): boolean {
try {
const u = new URL(url)
return u.port === '23000' || u.port === '8123'
return (
u.port === '23000' || // BTCPay
u.port === '8123' || // Home Assistant
u.port === '8085' || // Nextcloud (subpath breaks CSS/assets)
u.port === '2283' // Immich (subpath breaks SPA)
)
} catch {
return false
}
}
/** Rewrite to same-origin proxy so iframe can embed (nginx strips X-Frame-Options) */
function toEmbeddableUrl(url: string): string {
try {
const u = new URL(url)
const origin = window.location.origin
// Only Vaultwarden and Penpot support subpath proxy; Nextcloud/Immich open in new tab
if (u.port === '8082') return `${origin}/app/vaultwarden/`
if (u.port === '9001') return `${origin}/app/penpot/`
} catch {
/* ignore */
}
return url
}
export const useAppLauncherStore = defineStore('appLauncher', () => {
const isOpen = ref(false)
const url = ref('')
@@ -23,7 +42,7 @@ export const useAppLauncherStore = defineStore('appLauncher', () => {
return
}
previousActiveElement = (document.activeElement as HTMLElement) || null
url.value = payload.url
url.value = toEmbeddableUrl(payload.url)
title.value = payload.title
isOpen.value = true
}