Overview
Buildr’s containerization process is designed to be completely transparent to your application code. The entire workflow is triggered by a simple decorator, but underneath it orchestrates Dockerfile generation, image building, and container execution.Container Detection
The first critical step in the containerization process is determining whether the code is already running inside a container. This prevents infinite recursion where a containerized app tries to containerize itself.Detection Algorithm
Buildr uses a multi-layered approach to detect container execution:containerize.py:11-30
Environment Variable Check
First checks the
METAPARTICLE_IN_CONTAINER environment variable:trueor1→ Running in containerfalseor0→ Not in container- Not set → Continue to next check
Cgroup Analysis
Reads
/proc/1/cgroup to inspect the init process’s control group:- Contains
docker→ Docker container - Contains
kubepods→ Kubernetes pod - Otherwise → Not containerized
If
is_in_docker_container() returns True, the decorated function executes normally without any containerization steps.Dockerfile Generation
When containerization is needed, Buildr generates a Dockerfile optimized for Python applications:Auto-Generated Dockerfile
containerize.py:33-45
Dockerfile Structure
The auto-generated Dockerfile follows best practices:Base Image Selection
Base Image Selection
- Uses official Python Alpine Linux images for minimal size
- Version is controlled by
py_versionin package options (default: 3) - Alpine variant reduces image size significantly
Application Copy
Application Copy
- Copies the entire current directory to
/app/in the container - Includes your application code and
requirements.txt - Preserves directory structure
Dependency Installation
Dependency Installation
- Installs Python dependencies from
requirements.txt - Uses
--no-cacheto reduce image size - Requires a
requirements.txtfile in your project root
Command Specification
Command Specification
- Executes your Python script when the container starts
exec_fileis automatically determined fromsys.argv[0]- Runs as the container’s main process (PID 1)
Custom Dockerfile
You can provide your own Dockerfile for advanced use cases:When a custom Dockerfile is provided, Buildr copies it to
./Dockerfile and uses it for the build. This allows you to:- Use different base images
- Add custom build steps
- Include system dependencies
- Optimize layer caching
Executable Path Resolution
Buildr automatically determines which Python file to execute in the container:containerize.py:66-69
- Direct Execution
- Path Execution
When you run
python app.py:sys.argv[0]=app.py- No slash found, uses
app.pyas-is - Container CMD:
python /app/app.py
The Wrapper Function
The@Containerize decorator wraps your function to intercept execution:
containerize.py:62-85
Execution Flow
Signal Handling
Buildr provides graceful shutdown when you press Ctrl+C:containerize.py:77-80
SIGINT is received:
- Runner’s
cancel()method is called to stop the container - Python process exits cleanly with code 0
Complete Example
Here’s how all the pieces work together:example.py
Execution Trace
Best Practices
Always Include requirements.txt
The auto-generated Dockerfile expects
requirements.txt in your project root. Include all dependencies, even if just:Use .dockerignore
Exclude unnecessary files to speed up builds:
Pin Python Version
Specify
py_version for reproducible builds:Test Locally First
Run your code without containerization before adding the decorator to catch issues early
Next Steps
Builders
Learn how DockerBuilder creates images
Runners
Explore execution environments