Перейти к основному содержимому

Docker Compose Integration

Implementation Reference

Source Files:

  • packages/core/src/docker/compose.ts - Docker Compose operations
  • packages/core/src/docker/docker-client.ts - Docker client implementation
  • packages/core/src/adapters/docker-adapter.ts - Docker adapter
  • packages/core/src/docker/types.ts - Type definitions

Key Functions:

  • ComposeManager.up() - Start services
  • ComposeManager.down() - Stop and remove services
  • ComposeManager.exec() - Execute in service containers
  • ComposeManager.logs() - Get service logs
  • ComposeManager.ps() - List service containers
  • ComposeManager.restart() - Restart services

Overview

Xec provides seamless integration with Docker Compose, enabling multi-container application management through the execution engine. This allows you to orchestrate complex applications defined in docker-compose.yml files.

Compose File Support

Supported Versions

Xec supports Docker Compose file formats:

  • Version 2.x - Legacy format
  • Version 3.x - Most common format
  • Compose Specification - Latest format (recommended)

File Discovery

Compose files are discovered in order:

  1. Specified file path
  2. docker-compose.yml in current directory
  3. docker-compose.yaml in current directory
  4. compose.yml in current directory
  5. compose.yaml in current directory

Starting Services

Basic Operations

Start all services defined in compose file:

import { $ } from '@xec-sh/core';

// Start all services
await $.compose.up();

// Start specific services
await $.compose.up(['web', 'api']);

// Start with options
await $.compose.up({
detach: true, // Run in background
build: true, // Build images before starting
forceRecreate: true, // Recreate containers
noDepends: false, // Don't start dependencies
scale: {
worker: 3 // Scale worker service to 3 instances
}
});

// Start with custom compose file
await $.compose.up({
file: 'docker-compose.prod.yml',
project: 'myapp'
});

CLI Usage

# Start all services
xec compose up

# Start specific services
xec compose up web api

# Start with build
xec compose up --build

# Use specific compose file
xec compose -f docker-compose.prod.yml up

Stopping Services

Graceful Shutdown

Stop and optionally remove services:

// Stop all services (keep containers)
await $.compose.stop();

// Stop specific services
await $.compose.stop(['web', 'api']);

// Stop and remove containers
await $.compose.down();

// Remove with volumes
await $.compose.down({
volumes: true,
removeOrphans: true
});

// Stop with timeout
await $.compose.stop({
timeout: 30 // 30 seconds grace period
});

Service Execution

Running Commands in Services

Execute commands in service containers:

// Execute in service container
const result = await $.compose.exec('web', 'npm test');
console.log(result.stdout);

// Execute with options
await $.compose.exec('api', 'python manage.py migrate', {
user: 'app',
workdir: '/app',
env: {
DJANGO_SETTINGS: 'production'
}
});

// Interactive execution
await $.compose.exec('db', 'psql', {
interactive: true,
tty: true
});

// Execute in specific instance (scaled services)
await $.compose.exec('worker', 'celery inspect active', {
index: 2 // Third instance (0-indexed)
});

Running One-off Commands

Run commands in new containers:

// Run one-off command
await $.compose.run('web', 'npm run build');

// Run with options
await $.compose.run('api', 'python manage.py test', {
rm: true, // Remove container after run
no_deps: true, // Don't start dependencies
entrypoint: '/bin/sh', // Override entrypoint
user: 'root',
volumes: ['./data:/data']
});

Service Management

Restarting Services

Restart running services:

// Restart all services
await $.compose.restart();

// Restart specific services
await $.compose.restart(['web', 'worker']);

// Restart with timeout
await $.compose.restart({
timeout: 10
});

Scaling Services

Scale service instances:

// Scale services
await $.compose.scale({
web: 3,
worker: 5,
api: 2
});

// Scale with verification
const scaled = await $.compose.scale({
worker: 10
});

// Check scaling status
const services = await $.compose.ps();
const workerCount = services.filter(s => s.service === 'worker').length;
console.log(`Worker instances: ${workerCount}`);

Service Monitoring

Viewing Logs

Access service logs:

// Get all logs
const logs = await $.compose.logs();

// Get specific service logs
const webLogs = await $.compose.logs(['web']);

// Follow logs in real-time
const stream = $.compose.logs({
follow: true,
tail: 100,
timestamps: true
});

stream.on('data', (chunk) => {
console.log(chunk.toString());
});

// Stop following
stream.stop();

Service Status

Check service status:

// List all services
const services = await $.compose.ps();

services.forEach(service => {
console.log({
name: service.name,
service: service.service,
state: service.state,
ports: service.ports
});
});

// Check specific service
const isRunning = await $.compose.isRunning('web');

// Get service details
const details = await $.compose.inspect('api');

Environment Management

Environment Variables

Manage environment variables for services:

// Use .env file
await $.compose.up({
envFile: '.env.production'
});

// Override environment variables
await $.compose.up({
env: {
DATABASE_URL: 'postgres://localhost/myapp',
REDIS_URL: 'redis://localhost:6379'
}
});

// Service-specific environment
await $.compose.exec('web', 'npm start', {
env: {
NODE_ENV: 'production',
PORT: '3000'
}
});

Multiple Environments

Work with different environment configurations:

# Development
xec compose -f docker-compose.yml -f docker-compose.dev.yml up

# Production
xec compose -f docker-compose.yml -f docker-compose.prod.yml up

# Testing
xec compose -f docker-compose.test.yml up

Configuration in Xec

Compose Targets

Define compose services as targets in .xec/config.yaml:

targets:
compose:
web:
type: docker-compose
file: docker-compose.yml
service: web

api:
type: docker-compose
file: docker-compose.yml
service: api
workdir: /app

db:
type: docker-compose
file: docker-compose.yml
service: postgres
env:
PGUSER: postgres

# Multiple compose files
prod-web:
type: docker-compose
files:
- docker-compose.yml
- docker-compose.prod.yml
service: web
project: production

Compose Tasks

Define tasks for compose operations:

tasks:
dev:
description: Start development environment
steps:
- command: docker-compose up -d

test:
description: Run tests in containers
steps:
- command: docker-compose run --rm web npm test
- command: docker-compose run --rm api pytest

deploy:
description: Deploy with compose
params:
- name: env
values: [dev, staging, prod]
steps:
- command: docker-compose -f docker-compose.${params.env}.yml up -d
- command: docker-compose exec web npm run migrate

Advanced Features

Health Checks

Wait for services to be healthy:

// Wait for service health
await $.compose.waitHealthy('web', {
timeout: 60000,
interval: 2000
});

// Check all services health
const health = await $.compose.health();
const allHealthy = health.every(s => s.status === 'healthy');

Service Dependencies

Manage service dependencies:

// Start with dependencies
await $.compose.up(['web'], {
with_dependencies: true
});

// Start without dependencies
await $.compose.up(['worker'], {
no_deps: true
});

// Get dependency graph
const deps = await $.compose.dependencies();
console.log(deps);
// { web: ['api', 'db'], api: ['db'], worker: ['redis'] }

Build Management

Build and rebuild service images:

// Build all images
await $.compose.build();

// Build specific services
await $.compose.build(['web', 'api']);

// Build with options
await $.compose.build({
services: ['web'],
noCache: true,
pull: true,
parallel: true,
buildArgs: {
VERSION: '1.2.3'
}
});

// Rebuild and restart
await $.compose.up({
build: true,
forceRecreate: true
});

Multi-Project Support

Project Isolation

Work with multiple compose projects:

// Project A
await $.compose.up({
project: 'app-a',
file: 'app-a/docker-compose.yml'
});

// Project B
await $.compose.up({
project: 'app-b',
file: 'app-b/docker-compose.yml'
});

// List all projects
const projects = await $.compose.projects();

// Remove project
await $.compose.down({
project: 'app-a',
volumes: true
});

Performance Characteristics

Based on Implementation:

Operation Timings

  • Service Start: 1-5s per service (depends on image)
  • Service Stop: 100ms-10s (grace period)
  • Service Exec: 50-100ms overhead
  • Log Retrieval: 10-100ms
  • Health Check: 100-500ms per service

Resource Usage

  • Memory: ~2MB per service tracking
  • CPU: Minimal except during operations
  • Network: Unix socket communication

Error Handling

Common Errors

ErrorCodeSolution
Compose file not found7Check file path
Service not found3Verify service name
Port conflict8Change port mapping
Build failed8Check Dockerfile
Network error13Check network config

Error Recovery

// Retry with cleanup
async function safeComposeUp() {
try {
await $.compose.up();
} catch (error) {
if (error.message.includes('port is already allocated')) {
await $.compose.down();
await $.compose.up();
} else {
throw error;
}
}
}

// Health-based startup
async function startWithHealth() {
await $.compose.up({ detach: true });

const services = ['web', 'api', 'db'];
for (const service of services) {
await $.compose.waitHealthy(service);
}
}

Best Practices

Compose Management

  1. Use explicit project names - Avoid conflicts between projects
  2. Define health checks - Ensure reliable service state
  3. Use .env files - Manage environment-specific config
  4. Version control compose files - Track infrastructure changes
  5. Clean up resources - Remove unused volumes and networks

Development Workflow

# docker-compose.override.yml for local development
version: '3.8'
services:
web:
volumes:
- .:/app # Mount source code
environment:
- DEBUG=true
ports:
- "3000:3000"

db:
ports:
- "5432:5432" # Expose for debugging

Production Deployment

// Production deployment script
async function deployProduction() {
// Pull latest images
await $.compose.pull();

// Stop old containers
await $.compose.down();

// Start with production config
await $.compose.up({
file: 'docker-compose.prod.yml',
detach: true,
removeOrphans: true
});

// Wait for health
await $.compose.waitHealthy('web');

// Run migrations
await $.compose.exec('api', 'python manage.py migrate');
}