aboutsummaryrefslogtreecommitdiffstats
path: root/tools/docker_start.sh
diff options
context:
space:
mode:
Diffstat (limited to 'tools/docker_start.sh')
-rw-r--r--tools/docker_start.sh70
1 files changed, 70 insertions, 0 deletions
diff --git a/tools/docker_start.sh b/tools/docker_start.sh
new file mode 100644
index 0000000..cec5808
--- /dev/null
+++ b/tools/docker_start.sh
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# @describe Start (or reuse) a sandbox Docker container with a bind-mounted workspace.
+# @option --workspace! Host path to mount into the container at /work (must be under $AICHAT_SANDBOX_BASE).
+# @option --image Docker image to use. Default: aichat-docker:latest
+# @option --name Optional explicit container name. Default: auto-generated.
+# @option --network Enable network access (true/false). Default: true
+# @option --ttl_minutes Optional TTL label for cleanup tooling. Default: 0 (no TTL)
+
+main() {
+ local base="${AICHAT_SANDBOX_BASE:-$HOME/aichat-workspaces}"
+ local image="${argc_image:-aichat-docker:latest}"
+ local net="${argc_network:-true}"
+ local ttl="${argc_ttl_minutes:-0}"
+
+ mkdir -p "$base"
+
+ local ws
+ ws="$(realpath -m "${argc_workspace}")"
+
+ local base_real
+ base_real="$(realpath -m "$base")"
+ case "$ws" in
+ "$base_real"/*) ;;
+ *)
+ echo "ERROR: workspace must be under $base_real (got $ws)" >> "$LLM_OUTPUT"
+ exit 2
+ ;;
+ esac
+
+ mkdir -p "$ws"
+
+ local name="${argc_name:-aichat-sbx-$(date +%s)-$RANDOM}"
+
+ if docker ps -a --format '{{.Names}}' | grep -qx "$name"; then
+ printf '{"container":"%s","workspace":"%s","status":"already-exists"}\n' "$name" "$ws" >> "$LLM_OUTPUT"
+ return 0
+ fi
+
+ local net_arg=()
+ if [[ "$net" == "false" ]]; then
+ net_arg+=(--network none)
+ fi
+
+ local uid gid
+ uid="$(id -u)"
+ gid="$(id -g)"
+
+ docker run -d --rm \
+ --name "$name" \
+ -u "${uid}:${gid}" \
+ -w /work \
+ -v "${ws}:/work:rw" \
+ --cap-drop=ALL \
+ --security-opt=no-new-privileges \
+ --pids-limit 256 \
+ --memory 2g \
+ --cpus 2 \
+ "${net_arg[@]}" \
+ --label "aichat.sandbox=true" \
+ --label "aichat.ttl_minutes=${ttl}" \
+ "$image" \
+ sh -lc 'sleep infinity' >/dev/null
+
+ printf '{"container":"%s","workspace":"%s","status":"started"}\n' "$name" "$ws" >> "$LLM_OUTPUT"
+}
+
+eval "$(argc --argc-eval "$0" "$@")"
+