feat: add docker_volumes config for custom volume mounts

This commit is contained in:
Gesina Sands
2026-02-28 07:12:48 +10:00
parent e3cb957a10
commit f7677ed275
4 changed files with 44 additions and 3 deletions

8
cli.py
View File

@@ -285,6 +285,7 @@ def load_cli_config() -> Dict[str, Any]:
"container_memory": "TERMINAL_CONTAINER_MEMORY",
"container_disk": "TERMINAL_CONTAINER_DISK",
"container_persistent": "TERMINAL_CONTAINER_PERSISTENT",
"docker_volumes": "TERMINAL_DOCKER_VOLUMES",
# Sudo support (works with all backends)
"sudo_password": "SUDO_PASSWORD",
}
@@ -297,7 +298,12 @@ def load_cli_config() -> Dict[str, Any]:
for config_key, env_var in env_mappings.items():
if config_key in terminal_config:
if _file_has_terminal_config or env_var not in os.environ:
os.environ[env_var] = str(terminal_config[config_key])
val = terminal_config[config_key]
if isinstance(val, list):
import json
os.environ[env_var] = json.dumps(val)
else:
os.environ[env_var] = str(val)
# Apply browser config to environment variables
browser_config = defaults.get("browser", {})

View File

@@ -51,6 +51,7 @@ class DockerEnvironment(BaseEnvironment):
disk: int = 0,
persistent_filesystem: bool = False,
task_id: str = "default",
volumes: list = None,
network: bool = True,
):
super().__init__(cwd=cwd, timeout=timeout)
@@ -58,6 +59,11 @@ class DockerEnvironment(BaseEnvironment):
self._persistent = persistent_filesystem
self._task_id = task_id
self._container_id: Optional[str] = None
logger.info(f"DockerEnvironment volumes: {volumes}")
# Ensure volumes is a list (config.yaml could be malformed)
if volumes is not None and not isinstance(volumes, list):
logger.warning(f"docker_volumes config is not a list: {volumes!r}")
volumes = []
from minisweagent.environments.docker import DockerEnvironment as _Docker
@@ -99,10 +105,26 @@ class DockerEnvironment(BaseEnvironment):
# All containers get full security hardening (read-only root + writable
# mounts for the workspace). Persistence uses Docker volumes, not
# filesystem layer commits, so --read-only is always safe.
all_run_args = list(_SECURITY_ARGS) + writable_args + resource_args
# User-configured volume mounts (from config.yaml docker_volumes)
volume_args = []
for vol in (volumes or []):
if not isinstance(vol, str):
logger.warning(f"Docker volume entry is not a string: {vol!r}")
continue
vol = vol.strip()
if not vol:
continue
if ":" in vol:
volume_args.extend(["-v", vol])
else:
logger.warning(f"Docker volume '{vol}' missing colon, skipping")
logger.info(f"Docker volume_args: {volume_args}")
all_run_args = list(_SECURITY_ARGS) + writable_args + resource_args + volume_args
logger.info(f"Docker run_args: {all_run_args}")
self._inner = _Docker(
image=effective_image, cwd=cwd, timeout=timeout,
image=image, cwd=cwd, timeout=timeout,
run_args=all_run_args,
)
self._container_id = self._inner.container_id

View File

@@ -81,11 +81,20 @@ def _get_file_ops(task_id: str = "default") -> ShellFileOperations:
cwd = overrides.get("cwd") or config["cwd"]
logger.info("Creating new %s environment for task %s...", env_type, task_id[:8])
container_config = None
if env_type in ("docker", "singularity", "modal"):
container_config = {
"container_cpu": config.get("container_cpu", 1),
"container_memory": config.get("container_memory", 5120),
"container_disk": config.get("container_disk", 51200),
"container_persistent": config.get("container_persistent", True),
}
terminal_env = _create_environment(
env_type=env_type,
image=image,
cwd=cwd,
timeout=config["timeout"],
container_config=container_config,
)
with _env_lock:

View File

@@ -445,6 +445,7 @@ def _get_env_config() -> Dict[str, Any]:
"container_memory": int(os.getenv("TERMINAL_CONTAINER_MEMORY", "5120")), # MB (default 5GB)
"container_disk": int(os.getenv("TERMINAL_CONTAINER_DISK", "51200")), # MB (default 50GB)
"container_persistent": os.getenv("TERMINAL_CONTAINER_PERSISTENT", "true").lower() in ("true", "1", "yes"),
"docker_volumes": json.loads(os.getenv("TERMINAL_DOCKER_VOLUMES", "[]")),
}
@@ -471,6 +472,7 @@ def _create_environment(env_type: str, image: str, cwd: str, timeout: int,
memory = cc.get("container_memory", 5120)
disk = cc.get("container_disk", 51200)
persistent = cc.get("container_persistent", True)
volumes = cc.get("docker_volumes", [])
if env_type == "local":
return _LocalEnvironment(cwd=cwd, timeout=timeout)
@@ -480,6 +482,7 @@ def _create_environment(env_type: str, image: str, cwd: str, timeout: int,
image=image, cwd=cwd, timeout=timeout,
cpu=cpu, memory=memory, disk=disk,
persistent_filesystem=persistent, task_id=task_id,
volumes=volumes,
)
elif env_type == "singularity":
@@ -848,6 +851,7 @@ def terminal_tool(
"container_memory": config.get("container_memory", 5120),
"container_disk": config.get("container_disk", 51200),
"container_persistent": config.get("container_persistent", True),
"docker_volumes": config.get("docker_volumes", []),
}
new_env = _create_environment(