The AaC Builder is responsible for transforming agent configurations into deployable container images. It handles the complete build process from parsing agent.yaml to generating Docker images.
The builder performs these key functions:
- Configuration Parsing: Loads and validates agent.yaml
- Dockerfile Generation: Creates optimized Dockerfiles based on runtime
- Image Building: Uses Docker BuildKit for efficient builds
- Context Management: Creates optimized build contexts
- Multi-Platform Support: Handles different target platforms
The builder integrates with:
- Parser: For configuration validation
- Docker Engine: For image building
- BuildKit: For optimized builds
type Builder struct {
parser *parser.Parser
dockerClient *client.Client
}type BuildOptions struct {
Path string // Build context path
Tag string // Image tag
NoCache bool // Disable build cache
Push bool // Push after build
Platform string // Target platform
}type BuildResult struct {
ImageID string // Docker image ID
Size string // Image size (human readable)
Tags []string // Applied tags
}The builder first validates the build context:
- Checks for agent.yaml existence
- Parses and validates configuration
- Ensures all required files are present
Generates runtime-specific Dockerfiles:
FROM python:3.11-slim
WORKDIR /app
# Install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Environment variables
ENV OPENAI_API_KEY=your_key
# Expose ports
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD ["curl", "http://localhost:8080/health"]
# Run the application
CMD ["python", "main.py"]FROM node:18-slim
WORKDIR /app
# Install Node.js dependencies
COPY package*.json .
RUN npm ci --only=production
# Copy application code
COPY . .
# Environment variables
ENV NODE_ENV=production
# Expose ports
EXPOSE 8080
# Run the application
CMD ["node", "index.js"]FROM golang:1.21-alpine AS builder
FROM alpine:latest
WORKDIR /app
# Copy application code
COPY . .
# Expose ports
EXPOSE 8080
# Run the application
CMD ["./app"]Creates optimized tar archives for Docker builds:
- Excludes hidden files and directories
- Includes all source code and dependencies
- Optimizes for layer caching
Uses Docker API for building:
- Streams build output in real-time
- Handles build errors gracefully
- Provides progress feedback
- Base Image:
python:3.11-slim - Dependencies:
requirements.txt - Entry Point:
python main.py - Package Manager: pip
- Base Image:
node:18-slim - Dependencies:
package.json - Entry Point:
node index.js - Package Manager: npm
- Base Image:
golang:1.21-alpine(build),alpine:latest(runtime) - Dependencies: Go modules
- Entry Point:
./app - Build Process: Multi-stage build
spec:
environment:
- name: OPENAI_API_KEY
value: "your-api-key"
- name: LOG_LEVEL
value: "INFO"spec:
ports:
- container: 8080
host: 8080
protocol: tcpspec:
healthCheck:
command: ["curl", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
startPeriod: 5sspec:
dependencies:
- openai==1.0.0
- fastapi==0.104.0
- uvicorn==0.24.0# Build from current directory
agent build -t my-agent:latest .
# Build with specific tag
agent build -t my-agent:v1.0.0 .
# Build without cache
agent build -t my-agent:latest . --no-cachepackage main
import (
"fmt"
"github.com/pxkundu/agent-as-code/internal/builder"
)
func main() {
// Create builder instance
b := builder.New()
// Build options
options := &builder.BuildOptions{
Path: "./my-agent",
Tag: "my-agent:latest",
NoCache: false,
Push: false,
Platform: "linux/amd64",
}
// Build the agent
result, err := b.Build(options)
if err != nil {
fmt.Printf("Build failed: %v\n", err)
return
}
fmt.Printf("Build successful: %s\n", result.ImageID)
fmt.Printf("Image size: %s\n", result.Size)
}// Validate build context before building
err := b.ValidateContext("./my-agent")
if err != nil {
fmt.Printf("Invalid context: %v\n", err)
return
}- Dependencies installed first (cached layer)
- Source code copied last (changes frequently)
- Multi-stage builds for complex agents
- Excludes unnecessary files
- Minimizes build context size
- Optimizes for Docker layer caching
- Pins dependency versions
- Uses production-only dependencies
- Minimizes image size
- Missing agent.yaml: "no agent.yaml found"
- Invalid configuration: "invalid agent.yaml"
- Docker not available: "Docker client not available"
- Build context errors: "failed to create build context"
# Check Docker status
docker info
# Verify agent.yaml
agent build --validate-only .
# Enable verbose logging
export AAC_LOG_LEVEL=debug
agent build -t my-agent .Dockerfile.agent: Generated Dockerfile- Container image with specified tag
- Build logs and progress information
- Image ID and digest
- Size and layer information
- Applied tags and labels
# Build for specific platform
agent build -t my-agent:latest . --platform linux/arm64
# Build for multiple platforms
agent build -t my-agent:latest . --platform linux/amd64,linux/arm64# build-profiles.yaml
profiles:
development:
base_image: python:3.11-slim
debug: true
production:
base_image: python:3.11-slim
debug: false
optimization: truespec:
runtime: python
build:
base_image: custom/python:3.11
optimization: true// Build and push
result, err := b.Build(options)
if err != nil {
return err
}
// Push to registry
err = b.Push(options.Tag)
if err != nil {
return err
}// Build for runtime execution
result, err := b.Build(options)
if err != nil {
return err
}
// Use with runtime
runtime := runtime.New()
runOptions := &runtime.RunOptions{
Image: result.ImageID,
Ports: []string{"8080:8080"},
}- Use layer caching effectively
- Minimize dependency changes
- Optimize build context
- Stream large files
- Use efficient tar creation
- Monitor Docker daemon resources
- Use local Docker registry for development
- Optimize dependency downloads
- Cache base images locally
- Use multi-stage builds for complex agents
- Minimize layer count
- Optimize dependency installation
- Use minimal base images
- Scan for vulnerabilities
- Validate dependencies
- Pin dependency versions
- Use deterministic builds
- Document build environment
- Track build times
- Monitor image sizes
- Log build failures
-
Docker Issues
- Check Docker daemon status
- Verify Docker version compatibility
- Check available disk space
-
Configuration Issues
- Validate agent.yaml syntax
- Check required fields
- Verify runtime support
-
Dependency Issues
- Check dependency versions
- Verify package compatibility
- Test dependency installation
# Enable debug mode
export AAC_LOG_LEVEL=debug
# Show Docker info
docker info
# Check build context
ls -la
# Validate configuration
agent build --validate-only .- Parser - Configuration parsing
- Runtime - Agent execution
- Registry - Image distribution
- CLI Overview - Command-line usage
- Agent Configuration - Configuration reference