Skip to content

fix(docker): restore someguy sidecar with corrected IPNS config#325

Merged
FSM1 merged 8 commits into
mainfrom
fix/someguy-ipns-routing
Mar 23, 2026
Merged

fix(docker): restore someguy sidecar with corrected IPNS config#325
FSM1 merged 8 commits into
mainfrom
fix/someguy-ipns-routing

Conversation

@FSM1

@FSM1 FSM1 commented Mar 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • Restores self-hosted Someguy sidecar (removed in build(ci,docker): add release-please changelog-sections and remove broken someguy sidecar #322) with corrected configuration that fixes the IPNS endpoint hang
  • Root cause was threefold: no libp2p port (4004) exposed for DHT participation, standard DHT mode instead of accelerated, and resource limits too tight (0.5 CPU / 768MB / 512MB libp2p)
  • Updates staging deploy workflow to use http://someguy:8190 instead of https://delegated-ipfs.dev
  • Restores Prometheus metrics scraping for someguy in Alloy config

Verification

Direct endpoint testing (someguy on Docker host):

  • GET /routing/v1/ipns/<key> — 200 OK in 0.53s (was hanging indefinitely)
  • PUT /routing/v1/ipns/<key> — 200 OK in 0.12s (was hanging indefinitely)

SDK E2E tests: 83/83 pass with someguy as routing backend

Load test comparison (5 clients, IPNS publish storm):

Metric Someguy delegated-ipfs.dev
Errors 0 0
Throughput 8.4 ops/s 10.8 ops/s
createFolder p50 728ms 606ms
createFolder p99 1.27s 1.62s

Someguy has ~20% higher median latency (single node vs fleet) but tighter p99 tail latency. The latency gap will shrink as the DHT routing table warms over time.

Config changes vs previous (broken) deployment

Setting Previous Fixed
libp2p port 4004 Not exposed Exposed (TCP + UDP)
DHT mode standard accelerated
Connection limits 50/300 100/3000 (defaults)
libp2p memory 512MB 1GB
Container memory 768MB 2GB
Container CPU 0.5 1.0
Health check start period 30s 60s

Test plan

  • Someguy IPNS GET/PUT respond successfully (curl)
  • All 83 SDK E2E tests pass with someguy backend
  • Load test completes with zero errors
  • Load test metrics compared against delegated-ipfs.dev baseline
  • Deploy to staging and verify IPNS operations in Grafana

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a self-hosted delegated-routing service (someguy) with health checks, ports, and resource limits
    • Introduced delegated routing fallback support and a corresponding environment variable
    • Exposed Prometheus metrics for delegated routing (requests and fallbacks)
  • Chores

    • Upgraded IPFS test/e2e service containers to v0.40.0
    • Simplified CI workflow execution gating and updated staging routing configuration
  • Documentation

    • Added note about Vitest not auto-loading .env and passing env vars to e2e tests

FSM1 and others added 5 commits March 23, 2026 02:11
…NS testing

Previous staging deployment failed because: no libp2p port exposed (4004),
standard DHT mode instead of accelerated, and resource limits too tight.
This config fixes all three: exposes 4004 for DHT participation, uses
accelerated mode (default), and gives 2GB RAM / 1 CPU with 1GB libp2p memory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 1743c748c3e8
…324)

* chore(ci): parallelize CI jobs and bump Kubo to v0.40.0 in all workflows

Parallelize independent CI jobs to reduce pipeline time:
- test: no longer waits for typecheck (builds packages itself)
- sdk-e2e: no longer waits for test (independent suite with own services)
- build: no longer waits for all checks (compilation check only)

Before: changes → typecheck → test → sdk-e2e → build (sequential)
After:  changes → lint → {test, sdk-e2e, build} (parallel)

Also bumps Kubo v0.34.0 → v0.40.0 in ci.yml, e2e.yml, and load-test.yml
service containers to match docker-compose (PR #321).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: d1f8e21dba94

* chore(ci): add lint to all job needs, simplify if conditions

Address PR review:
- Add lint to typecheck/api-spec/migration-check needs for fail-fast
- Remove redundant !failure() && !cancelled() conditions now that
  jobs only depend on changes + lint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: fbaacaeafccc

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause of the Phase 19 someguy failure was threefold:
1. No libp2p port (4004) exposed — DHT couldn't receive inbound connections
2. DHT mode set to 'standard' instead of 'accelerated' (default)
3. Resource limits too tight (0.5 CPU, 768MB RAM, 512MB libp2p memory)

Fix: expose port 4004 (TCP+UDP), use accelerated DHT mode, allocate
2GB RAM / 1 CPU / 1GB libp2p memory, and increase start period to 60s.

Verified locally: someguy IPNS GET resolves in ~0.5s, PUT in ~0.1s,
and all 83 SDK E2E tests pass with someguy as the routing backend.

Also restores someguy Prometheus metrics scraping in Alloy config
and updates deploy-staging workflow to use http://someguy:8190.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 58b1c8d9fd40
Vitest does not auto-load .env files into process.env — env vars
must be passed explicitly on the command line or via dotenv setup.
This caused spurious 429 failures during someguy testing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 8a5fc5b5e16a
@coderabbitai

coderabbitai Bot commented Mar 23, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@FSM1 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 69566c7c-f26a-48b8-89e3-de55a43e645b

📥 Commits

Reviewing files that changed from the base of the PR and between 0250faa and 1ac2bee.

📒 Files selected for processing (3)
  • apps/api/src/ipns/delegated-routing.client.ts
  • docker/docker-compose.staging.yml
  • docker/docker-compose.yml

Walkthrough

Adds a self-hosted IPFS routing service (someguy) and monitoring, bumps Kubo/IPFS service images in CI/workflows, simplifies CI job wiring, and implements delegated-routing fallback, observability counters, and tests in the API codebase; plus operational notes and compose/stack updates.

Changes

Cohort / File(s) Summary
CI workflow updates
​.github/workflows/ci.yml, ​.github/workflows/e2e.yml, ​.github/workflows/load-test.yml, ​.github/workflows/deploy-staging.yml
Simplified job gating/needs in CI; replaced complex if-conditions with needs.changes.outputs.src == 'true'; added lint to some needs; bumped IPFS/Kubo container images from ipfs/kubo:v0.34.0ipfs/kubo:v0.40.0; changed staging DELEGATED_ROUTING_URL and added DELEGATED_ROUTING_FALLBACK_URL.
Self-hosted routing service (Docker compose)
docker/docker-compose.yml, docker/docker-compose.staging.yml
Added someguy service (ghcr.io/ipfs/someguy:v0.11.1) with HTTP port 8190, libp2p ports, healthcheck, env tunables, and resource limits.
Monitoring / Prometheus
docker/alloy-config.river
Added prometheus.scrape "someguy" target scraping /debug/metrics/prometheus every 30s and forwarding to Grafana Cloud remote_write receiver.
API: delegated routing client & metrics
apps/api/src/ipns/delegated-routing.client.ts, apps/api/src/ipns/delegated-routing.client.spec.ts, apps/api/src/metrics/metrics.service.ts
Implemented primary+optional fallback delegated-routing backends, retry-per-backend helpers, backend-labelled delegatedRoutingRequests and delegatedRoutingFallbacks counters, logging updates, and expanded tests asserting fallback behavior and metrics. Constructor now injects MetricsService.
Env / examples & docs
apps/api/.env.example, .learnings/2026-03-23-vitest-env-vars-not-auto-loaded.md, .planning/todos/done/2026-03-23-investigate-someguy-ipns-routing-failure-locally.md
Added DELEGATED_ROUTING_FALLBACK_URL example and two operational/learning notes (Vitest env behavior and local investigation plan for someguy IPNS routing issues).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant DelegatedRoutingClient
  participant PrimaryBackend as Primary (someguy/remote)
  participant FallbackBackend as Fallback (someguy/remote)
  participant Metrics

  Client->>DelegatedRoutingClient: publish / resolve request
  DelegatedRoutingClient->>Metrics: delegatedRoutingRequests.inc(operation=..., backend=primary, outcome=attempt)
  DelegatedRoutingClient->>PrimaryBackend: attempt request (with retries)
  alt Primary succeeds
    PrimaryBackend-->>DelegatedRoutingClient: 2xx response
    DelegatedRoutingClient->>Metrics: delegatedRoutingRequests.inc(operation=..., backend=primary, outcome=success)
    DelegatedRoutingClient-->>Client: return success
  else Primary fails (after retries) and fallback configured
    PrimaryBackend-->>DelegatedRoutingClient: terminal error
    DelegatedRoutingClient->>Metrics: delegatedRoutingRequests.inc(operation=..., backend=primary, outcome=error)
    DelegatedRoutingClient->>Metrics: delegatedRoutingFallbacks.inc(operation=...)
    DelegatedRoutingClient->>FallbackBackend: retry request against fallback (with retries)
    alt Fallback succeeds
      FallbackBackend-->>DelegatedRoutingClient: 2xx response
      DelegatedRoutingClient->>Metrics: delegatedRoutingRequests.inc(operation=..., backend=fallback, outcome=success)
      DelegatedRoutingClient-->>Client: return success
    else Fallback fails
      FallbackBackend-->>DelegatedRoutingClient: terminal error
      DelegatedRoutingClient->>Metrics: delegatedRoutingRequests.inc(operation=..., backend=fallback, outcome=error)
      DelegatedRoutingClient-->>Client: throw HttpException(BAD_GATEWAY)
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly summarizes the primary change: restoring the Someguy sidecar service with corrected IPNS configuration, which aligns with the objectives and the majority of changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/someguy-ipns-routing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docker/docker-compose.staging.yml`:
- Around line 121-122: Update the healthcheck command for the someguy service to
use curl instead of wget so the probe works with ghcr.io/ipfs/someguy:v0.11.1;
locate the healthcheck block (healthcheck: test:) in the docker-compose service
definition for someguy and replace the current 'wget -qO-
http://localhost:8190/version || exit 1' invocation with an equivalent curl
invocation that returns nonzero on failure (e.g., using curl --fail or -sS) so
the container can be marked healthy.

In `@docker/docker-compose.yml`:
- Around line 84-85: The healthcheck uses wget but the
ghcr.io/ipfs/someguy:v0.11.1 image does not include wget; update the healthcheck
test in the healthcheck block (the `test:` line) to call curl instead of wget
(e.g. use curl with silent/fail flags such as curl -fsS --fail
http://localhost:8190/version or similar so it returns non‑zero on failure) so
the container healthcheck works with the someguy image.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9e2f6c3d-b7f1-4474-aaf3-d07f2d185b8a

📥 Commits

Reviewing files that changed from the base of the PR and between 61e0428 and 9f07871.

📒 Files selected for processing (9)
  • .github/workflows/ci.yml
  • .github/workflows/deploy-staging.yml
  • .github/workflows/e2e.yml
  • .github/workflows/load-test.yml
  • .learnings/2026-03-23-vitest-env-vars-not-auto-loaded.md
  • .planning/todos/done/2026-03-23-investigate-someguy-ipns-routing-failure-locally.md
  • docker/alloy-config.river
  • docker/docker-compose.staging.yml
  • docker/docker-compose.yml

Comment thread docker/docker-compose.staging.yml Outdated
Comment thread docker/docker-compose.yml Outdated
When the primary routing backend (someguy) fails after all retries,
the DelegatedRoutingClient now falls back to a configurable secondary
URL (DELEGATED_ROUTING_FALLBACK_URL). For staging, this is
delegated-ipfs.dev as a safety net.

New Prometheus metrics:
- cipherbox_delegated_routing_requests_total{operation,backend,outcome}
  tracks every routing request with primary/fallback backend label
- cipherbox_delegated_routing_fallbacks_total{operation}
  counts how often the primary fails and fallback is triggered

These enable Grafana alerting on frequent fallback usage, which would
indicate someguy health issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: a6f0bc4244a3
@codecov

codecov Bot commented Mar 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.63%. Comparing base (e806cb9) to head (1ac2bee).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
apps/api/src/ipns/delegated-routing.client.ts 92.50% 0 Missing and 3 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #325      +/-   ##
==========================================
+ Coverage   50.58%   50.63%   +0.04%     
==========================================
  Files         115      116       +1     
  Lines        9196     9919     +723     
  Branches      720      727       +7     
==========================================
+ Hits         4652     5022     +370     
- Misses       4367     4718     +351     
- Partials      177      179       +2     
Flag Coverage Δ
api 83.09% <92.50%> (+0.08%) ⬆️
api-client 83.09% <92.50%> (+0.08%) ⬆️
core 83.09% <92.50%> (+0.08%) ⬆️
crypto 83.09% <92.50%> (+0.08%) ⬆️
desktop 28.64% <ø> (+2.73%) ⬆️
sdk 83.09% <92.50%> (+0.08%) ⬆️
sdk-core 83.09% <92.50%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
apps/api/src/ipns/delegated-routing.client.ts 94.11% <92.50%> (-0.21%) ⬇️

... and 10 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The ghcr.io/ipfs/someguy image includes curl but not wget, so the
wget-based healthcheck would fail inside the container.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: ed489ad9746f

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Restores the self-hosted Someguy delegated-routing sidecar and updates the API + staging infrastructure to use it as the primary IPNS delegated routing backend, with fallback to delegated-ipfs.dev and added observability.

Changes:

  • Add Someguy service back to local + staging docker-compose with corrected DHT/libp2p configuration and resource limits.
  • Add delegated routing Prometheus counters and implement primary→fallback routing logic in the API client.
  • Update staging deploy + monitoring to point to http://someguy:8190 and re-enable Someguy metrics scraping; bump Kubo versions in CI workflows.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docker/docker-compose.yml Restores Someguy service for local/dev with ports, env, and healthcheck.
docker/docker-compose.staging.yml Restores Someguy service in staging stack with DHT/libp2p config and healthcheck.
docker/alloy-config.river Re-adds Prometheus scraping for Someguy metrics endpoint.
apps/api/src/metrics/metrics.service.ts Adds Prometheus counters for delegated routing requests and fallbacks.
apps/api/src/ipns/delegated-routing.client.ts Implements primary/fallback routing URLs + emits delegated routing metrics.
apps/api/src/ipns/delegated-routing.client.spec.ts Extends tests for metrics emission and fallback behavior.
apps/api/.env.example Documents DELEGATED_ROUTING_FALLBACK_URL usage.
.planning/todos/done/2026-03-23-investigate-someguy-ipns-routing-failure-locally.md Adds investigation notes and resolution summary.
.learnings/2026-03-23-vitest-env-vars-not-auto-loaded.md Documents Vitest env var loading behavior relevant to E2E runs.
.github/workflows/load-test.yml Bumps Kubo service image to v0.40.0 for load tests.
.github/workflows/e2e.yml Bumps Kubo service image to v0.40.0 for E2E workflow.
.github/workflows/deploy-staging.yml Points staging delegated routing primary at Someguy with fallback to delegated-ipfs.dev.
.github/workflows/ci.yml Simplifies job gating and bumps Kubo service image to v0.40.0 across CI jobs.
Comments suppressed due to low confidence (2)

apps/api/src/ipns/delegated-routing.client.ts:140

  • If all retry attempts return HTTP 429, lastError is never set, so the final error log/exception path loses the actual failure reason (it will log an undefined message). Track the 429 case as an error (e.g., set lastError when rate-limited, especially on the last attempt) so the final failure message is informative.
        // Handle rate limiting
        if (status === 429) {
          if (attempt < this.maxRetries - 1) {
            const delayMs = this.getRetryDelayMs(retryAfter, attempt);
            this.logger.warn(`Rate limited on IPNS publish (${backend}), retrying in ${delayMs}ms`);
            await this.delay(delayMs);
          }
          continue;
        }

apps/api/src/ipns/delegated-routing.client.ts:248

  • In the 429 branch for resolve, lastError is never populated. If all retries hit rate limiting, the final error path won’t include the real reason. Set lastError (and optionally record a distinct outcome) when rate-limited so persistent 429 failures produce actionable logs/metrics.
        // Handle rate limiting
        if (status === 429) {
          if (attempt < this.maxRetries - 1) {
            const delayMs = this.getRetryDelayMs(retryAfter, attempt);
            this.logger.warn(`Rate limited on IPNS resolve (${backend}), retrying in ${delayMs}ms`);
            await this.delay(delayMs);
          }
          continue;
        }

Comment thread apps/api/src/ipns/delegated-routing.client.ts
Comment thread docker/docker-compose.yml
Comment thread docker/docker-compose.staging.yml
Prevents invalid Prometheus label values from being emitted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: b7c371d3f753
@FSM1 FSM1 enabled auto-merge (squash) March 23, 2026 02:27
@FSM1 FSM1 merged commit 0e9cb1e into main Mar 23, 2026
24 checks passed
@FSM1 FSM1 deleted the fix/someguy-ipns-routing branch March 23, 2026 02:30
This was referenced Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants