78 lines
2.5 KiB
TypeScript
78 lines
2.5 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;
|
|
}
|
|
|
|
interface DockerComposeServiceConfig {
|
|
container_name?: string;
|
|
profiles?: string[];
|
|
ports?: Array<string | number>;
|
|
}
|
|
|
|
/**
|
|
* 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 DockerComposeServiceConfig;
|
|
|
|
// 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?.[1] ? 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));
|
|
}
|