#435 App: Container Task Runner (container_runner)

closed low Created 2025-12-14 20:17 · Updated 2026-01-02 06:26

Description

Edit
## Overview Execute arbitrary Docker containers as workflow tasks with input/output handling. Enables extensibility for any workload. ## App Metadata - **App Name:** container_runner - **Publisher:** platform - **Version:** 1.0.0 - **Priority:** Low - **Complexity:** High - **Phase:** 3 (Advanced) ## Actions ### 1. run_container **Description:** Execute a Docker container and capture output **Parameters:** - image (str, required): Docker image name (e.g., 'python:3.11-slim') - command (list, optional): Command to run (overrides entrypoint) - args (list, optional): Arguments for command - environment (dict, optional): Environment variables - timeout_seconds (int, default=300): Container timeout - memory_limit (str, default='512m'): Memory limit - cpu_limit (float, default=1.0): CPU limit (cores) - network (str, default='none'): Network mode (none|bridge|host) - pull_policy (str, default='if_not_present'): Pull policy (always|if_not_present|never) **Returns:** { "success": true, "exit_code": 0, "stdout": "...", "stderr": "...", "duration_seconds": 45, "container_id": "abc123", "image_used": "python:3.11-slim" } ### 2. run_with_input **Description:** Run container with input data via stdin or volume **Parameters:** - image (str, required): Docker image name - command (list, optional): Command to run - input_data (str, optional): Data to pass via stdin - input_file (dict, optional): File to mount - content (str): File content - path (str): Mount path in container - output_file (str, optional): Path to read output file from container - (same resource limits as run_container) **Returns:** { "success": true, "exit_code": 0, "stdout": "...", "output_file_content": "...", "duration_seconds": 30 } ### 3. collect_output **Description:** Retrieve files from a container after execution **Parameters:** - container_id (str, required): Container ID from run_container - file_paths (list, required): Paths to retrieve - upload_to_s3 (bool, default=False): Upload files to S3 - s3_prefix (str, optional): S3 key prefix **Returns:** { "files": [ {"path": "/output/result.csv", "content": "...", "size_bytes": 1000}, {"path": "/output/report.pdf", "s3_url": "s3://...", "size_bytes": 50000} ] } ## Example Workflow - Run Python Script builder = WorkflowBuilder(name='run_python_analysis', version='1.0.0') builder.task( task_id='run_script', function='apps.platform.container_runner.run_with_input', kwargs={ 'image': 'python:3.11-slim', 'command': ['python', '/input/script.py'], 'input_file': { 'content': ''' import json data = {"result": sum(range(100))} print(json.dumps(data)) ''', 'path': '/input/script.py' }, 'timeout_seconds': 60 }, result_key='python_result' ) ## Example - Run ffmpeg Video Conversion builder.task( task_id='convert_video', function='apps.platform.container_runner.run_container', kwargs={ 'image': 'jrottenberg/ffmpeg:4.4-alpine', 'command': ['-i', '/input/video.mp4', '-vf', 'scale=640:480', '/output/small.mp4'], 'timeout_seconds': 600, 'memory_limit': '2g' } ) ## Security Considerations CRITICAL - Container execution is powerful but risky: - Whitelist allowed images (no arbitrary images) - Always use network='none' unless explicitly needed - Set strict resource limits - Never mount host paths except designated volumes - Run containers as non-root - Scan images for vulnerabilities (future) - Audit log all container executions ## Allowed Images Configuration { "allowed_images": [ "python:3.11-slim", "python:3.12-slim", "node:20-slim", "alpine:latest", "jrottenberg/ffmpeg:*", "imagemagick/imagemagick:*" ], "max_timeout_seconds": 3600, "max_memory": "4g", "max_cpu": 2.0, "enable_network": false } ## Implementation Notes - Use Docker SDK for Python (docker-py) - Workers already have Docker socket mounted - Create temporary volumes for input/output - Stream logs for long-running containers - Clean up containers and volumes after execution - Implement proper timeout handling (SIGTERM then SIGKILL) ## Docker Socket Security Workers mount /var/run/docker.sock - this gives container control. Mitigations: - Validate all inputs strictly - Use Docker API directly, not shell commands - Implement image whitelist - Log all operations - Consider rootless Docker in future ## Configuration Schema { "allowed_images": [], "default_timeout": 300, "default_memory": "512m", "default_cpu": 1.0, "max_timeout": 3600, "max_memory": "4g", "max_cpu": 4.0, "network_allowed": false, "cleanup_after_run": true } ## Secrets Config None (uses host Docker socket) ## Dependencies - docker (docker-py) Python SDK - Docker socket mounted on workers (already configured) - S3 for large file outputs (optional)

Comments

Loading comments...

Context

Loading context...

Audit History

View All
Loading audit history...