Skip to content

rag-ide: EC2 and local Docker platforms - #5

Merged
kchandan merged 4 commits into
mainfrom
feat-rag-ide-ec2
Oct 23, 2026
Merged

kchandan merged 4 commits into
mainfrom
feat-rag-ide-ec2

Conversation

@kchandan

Copy link
Copy Markdown
Member

What this adds

labagent launch rag-ide gains two platforms next to Modal (--param platform=modal|ec2|local):

ec2: ONE shared instance per cohort, one container per learner, a fraction of the cost of per-learner serverless sandboxes.

  • Image built on the box from a pinned, verified git commit (ref, 40-hex SHA).
  • Learner containers: unprivileged, CPU/memory/pid limited, all capabilities dropped, no-new-privileges.
  • Caddy serves https://<ip>.sslip.io/<learner>/ (Let's Encrypt, or tls=internal). Only ports 80/443 are open: no SSH, no instance profile, IMDSv2 with hop limit 1.
  • Cost safety on the box itself: hard shutdown after hours, and self-shutdown when no learner container is running. Instances terminate on shutdown.
  • The account must be on the labagent allow list (same guard as the cleanup engine). AMI from SSM, falling back to DescribeImages.
  • destroy terminates the instance (also orphans by tag) and removes the security group.

local: the same lab on this machine through Docker, loopback ports only, same steps/credentials/destroy. For demos and tests.

Found and fixed by the first real EC2 runs

  • Dockerfile.lab: the classic Docker builder (Ubuntu docker.io, no BuildKit) creates WORKDIR as root even after USER, so labagent rag init failed on the box. Directory is now chowned before USER. Reproduced locally with DOCKER_BUILDKIT=0; regression test added.
  • The readiness check verified the certificate, so tls=internal could never become ready.
  • Passwords were kept in memory until the last step; a failure after the instance started lost them. The 0600 credentials file is now written as soon as learners exist.
  • scripts/check_no_pii.py: one scoped exception for Canonical's public AMI publisher id (the scanner still flags every other 12-digit number).

Verified

  • 248 tests pass (Python 3.9), scanner clean. Includes the real EC2 gateway against moto and a real-Docker end-to-end test.
  • Local platform run for real: two containers on loopback, login works, password not visible in ps, clean destroy.
  • Real EC2 box (us-east-1, m6i.large, tls=internal): booted in ~6 min, image built, both learner IDEs reachable at their path, login accepted/rejected correctly, HTTP redirects to HTTPS, workbench page and assets served through the path prefix.
  • Boot script passes bash -n; generated Caddyfile passes caddy validate.

NOT verified yet

  • A real browser session through the proxy (websockets for terminal/extension host). A curl probe was inconclusive.
  • Let's Encrypt issuance on sslip.io (shared-name rate limits are a risk); only tls=internal ran on EC2.
  • The fixed readiness wait and early credentials file have unit tests but have not yet run on a real box.
  • Self-shutdown when idle (observation in progress when this was opened), and 30-learner scale.
  • Cost per cohort is an estimate.
  • Passwords sit in EC2 user-data, readable by anyone with EC2 read access in that account (learners cannot read it).

The lab image pin (PINNED_REF) points at commit 737a284 in this PR; merging with a merge commit keeps that SHA in main history.

🤖 Generated with Claude Code

kchandan and others added 4 commits October 23, 2026 13:30
…per learner)

--param platform=ec2 launches a single instance with a pinned lab image built from
a verified git commit, a container per learner (unprivileged, capped, capabilities
dropped), Caddy for HTTPS on an sslip.io name, a security group with only 80/443,
IMDSv2 with hop limit 1, no instance profile, a hard time cap and self-shutdown when
no learner is left. The account must be on the labagent allow list. Not yet run
against a real AWS account.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…uilder)

The classic Docker builder (Ubuntu's docker.io has no BuildKit) creates WORKDIR as
root even after USER, so 'labagent rag init' failed with a PermissionError on the
first real EC2 boot. Create and chown the directory before switching user.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…n resume

platform=local runs the same one-container-per-learner lab on this machine through
Docker (loopback ports, same credentials file and destroy), for demos and tests.

Two bugs found by the first real EC2 run:
- readiness check verified the certificate, so tls=internal could never become ready
- passwords lived only in memory until the last step, so a failure after the instance
  started lost them; the credentials file is now written as soon as learners exist

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@kchandan
kchandan merged commit 9a4350d into main Oct 23, 2026
3 checks passed
@kchandan
kchandan deleted the feat-rag-ide-ec2 branch October 23, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant