Skip to content

feat(setup): add Apple container orchestrator for the storage stack#3347

Open
anthonykurtdavid wants to merge 5 commits into
HKUDS:mainfrom
SmallBizAI:feat/apple-container-stack
Open

feat(setup): add Apple container orchestrator for the storage stack#3347
anthonykurtdavid wants to merge 5 commits into
HKUDS:mainfrom
SmallBizAI:feat/apple-container-stack

Conversation

@anthonykurtdavid

Copy link
Copy Markdown

Description

Adds a native Apple container orchestrator so Apple Silicon users can run LightRAG's full Postgres / Neo4j / Milvus storage stack (plus the LightRAG API server) without Docker Desktop. Apple's container runtime (v1.0.0) has no Docker Compose support and a few gaps that make docker-compose-full.yml unusable as-is, so this ships a self-contained bash orchestrator that reimplements the missing pieces.

Related Issues

None. Works around three upstream Apple-runtime limitations: no Compose, no container-to-container service DNS (apple/container#856), and broken bind mounts for DB data dirs (apple/container#333).

Changes Made

  • scripts/setup/apple-container.sh — orchestrator with up / down / status / logs / restart / pull / help. Creates a dedicated network, launches Postgres, Neo4j, Milvus (standalone + etcd + MinIO) and LightRAG in dependency order with health-wait loops, and wires dependents by the container IP captured at up time.
  • docs/AppleContainerSetup.md — deployment guide (prerequisites, image table, storage/volume/port mapping, Compose-feature comparison, troubleshooting, trust-boundary note). Linked from README.md.
  • tests/setup/test_apple_container.py — 8 pytest.mark.offline unit tests (help/arg parsing, generate_env_file storage→IP mapping, _set_kv idempotency, bash -n syntax, image-tag pins). All daemon-free, so they run in CI on Linux.
  • Makefilemake apple-up / apple-down / apple-status / apple-logs / apple-restart / apple-pull convenience targets (reuse the Makefile's bash-4 resolver).
  • .gitignore — ignores the generated .apple-container.env (contains copied secrets).

How it works: up launches services in order, reads each dependency's vmnet IP via container inspect, and bakes it into the next service's environment. LightRAG receives a generated .apple-container.env (a copy of your .env with storage endpoints rewritten to in-network IPs), so your real .env is never mutated. Databases are not published to host ports (matching docker-compose-full.yml); LightRAG reaches them in-network. Image tags mirror the Compose stack; Postgres uses pgvector/pgvector:pg18 (the setup template's AGE image is amd64-only) and Milvus uses the CPU (non--gpu) tag.

Checklist

  • Changes tested locally
  • Code reviewed
  • Documentation updated (if necessary)
  • Unit tests added (if applicable)

Additional Notes

Scope / limitations (honest):

  • macOS 26 (Tahoe) + Apple Silicon only; requires the container runtime and bash 4+. Not a replacement for the Docker Compose path.
  • CPU Milvus, no local reranker (no Metal-in-container passthrough). mix/hybrid queries emit a "rerank not configured" warning and fall back to naive-favored retrieval unless a hosted reranker is configured.
  • Services are wired by IP (Apple container 1.0.0 has no service DNS) → run down && up to re-wire after a dependency's IP changes.
  • Named volumes (not bind mounts). Local single-user dev only (default dev credentials).

Testing: 8 offline unit tests pass; pre-commit (ruff-format + ruff) and shellcheck are clean. Manually validated end-to-end on macOS 26 / Apple M2: full stack up on container 1.0.0, ingested a document → 106 entities / 134 relations, a real RAG query returned HTTP 200, and data persisted across a down / up cycle. CI cannot exercise the container daemon, so daemon-dependent paths were validated manually only.

Add scripts/setup/apple-container.sh to run the full LightRAG storage stack
(PostgreSQL, Neo4j, Milvus standalone + etcd + minio) plus the LightRAG API
server on Apple's native `container` CLI (macOS 26, Apple Silicon) — a
Docker-Compose-free path for arm64 dev boxes that need the production-like
PG/Neo4j/Milvus backends without Docker Desktop.

Apple `container` 1.0.0 has no Compose support, so the script reimplements:
- start ordering + health-wait loops (no depends_on / healthcheck), reusing the
  repo's PORT_HEX /proc/net/tcp probe idiom;
- service wiring by the container IP `container` assigns on a shared network
  (1.0.0 has no working container-to-container service DNS, apple/container#856),
  so no sudo and no DNS setup are required;
- named volumes (host bind mounts of DB data dirs are broken on Apple container,
  apple/container#333).

All images are arm64-verified. Postgres uses pgvector/pgvector:pg18 (the setup
template's AGE image is amd64-only; AGE is not needed since graph=Neo4j and
vector=Milvus). Milvus uses the CPU tag v2.6.11, not the -gpu tag. LLM and
embeddings run over outbound HTTPS (e.g. OpenAI); no GPU and no vLLM.

Convenience `make apple-up`/`apple-down`/`apple-status`/`apple-logs`/
`apple-restart`/`apple-pull` targets wrap the script, reusing the Makefile's
existing bash-4 interpreter resolver.

Also adds docs/AppleContainerSetup.md (linked from README.md) and offline tests
in tests/setup/test_apple_container.py; the generated .apple-container.env is
git-ignored. Shellcheck-, ruff- and pre-commit-clean; validated end-to-end on
macOS 26 / Apple Silicon.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@danielaskdd

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d34e71a045

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/setup/apple-container.sh
Comment thread scripts/setup/apple-container.sh
Address PR review feedback:
- Prefix all stack containers with `lightrag-` (configurable via
  LIGHTRAG_AC_PREFIX) so down/up never stop, remove, or reuse a same-named
  container from another project; logs/restart now validate the service name.
- Make container_ip accept both the `ipv4Address` (container CLI 1.0.x) and a
  plain `address` field; document the namespacing in AppleContainerSetup.md.

Re-validated end-to-end on macOS 26 / Apple M2: stack up with lightrag-* names,
/health healthy, data preserved (106 entities); shellcheck + offline tests clean.
@danielaskdd

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8886188ead

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/setup/apple-container.sh Outdated
Address PR review feedback: derive the storage volume names from the same
prefix as the container names (VOLUME_PREFIX from LIGHTRAG_AC_PREFIX), so two
stacks configured with different prefixes never share Postgres/Neo4j/Milvus
data and a `down --purge` from one never deletes the other's volumes.

Re-validated on macOS 26 / Apple M2: up creates namespaced lightrag_* volumes,
stack /health healthy; shellcheck and 9 offline tests clean.
@danielaskdd

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a20d7217da

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/setup/apple-container.sh Outdated
Comment thread scripts/setup/apple-container.sh
Address PR review feedback:
- Read Postgres/Neo4j/MinIO credentials from the source .env (precedence:
  shell override > .env value > dev default) so a password set in .env is used
  to create the database and matches what the lightrag container connects with,
  instead of being silently overwritten with the `rag` default.
- Write MILVUS_DB_NAME (default `lightrag`) into the generated env-file, since
  MilvusVectorDBStorage requires it in addition to MILVUS_URI; a minimal .env
  would otherwise fail LightRAG's startup validation and time out `up`.

Re-validated on macOS 26 / Apple M2 with a fresh purge: Postgres created with
the .env user, stack /health healthy; 11 offline tests and shellcheck clean.
@danielaskdd

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ca973bc70a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/setup/apple-container.sh Outdated
Comment on lines +263 to +264
grep -vE "^${key}=" "$file" > "${file}.tmp" 2>/dev/null || true
mv "${file}.tmp" "$file"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve private permissions while rewriting env file

When generate_env_file copies a user's .env and calls chmod 600, the first _set_kv call immediately writes a new ${file}.tmp using the process umask and then mvs it over the private file. With the default macOS umask 022, the final .apple-container.env becomes mode 644, exposing copied API keys/passwords to other local users despite the script's promise to keep it private. Re-apply chmod 600 after the rewrite or create the temp file with restrictive permissions before replacing the original.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — _set_kv now creates its temp file under umask 077, so every rewrite (and the final mv) keeps .apple-container.env at mode 600; the initial chmod 600 is no longer undone. Added a test asserting the generated file's permissions.

Address PR review feedback: _set_kv created the temp file under the process
umask (022 -> 644) and mv'd it over the private .apple-container.env, undoing
the initial chmod 600 and exposing the copied API keys/passwords to other local
users. Create the temp under umask 077 so every rewrite keeps mode 600, and add
a test asserting the generated file's permissions.
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.

2 participants