How Buildr Works
Buildr uses a decorator pattern to transform your Python functions into containerized applications. When you decorate a function with@Containerize, Buildr intercepts the function call and orchestrates a complete build-and-run lifecycle.
Core Architecture
Buildr’s architecture consists of three main components:Containerize
The main decorator that orchestrates the entire containerization workflow
Builder
Responsible for building container images from your code
Runner
Executes the containerized application in the target environment
The Decorator Pattern
Buildr leverages Python decorators to provide a seamless containerization experience. Here’s how it works:containerize.py:48-86
Decorator Initialization
When you apply the@Containerize decorator, the __init__ method runs immediately:
- Load Options - Runtime and package options are validated and loaded
- Generate Image Name - Constructs the Docker image tag from repository and name
- Select Components - Initializes the appropriate builder and runner based on configuration
Build and Run Lifecycle
When your decorated function is called, Buildr executes a sophisticated lifecycle:Container Detection
Buildr first checks if the code is already running inside a container using If already in a container, the function executes normally and the lifecycle ends.
is_in_docker_container():containerize.py:11-30
Dockerfile Generation
If not in a container, Buildr generates a Dockerfile tailored to your application:You can provide a custom Dockerfile or use the auto-generated one.
containerize.py:33-45
Image Build
The selected builder (e.g., DockerBuilder) builds the container image:
containerize.py:72
Image Publish (Optional)
If
publish: True is set, the image is pushed to the registry:containerize.py:74-75
Component Selection
Buildr uses a factory pattern to select the appropriate builder and runner:- Builder Selection
- Runner Selection
builder/__init__.py:4-7
docker- Uses Docker API to build images (default)
Configuration System
Buildr uses named tuples for type-safe configuration:Runtime Options
Runtime Options
option.py:21-25
executor: Runtime environment (docker/metaparticle)replicas: Number of container replicasports: Port mappings for the containerpublic: Whether to expose the service publiclyshardSpec: Sharding configurationjobSpec: Job execution configuration
Package Options
Package Options
option.py:42-47
repository: Required - Docker registry repositoryname: Container name (defaults to current directory)builder: Builder to use (default: ‘docker’)publish: Whether to push to registrypy_version: Python version for base image (default: 3)dockerfile: Path to custom Dockerfile (optional)
Usage Example
Here’s a complete example showing all components in action:When you run this script, Buildr will:
- Detect you’re not in a container
- Generate a Dockerfile
- Build the image as
docker.io/myrepo/my-service:latest - Push the image to the registry
- Run the container with port 8080 exposed
- Stream logs to your terminal
Next Steps
Containerization
Deep dive into the containerization process
Builders
Learn about the builder system
Runners
Explore different execution environments