07 — Deployment & Environments

Topology

flowchart TB
    subgraph Edge["Vercel (edge)"]
        WWW[drpxbt.xyz]
        APP[app.drpxbt.xyz — planned<br/>terminal]
        PA[hunter-platform<br/>serverless]
    end

    subgraph Cluster["Our infrastructure"]
        GW[hunter-gateway<br/>gateway ×N]
        AG[hunter-agent]
        MCPS[MCP servers]
        WK[hunter-workers]
        PG[(Postgres + pgvector)]
        RD[(Redis)]
        VLLM[vLLM on GPUs]
    end

    subgraph Chain["Base"]
        CT[Contracts]
    end

    WWW --> APP --> GW
    APP --> PA
    APP --> CT
    GW --> VLLM
    GW --> PG
    GW --> PA
    AG --> GW
    AG --> MCPS
    AG --> PG
    WK --> AG
    WK --> RD
    WK --> CT
    WK --> PA

Static and serverless surfaces run on Vercel; anything that touches the GPUs or holds long-lived state runs on our own infrastructure. The GPU subnet is not publicly routable — the gateway is the only ingress.

Environments

Environment Chain Models Purpose
Local (hunter-demo) anvil Small local model or mock Full-stack development
Staging Base Sepolia One small model Integration, contract rehearsal
Production Base mainnet Full roster Live

Config is environment-variable only — no environment-specific code paths. Every service ships .env.example documenting its full surface.

Local development

hunter-demo composes the stack. [PLANNED] additions: gateway + CPU model backend, Postgres/pgvector, Redis, an anvil node with contracts deployed by a bootstrap script, and a seed script that locks tokens for a demo wallet so the whole tier → API key → inference path works offline.

Individually:

# Gateway
cd hunter-gateway && uv venv && uv pip install -e ".[dev]"
uv run uvicorn hunter_server.main:app --reload --port 8080

# Agent
cd hunter-agent && uv sync --extra dev
CONFIG_FILE=./characters/hunter.json uv run uvicorn hunter.main:app --reload

# Contracts
cd hunter-contracts && npm ci && npm test

# Frontends
cd hunter-terminal && npm ci && npm run dev

CI/CD

Every repository gates merges on GitHub Actions (push + pull_request):

Repo Job Gate
hunter-contracts npm ci → compile → test full contract suite
hunter-gateway uv venv → pytest tests
hunter-agent uv sync → pytest and pylint tests + lint
hunter-platform pytest + app-factory import routes register
hunter-mcps pytest (mcp-twitter) tests
airdropio-scraper uv sync → pytest tests
drpxbt.xyz, hunter-terminal tsc --noEmit → build typecheck + build
hunterpods-frontend build (tsc && vite build) typecheck + build
hunter-workers, hunter-podcast, hunter-scrapers compileall + pytest-if-present syntax

Two runner-environment rules learned the hard way and encoded in every workflow:

  1. Never uv pip install --system — GitHub runners' Python is externally managed (PEP 668) and rejects it. Create a project venv.
  2. Invoke pytest as python -m pytest — bare pytest does not put the repository root on sys.path, so import app / import src fails in CI while passing locally.

Python dependency management is uv (uv.lock) for actively developed services. Poetry workflows were removed: poetry install does not install PEP 621 [project.optional-dependencies], which silently produced an environment with no test runner — See ADR-005 for why the toolchain moved to uv.

Contract deployment

cd hunter-contracts && cp .env.example .env     # RPC, key, addresses
npm run deploy:sepolia
npm run deploy:base                  # only after audit

Compilation pins the npm solc wasm build via a Hardhat subtask override, so builds are deterministic and work behind proxies/offline where binaries.soliditylang.org is unreachable (ADR-007).

Runtime configuration

Service Critical variables
hunter-gateway HUNTER_DATABASE_URL, HUNTER_JWT_SECRET_KEY, HUNTER_MODELS_CONFIG, HUNTER_TIER_CREDITS, HUNTER_ENTITLEMENTS_URL, HUNTER_X402_*
hunter-agent CONFIG_FILE, DB_URI, JWT_SECRET_KEY, MCP_CONFIG, ACP_SERVICE_TOKEN, OPENAI_BASE_URL (→ gateway)
hunter-platform DB_*, API_TOKEN, API_VERSION
hunter-mcps TWITTERAPI_IO_KEY
drpxbt.xyz VITE_BASE_RPC_URL, VITE_DRPXBT_ADDRESS, VITE_TIERLOCK_ADDRESS, VITE_STAKING_ADDRESS
hunter-terminal VITE_BACKEND_API_URL, VITE_WALLETCONNECT_PROJECT_ID, token-gate vars

JWT_SECRET_KEY must be identical in hunter-agent and hunter-gateway — that shared secret is what makes one SIWE session work across both.

Scaling

Component Strategy First bottleneck
Gateway Horizontal (stateless) Postgres write throughput on the ledger
vLLM Add GPU nodes to the pool GPU memory / concurrent sequences
Agent Horizontal per room Long tool chains — needs checkpointing
Workers One process per queue Redis, then external API rate limits
Platform API Serverless auto-scale Connection pool
Postgres Vertical, then read replicas Usage-ledger inserts

Known scaling work, in the order it will bite: usage-ledger partitioning by month, Redis token buckets for per-key rate limiting (today only monthly credit quotas exist), LangGraph Postgres checkpointing for resumable pipelines, and a health-checked multi-node upstream pool in the gateway.

HUNTER · $DRPXBT · drpxbt.xyz edit this page