Skip to content

fix(docker): wire env, observability, and local node for Docker stack#49

Merged
0xfandom merged 4 commits intomainfrom
fix/docker-env-observability
Apr 6, 2026
Merged

fix(docker): wire env, observability, and local node for Docker stack#49
0xfandom merged 4 commits intomainfrom
fix/docker-env-observability

Conversation

@0xfandom
Copy link
Copy Markdown
Collaborator

@0xfandom 0xfandom commented Apr 2, 2026

Summary

Docker setup lacked proper env var consumption, Ethereum node integration, and observability wiring.

Changes

Go services read env vars

  • cmd/executor/main.go reads GRPC_ADDRESS from environment, falls back to localhost:50051
  • cmd/monitor/metrics.go reads METRICS_PORT and DASHBOARD_PORT from environment, falls back to 9090/8080

Docker compose wiring

  • aether-rust receives ETH_RPC_URL, GRPC_ADDRESS, AETHER_NODES_CONFIG with .env passthrough
  • aether-rust binds gRPC to 0.0.0.0:50051 so Go container can reach it over Docker network
  • go.Dockerfile copies internal/ package (was missing, caused Docker build failure)

Observability

  • Added Grafana service with auto-provisioned Prometheus datasource (port 3000)
  • Prometheus config notes Rust metrics endpoint is not yet available
  • Loki explicitly deferred — logs available via docker logs

Local Ethereum node

  • Added opt-in reth service (docker compose --profile node up -d)
  • Shared IPC volume (reth-ipc:/tmp) between reth and aether-rust for low-latency node access
  • Matches config/nodes.yaml which has local-reth at priority 0, Alchemy WS at priority 1

Acceptance criteria

Criteria Status
Compose env vars consumed by services Go executor logs GRPC_ADDRESS=aether-rust:50051 (from env)
Rust configurable for external or local node Tries reth IPC (priority 0), falls back to Alchemy WS (priority 1)
Local-node path documented and reproducible docker compose --profile node up -d starts reth with shared IPC volume
Prometheus/Grafana present or deferred Grafana added, Loki explicitly deferred
README/docs match real stack Grafana in compose, Loki deferred with comment

Test plan

  • All Rust tests pass (268+ tests)
  • All Go tests pass
  • Clippy clean
  • Docker images build successfully (aether-rust, aether-go)
  • Docker: Go executor connects to Rust arb stream over Docker network
  • Docker: Rust tries local reth IPC, falls back to Alchemy WS
  • Docker: Grafana, Prometheus, Postgres, Redis all running
  • start.sh boots all services with ESTABLISHED gRPC connections

Closes #45

0xfandom added 3 commits April 2, 2026 12:08
- Executor reads GRPC_ADDRESS from environment, falls back to localhost:50051
- Monitor reads METRICS_PORT and DASHBOARD_PORT from environment, falls back to 9090/8080
- aether-rust receives ETH_RPC_URL, GRPC_ADDRESS, AETHER_NODES_CONFIG with .env passthrough
- Added Grafana service with auto-provisioned Prometheus datasource
- Added opt-in reth service (--profile node) with shared IPC volume for low-latency node access
- Prometheus config notes Rust metrics endpoint is not yet available
- Loki explicitly deferred — logs available via docker logs
- GRPC_ADDRESS set to 0.0.0.0:50051 so Go container can reach Rust over Docker network
- go.Dockerfile copies internal/ package required by executor and monitor builds
@0xfandom 0xfandom requested a review from Pablosinyores April 2, 2026 07:02
Copy link
Copy Markdown
Owner

@Pablosinyores Pablosinyores left a comment

Choose a reason for hiding this comment

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

Review: fix(docker): wire env, observability, and local node for Docker stack

Issue #45 Acceptance Criteria

  • Compose env vars consumed by services — GRPC_ADDRESS in executor, METRICS_PORT/DASHBOARD_PORT in monitor
  • Rust configurable for external or local node — ETH_RPC_URL, AETHER_NODES_CONFIG env vars + .env passthrough
  • Local-node path documented and reproducible — opt-in reth profile with shared IPC volume
  • Prometheus/Grafana present or deferred — Grafana added with auto-provisioned datasource, Loki explicitly deferred with comment
  • README/docs match real stack — Grafana in compose, Loki deferred with inline comment

Findings

WARNING (W1): env_file: ../../.env will fail if .env doesn't exist

Docker Compose v3.8 spec errors on missing env_file. New users cloning the repo without a .env file will get a startup error. The .env is gitignored (correctly), but there's no .env.example to copy from.

Suggested fix: Either add required: false (Compose v2.24+) or add a .env.example with placeholder values.

Non-blocking — this is a DX issue, not a correctness issue.

SUGGESTION (S1): Grafana default admin password

GF_SECURITY_ADMIN_PASSWORD=admin is fine for local dev but should be called out. Since GF_AUTH_ANONYMOUS_ENABLED=true with Viewer role is set, anonymous users get read-only access, which is the right default for a monitoring dashboard. Acceptable for dev compose.

SUGGESTION (S2): No port validation on env var reads

METRICS_PORT and DASHBOARD_PORT are used directly as strings in ":" + metricsPort. Malformed values (e.g., METRICS_PORT=abc) will produce a confusing listen tcp: address :abc: invalid port error. Not worth fixing for internal infra config.

Code Quality

  • Env var fallback pattern is clean and idiomatic Go
  • GRPC_ADDRESS=0.0.0.0:50051 for Rust container is correct for Docker cross-container networking
  • go.Dockerfile correctly adds COPY internal/ internal/ — required for the build since executor/monitor import from internal/
  • Grafana provisioning datasource correctly points to http://prometheus:9090 (Docker service name)
  • Reth profile-gated correctly — won't start unless explicitly requested
  • Shared reth-ipc:/tmp volume enables IPC between reth and aether-rust containers
  • Prometheus config honestly notes Rust metrics aren't available yet

Tests

  • All CI checks pass (toolchain, rust, go, solidity)
  • Rust workspace: all tests pass, clippy clean
  • Solidity: 12/12 tests pass

Security

  • No secrets in compose (postgres password is aether_dev — acceptable for local dev)
  • .env is gitignored
  • No AI attribution in commits
  • Conventional commit format followed

Verdict: APPROVE

Clean infrastructure PR that correctly wires env vars, adds observability tooling, and provides an opt-in local node path. All acceptance criteria met. W1 is a DX improvement that can be a follow-up.

- AETHER_NODES_CONFIG=/app/config/nodes.yaml
env_file:
- ../../.env
restart: unless-stopped
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

WARNING: env_file will error if ../../.env doesn't exist.

New developers cloning the repo without a .env will get a Docker Compose startup failure. Consider adding required: false (Compose v2.24+):

env_file:
  - path: ../../.env
    required: false

Or ship a .env.example with placeholder values that users copy.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed — switched to required: false (Compose v2.24+) on both aether-rust and aether-go so missing .env no longer blocks startup.

env_file:
  - path: ../../.env
    required: false

We also ship a .env.example at repo root for reference.

ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

SUGGESTION: GF_SECURITY_ADMIN_PASSWORD=admin is fine for local dev. If this compose file ever gets used in staging/prod, this should be pulled from .env or a secret. Fine as-is for now.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Agreed — keeping admin for local dev. Will move to .env / secrets if this compose file ever targets staging/prod.

Comment thread cmd/executor/main.go Outdated
cfg := defaultConfig()

// Environment overrides for container / systemd deployments
if v := os.Getenv("GRPC_ADDRESS"); v != "" {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

WARNING: Duplicate GRPC_ADDRESS read. The main branch already has this env override at line 76 (with a log message). This new block at line 52 is redundant — it sets the value, then line 76 sets it again. Remove this block and keep the existing one.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch — removed the redundant block at line 52. The existing read at line 76 (with logging) is the one that stays.

@Pablosinyores
Copy link
Copy Markdown
Owner

Additional Findings (Post-Review)

After cross-referencing with the full main branch codebase, two additional issues surfaced:

WARNING (W2): Duplicate GRPC_ADDRESS env read in loadConfig()

The main branch already reads GRPC_ADDRESS at line 71 of cmd/executor/main.go (with a log message). This PR adds a second read at line 52 (without a log). Both set cfg.GRPCAddress, so the first read is redundant dead code. Fix: Remove the new read at line 52 since the existing one at line 76 already handles this correctly with logging. (See inline comment on that line.)

WARNING (W3): aether-go service missing env_file

aether-rust has env_file: ../../.env but aether-go does not. The Go executor reads SEARCHER_KEY and ETH_RPC_URL from env (main.go:99 and main.go:114). Without env_file, these won't be available in the Docker container — the executor starts without transaction signing and without on-chain nonce sync. Fix: Add env_file: ../../.env to the aether-go service, or explicitly pass the needed vars via the environment block.


These don't change the APPROVE verdict — they're quick fixes that should ideally be addressed before merge but aren't blockers.

@Pablosinyores Pablosinyores assigned 0xfandom and unassigned 0xfandom Apr 2, 2026
…ESS, wire Go env

- Use `required: false` on env_file so missing .env doesn't break docker compose up
- Add env_file to aether-go service so SEARCHER_KEY and ETH_RPC_URL are available
- Remove duplicate GRPC_ADDRESS read in loadConfig(); keep the existing one with logging
@0xfandom
Copy link
Copy Markdown
Collaborator Author

0xfandom commented Apr 6, 2026

All three findings addressed in 44eb9cc:

  • W1 (env_file safety): Switched to required: false on both aether-rust and aether-go services
  • W2 (duplicate GRPC_ADDRESS): Removed the redundant read at line 52, keeping the existing one at line 76 with logging
  • W3 (aether-go missing env_file): Added env_file with required: false so SEARCHER_KEY and ETH_RPC_URL are available in the container

All tests passing (Go + Rust + clippy + docker compose config + start.sh).

@0xfandom 0xfandom requested a review from Pablosinyores April 6, 2026 09:55
Copy link
Copy Markdown
Owner

@Pablosinyores Pablosinyores left a comment

Choose a reason for hiding this comment

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

Re-Review: fix(docker): wire env, observability, and local node for Docker stack

Re-review after 44eb9cc addressed all review findings.

Previous Findings Resolution

Finding Severity Status Fix
W1: env_file fails if .env missing WARNING ✅ RESOLVED Switched to required: false on both services
S1: Grafana default admin password SUGGESTION ✅ ACKNOWLEDGED Fine for local dev
Inline: Duplicate GRPC_ADDRESS read WARNING ✅ RESOLVED Redundant block removed

Verdict: APPROVE (re-confirmed)

All review findings addressed cleanly. Ready to merge.

@0xfandom 0xfandom merged commit 601e38c into main Apr 6, 2026
4 checks passed
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.

fix(docker): wire env, observability, and geth/reth/erigon startup for local stack

2 participants