Skip to main content

Deployment Architecture

Cocoon's MVP stack runs as a set of Docker containers orchestrated via Docker Compose. This page describes each service, its role, and the network topology — both for a single-chain deployment and the two-chain interoperability demo.

Services Overview

ServicePortImageDescription
erigon8545custom Erigon buildChain A — private EVM chain (Chain ID 33, 1-second Clique PoA blocks)
erigon28555custom Erigon buildChain B — second private chain for interop demo (Chain ID 34)
deployFoundry one-shotDeploys all contracts to Chain A on first boot
deploy-chain2Foundry one-shotDeploys contracts to Chain B for interop testing
backend8546Go serviceJSON-RPC proxy for Chain A: session auth, IBAN registry, audit log, permission enforcement
backend28556Go serviceJSON-RPC proxy for Chain B
user_db8548Python FastAPIShared user identity, authentication, KYC, and session management service
dashboard3000Next.js 14Admin dashboard: user management, KYC review, permissions, audit log
frontend3001Next.js 14Investor portal for Chain A: portfolio, payments, swaps, MMF subscribe/redeem
frontend23011Next.js 14Investor portal for Chain B (interop demo)
explorer3002Next.js 14Block explorer: real-time blocks, transactions, address resolution
note

In the single-chain configuration (docker compose up erigon deploy backend user_db dashboard frontend explorer), erigon2, backend2, deploy-chain2, and frontend2 are not started, reducing resource requirements significantly.

Network Topology

warning

Port 8545 (Erigon RPC) must never be exposed to external networks. All external RPC traffic must pass through the backend proxy on port 8546, which enforces session validation, CORS, and audit logging. In production, bind Erigon to 127.0.0.1 and restrict Docker port publishing accordingly.

Port Allocation

PortServiceVisibilityNotes
8545Erigon Chain A (RPC)Internal onlyDirect access bypasses all auth and audit
8546Backend proxy Chain APublicAuth-enforced gateway for all RPC calls
8547ProverInternalZK proof generation service
8548User DBInternalShared by all services
8551Erigon Engine APIInternalConsensus/execution engine communication
8555Erigon Chain B (RPC)Internal onlySecond chain for interop demo
8556Backend proxy Chain BInternal
3000Admin dashboardRestrictedAdmin accounts only
3001Investor portal (A)AuthenticatedSession required
3011Investor portal (B)Authenticated
3002Block explorerPublic (demo)Can be restricted in production

Startup Sequence

Docker Compose health checks enforce the correct initialization order:

  1. Erigon starts and waits until the node is healthy (accepting RPC calls).
  2. The deploy one-shot container deploys all Solidity contracts and writes addresses to deployments.json.
  3. The backend proxy starts, reading deployments.json to configure the PermissionRegistry address.
  4. The user DB starts independently (it has no chain dependency).
  5. Dashboard, frontend, and explorer start once backend and user DB are healthy.

If deploy exits with a non-zero code, the contracts were not deployed. Check logs with docker compose logs deploy before starting the other services.

Contract Deployment

On first boot, the deploy container runs contracts/deploy.sh, which:

  1. Deploys the core contracts: PermissionRegistry, MMFToken, Stablecoin, StateAnchorRegistry, IdentityRegistry, ClaimTopicsRegistry, TrustedIssuersRegistry
  2. Deploys the Uniswap V3 infrastructure: UniswapV3Factory, SwapRouter, NonfungiblePositionManager, QuoterV2
  3. Deploys six RWA tokens: SPYToken, TLTToken, BTCToken, ETHToken, EURToken, CHFToken
  4. Creates 15 trading pools across all token pairs
  5. Seeds initial liquidity
  6. Writes all addresses to deployments.json

Contract addresses are stable across restarts (Anvil uses a deterministic deployer). A full reset with docker compose down -v will produce new addresses and require a frontend rebuild.

Two-Chain Interoperability Setup

For the cross-chain demo, a second chain (Chain B, ID 34) runs alongside Chain A. The interop feature allows assets to be bridged atomically between the two chains via the StateAnchorRegistry contracts on both chains.

Additional environment variables required for interop:

INTEROP_ENABLED=true
INTEROP_ADMIN=0xYourAdminAddress
INTEROP_ADMIN_KEY=your_admin_private_key
PEER_CHAINS=34=http://erigon2:8545=/app/deployments.chain2.json

The interop listener on each backend proxy watches the peer chain for state anchor events and processes cross-chain messages.

Data Volumes

VolumeServiceContains
erigon-dataerigonChain A block data, state, chain DB
erigon2-dataerigon2Chain B block data
userdb-datauser_dbUser accounts, sessions, KYC documents (SQLite)
backend-databackendAudit log SQLite database
prover-dataproverGenerated ZK proofs, proof queue
warning

docker compose down -v deletes all volumes. Chain A and B data, all user accounts, KYC submissions, and audit logs will be lost. Use only for a clean development reset.

Resource Requirements

ConfigurationRAMDiskNotes
Single chain8 GB minimum10 GBChain A only
Single chain16 GB recommended20 GBWith prover enabled
Dual chain (interop)16 GB minimum30 GBChains A + B

The prover is the most CPU-intensive service. For local development without proof generation, set PROVER_BACKEND=mock to skip actual proof computation.