Skip to content

feat(platform): add single-container distribution - #13758

Merged
ntindle merged 42 commits into
devfrom
feat/single-container-04-image
Aug 10, 2026
Merged

feat(platform): add single-container distribution#13758
ntindle merged 42 commits into
devfrom
feat/single-container-04-image

Conversation

@ntindle

@ntindle ntindle commented Aug 1, 2026

Copy link
Copy Markdown
Member

Why / What / How

Why

AutoGPT Platform should be runnable as a complete local appliance with one docker run, including FalkorDB-backed memory, without changing the images or deployment behavior used by hosted infrastructure.

What

Adds a dedicated single-container appliance containing the frontend, backend services, PostgreSQL, a three-node Valkey cluster, RabbitMQ, FalkorDB, nginx, Supervisor, and Tini.

The appliance persists application and service state under /data, generates installation secrets on first boot, and exposes only nginx on container port 3000.

How

Buildx Bake builds the existing backend server target, then uses it as the base for autogpt_platform/single-container/Dockerfile. Internal services bind to loopback and Supervisor manages their lifecycle. Health checks and a fail-stop watchdog allow Docker restart policies to recover the appliance when a required service cannot recover internally.

The frontend server runs as its own Unix user with a clean environment and a passwordless local PostgreSQL role limited to the Better Auth tables and required User columns. It does not receive PostgreSQL superuser credentials. Internal AppService traffic stays loopback-only inside the appliance trust boundary.

The effective PR diff adds only autogpt_platform/single-container/ plus its CI workflow and smoke script. Existing backend source, frontend source, Dockerfiles, the root .dockerignore, and Compose files do not differ from dev.

Changes 🏗️

  • Adds the dedicated appliance Dockerfile, runtime scripts, nginx configuration, Supervisor configuration, and Bake targets.
  • Enables FalkorDB-backed Graphiti memory by default.
  • Persists generated application secrets, databases, queues, caches, and memory data under /data.
  • Runs startup migrations without downloading Prisma tooling at runtime.
  • Adds health checks, required-service recovery, clean shutdown, and whole-container fail-stop handling.
  • Defaults new-account signup to disabled until explicitly enabled by the operator.
  • Isolates the frontend and nginx with dedicated operating-system users and a least-privilege frontend database role.
  • Pins internal topology to loopback so persisted backend configuration cannot expose internal listeners.
  • Adds native linux/amd64 and linux/arm64 build, runtime-smoke, vulnerability-scan, and secret-scan CI.
  • Keeps the validation workflow non-publishing.

Test plan

  • Run all 59 appliance Python tests.
  • Run ShellCheck for the appliance and smoke scripts.
  • Run bash -n and git diff --check.
  • Run the repository pre-commit suite under Node 24, including backend/frontend type checks and API generation checks.
  • Build and smoke-test the exact current-head image on linux/amd64 and linux/arm64.
  • Verify literal docker run, /data reuse, generated-secret persistence, FalkorDB graph persistence, frontend database isolation, and service recovery on the exact current head.
  • Pass current-head Trivy vulnerability and embedded-secret scans.

Checklist 📋

For code changes:

  • I have clearly listed my changes in the PR description.
  • I have made a test plan.
  • I have tested my changes according to the complete test plan above.

For configuration changes:

  • .env.default is already compatible with these changes.
  • docker-compose.yml is already compatible with these changes.
  • I have included a list of configuration changes under Changes.

Stack navigation

This appliance is based directly on dev. Publication and end-user documentation are handled separately.


Note

Medium Risk
Large new packaging surface with auth, secrets, and DB privilege boundaries; mitigated by extensive smoke tests and isolation checks, but it is still a new distribution path operators may run in production.

Overview
Introduces an experimental single-container AutoGPT Platform you can run with one docker run, bundling the frontend, backend services, PostgreSQL, Valkey, RabbitMQ, FalkorDB (Graphiti memory on by default), nginx, and Supervisor. State and generated secrets live on a /data volume; only port 3000 is exposed.

The image is built via Docker Bake from the existing backend server target plus a new autogpt_platform/single-container/ stack (entrypoint/bootstrap, runtime config, least-privilege frontend DB role, loopback-pinned internal ports, health checks, watchdog). Operators get .env.example for public URL, signup policy, and LLM keys.

CI adds platform-single-container-docker.yml: unit tests for appliance helpers, per-arch image build, a long end-to-end smoke script (health, auth, hostile backend.json, isolation, FalkorDB/nginx recovery), and Trivy critical vuln + secret scans. Hosted multi-container deployments are unchanged.

Reviewed by Cursor Bugbot for commit 2d36895. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a complete single-container appliance with bundled services, persistent configuration, supervised startup, local Nginx routing, health probes, recovery handling, administrative tooling, and multi-architecture CI smoke tests.

Changes

Single-container appliance

Layer / File(s) Summary
Image build and bundled assets
autogpt_platform/single-container/Dockerfile, autogpt_platform/single-container/docker-bake.hcl, autogpt_platform/single-container/.env.example, autogpt_platform/single-container/licenses/*
Builds the frontend and appliance image. Bundles PostgreSQL, Valkey, RabbitMQ, FalkorDB, ClamAV, Nginx, runtime utilities, and license materials.
Runtime configuration and startup security
autogpt_platform/single-container/runtime_config.py, autogpt_platform/single-container/entrypoint.sh, autogpt_platform/single-container/common.sh, autogpt_platform/single-container/nginx/*, autogpt_platform/single-container/rabbitmq/*, autogpt_platform/single-container/clamav/*
Validates URLs, secrets, toggles, permissions, and service settings. Generates protected runtime and local service configuration.
Supervised services and bootstrap
autogpt_platform/single-container/supervisor/*, autogpt_platform/single-container/bootstrap.sh, autogpt_platform/single-container/run-*.sh, autogpt_platform/single-container/watchdog.sh
Starts bundled services, waits for dependencies, initializes Valkey and PostgreSQL, applies migrations, publishes readiness, and handles service failures.
Networking, health, and administration
autogpt_platform/single-container/probe.py, autogpt_platform/single-container/healthcheck.sh, autogpt_platform/single-container/promote-admin.sh, autogpt_platform/single-container/fatal_listener.py, autogpt_platform/single-container/python/sitecustomize.py, autogpt_platform/single-container/tests/*
Adds service probes, endpoint health checks, administrator promotion, fatal-process handling, log redaction, and unit tests.
Build matrix and smoke validation
.github/workflows/platform-single-container-docker.yml, .github/scripts/platform-single-container-smoke.sh
Builds Linux AMD64 and ARM64 images, scans them, and validates persistence, topology, security, recovery, restart, and shutdown behavior.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: platform/frontend, platform/backend

Suggested reviewers: 0ubbe, swiftyos

Poem

A rabbit packs services tight,
With secrets guarded from sight.
It checks ARM and x86,
Restarts each bundled box.
“Healthy,” it says, “good night!”

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the addition of a single-container distribution for the platform.
Description check ✅ Passed The description directly explains the single-container appliance, bundled services, persistence, security, CI, and validation plan.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/single-container-04-image

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.93%. Comparing base (62d3c4d) to head (2d36895).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #13758      +/-   ##
==========================================
- Coverage   77.95%   77.93%   -0.02%     
==========================================
  Files        2921     2921              
  Lines      219700   219693       -7     
  Branches    20836    20835       -1     
==========================================
- Hits       171258   171216      -42     
- Misses      43840    43871      +31     
- Partials     4602     4606       +4     
Flag Coverage Δ
platform-frontend-e2e 29.22% <ø> (-0.87%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Platform Backend 83.91% <ø> (+<0.01%) ⬆️
Platform Frontend 55.69% <ø> (-0.13%) ⬇️
AutoGPT Libs ∅ <ø> (∅)
Classic AutoGPT 28.43% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@capy-ai

capy-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown

PR #13758 single-container test report

Verdict: BLOCKED — runtime acceptance could not begin because the image does not build on the available Docker storage stack.

Results

Scenario Result
Checkout PR head 4c44830b PASS
Runtime/configuration unit tests PASS — 15/15
Compose contract PASS — one service, one /data volume, loopback port 3000, single-container target
Missing env-file sentinel PASS — Compose fails closed
Exact single-container image build BLOCKED
Minimal remote ADD --checksum reproduction REPRODUCED
Direct asset checksum and local COPY control PASS
Startup, health, routing, signup/login NOT RUN
Restart persistence NOT RUN
Watchdog recovery NOT RUN

Build blocker

Both independent VMs use Docker with fuse-overlayfs over virtiofs. BuildKit fails while hashing the Dockerfile's remote FalkorDB license:

failed to calculate checksum ... failed to create hash for /LICENSE.txt: operation not supported

A three-line Dockerfile containing only the same pinned remote ADD --checksum reproduces the failure. Downloading the same URL directly produces the expected SHA-256, and replacing the remote ADD with a verified local COPY passes that isolated step. This isolates the blocker to BuildKit's remote-source hashing on this storage stack rather than the URL or checksum.

The primary VM additionally reproduced unsupported hashing on cross-stage COPY, so a locally modified image would not provide trustworthy runtime evidence here. No product source changes were retained.

Recommendation

Do not treat PR #13758 as runtime-verified from this run. Run the architecture smoke workflow from stacked PR #13759 on standard GitHub-hosted Docker workers, or make the Dockerfile inputs compatible with fuse-overlayfs/virtiofs, then repeat startup, health, persistence, authentication, private-port, and watchdog scenarios.

@github-actions github-actions Bot added the cla: signed CLA signed by all contributors label Aug 6, 2026
ntindle added a commit to claude-dev-code/AutoGPT that referenced this pull request Aug 6, 2026
…-Gravitas#13755)

### Why / What / How

**Why**

The single-container appliance supervises backend roles in one network
namespace. Internal metrics listeners should not be exposed beyond
container loopback, and notification workers must stop cleanly when
Supervisor terminates the process.

**What**

- Binds executor and Copilot executor metrics endpoints to loopback.
- Gives notification queue polling an explicit task lifecycle.
- Adds regression coverage for clean cancellation and shutdown.

**How**

The metrics servers use an explicit loopback host. The notification
runner tracks its polling task, cancels and awaits it during shutdown,
and avoids leaving an event-loop-bound task behind.

### Stack

Part **1 of 6** in the single-container stack. This is the bottom PR and
targets `dev`. Review and merge the stack bottom-up. It supersedes the
corresponding backend portion of draft Significant-Gravitas#13754.

### Changes 🏗️

- 4 focused backend source/test files.
- No Docker image or configuration changes in this layer.

### Checklist 📋

#### For code changes:

- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] Signed commit passed the repository pre-commit suite under Node
24, including backend lint, formatting, type checking, API generation,
and secret checks
- [x] Notification regression coverage is included
- [ ] Let PR CI validate this isolated layer

#### For configuration changes:

- [x] Not applicable; this layer does not change configuration


### Stack navigation

Bottom → top:

1. [Significant-Gravitas#13755 — backend
supervision](Significant-Gravitas#13755)
2. [Significant-Gravitas#13757 — frontend
routing](Significant-Gravitas#13757)
3. [Significant-Gravitas#13756 — runtime
options](Significant-Gravitas#13756)
4. [Significant-Gravitas#13758 — single-container
image](Significant-Gravitas#13758)
5. [Significant-Gravitas#13759 — validation and publication
CI](Significant-Gravitas#13759)
6. [Significant-Gravitas#13760 — operations
documentation](Significant-Gravitas#13760)

The base refs already form GitHub's required linear chain. The native
Stack association is pending GitHub's repository-by-repository
public-preview rollout; the Stack API currently returns its documented
not-enabled response for this repository.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes shutdown ordering and timeouts for the notification RabbitMQ
path and alters metrics bind behavior; mistakes could hang supervisor
restarts or affect scrape access, though behavior is heavily tested and
bounded.
> 
> **Overview**
> Hardens backend processes for **single-container supervision**:
internal Prometheus listeners follow the same bind address as other
service RPC (`pyro_host`), and the notification service shuts down
RabbitMQ consumers with **bounded, non-blocking** teardown.
> 
> **Graph and Copilot executors** now pass
`addr=settings.config.pyro_host` into `start_http_server`, so metrics
stay on loopback in the appliance runtime while docker-compose can still
scrape via `0.0.0.0`.
> 
> **NotificationManager** keeps strong references to the background
`_run_service` future/task, routes shutdown through a new
`_shutdown_service` barrier (cancel consumers, then disconnect with
per-stage timeouts), and replaces the old synchronous disconnect in
`cleanup()` with `run_and_wait(..., timeout=CLEANUP_TIMEOUT_SECONDS)`
plus handling for already-closed or racing event loops.
> 
> **AppService** gains an optional timeout on `run_and_wait` and skips
scheduling `loop.stop()` when the shared loop is already closed.
> 
> Regression tests cover future retention, ordered shutdown,
cancellation timeouts, and loop-edge cases.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c38bd9e. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
autogpt-pr-reviewer[bot]
autogpt-pr-reviewer Bot previously approved these changes Aug 10, 2026

@autogpt-pr-reviewer autogpt-pr-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Automated Review — PR #13758

PR #13758 — feat(platform): add single-container distribution
Author: ntindle | Files: 46

🎯 Verdict: APPROVE

PR Description Quality

✅ Has Why + What + How — the description explains the appliance goal (one docker run to boot the full platform), enumerates the bundled services, and documents first-boot secret generation, /data persistence, and the closed-by-default signup posture.

What This PR Does

Adds a fully self-contained, opt-in single-container distribution of the AutoGPT Platform: one image bundling the frontend, backend services, Postgres, a Valkey cluster, RabbitMQ, FalkorDB, nginx, and Supervisor, runnable with a single docker run. It generates installation secrets on first boot, persists state under /data, exposes only nginx on :3000, and enforces least-privilege isolation (per-service OS users, a scoped autogpt_frontend Postgres role, loopback-pinned internal topology). The change is entirely additive — it lives under autogpt_platform/single-container/ plus one CI workflow and one smoke script, and touches no existing backend/frontend/compose sources.

Specialist Findings

🛡️ Security ✅ — Traced trust boundaries end-to-end (secret generation, per-service users, least-privilege PG role, loopback pinning, privilege-dropping launchers, nginx edge, log redaction); injection surfaces are clean (promote-admin.sh uses psql :'target_email' quoting, frontend role uses passwordless peer auth). No critical/high/medium findings. Two 🔵 defense-in-depth notes only.

🏗️ Architecture ✅ — Cleanly isolated and additive; Bake reuses the backend server target as a named context rather than forking build logic. Main long-term risk is several hand-maintained config mirrors (common.sh:73, entrypoint.sh:155, run-frontend.sh:10, healthcheck.sh:21) that can silently drift. All 🟠/🔵.

Performance ✅ — Infra-only, no hot request path. Steady-state note: the watchdog (watchdog.sh:25) and Docker HEALTHCHECK (Dockerfile:248) both run the full ~12-HTTP-probe battery every 30s, doubling idle health-probe cost; plus a 3-node Valkey cluster with zero replicas on one host (entrypoint.sh:270).
🟠 Duplicate continuous health probing (watchdog.sh:25)

🧪 Testing ✅ — Exceptionally well-tested: 59 unit tests + an 850-line negative-case smoke script (DB isolation, topology pinning, log-leak prevention, corrupt-config rejection, secret-rotation refusal). Gap: the AUTOGPT_ENABLE_BOT_SERVICES=true path is never exercised.
🟠 Bot-services enabled path untested (.github/scripts/platform-single-container-smoke.sh:795)

📖 Quality ✅ — Readability grade A; descriptive naming, small single-purpose functions, set -Eeuo pipefail throughout, high-signal comments. Nits are DRY loops and the hardcoded healthcheck program roster.

📦 Product ✅ — Requirements fully met, scope disciplined. Two operator-experience concerns: first-admin onboarding requires a multi-step CLI ritual with two container recreations, and AUTOGPT_PUBLIC_URL mismatches fail silently at auth time.
🟠 First-run admin onboarding friction (.env.example:11); 🟠 silent AUTOGPT_PUBLIC_URL footgun (entrypoint.sh:102)

📬 Discussion ✅ — All 266 review threads resolved, GitHub reviewDecision: APPROVED (human approval by Torantulino after the final commit), no merge conflicts (MERGEABLE/CLEAN). Prior sentry/coderabbit/cursor concerns all addressed in landed commits. The stale capy-ai BLOCKED verdict was a harness limitation on an old SHA, superseded.

🔎 QA ✅ — Ran 8 Bash checks: 59 appliance unit tests pass, all shell scripts pass bash -n, bake config resolves, first-boot secret generation (11 keys, mode 0600) and idempotent persistence confirmed, and negative tests passed (4 malformed public-URLs rejected rc=2; env-supplied POSTGRES_PASSWORD rotation refused). Honest limitation: the full appliance image could not be built in-sandbox, so end-to-end docker run behaviors rely on the native amd64/arm64 CI smoke job.

🟠 Should Fix

  1. Bot-services enabled path untested (.github/scripts/platform-single-container-smoke.sh:795) — no test sets AUTOGPT_ENABLE_BOT_SERVICES=true, so startup of copilot-bot/platform-linking-manager/copilot-chat-bridge and their health URLs is never exercised; a regression there passes all tests. (Flagged by: testing)
  2. Duplicate continuous health probing (watchdog.sh:25 / Dockerfile:248) — the same full probe battery runs twice per 30s window forever on an appliance meant to sit idle cheaply. Have the watchdog consult Docker health state or a cached marker, or stagger the intervals. (Flagged by: performance)
  3. Healthcheck program roster duplicates supervisord.conf (healthcheck.sh:21) — hardcoded Supervisor program list silently narrows coverage when a program is renamed/added. Derive from supervisorctl status or add a CI assertion. (Flagged by: quality, architect — 2 specialists)
  4. First-run admin onboarding friction (.env.example:11) — the advertised single docker run lands on a login page the operator cannot register on; creating the first admin needs enable-signup → recreate → sign up → docker exec ... promote → disable → recreate. Surface the bootstrap steps in the disabled-signup UI state or ship a one-time first-run token. (Flagged by: product)
  5. Silent AUTOGPT_PUBLIC_URL footgun (entrypoint.sh:102) — defaults to http://localhost:3000; validation checks URL validity but not whether it matches the published port, so -p 8080:3000 without setting it yields a "healthy" container with broken auth cookies/redirects. Warn loudly at startup when the public URL likely differs from the mapping. (Flagged by: product)

🟡 Nice to Have

  1. Runtime secret-key allowlist is a third copy (common.sh:73) — duplicates runtime_config.py _new_values/_validate_values; add a CI assertion the three sets match. (architect)
  2. APP_ENV=dev masquerade (entrypoint.sh:155) — a self-hosted appliance is semantically LOCAL; future dev-gated backend branches could silently activate. Prefer LOCAL + explicit doc/metrics-disable toggle. (architect)
  3. 3-node Valkey cluster with zero replicas on one host (entrypoint.sh:270) — no HA benefit, 3× process/AOF/gossip cost; use a single instance if the backend allows, else document the cost. (performance)
  4. Static assets proxied through Node (nginx.conf:117) — serve immutable /_next/static/* directly from nginx via alias + long-lived cache headers. (performance)
  5. Belt-and-suspenders gating of openapi/metrics (nginx/nginx.conf:90) — backend still emits /openapi.json and /metrics; a single case-sensitive nginx return 404 is the sole gate. Also disable openapi_url/gate /metrics at the app. (security)
  6. CORS origins not pinned to public URL (entrypoint.sh:155) — export BACKEND_CORS_ALLOW_ORIGINS="${AUTOGPT_PUBLIC_URL}"; largely inert same-origin but latent if published at a non-localhost origin. (security)
  7. Watchdog fail-stop counter reset untested (watchdog.sh:31), probe_tcp appears dead / amqp branches untested (probe.py:61), run-service.sh unknown-service branch untested (run-service.sh:26). (testing)

🔵 Nits

  1. DRY loops for Valkey/nginx dirs (entrypoint.sh:49, :66; bootstrap.sh:27) — collapse repeated install -d / wait_until lines into loops over the port/subdir set. (quality)
  2. Long |-delimited key allowlist (common.sh:62) — a multi-line array reads and diffs better. (quality)
  3. Add an orientation README.md for the ~15-file single-container/ directory. (quality)

QA Screenshots

Screenshot Description
frontend baseline loads Frontend baseline renders (212 KB), confirming the sandbox environment is healthy ✅

Human Review Needed

NO — Not required because all changed paths are confined to the isolated AutoGPT single-container distribution; security review completed with no high or critical findings or blockers.

Risk Assessment

Merge risk: LOW | Rollback: EASY (fully additive, isolated directory + one CI workflow; revert removes the feature with no impact on existing deployments)

CI Status

GitHub CI (per discussion review): ✅ ~40/40 checks green on linux/amd64 and linux/arm64 (build+smoke+scan, CodeQL, Codecov gates, lint, types, e2e), reviewDecision: APPROVED, no merge conflicts. Local harness: ✅ all 5 configured checks pass (frontend lint, backend lint, frontend typecheck, frontend unit tests, frontend build).


UI Testing — Variant Results

✅ local: All 59 appliance unit tests, shell syntax/lint, bake validation, first-boot secret generation/persistence, public-URL validation, and secret-rotation negative tests pass; full-image E2E is out of scope for this sandbox and is covered by the native CI smoke job.

✅ hosted: All in-session verifiable checks pass (59/59 unit tests, bash -n on 12 scripts, shellcheck -x rc=0, valid bake plan, all 21 COPY sources present, healthcheck/supervisor names consistent); full image build + smoke test and the additive-only diff claim are CI-gated and could not be reproduced in this sandbox, but no defect was observed.

Comment thread autogpt_platform/single-container/nginx/nginx.conf
Comment thread autogpt_platform/single-container/entrypoint.sh
Comment thread autogpt_platform/single-container/common.sh
Comment thread autogpt_platform/single-container/entrypoint.sh
Comment thread autogpt_platform/single-container/run-frontend.sh
Comment thread autogpt_platform/single-container/healthcheck.sh
Comment thread autogpt_platform/single-container/common.sh
Comment thread autogpt_platform/single-container/.env.example
Comment thread autogpt_platform/single-container/entrypoint.sh
Comment thread autogpt_platform/single-container/entrypoint.sh
@github-actions

Copy link
Copy Markdown
Contributor

🔄 Auto-redeploying: new commits pushed to a PR with an active deployment. Refreshing development environment for PR #13758.

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

🔄 Auto-redeploying: new commits pushed to a PR with an active deployment. Refreshing development environment for PR #13758.

@ntindle

ntindle commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

/review

@autogpt-pr-reviewer

Copy link
Copy Markdown

Queued a review for PR #13758 at c749f91.

@github-actions

Copy link
Copy Markdown
Contributor

🔄 Auto-redeploying: new commits pushed to a PR with an active deployment. Refreshing development environment for PR #13758.

@github-actions github-actions Bot added cla: pending CLA not yet signed by all contributors cla: signed CLA signed by all contributors and removed cla: signed CLA signed by all contributors cla: pending CLA not yet signed by all contributors labels Aug 10, 2026
@ntindle

ntindle commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

/reapprove

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approved at the request of @ntindle (#13758 (comment))

@autogpt-pr-reviewer autogpt-pr-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Automated Review — PR #13758

PR #13758 — feat(platform): add single-container distribution
Author: ntindle | Files: 46

🎯 Verdict: APPROVE

PR Description Quality

✅ Has Why + What + How — the PR explains the goal (a one-docker run local appliance), what it adds (self-contained image bundling backend, frontend, Postgres, Valkey cluster, RabbitMQ, FalkorDB behind nginx), and how (a Bake target layered on the existing backend server image), with a fully-ticked test plan.

What This PR Does

Adds a new, fully self-contained single-container distribution of the AutoGPT platform so it can be run locally as a complete appliance. Everything lives under autogpt_platform/single-container/ plus one CI workflow and one smoke script — it does not touch existing backend/frontend source, Dockerfiles, or Compose, so hosted deployments are unaffected. The image bundles all services with strong per-service OS-user isolation, a least-privilege frontend DB role, generated-once persisted secrets, and an nginx front door that is the only exposed port.

Specialist Findings

🛡️ Security ✅ — Reviewed every runtime script, nginx/supervisor/rabbitmq config, secret generation, and privilege-dropping logic; found no injection, auth-bypass, secret-exposure, or privilege-escalation vulnerability. Verified SQL parameterization in promote-admin.sh:20, 0600 root:root secret files, setpriv cap-dropping (run-frontend.sh:76), host-header/redirect pinning (nginx.conf:120-131), and TOCTOU-safe secret persistence.
🔵 Two informational notes: provider API keys are passed into the frontend env (run-frontend.sh:31, by design for transcription), and the bootstrap-admin window opens unauthenticated signup while enabled (documented, defaults closed).

🏗️ Architecture ✅ — Cleanly isolated and correctly layered on the existing backend image via a named Bake context, with zero coupling introduced into the hosted path. Main risk is unenforced drift between the appliance and backend conventions.
🟠 Supervised-program list is hand-duplicated between healthcheck.sh:21 and supervisord.conf — a missed edit silently drops health coverage or fails every check.

Performance ✅ — No application hot paths; nginx is well-tuned and probe.py parallelizes probes. Flags steady-state resource tuning for the appliance profile.
🟠 PostgreSQL max_connections left at default 100 (entrypoint.sh:113) against an aggregate Prisma + frontend-role + scheduler pool ceiling that can approach it under concurrent load.
🔵 Redundant dual 30s health suites (Docker HEALTHCHECK + watchdog.sh:43) and AOF on all three Valkey nodes (entrypoint.sh:269) add avoidable steady-state overhead.

🧪 Testing ✅ — Unusually strong: 59 Python unit tests + an 850-line CI smoke test doing real runtime verification (UID isolation, Postgres privilege introspection, restart recovery), with well-represented negative cases.
🟠 Valkey cluster non-fresh recovery / "refusing to erase persistent state" data-safety branch (bootstrap.sh:92) is never exercised.
🔵 Bash config-loader rejection paths (common.sh:77) and the initial-health fail-stop (watchdog.sh:60) untested; some test_entrypoint.py tests grep source substrings rather than behavior.

📖 Quality ✅ — Readability grade A: descriptive naming, why-not-what comments, guard-clause style, atomic writes. Findings are minor DRY/formatting nits (nginx.conf:73 duplicate ws block, infra ports as bare literals in common.sh:12, DSN duplicated in run-frontend.sh:8).

📦 Product ⚠️ — The "one docker run" story starts the stack, but signup is disabled by default (AUTH_ALLOW_NEW_ACCOUNTS=false), so first login requires an env toggle, two container recreations, and a CLI promote step documented only in logs/.env.example.
🟠 First-run admin bootstrap is a cliff (.env.example:16) — opt-in/experimental, so not a hard block, but worth smoothing before end-user positioning.

📬 Discussion ⚠️ — All 288 review threads resolved with exhaustive author engagement. Two earlier human approvals (including founder @Torantulino) were deliberately self-dismissed to force re-review after merging dev, so reviewDecision is currently REVIEW_REQUIRED; the core Build, smoke, and scan (amd64/arm64) + e2e/python-analyze CI jobs were still pending on head 2d36895.

🔎 QA ✅ — Could not build/boot the multi-GB appliance image in-sandbox (honest limitation), so executed the PR's actual code paths directly: 59 unit tests pass, secret generation is idempotent (259a3375…41c3 stable across re-runs), all 12 shell scripts pass bash -n, and probe.py correctly distinguishes 200 / 404 / connection-refused. All negative tests rejected correctly. Container-integration proof is deferred to CI.

QA Screenshots

Screenshot Description
baseline dev frontend Baseline dev frontend renders (PR does not alter UI) ✅

🟠 Should Fix

  1. Health-check program list duplicated from supervisord (healthcheck.sh:21) — derive the required-program set from supervisorctl status or add a test asserting the two lists stay in sync. (Flagged by: architect — 1)
  2. PostgreSQL max_connections untuned vs aggregate pool budget (entrypoint.sh:113) — raise max_connections in the appended config or derive per-service connection_limit from a documented total cap, so concurrent load can't surface as connection-refused outages. (Flagged by: performance — 1)
  3. Valkey non-fresh recovery / data-safety branch untested (bootstrap.sh:92) — add a test that seeds an unrecoverable cluster state and asserts it fails fatally without destroying persisted memory/queue state, plus an already-formed-cluster recovery case. (Flagged by: testing — 1)
  4. First-run admin bootstrap requires two container recreations (.env.example:16) — provide a one-shot create-first-admin path that doesn't require enabling open signup, and/or surface the bootstrap instructions on the login page instead of only in logs/.env.example. (Flagged by: product — 1)

🟡 Nice to Have

  1. Schema-drift pointer for frontend DB grants (bootstrap.sh:170) — comment linking the grant block to schema.prisma/Better Auth so schema changes prompt review here. (architect)
  2. Reduce steady-state overhead (watchdog.sh:43, entrypoint.sh:269) — let the watchdog read Docker's health status instead of re-running the full suite, and disable/relax AOF on cache Valkey nodes if durability isn't required. (performance)
  3. Cover bash config-loader + initial-health fail-stop branches (common.sh:77, watchdog.sh:60) and make substring-based test_entrypoint.py checks behavioral where feasible. (testing)
  4. Centralize infrastructure ports (common.sh:12) — hoist Postgres/Valkey/FalkorDB/frontend ports alongside the app-port constants. (quality)

🔵 Nits

  1. Duplicate nginx ws location block (nginx.conf:73) — collapse into location ~ ^/_agpt/ws/?$. (quality)
  2. Duplicated frontend DSN literal (run-frontend.sh:8 & Dockerfile) — add a cross-referencing comment or derive from one source. (quality)
  3. user=root on [program:next] (supervisord.conf:269) — one-line comment noting root is required for the setpriv cap-drop chain, so a maintainer doesn't "fix" it. (architect, quality)
  4. Three blank lines between supervisor blocks (supervisord.conf:109) — reduce to one. (quality)

Human Review Needed

NO — Not required because all changed paths are confined to the isolated AutoGPT single-container distribution; security review completed with no high or critical findings or blockers.

Risk Assessment

Merge risk: LOW | Rollback: EASY — the change is fully additive and opt-in; deleting the single-container/ directory and its two CI/smoke files reverts it with no impact on existing deployments.

CI Status

Local harness: ✅ all 5 checks pass (frontend lint, backend lint, frontend typecheck, frontend unit tests, frontend build). GitHub CI: the PR's authoritative Build, smoke, and scan (linux/amd64 & linux/arm64), e2e, and python-analyze jobs were reported PENDING on head 2d36895 and must go green before merge (that per-arch smoke job is the only place the assembled appliance is actually booted). Additionally, the two prior human approvals were self-dismissed, so reviewDecision is REVIEW_REQUIRED — a fresh human approval is needed at merge time per GitHub policy, independent of this automated review.


UI Testing — Variant Results

✅ local: All executable code paths (59 unit tests, secret generation idempotency, probe.py, config guards, all shell syntax) pass with correct positive and negative behavior; full appliance boot is covered by CI, not reproducible in this sandbox.

✅ hosted: All reproducible test-plan items independently pass (59/59 unit tests, bash -n, negative-path present); appliance runtime itself is only exercisable via the per-arch CI smoke job, not the dev stack, so no blocking defect found with a specific file/line.

Comment thread autogpt_platform/single-container/healthcheck.sh
Comment thread autogpt_platform/single-container/bootstrap.sh
Comment thread autogpt_platform/single-container/supervisor/supervisord.conf
Comment thread autogpt_platform/single-container/entrypoint.sh
Comment thread autogpt_platform/single-container/watchdog.sh
Comment thread autogpt_platform/single-container/common.sh
Comment thread autogpt_platform/single-container/run-frontend.sh
Comment thread autogpt_platform/single-container/supervisor/supervisord.conf
Comment thread autogpt_platform/single-container/.env.example
Comment thread autogpt_platform/single-container/.env.example
@ntindle

ntindle commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

Final local verification passed on exact head 2d368953ae45444e2fc1dd4db3a430e1b21fc78b.

  • Built native ARM64 image sha256:7ba42df1995ba33a499b96fb3ef1a03d5fdce6d61870bc275e212519b8ab779d; OCI version/revision both match the exact head.
  • Full repository smoke passed: fresh-volume boot, auth, scoped frontend DB role, hostile-listener isolation, FalkorDB memory persistence, same-volume container replacement, and forced failure/restart recovery.
  • Final handoff container is healthy with restart count 0; http://127.0.0.1:3300/healthz returns ok.
  • GitHub AMD64 and ARM64 build/smoke/scan jobs are also green.

Login UI:

AutoGPT login

Internal tooling remains private (/_agpt/docs → 404):

Private route 404

@ntindle
ntindle added this pull request to the merge queue Aug 10, 2026
Merged via the queue into dev with commit 18608f5 Aug 10, 2026
37 checks passed
@github-project-automation github-project-automation Bot moved this from 👍🏼 Mergeable to ✅ Done in AutoGPT development kanban Aug 10, 2026
@github-project-automation github-project-automation Bot moved this to Done in Frontend Aug 10, 2026
@ntindle
ntindle deleted the feat/single-container-04-image branch August 10, 2026 20:58
@github-actions

Copy link
Copy Markdown
Contributor

🧹 Auto-undeploying: PR closed with active deployment. Cleaning up development environment for PR #13758.

@Pwuts

Pwuts commented Aug 10, 2026

Copy link
Copy Markdown
Member

🧹 Preview Environment Cleaned Up

All resources for PR #13758 have been removed:

  • ☸️ Kubernetes namespace deleted
  • 🗃️ Preview branch database deleted

Cleanup completed successfully.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla: signed CLA signed by all contributors size/xl

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants