Skip to content

Commit e7169a4

Browse files
authored
Merge pull request #53 from chiruu12/feat/agentos-deploy
AgentOS Phase 5: Docker deployment
2 parents 186ffb3 + ded64c0 commit e7169a4

6 files changed

Lines changed: 156 additions & 0 deletions

File tree

.dockerignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.git
2+
.github
3+
.context
4+
.venv
5+
venv
6+
__pycache__
7+
*.pyc
8+
.pytest_cache
9+
.mypy_cache
10+
.ruff_cache
11+
site
12+
dist
13+
build
14+
*.egg-info
15+
.hive
16+
logs
17+
tests
18+
docs
19+
.env
20+
.DS_Store

Dockerfile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Hive AgentOS -- containerized REST API + control plane.
2+
#
3+
# Build: docker build -t hive-agentos .
4+
# Run: docker run -p 8000:8000 -e ANTHROPIC_API_KEY=sk-... -v hive_state:/data hive-agentos
5+
# Then open http://localhost:8000/ (control plane) or /docs (API).
6+
7+
FROM python:3.12-slim AS build
8+
9+
# uv for a fast, reproducible install. Pinned so builds don't drift with uv releases
10+
# (keep in sync with the uv that resolved uv.lock).
11+
COPY --from=ghcr.io/astral-sh/uv:0.9.3 /uv /usr/local/bin/uv
12+
13+
WORKDIR /app
14+
COPY pyproject.toml uv.lock README.md ./
15+
COPY src ./src
16+
COPY profiles ./profiles
17+
COPY skills ./skills
18+
COPY models.yaml ./models.yaml
19+
20+
# Install the package (with the API extra) into a self-contained venv.
21+
# --no-editable copies hive into site-packages (an editable install would leave a
22+
# .pth pointing at /app/src, which the runtime stage does not carry).
23+
ENV UV_PROJECT_ENVIRONMENT=/opt/venv
24+
RUN uv sync --frozen --extra api --no-dev --no-editable
25+
26+
27+
FROM python:3.12-slim AS runtime
28+
29+
# Non-root user; agent workspaces and state live under /data.
30+
RUN useradd --create-home --uid 1000 hive \
31+
&& mkdir -p /data && chown hive:hive /data
32+
COPY --from=build /opt/venv /opt/venv
33+
ENV PATH="/opt/venv/bin:$PATH"
34+
35+
USER hive
36+
WORKDIR /data
37+
38+
EXPOSE 8000
39+
40+
# Report container health via the API's readiness endpoint (urllib ships with the
41+
# slim base, so no extra dependency). Enables `docker ps` health + service_healthy.
42+
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
43+
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/healthz')" \
44+
|| exit 1
45+
46+
# The API server, with the heartbeat loop in-process. `hive init` is idempotent and
47+
# scaffolds .hive/ in the mounted /data volume on first run. Its stderr is kept (not
48+
# silenced) so a real init failure -- bad /data permissions, disk full -- is visible.
49+
ENTRYPOINT ["sh", "-c", "hive init 2>&1 || true; exec hive serve --host 0.0.0.0 --port 8000 --with-daemon"]

docker-compose.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Hive AgentOS -- one-command local deployment.
2+
#
3+
# ANTHROPIC_API_KEY=sk-... docker compose up --build
4+
#
5+
# Control plane: http://localhost:8000/ API docs: http://localhost:8000/docs
6+
7+
services:
8+
hive:
9+
build: .
10+
image: hive-agentos
11+
ports:
12+
# Bind to loopback only -- matches the local-dev / reverse-proxy posture. Use
13+
# "8000:8000" (or put a proxy in front) to expose it on the network.
14+
- "127.0.0.1:8000:8000"
15+
environment:
16+
# Pass through provider keys from your shell / .env (only what you use).
17+
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
18+
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
19+
- GROQ_API_KEY=${GROQ_API_KEY:-}
20+
- HIVE_DEFAULT_MODEL=${HIVE_DEFAULT_MODEL:-claude-haiku-4-5}
21+
volumes:
22+
# Persist agent state, logs, and workspaces across restarts.
23+
- hive_state:/data
24+
restart: unless-stopped
25+
26+
volumes:
27+
hive_state:

docs/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
`hive serve` (no build step, no data egress) -- the pending-approval queue with
3535
approve/deny, a live agents list, and sessions, auto-refreshing. Tenant-aware via
3636
an `X-Hive-User` field.
37+
- **Docker deployment**: a multi-stage `Dockerfile` and `docker-compose.yml` run the
38+
REST API + control plane and the heartbeat daemon in one non-root container with a
39+
persistent `/data` volume. `ANTHROPIC_API_KEY=sk-... docker compose up --build`.
3740

3841
## [0.6.1] -- 2026-06-03
3942

docs/guide/deployment.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Deployment
2+
3+
Hive ships a `Dockerfile` and `docker-compose.yml` that run the REST API and the
4+
heartbeat daemon together in one container -- the agent OS in your own infrastructure.
5+
6+
## Docker Compose (one command)
7+
8+
```bash
9+
ANTHROPIC_API_KEY=sk-... docker compose up --build
10+
```
11+
12+
- Control plane: <http://localhost:8000/>
13+
- API docs: <http://localhost:8000/docs>
14+
15+
Provider keys are read from your shell (or a `.env` file) and passed through; set only
16+
the ones you use (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GROQ_API_KEY`,
17+
`HIVE_DEFAULT_MODEL`). Agent state, logs, and workspaces persist in the `hive_state`
18+
volume across restarts.
19+
20+
## Plain Docker
21+
22+
```bash
23+
docker build -t hive-agentos .
24+
docker run -p 8000:8000 \
25+
-e ANTHROPIC_API_KEY=sk-... \
26+
-v hive_state:/data \
27+
hive-agentos
28+
```
29+
30+
## How the image is built
31+
32+
- **Multi-stage**: a build stage installs the package (with the `[api]` extra) into a
33+
self-contained venv via `uv sync --no-editable`; the slim runtime stage copies only
34+
that venv.
35+
- Runs as a **non-root** user; all writable state lives under `/data` (the working
36+
directory and the mount point), so the container filesystem stays read-only-friendly.
37+
- The entrypoint runs the idempotent `hive init` then
38+
`hive serve --host 0.0.0.0 --port 8000 --with-daemon`, so a single process serves
39+
HTTP and drives agents.
40+
41+
## Scaling notes
42+
43+
`hive serve` (without `--with-daemon`) is **stateless** and can run behind a load
44+
balancer with several replicas, all reading/writing one shared `.hive/hive.db` (SQLite
45+
WAL handles concurrent access). Run **one** `--with-daemon` instance (or a standalone
46+
`hive start`) to drive the heartbeat, and scale the API replicas separately. For
47+
heavier multi-writer loads, point the daemon and API at shared storage for `/data`.
48+
49+
## Production checklist
50+
51+
- Set real provider API keys via secrets, not in the image.
52+
- Put the API behind TLS and authentication (the server binds `0.0.0.0` in the
53+
container; restrict exposure at the proxy/ingress).
54+
- Back up the `/data` volume (it holds the SQLite DB, event logs, and workspaces).
55+
- Tune `.hive/config.yaml` (`daemon.heartbeat`, `daemon.max_concurrent_agents`) for
56+
your workload; enable `approval` and `guardrails` for untrusted use.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ nav:
6666
- CLI Reference: guide/cli-reference.md
6767
- REST API: guide/rest-api.md
6868
- Evals: guide/evals.md
69+
- Deployment: guide/deployment.md
6970
- Architecture: guide/architecture.md
7071
- Extending:
7172
- Extension Points: extending/index.md

0 commit comments

Comments
 (0)