Docker Setup
The project supports containerized deployment with Docker Compose, offering both development and production configurations.
Prerequisites
- Docker Engine 20.10+
- Docker Compose 2.0+
- 4GB+ RAM, 10GB+ disk space
Container Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Nginx Proxy │────│ Django App │────│ MySQL DB │
│ (Production) │ │ (Web/API) │ │ (Data) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Development container (Dockerfile.dev): Python 3.11 with Chrome, Firefox, WebDrivers, dev tools, and live code reloading via volume mounts.
Production container (Dockerfile.prod): Multi-stage build with Gunicorn, health checks, and security hardening.
Quick Start
Development
cp .env.sample .env
# Edit .env with your API keys and settings
docker-compose --profile development up --build
# Access: http://localhost:8000
# Admin: http://localhost:8000/admin
The development web and cron containers use the committed
main.settings_dev module, so a local untracked main/settings.py file is not
required for Docker Compose.
Local Agent Console
The agent-local profile runs the local visual agent stack that was previously
kept in a separate dockerized workspace. It is intended for this computer only.
All exposed ports are bound to 127.0.0.1.
When testing the embedded Django page, open LTI through 127.0.0.1 rather than
localhost so the local console cookie remains same-site in the iframe.
# Optional: configure a model key for autonomous Computer Use runs.
cp .env.agent-local.example .env.agent-local
# Edit .env.agent-local locally. Do not commit it.
docker compose --profile development --profile agent-local up --build
# Django tester console entry point, after signing in through Django/admin
open http://127.0.0.1:8000/local-agent-console
# Direct local operator console, useful for debugging the dev stack
open http://127.0.0.1:13020
# noVNC desktop
open http://127.0.0.1:16901/vnc.html
If the Django development stack is already running, docker compose --profile
agent-local up --build is enough to start only the local agent services. The
first supported rollout is authenticated dev access through
/local-agent-console; the same Django-owned route is the target model for
later LTI dev/prod access. The Django admin also exposes
/admin/local-agent-console/ as a staff shortcut to the same health and service
links.
The LTI-owned local stack intentionally uses host ports 13020, 12222,
15901, and 16901 so it can run beside the older standalone dockerized
prototype if that prototype is still active on this computer. The VM API is not
published as a host port; the local console proxies authenticated VM API calls
over the Docker network. SSH, VNC, and VM API secrets are generated into the
agent_api_secrets Docker volume at VM startup. Credential values are not
returned by the local console API by default; set LOCAL_AGENT_SHOW_CREDENTIALS=1
in .env.agent-local only for local debugging on this computer.
The local console can start deterministic VM commands without a model key. A real
autonomous task requires ANTHROPIC_API_KEY or a future configured model
credential in .env.agent-local.
Local runner bridge
Phase 3C adds an outbound runner bridge that keeps the local VM private while
letting LTI own run state, progress events, and artifacts. After creating an
ApiClient with lti:read and lti:runner:write scopes, set the local
LTI_AGENT_API_TOKEN and console token in .env.agent-local, then run one
polling cycle with:
python manage.py create_api_client \
--name albert-mac-local-runner \
--scope lti:read \
--scope lti:runner:write \
--confirm-print-token
Run the command only in a trusted interactive shell because it prints the raw bearer token exactly once.
python agent_runtime/runner_bridge.py --once
Omit --once to keep polling. The bridge leases one pending runner-compatible
execution. Manual-AI work starts the existing local console task API.
Contracted E2E work runs ordered read-only API or declarative Selenium browser
steps directly and never opens the local visual console. Both paths post
redacted progress logs as text artifacts and complete through
/agent-api/v1/agentic-qa/.... Screenshot evidence for this slice should be
sent as structured payload; runner-supplied external URLs and multipart file
uploads are not part of the runner bridge contract yet. After each terminal
console task, the bridge requests /api/agent/screenshot from the local console
and records the screenshot filename/proxy_url as a structured screenshot
artifact payload in LTI. Use
LTI_AGENT_POLL_INTERVAL_SECONDS to tune polling cadence,
LTI_AGENT_LEASE_SECONDS to set the LTI lease, and
LTI_AGENT_TASK_TIMEOUT_SECONDS to cap a single local console task. The bridge
reads runner and console tokens only from environment variables so bearer tokens
do not appear in shell history or process listings. The bridge
requires the lease to be longer than the task timeout; when the timeout is
reached, the bridge posts an error event and completes the execution as blocked
with the timeout in the log artifact. While a console task is still running, the
bridge renews the LTI lease before completion so another runner cannot reclaim
the same execution mid-task. For operator smoke checks that must prove the
runner actually claimed work, run
python agent_runtime/runner_bridge.py --once --require-execution; it exits
with code 2 if no pending LTI execution is available.
The bridge redacts common bearer-token, DR-token, password, and secret patterns
before sending event messages or log artifacts; LTI applies the same redaction
again before durable storage.
Generate the deterministic acceptance smoke matrix before creating its run:
python manage.py generate_scenario_matrix --output /tmp/lti-scenario-matrix.json
python manage.py generate_scenario_matrix --apply
Generation requires the acceptance target manifest. It inventories current LTI list-language and donation-form configuration, reports unsafe forms as blocked, and does not call an external service. Apply mode is idempotent. The first catalog intentionally contains only read-only frontend and FRAPI health checks; signature and payment mutations remain disabled until their data and cleanup contracts are approved.
The unauthenticated report payload intentionally stays high-level: execution status, redacted summary fields, timestamps, artifact counts, artifact types, and redaction status. Runner IDs, raw artifact payloads, file paths, and external evidence URLs stay in the authenticated API/admin surfaces.
This Phase 3C runner path stores evidence only in database text/payload fields; it does not introduce new FileField/media writes for runner artifacts.
Production
cp .env.sample .env.prod
# Configure production values
docker-compose --profile production up --build -d
# Access via Nginx: http://localhost
Environment Variables
# Database
DB_HOST=db
DB_NAME=cgo_testing_interface
DB_USER=db
DB_PASSWORD=your_secure_password
# Django
DJANGO_SECRET_KEY=your_secret_key_here
DEBUG=0
ALLOWED_HOSTS=your-domain.com,localhost
# External APIs
STRIPE_API_KEY=sk_test_...
ASANA_ACCESS_TOKEN=...
EMAIL_PASSWORD=app_specific_password
Common Operations
# Run tests inside container
docker-compose exec web-dev python manage.py test
docker-compose exec web-dev behave features/
# Database management
docker-compose exec web-dev python manage.py migrate --fake-initial
docker-compose exec web-dev python manage.py createsuperuser
docker-compose exec db mysql -u db -p cgo_testing_interface
# Update production
git pull origin main
docker-compose --profile production up --build -d
# Database backup
docker-compose exec db mysqldump -u root -p cgo_testing_interface > backup.sql
# Restore
docker-compose exec -T db mysql -u root -p cgo_testing_interface < backup.sql
# Logs
docker-compose logs -f web-prod
Troubleshooting
Database connection error: Check docker-compose ps db, restart with docker-compose restart db.
Selenium tests fail: Verify Chrome is installed: docker-compose exec web-dev google-chrome --version.
File Structure
├── Dockerfile.dev # Development container
├── Dockerfile.prod # Production container
├── agent_runtime/ # Local visual agent VM and operator console
├── docker-compose.yml # Service orchestration
├── .env.sample # Environment template
└── Docker/
├── mysql/init/01-init.sql # DB initialization
└── nginx/nginx.conf # Reverse proxy config
For the full Configuration reference, see the configuration page.