From 2d3d5caacb47f8612b65fca3506e3ee48e9495f9 Mon Sep 17 00:00:00 2001 From: Jeena Date: Sat, 28 Mar 2026 22:07:58 +0000 Subject: [PATCH] container: Improve usability of web mode, error handling, and CLI commands Use --network host so that web interfaces (e.g. opencode web) are accessible from the host. Suppress Python tracebacks when the tool exits with a non-zero code. Ignore SIGTSTP to prevent Ctrl+Z from leaving orphaned containers. Rename force-cleanup to purge. --- README.md | 4 ++-- agent-container.py | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 8aec2c1..d2ffffc 100644 --- a/README.md +++ b/README.md @@ -63,12 +63,12 @@ agent-container update This removes all existing containers and rebuilds the image from scratch. Containers are recreated automatically on the next run. The persistent home directory is not affected. -### Force Cleanup +### Purge To remove all containers, the image, and the persistent home directory: ```sh -agent-container force-cleanup +agent-container purge ``` ## Sharing host config files via hard links diff --git a/agent-container.py b/agent-container.py index f0aa97c..ce38ca3 100755 --- a/agent-container.py +++ b/agent-container.py @@ -3,6 +3,7 @@ import hashlib import logging import os +import signal import subprocess import sys import time @@ -16,7 +17,7 @@ Usage: agent-container opencode [args...] Run OpenCode in the container agent-container claude [args...] Run Claude Code in the container agent-container update Rebuild image with latest versions - agent-container force-cleanup Remove all containers, image, and data + agent-container purge Remove all containers, image, and data """ @@ -78,8 +79,8 @@ class AgentContainer: ) elif command == "update": self.update() - elif command == "force-cleanup": - self.force_cleanup() + elif command == "purge": + self.purge() else: logger.error(f"Unknown command: {command}") print(USAGE, file=sys.stderr) @@ -132,8 +133,10 @@ class AgentContainer: raise RuntimeError("Container failed to start after recreation") try: + signal.signal(signal.SIGTSTP, signal.SIG_IGN) self._exec_tool(tool, args, env_vars, extra_env or {}) finally: + signal.signal(signal.SIGTSTP, signal.SIG_DFL) self.stop_container() def _exec_tool( @@ -151,7 +154,7 @@ class AgentContainer: for var, val in extra_env.items(): env_args += ["-e", f"{var}={val}"] - subprocess.run( + result = subprocess.run( [ "docker", "exec", @@ -163,8 +166,9 @@ class AgentContainer: tool, *args, ], - check=True, ) + if result.returncode != 0: + sys.exit(result.returncode) # ========================= # Image handling @@ -213,6 +217,8 @@ class AgentContainer: "create", "--name", self.container_name, + "--network", + "host", "--user", f"{self.host_uid}:{self.host_gid}", "--volume", @@ -263,8 +269,8 @@ class AgentContainer: self.build_image(no_cache=True) logger.info("Update complete. Containers will be recreated on next run.") - def force_cleanup(self) -> None: - logger.info("Running force cleanup...") + def purge(self) -> None: + logger.info("Purging all containers, image, and data...") self._remove_all_containers() if self.image_exists():