mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-11-13 09:13:30 +01:00
135 lines
5.5 KiB
YAML
135 lines
5.5 KiB
YAML
# ai/compose.yaml
|
|||
|
|
# Sandbox for the AkkudoktorEOS AI coding agent.
|
||
|
|
# The launchers (run.sh, run.ps1, run.bat) sanity-check a few of the controls below.
|
||
|
|
# The real protection of this file is the read-only mount of ai/: the agent
|
||
|
|
# cannot change the sandbox definition from inside the sandbox.
|
||
|
|
|
||
|
|
services:
|
||
|
|
ai-dev:
|
||
|
|
build:
|
||
|
|
context: .
|
||
|
|
dockerfile: Dockerfile
|
||
|
|
args:
|
||
|
|
UID: ${HOST_UID:-1000}
|
||
|
|
GID: ${HOST_GID:-1000}
|
||
|
|
image: akkudoktor-eos-ai:latest
|
||
|
|
# NOTE: no container_name — required for `docker compose run` and parallelism.
|
||
|
|
working_dir: /workspace
|
||
|
|
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
# Filesystem isolation
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
read_only: true
|
||
|
|
|
||
|
|
volumes:
|
||
|
|
# Repo, read-write (needed by the agent to edit code).
|
||
|
|
- ..:/workspace:rw
|
||
|
|
|
||
|
|
# Read-only overlays for the sandbox definition the launcher uses.
|
||
|
|
# Without them the agent could rewrite what the next launch runs.
|
||
|
|
# - ai/: compose.yaml, Dockerfile, entrypoint.sh and the launchers.
|
||
|
|
# - ai/skills/: read-only unless the launcher is started with
|
||
|
|
# AI_SANDBOX_SKILLS_RW=1 (the launcher sets AI_SANDBOX_SKILLS_MODE).
|
||
|
|
# .git stays writable, so the agent can commit. Read-only overlays of
|
||
|
|
# .git/hooks or .git/config would not protect the host anyway: git also
|
||
|
|
# reads config and hooks from the directory named in .git/commondir, and
|
||
|
|
# .git itself can be renamed. Neither can tracked files the host runs
|
||
|
|
# (Makefile, .pre-commit-config.yaml, tests, scripts) be protected this
|
||
|
|
# way: review .git and every change on the host before running git or
|
||
|
|
# anything else there (docs/develop/ai.md, review checklist).
|
||
|
|
- ../ai:/workspace/ai:ro
|
||
|
|
- ../ai/skills:/workspace/ai/skills:${AI_SANDBOX_SKILLS_MODE:-ro}
|
||
|
|
|
||
|
|
# Persistent state for CLI auth, caches and Claude memory/transcripts.
|
||
|
|
# This volume persists between sessions, so a misled session can leave
|
||
|
|
# state behind that takes effect later (e.g. agent settings and hooks in
|
||
|
|
# ~/.claude, ~/.gitconfig, the venv in ~/.cache). The entrypoint resets
|
||
|
|
# the shell startup files on every start; for everything else, remove the
|
||
|
|
# volume (docker volume rm akkudoktor-ai-home) if a session may have been
|
||
|
|
# misled. entrypoint.sh lives in the image (/usr/local/bin), not here.
|
||
|
|
# No `nocopy`: an empty volume is populated from the image's /home/dev,
|
||
|
|
# which also gives it the owner of /home/dev (the dev user). With
|
||
|
|
# `nocopy`, a fresh volume is owned by root and the container cannot start.
|
||
|
|
- type: volume
|
||
|
|
source: ai-home
|
||
|
|
target: /home/dev
|
||
|
|
|
||
|
|
tmpfs:
|
||
|
|
# /tmp is needed by many tools but must never be executable.
|
||
|
|
- /tmp:rw,nosuid,nodev,noexec,size=512m,mode=1777
|
||
|
|
# /run and /var/tmp kept in-memory, noexec.
|
||
|
|
- /run:rw,nosuid,nodev,noexec,size=64m
|
||
|
|
- /var/tmp:rw,nosuid,nodev,noexec,size=256m
|
||
|
|
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
# Privilege & capability isolation
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
privileged: false
|
||
|
|
cap_drop:
|
||
|
|
- ALL
|
||
|
|
security_opt:
|
||
|
|
- no-new-privileges:true
|
||
|
|
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
# Network
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
networks:
|
||
|
|
- ai-net
|
||
|
|
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
# Testing ports — loopback-only on the host.
|
||
|
|
# 127.0.0.1:... prevents exposing these services to the LAN/VPN.
|
||
|
|
# Add new ports here only when you have a concrete test need.
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
ports:
|
||
|
|
- "127.0.0.1:8503:8503"
|
||
|
|
- "127.0.0.1:8504:8504"
|
||
|
|
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
# Resource limits (defense in depth against runaway agents)
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
mem_limit: 4g
|
||
|
|
memswap_limit: 4g # == mem_limit: disables swap for this cgroup
|
||
|
|
pids_limit: 512 # fork-bomb protection
|
||
|
|
cpus: 2.0
|
||
|
|
ulimits:
|
||
|
|
nofile:
|
||
|
|
soft: 4096
|
||
|
|
hard: 8192
|
||
|
|
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
# Environment
|
||
|
|
# ------------------------------------------------------------------
|
||
|
|
environment:
|
||
|
|
- TERM=xterm-256color
|
||
|
|
- CLAUDE_CONFIG_DIR=/home/dev/.claude
|
||
|
|
- HOME=/home/dev
|
||
|
|
# Keep the agent's virtual environment out of the host's .venv in every
|
||
|
|
# shell and tool call (see ai/skills/python-environment/SKILL.md).
|
||
|
|
- UV_PROJECT_ENVIRONMENT=/home/dev/.cache/eos-venv
|
||
|
|
# Disable shell history writing so a hijacked home doesn't retain commands.
|
||
|
|
- HISTFILE=/dev/null
|
||
|
|
- HISTSIZE=0
|
||
|
|
# Trust the repository: Docker Desktop (Windows, macOS) shows the bind
|
||
|
|
# mount as owned by root, and git refuses a repository owned by another
|
||
|
|
# user ("dubious ownership"). Set here, not in ~/.gitconfig, so it does
|
||
|
|
# not depend on the home volume.
|
||
|
|
- GIT_CONFIG_COUNT=1
|
||
|
|
- GIT_CONFIG_KEY_0=safe.directory
|
||
|
|
- GIT_CONFIG_VALUE_0=/workspace
|
||
|
|
# Optional git identity, passed through from the host shell
|
||
|
|
# (export GIT_USER_NAME / GIT_USER_EMAIL before ./ai/run.sh).
|
||
|
|
- GIT_USER_NAME
|
||
|
|
- GIT_USER_EMAIL
|
||
|
|
|
||
|
|
stdin_open: true
|
||
|
|
tty: true
|
||
|
|
|
||
|
|
networks:
|
||
|
|
ai-net:
|
||
|
|
driver: bridge
|
||
|
|
|
||
|
|
volumes:
|
||
|
|
ai-home:
|
||
|
|
name: akkudoktor-ai-home
|