Files
devops-lib-gcp/docs/adr/0015-node-install-logic-paired-across-buildnode-groovy-and-dockerfile.md
T
2026-08-26 02:02:24 +05:30

60 lines
3.8 KiB
Markdown

# ADR-0015: Node install logic paired across buildNode.groovy and Dockerfile
**Status:** Accepted
**Category:** PATTERN
**Date decided:** Early on
**Date documented:** 2026-05-13
## Context
Meesho Node services use both `npm` and `pnpm` depending on the repo. Some teams need to pass extra flags (e.g. `--legacy-peer-deps`) and the shared library cannot anticipate every combination. The install step has to run inside the Docker build (the image needs `node_modules` baked in), but the choice of *which* package manager and *which* flags to run is information the Dockerfile alone can't recover from a clean container — it has to be told.
## Decision
The install step is split deliberately across the two files. `src/com/meesho/stages/buildNode.groovy` does the detection: it reads `config.yaml`, sees whether the repo uses `npm` or `pnpm`, and resolves the optional `npm_install_arg` override; it then passes the resolved values to `resources/com/meesho/node-Dockerfile` as Docker build-args. The Dockerfile does the execution: it consumes those build-args and runs the actual install, falling back to a sane default in an `else` branch when no value was passed. Detection lives at the layer that can see the config; execution lives at the layer that runs inside the container.
## Alternatives Considered
No alternatives were explicitly evaluated by the team during this interview. The split mirrors what is naturally separable — config interpretation vs runtime install — and has not been revisited.
## Consequences
**Positive:**
- Teams can override the install command for their service through `npm_install_arg` in `config.yaml` without forking the library Dockerfile — observed in #devops-tech (Nov 2025) when a team added `--legacy-peer-deps` purely via config.
- The Dockerfile's `else` fallback means a developer can `docker build` locally without Jenkins or `config.yaml` and still get a working install.
- Neither layer needs to know more than it actually does: Groovy doesn't run `npm`, the Dockerfile doesn't read YAML.
**Negative:**
- Any change to install behaviour has to land in both files at once (tribal-knowledge #11). The pair-edit invariant is real but has not yet caused a production incident.
- Build-args are stringly-typed, so a typo on either side fails late — at install time inside the Docker build.
**Neutral:**
- The "detection in Groovy, execution in Dockerfile" split is mirrored elsewhere in `devops-lib` (e.g. Maven, Go); Node just happens to be the most config-driven and therefore the most visible example.
## Constraints
- The package-manager choice has to be visible at Docker-build time inside the container; build-args are the cleanest way to inject it.
- The library must support repos that build locally (no Jenkins, no `config.yaml`) for developer ergonomics.
## Current Assessment
- **Still appropriate** — the split works, the override knob is being used as intended, and no incident has surfaced. A future hardening could add a CI check that any PR touching the install logic on one side also touches the other, but it is not load-bearing today.
## Related Decisions
None directly. The "detection in Groovy, execution in container" split is a pattern repeated in other build stages (Maven, Go), but each has its own per-language ADR scope.
## Notes
- Key files: `src/com/meesho/stages/buildNode.groovy`, `resources/com/meesho/node-Dockerfile`
- `npm_install_arg` in `config.yaml` is a documented public extension point — see service-team usage in #devops-tech (Nov 2025) for the `--legacy-peer-deps` case.
- Discovery id: PATTERN-2
<!-- adr-generator-meta
discovery_id: PATTERN-2
run_id: 90b9a400-266c-4786-b793-d811efa99276
last_completed_at: 2026-05-13T12:28:00Z
mode: create
cache_uri: gs://ai-blitz-agent-readability/adr/devops-lib/adr-discovery.json
-->