Enable New App Builder#267
Conversation
…lob-storage Use default blob storage env vars for Docker Compose
Fix r2 for 4.0.0
|
| Filename | Overview |
|---|---|
| compose.yaml | Adds js-executor, agent-sandbox-controller, agent-sandbox-proxy, r2-agent-worker, minio, and minio-init services; hardcoded MinIO credentials are not randomized; minio-init uses fragile sleep-based wait; r2-agent-worker missing depends_on for sandbox services |
| install.sh | Adds AppArmor setup prompt, EC keypair generation for agent JWT, and writes MinIO/agent-sandbox env vars to docker.env; MinIO credentials are hardcoded literals (not randomized) inconsistent with the rest of the secrets |
| appArmor/docker-default | New AppArmor profile replacing Docker's global docker-default; adds broad mount, and pivot_root, permissions needed for gVisor/pasta; applies to all containers on the host as an intentional design trade-off |
| scripts/setup-docker-apparmor.sh | New idempotent script that installs the custom AppArmor profile and systemd drop-in; includes --check mode, preflight checks for AppArmor availability, and clean skip on non-AppArmor hosts |
| Dockerfile | Adds agent-sandbox-service and js-executor-service as new multi-stage build targets; straightforward and consistent with existing code-executor pattern |
| gvisor-seccomp.json | New seccomp profile extending Docker default with gVisor-required syscalls (mount, umount2, pivot_root, ptrace, clone/unshare/setns); well-commented with purpose for each addition |
| nsjail-seccomp.json | New seccomp profile for nsjail-based js-executor; follows Docker default structure with capability-gated additions for clone, mount, pivot_root, and sethostname; no obvious missing or over-privileged syscalls |
| README.md | Configuration steps renumbered and expanded with blob storage guidance for MinIO/R2/S3; changes are documentation-only |
| appArmor/README.md | Adds thorough documentation explaining why the docker-default AppArmor override is necessary for agent-sandbox, including the exact symptom, the three deltas from upstream, and verification steps |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
Client["Browser / API Client"]
HTTPS["https-portal\n(nginx, :443/:80)"]
API["api\n(MAIN_BACKEND + RR_GIT_SERVER\n:3000)"]
CE["code-executor\n(nsjail seccomp)"]
JE["js-executor\n(nsjail seccomp, NET_ADMIN)"]
ASC["agent-sandbox-controller\n(Docker socket, gVisor seccomp)"]
ASP["agent-sandbox-proxy\n(:3019)"]
R2W["r2-agent-worker\n(Temporal: r2-agent queue)"]
PG["postgres"]
Temporal["temporal"]
MinIO["minio\n(:9000/:9001)"]
MinioInit["minio-init\n(creates buckets)"]
Sandbox["sandbox containers\n(spawned by controller)"]
Client --> HTTPS --> API
API --> PG
API --> JE
API --> CE
API --> MinIO
R2W --> Temporal
R2W --> ASC
R2W --> JE
R2W --> CE
ASC -->|Docker socket| Sandbox
ASC --> PG
ASC --> MinIO
ASP --> API
Sandbox -->|HTTP proxy| ASP
MinioInit --> MinIO
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
Client["Browser / API Client"]
HTTPS["https-portal\n(nginx, :443/:80)"]
API["api\n(MAIN_BACKEND + RR_GIT_SERVER\n:3000)"]
CE["code-executor\n(nsjail seccomp)"]
JE["js-executor\n(nsjail seccomp, NET_ADMIN)"]
ASC["agent-sandbox-controller\n(Docker socket, gVisor seccomp)"]
ASP["agent-sandbox-proxy\n(:3019)"]
R2W["r2-agent-worker\n(Temporal: r2-agent queue)"]
PG["postgres"]
Temporal["temporal"]
MinIO["minio\n(:9000/:9001)"]
MinioInit["minio-init\n(creates buckets)"]
Sandbox["sandbox containers\n(spawned by controller)"]
Client --> HTTPS --> API
API --> PG
API --> JE
API --> CE
API --> MinIO
R2W --> Temporal
R2W --> ASC
R2W --> JE
R2W --> CE
ASC -->|Docker socket| Sandbox
ASC --> PG
ASC --> MinIO
ASP --> API
Sandbox -->|HTTP proxy| ASP
MinioInit --> MinIO
Comments Outside Diff (4)
-
compose.yaml, line 333-351 (link)Hardcoded MinIO credentials exposed on all interfaces
The
minioservice embedsMINIO_ROOT_USER=retool/MINIO_ROOT_PASSWORD=retoolminiodirectly incompose.yaml(notdocker.env), soinstall.sh's randomization logic never applies to them. The same static strings are written into the generateddocker.envasRR_DEFAULT_S3_ACCESS_KEY_ID=retoolandRR_DEFAULT_S3_SECRET_ACCESS_KEY=retoolminio. Ports9000and9001are published on all interfaces, so any host reachable on the network exposes a MinIO Console with these publicly-known defaults. All other secrets generated byinstall.sh(postgres password, JWT keys, encryption key) are randomized — MinIO is the only service that ships with a static, guessable credential pair. Users who follow the setup instructions but keep the bundled MinIO without manually rotating the root password will have a fully accessible object-store admin console. -
compose.yaml, line 353-368 (link)minio-inituses a fixedsleep 3to wait for MinIO readinessThe
sleep 3heuristic beforemc alias setwill fail silently on slow starts (e.g., first boot with no cached layers, resource-constrained hosts). If the MinIO API is not yet listening whenmc alias setruns, the command exits non-zero and the required buckets are never created, causing theapiservice (whichdepends_on: minio) to start but fail on the first blob-storage operation. A more reliable approach is to loop until the health check endpoint responds before runningmccommands. -
compose.yaml, line 314-328 (link)r2-agent-workerdepends_on omits agent-sandbox servicesThe
r2-agent-workerservice connects to theagent-sandboxnetwork and routes tasks toagent-sandbox-controllerandagent-sandbox-proxy, but neither service appears in itsdepends_onlist (onlypostgresis listed). On a freshdocker compose up, the agent-sandbox services may not have started before the worker begins processing tasks, causing early failures that may or may not retry correctly depending on the worker's reconnection logic. -
appArmor/docker-default, line 126-141 (link)Broad
mount,applies to all containers, not just agent-sandboxReplacing the global
docker-defaultprofile means every container on the host — postgres, Temporal, the main backend, etc. — now inherits the unrestrictedmount,andpivot_root,rules. The README justifies this as necessary because the profile name is hard-coded by the Docker daemon, but it is worth confirming that the team has accepted this as the intended trade-off: a container breakout from any service can now attempt bind-mounts or pivot_root operations that would have been blocked by the upstream profile.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Reviews (1): Last reviewed commit: "Merge pull request #265 from tryretool/l..." | Re-trigger Greptile
No description provided.