refactor: update ComposeService and DockerController for improved error handling and path configuration; adjust docker-compose.yml for clarity on volume mappings

This commit is contained in:
SaelixCode
2026-02-20 23:06:18 -05:00
parent c301c2f9d6
commit e686508dec
3 changed files with 26 additions and 14 deletions
+4 -1
View File
@@ -6,7 +6,7 @@ export class ComposeService {
private baseDir: string; private baseDir: string;
constructor() { constructor() {
this.baseDir = process.env.COMPOSE_DIR || path.join(process.cwd(), '..', 'docker', 'compose'); this.baseDir = process.env.COMPOSE_DIR || '/app/compose';
} }
/** /**
@@ -45,6 +45,7 @@ export class ComposeService {
}); });
child.on('error', (error: Error) => { child.on('error', (error: Error) => {
console.error(`Docker Compose Error for ${stackName}:`, error.message);
ws.send(`Error: ${error.message}\n`); ws.send(`Error: ${error.message}\n`);
}); });
} }
@@ -93,6 +94,7 @@ export class ComposeService {
}); });
pullProcess.on('error', (error: Error) => { pullProcess.on('error', (error: Error) => {
console.error(`Docker Compose Pull Error for ${stackName}:`, error.message);
sendOutput(`Pull error: ${error.message}\n`); sendOutput(`Pull error: ${error.message}\n`);
reject(error); reject(error);
}); });
@@ -128,6 +130,7 @@ export class ComposeService {
}); });
upProcess.on('error', (error: Error) => { upProcess.on('error', (error: Error) => {
console.error(`Docker Compose Up Error for ${stackName}:`, error.message);
sendOutput(`Update error: ${error.message}\n`); sendOutput(`Update error: ${error.message}\n`);
reject(error); reject(error);
}); });
+13 -6
View File
@@ -38,7 +38,7 @@ class DockerController {
public async getContainersByStack(stackName: string) { public async getContainersByStack(stackName: string) {
try { try {
const stackDir = path.join(COMPOSE_DIR, stackName); const stackDir = path.join(COMPOSE_DIR, stackName);
const { stdout } = await execAsync('docker compose ps --format json -a', { const { stdout, stderr } = await execAsync('docker compose ps --format json -a', {
cwd: stackDir, cwd: stackDir,
env: { env: {
...process.env, ...process.env,
@@ -65,10 +65,16 @@ class DockerController {
// Try parsing as a standard JSON array // Try parsing as a standard JSON array
const parsed = JSON.parse(stdout); const parsed = JSON.parse(stdout);
containers = Array.isArray(parsed) ? parsed : [parsed]; containers = Array.isArray(parsed) ? parsed : [parsed];
} catch { } catch (parseError) {
// Fallback: parse newline-separated JSON objects, filtering out empty lines // Fallback: parse newline-separated JSON objects, filtering out empty lines
const lines = stdout.trim().split('\n').filter(line => line.trim() !== ''); try {
containers = lines.map(line => JSON.parse(line) as ComposeContainer); const lines = stdout.trim().split('\n').filter(line => line.trim() !== '');
containers = lines.map(line => JSON.parse(line) as ComposeContainer);
} catch (innerError) {
// Log parsing failure with stderr for debugging
console.error(`Docker Compose JSON Parse Error for ${stackName}:`, stderr || (parseError as Error).message);
return [];
}
} }
// Map to frontend's expected interface // Map to frontend's expected interface
@@ -81,8 +87,9 @@ class DockerController {
Status: c.Status || '' Status: c.Status || ''
})); }));
} catch (error) { } catch (error) {
// If command fails (e.g., stack not deployed), return empty array // If command fails (e.g., stack not deployed, invalid YAML, missing env_file)
console.error('Failed to get containers for stack:', stackName, error); const execError = error as { stderr?: string; message?: string };
console.error(`Docker Compose Error for ${stackName}:`, execError.stderr || execError.message);
return []; return [];
} }
} }
+9 -7
View File
@@ -9,12 +9,14 @@ services:
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
# DATA DIRECTORY # Persistent data for your admin login
# Left Side: Where Sencho saves your admin login (Change this if you want it elsewhere)
# Right Side: Internal container path (DO NOT CHANGE)
- ./data:/app/data - ./data:/app/data
# STACKS DIRECTORY # ⚠️ THE 1:1 PATH RULE (MUST MATCH EXACTLY)
# Left Side: The absolute path to your Docker compose stacks on your server # Left Side (Host) === Right Side (Container)
# Right Side: Internal container path (DO NOT CHANGE) # Change both sides to where you actually store your compose files!
- /path/to/your/server/stacks:/app/compose - /opt/stacks:/opt/stacks
environment:
# This MUST match the path you set in the volumes above!
- COMPOSE_DIR=/opt/stacks