Pular para conteúdo

Docker — infraestrutura do DCP

Tradução informativa da versão em inglês, atualizada em 25/10/2026. Em caso de divergência, prevalece a versão em inglês. Identificadores, comandos e blocos de código são mantidos sem tradução.

Configuração do Docker Compose para implantar todos os serviços do DCP como contêineres. Inclui verificação, ancoragem, log de transparência e revogação.

Início rápido

cd docker
docker compose up

docker compose up fica em primeiro plano: execute as checagens abaixo em um segundo terminal, ou inicie a pilha com docker compose up -d. Isso inicia os quatro serviços em cinco contêineres (dois logs de transparência):

Contêiner Porta Descrição
verification 3000 Servidor de verificação de bundles
anchor 3001 Serviço de ancoragem: só registros locais; o envio on-chain não está implementado
transparency-log-a 3002 Log de transparência log-alpha, com provas de Merkle
transparency-log-b 3012 Log de transparência log-beta, par de gossip do log-alpha
revocation 3003 Serviço de revogação de agentes

Checar se tudo está em execução

curl http://localhost:3000/health
curl http://localhost:3001/health
curl http://localhost:3002/health
curl http://localhost:3012/health
curl http://localhost:3003/health

Uma resposta saudável só significa que o processo responde por HTTP. Ela não checa persistência, ancoragem nem gossip (o gossip_peers de um log conta os pares configurados, fixados ou não).

Serviços

verification (:3000)

Servidor de verificação de Signed Bundles do DCP (V1 + V2 + fase 3). As duas requisições de verificação abaixo são modelos: {...} e ... representam um bundle assinado real, então não funcionam como estão. O exemplo completo no fim desta página usa, em vez disso, um fixture de teste.

# V1 verification
curl -X POST http://localhost:3000/verify \
  -H "Content-Type: application/json" \
  -d '{"signed_bundle": {"bundle": {...}, "signature": {...}}, "public_key_b64": "..."}'

# V2 composite verification
curl -X POST http://localhost:3000/v2/bundle/verify \
  -H "Content-Type: application/json" \
  -d '{"signed_bundle": {"bundle": {"dcp_bundle_version":"2.0","manifest":{...},...}, "signature": {"composite_sig":{...},...}}}'

# Capability discovery
curl http://localhost:3000/.well-known/dcp-capabilities.json

anchor (:3001)

Serviço de ancoragem de hashes de bundles em blockchain. Veja services/anchor/README.md.

transparency-log (:3002)

Log de transparência só de anexação com provas de inclusão. Veja services/transparency-log/README.md.

revocation (:3003)

Serviço de publicação e consulta de revogações. Veja services/revocation/README.md.

Configuração

Variáveis de ambiente

Cada serviço é configurado por variáveis de ambiente em docker-compose.yml:

verification

Variável Padrão Descrição
PORT 3000 Porta HTTP
VERIFIER_MODE hybrid_required Modo de verificação V2
ALLOW_V1_BUNDLES true Aceita bundles no formato V1
REQUIRE_SESSION_BINDING, REQUIRE_COMPOSITE_BINDING, MAX_KEY_AGE_DAYS, PQ_CHECKPOINT_INTERVAL, ADVISORY_POLL_INTERVAL_MS definidas na imagem e aqui O servidor ainda não as lê. Vale a sua política embutida (vinculação de sessão e composta obrigatórias, idade de chave de 365 dias); GET /v2/policy a mostra

Os endpoints do DCP-05 ao DCP-09 do gateway não precisam de token e não verificam assinaturas; não publique a porta 3000 para clientes não confiáveis sem a sua própria autorização na frente (docs/OPERATOR_GUIDE.md).

anchor

Variável Padrão Descrição
PORT 3001 Porta HTTP
ANCHOR_MODE batch "individual" ou "batch"
BATCH_INTERVAL_MS 60000 Intervalo de esvaziamento (ms)
ANCHOR_RPC_URL — URL JSON-RPC do nó L2
ANCHOR_PRIVATE_KEY — Chave privada da carteira
ANCHOR_CONTRACT — Endereço do contrato DCPAnchor
OPERATOR_TOKEN — Token Bearer para POST /flush (repassado do ambiente do host)

O envio on-chain ainda não está implementado, então as três configurações de cadeia ANCHOR_* não são usadas.

transparency-log

Variável Padrão Descrição
PORT 3002 Porta HTTP
LOG_ID gerado automaticamente Identificador único desta instância do log
OPERATOR_KEY efêmera Semente Ed25519 da chave que assina as STHs: 64 caracteres hexadecimais (openssl rand -hex 32), uma por log. Qualquer outra coisa interrompe o serviço
OPERATOR_TOKEN — Token Bearer para POST /gossip/peers (repassado do ambiente do host)
GOSSIP_PEERS — Pares separados por vírgulas, cada um <endpoint>#<base64 Ed25519 public key> (por exemplo, http://log-b:3002#q1w2...); as cabeças de árvore de pares não fixados são ignoradas
GOSSIP_INTERVAL_MS 30000 Intervalo de consulta do gossip, em milissegundos

Para que os dois logs do Compose façam gossip, dê a cada um uma chave fixa e fixe a do outro. Execute isto a partir da raiz do repositório, com as dependências da raiz instaladas (usa o tweetnacl do node_modules da raiz). Não há nenhum arquivo compose na raiz, então indique este com -f:

export TLOG_ALPHA_OPERATOR_KEY=$(openssl rand -hex 32) TLOG_BETA_OPERATOR_KEY=$(openssl rand -hex 32)
pub() { node -e 'const n = require("tweetnacl"); console.log(Buffer.from(n.sign.keyPair.fromSeed(Buffer.from(process.argv[1], "hex")).publicKey).toString("base64"))' "$1"; }
export TLOG_ALPHA_PUBLIC_KEY=$(pub $TLOG_ALPHA_OPERATOR_KEY) TLOG_BETA_PUBLIC_KEY=$(pub $TLOG_BETA_OPERATOR_KEY)
docker compose -f docker/docker-compose.yml up

Os logs guardam a árvore em memória: uma OPERATOR_KEY fixa mantém a mesma chave de assinatura entre reinicializações, mas uma reinicialização continua começando uma árvore vazia.

revocation

Variável Padrão Descrição
PORT 3003 Porta HTTP
TRUST_PROXY — true só atrás de um proxy que acrescenta o IP do cliente a X-Forwarded-For
REVOCATION_STATE_PATH só memória Arquivo de estado só de anexação. Este arquivo compose define /data/revocation-state.jsonl no volume revocation-data

Os serviços de verificação e de revogação também leem OPERATOR_TOKEN: para os endpoints de administração do gateway e para registrar agent_ids novos nos dois. A partir da raiz do repositório, execute OPERATOR_TOKEN=$(openssl rand -hex 32) docker compose -f docker/docker-compose.yml up para desbloqueá-los; sem ele, eles respondem 401.

Estado: todos os serviços guardam o estado em memória e começam vazios após uma reinicialização ou um docker compose down, exceto revocation. Aqui os seus registros e revogações vão para o volume revocation-data, então sobrevivem a uma reinicialização e a docker compose down; docker compose down -v apaga o volume e, com ele, esses dados.

A ancoragem em blockchain não está implementada

O serviço de ancoragem não envia nada on-chain. As configurações ANCHOR_RPC_URL, ANCHOR_PRIVATE_KEY e ANCHOR_CONTRACT comentadas em docker-compose.yml não são lidas (definir ANCHOR_RPC_URL só registra um aviso), então não coloque ali nenhuma chave de carteira. Os registros ficam locais, em memória, com tx_hash: null e onchain: false.

Dockerfile

O Dockerfile usa um build em várias etapas com alvos independentes:

Base: node:20-alpine
├── verification  → node server/index.js        (port 3000)
├── anchor        → node services/anchor/index.js      (port 3001)
├── transparency-log → node services/transparency-log/index.js (port 3002)
└── revocation    → node services/revocation/index.js  (port 3003)

Build individual

# Build a specific service (from the repo root: the build context is the repo)
docker build -f docker/Dockerfile --target anchor -t dcp-anchor .

# Run
docker run -p 3001:3001 -e ANCHOR_MODE=batch dcp-anchor

Build de tudo

# from the repo root
docker compose -f docker/docker-compose.yml build

Checagens de saúde

Todos os serviços têm checagens de saúde configuradas:

  • Intervalo: 30 segundos
  • Tempo limite: 5 segundos
  • Tentativas: 3
  • Comando: wget -qO- http://localhost:PORT/health
  • Política de reinicialização: unless-stopped

Uma checagem que passa só significa que o processo responde por HTTP; não é evidência de persistência, ancoragem, gossip nem preparo para produção.

Exemplo completo — verificar um bundle

# Run from the repo root: the example files are under tests/.
# 1. Start services
docker compose -f docker/docker-compose.yml up -d

# 2. Verify a signed bundle (note: body must wrap in signed_bundle key)
curl -X POST http://localhost:3000/verify \
  -H "Content-Type: application/json" \
  -d "{\"signed_bundle\": $(cat tests/conformance/examples/citizenship_bundle.signed.json)}"

# 3. Take the bundle_hash the signature carries (computed over the canonical bundle) and anchor it
HASH=$(node -e 'console.log(require("./tests/conformance/examples/citizenship_bundle.signed.json").signature.bundle_hash)')
curl -X POST http://localhost:3001/anchor \
  -H "Content-Type: application/json" \
  -d "{\"bundle_hash\": \"$HASH\"}"

# 4. Add to transparency log (service on port 3002, route is /add)
curl -X POST http://localhost:3002/add \
  -H "Content-Type: application/json" \
  -d "{\"bundle_hash\": \"$HASH\"}"

# 5. Stop
docker compose -f docker/docker-compose.yml down

Licença

Apache-2.0