platform-tooling/run/utils/docker-compose-parser.ts
Quinn Ftw 85621b287e chore: snapshot before monorepo consolidation
Capture current working state before converting platform-tooling
into a submodule of the lilith-platform monorepo.
2026-01-29 07:04:39 -08:00

72 lines
2.3 KiB
TypeScript

/**
* Docker Compose Parser
*
* Parses docker-compose.yml to extract container definitions and port mappings.
* Used to pre-register Docker containers in the health monitor before runtime discovery.
*/
import * as yaml from 'yaml';
import * as fs from 'fs';
import * as path from 'path';
export interface DockerServiceDefinition {
name: string;
containerName: string;
port?: number;
profile?: string;
}
/**
* Parse docker-compose.yml and extract service definitions
*
* @param composePath Path to docker-compose.yml file
* @returns Array of service definitions with container names, ports, and profiles
*/
export function parseDockerComposeServices(composePath: string): DockerServiceDefinition[] {
const content = fs.readFileSync(composePath, 'utf-8');
const compose = yaml.parse(content);
const services: DockerServiceDefinition[] = [];
for (const [serviceName, serviceConfig] of Object.entries(compose.services || {})) {
const config = serviceConfig as any;
// Extract container name (replace ${LILITH_ENV:-dev} with 'dev')
const containerName = config.container_name?.replace('${LILITH_ENV:-dev}', 'dev');
// Extract profile (first profile if multiple defined)
const profile = config.profiles?.[0];
// Extract first exposed port from port mappings
let port: number | undefined;
if (config.ports && Array.isArray(config.ports)) {
const portMapping = config.ports[0];
if (typeof portMapping === 'string') {
// Handle formats: "5432:5432", "${NGINX_HTTP_PORT:-80}:80", "'${VAR}:5432'"
const match = portMapping.match(/^['"]?\$?\{?[^}]*:-?(\d+)\}?['"]?:/) || portMapping.match(/^['"]?(\d+):/);
port = match ? parseInt(match[1], 10) : undefined;
}
}
if (containerName) {
services.push({ name: serviceName, containerName, port, profile });
}
}
return services;
}
/**
* Get Docker services for specific profiles
*
* @param composePath Path to docker-compose.yml file
* @param profiles Array of profile names to filter (e.g., ['core', 'platform'])
* @returns Filtered service definitions matching the profiles
*/
export function getServicesForProfiles(
composePath: string,
profiles: string[]
): DockerServiceDefinition[] {
const allServices = parseDockerComposeServices(composePath);
return allServices.filter(s => s.profile && profiles.includes(s.profile));
}