@@ -5,9 +5,34 @@ import { isAuthEnabled, validateSession } from '$lib/server/auth';
55import { setServerStartTime } from '$lib/server/uptime' ;
66import { checkLicenseExpiry , getHostname } from '$lib/server/license' ;
77import { initCryptoFallback } from '$lib/server/crypto-fallback' ;
8+ import { detectHostDataDir } from '$lib/server/host-path' ;
9+ import { listContainers , removeContainer } from '$lib/server/docker' ;
10+ import { rmSync , readdirSync , existsSync } from 'fs' ;
11+ import { join } from 'path' ;
812import type { HandleServerError , Handle } from '@sveltejs/kit' ;
913import { redirect } from '@sveltejs/kit' ;
1014
15+ // Cleanup orphaned scanner version containers from previous runs
16+ async function cleanupOrphanedScannerContainers ( ) {
17+ try {
18+ const containers = await listContainers ( true ) ;
19+ const orphaned = containers . filter ( c =>
20+ c . name ?. startsWith ( 'dockhand-grype-version-' ) ||
21+ c . name ?. startsWith ( 'dockhand-trivy-version-' )
22+ ) ;
23+ for ( const c of orphaned ) {
24+ try {
25+ await removeContainer ( c . id , true ) ;
26+ } catch { /* ignore */ }
27+ }
28+ if ( orphaned . length > 0 ) {
29+ console . log ( `[Startup] Cleaned up ${ orphaned . length } orphaned scanner containers` ) ;
30+ }
31+ } catch ( error ) {
32+ // Silently ignore - Docker may not be available yet or no containers to clean
33+ }
34+ }
35+
1136// License expiry check interval (24 hours)
1237const LICENSE_CHECK_INTERVAL = 86400000 ;
1338
@@ -24,10 +49,46 @@ if (!initialized) {
2449 // Initialize crypto fallback first (detects old kernels and logs status)
2550 initCryptoFallback ( ) ;
2651
52+ // Cleanup orphaned TLS temp directories from previous crashes
53+ const dataDir = process . env . DATA_DIR || './data' ;
54+ const tmpDir = join ( dataDir , 'tmp' ) ;
55+ if ( existsSync ( tmpDir ) ) {
56+ try {
57+ const entries = readdirSync ( tmpDir ) ;
58+ for ( const entry of entries ) {
59+ if ( entry . startsWith ( 'tls-' ) ) {
60+ const path = join ( tmpDir , entry ) ;
61+ try {
62+ rmSync ( path , { recursive : true , force : true } ) ;
63+ console . log ( `[Startup] Cleaned orphaned TLS temp dir: ${ entry } ` ) ;
64+ } catch { /* ignore */ }
65+ }
66+ }
67+ } catch { /* ignore */ }
68+ }
69+
2770 setServerStartTime ( ) ; // Track when server started
2871 initDatabase ( ) ;
2972 // Log hostname for license validation (set by entrypoint in Docker, or os.hostname() outside)
3073 console . log ( 'Hostname for license validation:' , getHostname ( ) ) ;
74+
75+ // Detect host data directory for path translation
76+ // This allows Dockhand to translate container paths to host paths for compose volume mounts
77+ detectHostDataDir ( ) . then ( hostPath => {
78+ if ( hostPath ) {
79+ console . log ( `[Startup] Host data directory detected: ${ hostPath } ` ) ;
80+ } else {
81+ console . warn ( '[Startup] Could not detect host data path.' ) ;
82+ console . warn ( '[Startup] Git stacks with relative volume paths may not work correctly.' ) ;
83+ console . warn ( '[Startup] Consider setting HOST_DATA_DIR or using matching volume paths (-v /app/data:/app/data)' ) ;
84+ }
85+ } ) . catch ( err => {
86+ console . error ( '[Startup] Failed to detect host data directory:' , err ) ;
87+ } ) ;
88+ // Cleanup orphaned scanner containers from previous runs (non-blocking)
89+ cleanupOrphanedScannerContainers ( ) . catch ( err => {
90+ console . error ( 'Failed to cleanup orphaned scanner containers:' , err ) ;
91+ } ) ;
3192 // Start background subprocesses for metrics and event collection (isolated processes)
3293 startSubprocesses ( ) . catch ( err => {
3394 console . error ( 'Failed to start background subprocesses:' , err ) ;
@@ -174,4 +235,3 @@ export const handleError: HandleServerError = ({ error, event }) => {
174235 code : 'INTERNAL_ERROR'
175236 } ;
176237} ;
177- // CI trigger 1766327149
0 commit comments