Skip to content

durableprogramming/composek

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

composek

A command-line tool for reading and setting values in Docker Compose YAML files, built with care for those who need steady, trustworthy tools in their daily work.

Why composek Exists

Docker Compose files grow complex over time. Teams need to change settings, swap out image tags, and shift environment values across many files and settings. Doing this by hand leads to mistakes. Using sed or awk feels fragile. composek fills this gap with a tool built just for this job.

The tool follows the Durable Programming way of thinking - software should be clear, stable, and built to last. Rather than chase the newest trends, composek focuses on doing one thing well: helping you work with Docker Compose files without fear of breaking them.

What composek Does

At its heart, composek reads and writes Docker Compose YAML files. It knows the shape of these files and works with that knowledge to make safe changes. The tool can:

  • Read any value from a compose file using a simple path syntax
  • Set new values while keeping the rest of the file intact
  • Work with complex nested structures without breaking formatting
  • Handle multiple services, volumes, networks, and configs
  • Process many files at once for bulk updates
  • Output results in formats that work well with other tools

The design puts safety first. When composek changes a file, it keeps comments, order, and spacing as much as the YAML format allows. This means your files stay readable and your git diffs stay clean.

Getting Started

Install composek through your system's package manager or build from source:

# From source with Rust
cargo install composek

# On Debian/Ubuntu (once packaged)
apt install composek

# With Nix
nix-env -i composek

Once installed, you can start reading values right away:

# Get the image for a service
composek get docker-compose.yml services.web.image

# Check a port mapping
composek get docker-compose.yml services.web.ports[0]

Setting values works just as simply:

# Update an image tag
composek set docker-compose.yml services.web.image nginx:1.21

# Change an environment variable
composek set docker-compose.yml services.web.environment.DEBUG true

How It Works

composek uses a path syntax to find values in your compose files. Think of it like a street address - you start broad and get more specific:

  • services.web.image - The image for the web service
  • services.web.ports[0] - The first port mapping for the web service
  • services.web.environment.DATABASE_URL - An environment variable
  • volumes.data.driver - The driver for a volume named 'data'

The tool understands Docker Compose file structure. It knows that services have images, environments can be lists or maps, and ports follow certain patterns. This knowledge helps it make smart choices about how to read and write data.

Reading Values

The get command pulls out values and prints them to stdout:

# Simple value
composek get docker-compose.yml services.web.image
# Output: nginx:latest

# Array value
composek get docker-compose.yml services.web.ports
# Output: 
# - "80:80"
# - "443:443"

# Nested object
composek get docker-compose.yml services.web.deploy
# Output (as YAML):
# replicas: 3
# restart_policy:
#   condition: on-failure

You can control output format with flags:

  • --json - Output as JSON for parsing by other tools
  • --raw - Output plain values without quotes or formatting
  • --yaml - Output as YAML (default for complex values)

Setting Values

The set command changes values while keeping your file's structure intact:

# Simple replacement
composek set docker-compose.yml services.web.image nginx:alpine

# Set nested value
composek set docker-compose.yml services.web.deploy.replicas 5

# Add new environment variable
composek set docker-compose.yml services.web.environment.NEW_VAR "value"

# Update array element
composek set docker-compose.yml services.web.ports[0] "8080:80"

The tool makes backup files by default before changing anything. Use --no-backup if you don't want this safety net.

Working with Multiple Files

Real projects often have many compose files - one for dev, one for staging, one for production. composek handles this:

# Update image across all files
composek set --file-pattern "docker-compose*.yml" services.web.image myapp:v2.0

# Get values from multiple files
composek get docker-compose.yml docker-compose.prod.yml services.web.image

# Process files in subdirectories
composek set --recursive . services.web.image nginx:stable

Real-World Use Cases

CI/CD Pipelines

Build systems need to update image tags after creating new versions:

# In your build script
NEW_TAG="myapp:${BUILD_NUMBER}"
composek set docker-compose.yml services.api.image "$NEW_TAG"
composek set docker-compose.yml services.worker.image "$NEW_TAG"

Environment Management

Switch settings between environments without maintaining multiple copies of the same file:

# Switch to production database
composek set docker-compose.yml services.api.environment.DATABASE_URL "$PROD_DB_URL"

# Enable debug mode for development
composek set docker-compose.yml services.api.environment.DEBUG true

Bulk Updates

Update many services at once when infrastructure changes:

# Update all Redis connections
for service in api worker cache; do
  composek set docker-compose.yml services.$service.environment.REDIS_URL "redis://new-host:6379"
done

Configuration Validation

Check that your compose files match expected values:

# Verify production settings
IMAGE=$(composek get docker-compose.prod.yml services.web.image)
if [[ $IMAGE != *":stable" ]]; then
  echo "Warning: Production not using stable image tag"
  exit 1
fi

Advanced Features

Path Expressions

Beyond simple paths, composek supports more complex queries:

  • Wildcards: services.*.image - Get all service images
  • Filters: services.*.ports[?(@=~"80:")] - Find services using port 80
  • Deep search: **.environment.DEBUG - Find DEBUG setting anywhere

Merge and Override

When Docker Compose merges multiple files, composek can simulate this:

# See effective configuration
composek merge docker-compose.yml docker-compose.override.yml -o effective.yml

# Get value after merge
composek get --merge docker-compose.yml docker-compose.prod.yml services.web.image

Template Support

Use composek with template files for dynamic configuration:

# Replace placeholders
composek set template.yml services.web.image "{{IMAGE_TAG}}"
composek template template.yml --var IMAGE_TAG=v1.2.3 -o docker-compose.yml

Validation

Check that your compose files are valid before using them:

# Validate syntax and structure
composek validate docker-compose.yml

# Check against Docker Compose schema
composek validate --strict docker-compose.yml

Design Philosophy

composek embodies several key principles from the Durable Programming philosophy:

Simplicity Over Complexity - The tool does one job well rather than trying to be a general YAML processor. It understands Docker Compose specifically, which lets it be both simpler and more powerful for this use case.

Safety First - Changes to infrastructure files can break deployments. composek takes several steps to prevent accidents:

  • Backups before changes
  • Validation of input values
  • Preservation of file structure
  • Clear error messages when things go wrong

Composability - Like Unix tools, composek works well in pipelines. It reads from stdin, writes to stdout, and returns proper exit codes. This makes it easy to combine with grep, jq, and other command-line tools.

Long-Term Thinking - The tool is built to last. It uses stable libraries, avoids needless dependencies, and maintains backward compatibility. Your scripts written today should still work in five years.

Error Handling

When things go wrong, composek gives clear, helpful error messages:

$ composek get docker-compose.yml services.web.imagen
Error: Path not found: services.web.imagen
Did you mean: services.web.image

$ composek set docker-compose.yml services.web.ports "80"
Error: Invalid value for ports - expected array, got string
Example: composek set docker-compose.yml services.web.ports '["80:80"]'

The tool returns different exit codes for different problems:

  • 0 - Success
  • 1 - General error
  • 2 - File not found
  • 3 - Path not found
  • 4 - Invalid value type
  • 5 - Validation error

Performance

composek is built for speed without sacrificing safety. It can process hundreds of files in seconds, making it suitable for large monorepos with many services. The tool uses:

  • Streaming YAML parser for large files
  • Parallel processing for multiple files
  • Minimal memory usage through careful data structure design
  • Smart caching when reading the same file multiple times

Integration Examples

Git Hooks

Prevent commits with invalid compose files:

#!/bin/bash
# .git/hooks/pre-commit
if ! composek validate docker-compose*.yml; then
  echo "Compose file validation failed"
  exit 1
fi

Makefiles

Integrate composek into your build process:

VERSION := $(shell git describe --tags --always)

update-version:
	composek set docker-compose.yml services.api.image myapp:$(VERSION)
	composek set docker-compose.yml services.worker.image myapp:$(VERSION)

deploy: update-version
	docker-compose up -d

Shell Scripts

Build robust deployment scripts:

#!/bin/bash
set -e

# Configuration
ENV=${1:-production}
IMAGE_TAG=${2:-latest}

# Update compose file for environment
composek set docker-compose.yml services.web.image "myapp:${IMAGE_TAG}"

# Set environment-specific values
case $ENV in
  production)
    composek set docker-compose.yml services.web.deploy.replicas 3
    composek set docker-compose.yml services.web.environment.LOG_LEVEL warn
    ;;
  staging)
    composek set docker-compose.yml services.web.deploy.replicas 1
    composek set docker-compose.yml services.web.environment.LOG_LEVEL debug
    ;;
esac

# Deploy
docker-compose up -d

Troubleshooting

Common Issues

File Not Found

$ composek get docker-compose.yml services.web.image
Error: Cannot open file: docker-compose.yml

Make sure you're in the right directory or use full paths.

Invalid Path Syntax

$ composek get docker-compose.yml services/web/image
Error: Invalid path syntax. Use dots to separate path segments.
Example: services.web.image

Type Mismatches

$ composek set docker-compose.yml services.web.ports "80:80"
Error: ports must be an array. Use '["80:80"]' or set individual elements with ports[0]

Debug Mode

Run with -v or --verbose for detailed output:

composek -v get docker-compose.yml services.web.image
# Shows parsing steps and path resolution

Contributing

composek welcomes contributions that align with its philosophy of simplicity and reliability. Before adding features, ask:

  • Does this solve a real problem for Docker Compose users?
  • Can it be done simply without adding complexity?
  • Will it remain stable as Docker Compose evolves?

The project maintains high standards for:

  • Clear, well-tested code
  • Comprehensive documentation
  • Backward compatibility
  • Helpful error messages

License

composek is released under the MIT License, allowing free use in both open source and commercial projects. This choice reflects our belief that good tools should be available to all who need them.

Support

For bugs and feature requests, open an issue on GitHub. For questions about using composek in your workflow, check the wiki or discussions. Commercial support is available for organizations needing guaranteed response times or custom features.

Remember: composek is built by people who use Docker Compose every day and feel the same pain points you do. It's a tool made to last, designed to fit into your workflow without friction, and maintained with care for the long term.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages