Skip to content

docs: add beacon configuration file (rcConfig) reference - #9574

Closed
lodekeeper wants to merge 1 commit into
ChainSafe:unstablefrom
lodekeeper:docs/rcconfig-file-reference
Closed

docs: add beacon configuration file (rcConfig) reference#9574
lodekeeper wants to merge 1 commit into
ChainSafe:unstablefrom
lodekeeper:docs/rcconfig-file-reference

Conversation

@lodekeeper

Copy link
Copy Markdown
Contributor

Motivation

A user in Discord asked whether Lodestar supports passing configuration via a file instead of CLI flags. The answer is --rcConfig, but there is currently no reference documenting the file format or showing an example — the flag only appears as a one-line entry on the auto-generated CLI reference pages (added in #7270).

Description

Adds a dedicated Configuration File docs page under Beacon Node that documents the global --rcConfig flag:

  • Accepted formats (YAML / JSON)
  • How each key maps to a CLI flag (without the leading --)
  • That nested options must use dotted keys (e.g. rest.address), not nested maps — a consequence of dot-notation: false in the yargs parser config
  • That command line flags take precedence over file values
  • A complete beacon node example in both YAML and JSON

Also links the new page from the sidebar and the Starting a Node guide for discoverability.

The format and precedence behavior were verified against the yargs config parser and the existing rcConfig usage in the crucible test clients (packages/cli/test/utils/crucible/clients/beacon/lodestar.ts).

🤖 Generated with AI assistance

Adds a dedicated docs page covering the global --rcConfig flag: accepted
formats (YAML/JSON), how each key maps to a CLI flag, the dotted-key
representation required for nested options (e.g. rest.address), command
line precedence over file values, and a full beacon node example.

Links the new page from the sidebar and the Starting a Node guide so the
config file option is discoverable.

🤖 Generated with AI assistance
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lodekeeper
lodekeeper requested a review from a team as a code owner June 30, 2026 22:34

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a new documentation page detailing how to use a configuration file with Lodestar via the --rcConfig flag. It includes instructions on file formats (YAML and JSON), running the node with a configuration file, and overriding options. Additionally, it updates the 'Starting a Node' documentation to link to this new page and adds the page to the sidebar navigation. There are no review comments, and the changes look clean and well-structured, so I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@lodekeeper

Copy link
Copy Markdown
Contributor Author

Superseded by #9578. Per feedback, a whole docs page dedicated to --rcConfig is overkill — instead #9578 adds a small example directly to the --rcConfig CLI option, so it renders inline in the generated CLI reference (beacon-cli#--rcconfig). Closing in favor of that inline approach.

@lodekeeper lodekeeper closed this Jul 2, 2026
nflaig added a commit that referenced this pull request Jul 5, 2026
## Motivation

Lodestar's `--rcConfig` file currently requires nested options to be
written as **dotted keys**:

```yaml
rest.address: "0.0.0.0"
rest.port: 9596
```

This surprised a user who expected the idiomatic nested YAML form
(`rest:` → `address:`). The nested form is nicer, but we don't want to
break existing dotted configs — so this PR supports **both**.

## Description

### Nested maps → dotted keys

Nested maps in the config file are flattened to dotted keys before being
handed to yargs, so both of these produce identical results:

```yaml
# dotted (still works)
rest.address: "0.0.0.0"
rest.port: 9596

# nested (now works too)
rest:
  address: "0.0.0.0"
  port: 9596
```

**Why flattening:** `cli.ts` sets `parserConfiguration({"dot-notation":
false})` (needed so `.strict()` keeps working with dotted option names),
so options are registered as literal dotted keys (`"rest.address"`) and
yargs `.config()` only matches literal dotted keys from the file —
nested maps are silently ignored today. Flattening the parsed file in
the `rcConfig` read callback bridges the gap without touching parser
config or the strictness guarantees.

- **Arrays are preserved** as values (not flattened by index) so array
options (`rest.namespace`, `bootnodes`, …) keep working.
- **Already-dotted keys pass through unchanged** → fully backward
compatible.
- **Prototype-pollution safe:** `__proto__` is skipped and non-plain
input returns `{}`.
- If an option is given in both nested and dotted form, the value
appearing last in the file wins.
- Applies to every command that shares the global `--rcConfig` option
(beacon / validator / bootnode).

### `.enabled` → bare on/off flag

On/off options are registered as a bare boolean flag (e.g. `--metrics`),
which reads awkwardly as a nested map. After flattening,
`{prefix}.enabled` is rewritten to the bare `{prefix}` flag so the
natural nested form works:

```yaml
metrics:
  enabled: true   # → the --metrics flag
  port: 8008
```

`metrics.enabled: true` → `metrics: true`. If both `{prefix}` and
`{prefix}.enabled` are present, `.enabled` is left as-is so the conflict
surfaces at yargs' strict check instead of being silently swallowed.

## Testing

- **`flattenObject`** — 13 unit tests: nested → dotted, dotted
pass-through, mixed nested+dotted, array preservation,
arrays-of-objects, primitive/null values, deep nesting, top-level
scalars, empty-map elision, nested/dotted collision precedence,
`__proto__` guard, non-plain input, and non-plain object leaves
(`Date`).
- **`translateEnabledKeys`** — 7 unit tests: `.enabled` → bare flag, the
nested `metrics: {enabled, port}` form, multiple prefixes, the
already-set conflict case, no-op when absent, a top-level `enabled` is
not translated, and deeply-prefixed keys.
- `check-types`, `biome lint`, full build, and the existing cli `util` /
`options` / `beacon` unit suites pass — no regressions.

## Docs

Adds a compact example to the `--rcConfig` option showing both forms (a
nested map and a dotted key), so it renders in the generated CLI
reference
([beacon-cli#--rcconfig](https://chainsafe.github.io/lodestar/run/beacon-management/beacon-cli#--rcconfig)).
Because `--rcConfig` is a **global** option, its example renders in
every command's docs, so it uses options common to all of them
(`network` / `logLevel` / `metrics`) rather than a beacon-only option.

Rendering an option `example` that's a config snippet (no shell command)
needed a small docsgen change: `renderOption` renders the `example`
description directly, and `CliOptionDefinition.example` becomes
description-only (`Omit<CliExample, "title" | "command">`). The
`example` is docs-only (yargs ignores it, so `--help` is unchanged) and
the generated `*-cli.md` files are gitignored.

This supersedes the dedicated docs page in #9574 (now closed) — a whole
page was overkill; an inline example is enough.

---
🤖 Generated with AI assistance

---------

Co-authored-by: lodekeeper <lodekeeper@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Nico Flaig <nflaig@protonmail.com>
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.

1 participant