Skip to content

Docker image builds fail on dev installs with root-owned PVC data in build context #304

Description

@bussyjd

Summary

When running OBOL_DEVELOPMENT=true obolup.sh on a machine with leftover PVC data from a previous cluster, all three local Docker image builds fail with permission denied. The stack comes up but with degraded x402/monetization functionality.

Reproduction

# On a machine with an existing .workspace/data/ containing root-owned PVC dirs
OBOL_DEVELOPMENT=true bash ./obolup.sh
# → Answer "y" to start cluster

Error

=> ERROR [internal] load build context                                                                  0.1s
ERROR: failed to build: failed to solve: error from sender: open /home/claude/obol-stack/.workspace/data/openclaw-magnetic-seagull/remote-signer-keystores: permission denied

All three images fail with the same error:

  • ghcr.io/obolnetwork/x402-verifier:latest
  • ghcr.io/obolnetwork/serviceoffer-controller:latest
  • ghcr.io/obolnetwork/x402-buyer:latest

Root cause

docker build sends the entire project root as build context, which includes .workspace/data/. That directory contains root-owned PVC directories from previous OpenClaw deployments (keystores, etc.). Docker's context sender can't read them → build fails.

Affected images and impact

1. x402-verifier (Dockerfile.x402-verifier)

  • Role: Traefik ForwardAuth middleware enforcing x402 micropayments per route
  • Namespace: x402, 2 replicas with PDB
  • Impact when missing: Pod stays in ImagePullBackOff. Traefik requests to monetized routes hang (no ForwardAuth response). Discovery endpoint (/.well-known/agent-registration.json) unavailable.

2. serviceoffer-controller (Dockerfile.serviceoffer-controller)

  • Role: Kubernetes operator that reconciles ServiceOffer CRDs through the 6-stage lifecycle (ModelReady → UpstreamHealthy → PaymentGateReady → RoutePublished → Registered → Ready). Creates Middleware, HTTPRoute, and RegistrationRequest resources.
  • Namespace: x402, 1 replica
  • Impact when missing: obol sell http creates ServiceOffer CRs but they never reach Ready. No routes are published, no Traefik middleware is created, no on-chain registration happens.

3. x402-buyer (Dockerfile.x402-buyer)

  • Role: OpenAI-compatible reverse proxy sidecar in the LiteLLM pod (port 8402). Handles buy-side x402 payments using pre-signed ERC-3009 authorizations.
  • Namespace: llm (sidecar in litellm Deployment)
  • Impact when missing: LiteLLM pod starts but sidecar container fails. paid/* model routes don't work. Buy-side payment flow is broken.

Proposed fix

Add .workspace/ to .dockerignore at the project root. The build context never needs PVC data, config, or bin directories. This also speeds up the Docker build by excluding large irrelevant files.

# .dockerignore
.workspace/
.worktrees/
.git/

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions