Document npm registry endpoints and auth gotchas
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Add the exact pip/npm registry endpoints and secret names, the scope-scoped (not global) registry requirement given Verdaccio's missing uplink, the host-scoped _auth rule, the per-item Drone shell caveat, and the Verdaccio storage uid/permissions gotcha behind the confusing "404 no such package available" error on publish.
This commit is contained in:
@@ -72,8 +72,13 @@ pipelines**:
|
||||
the disaster-recovery / replay path.
|
||||
|
||||
Secrets: `NPM_REPO_URL`, `NPM_USERNAME`, `NPM_PASSWORD`. Auth is a generated
|
||||
`.npmrc` (`registry=` + `_auth=` base64 of `user:pass`) written from secrets at
|
||||
runtime — the committed `.npmrc` in a repo only points at the registry URL.
|
||||
`.npmrc` written from secrets at runtime. It sets a **scope-scoped** registry,
|
||||
never a global one — `@aetoskia:registry=$NPM_REPO_URL` — plus a host-scoped
|
||||
auth line `//<host>/:_auth=<base64(user:pass)>`. The scope and host are derived
|
||||
from `package.json` and `NPM_REPO_URL` respectively. A global `registry=` would
|
||||
push public transitive deps through Verdaccio (which has no uplink) and 404
|
||||
`npm install`; a bare `_auth=` is rejected by modern npm. See
|
||||
[93 – Library Registry](93_library_registry.md).
|
||||
|
||||
- **Ship as-is.** Name and version come from `package.json`, so the same file
|
||||
is reused verbatim across every npm package.
|
||||
|
||||
@@ -64,6 +64,56 @@ so the CI credentials (`PIP_USERNAME` / `PIP_PASSWORD`, `NPM_USERNAME` /
|
||||
Verdaccio requires **bcrypt** htpasswd entries; see
|
||||
[90 – Drone Pipelines](90_drone_pipelines.md) for the CI wiring.
|
||||
|
||||
### Endpoints
|
||||
|
||||
| Registry | URL | Backend | CI secret |
|
||||
|---|---|---|---|
|
||||
| PyPI | `https://pip.aetoskia.com` | pypiserver (`server-pi:6007`) | `PIP_REPO_URL` |
|
||||
| npm | `https://npm.aetoskia.com` | Verdaccio (`server-pi:6008`) | `NPM_REPO_URL` |
|
||||
|
||||
Both are exposed through Traefik on the `websecure` entrypoint as **bare
|
||||
origins** — no path, no trailing slash. Set the secret values exactly as above.
|
||||
|
||||
### npm: scope the registry, never set it globally
|
||||
|
||||
Verdaccio here has **no uplink / proxy**, so it can only serve `@aetoskia/*`
|
||||
packages. A global `registry=https://npm.aetoskia.com` in `.npmrc` would route
|
||||
*every* dependency — including public transitive deps such as
|
||||
`zod-to-json-schema` (pulled in by `@modelcontextprotocol/sdk`) — through
|
||||
Verdaccio, which 404s on anything it does not host. Always scope the registry to
|
||||
the account:
|
||||
|
||||
```
|
||||
@aetoskia:registry=https://npm.aetoskia.com
|
||||
//npm.aetoskia.com/:_auth=<base64(user:password)>
|
||||
```
|
||||
|
||||
Public deps then resolve from `registry.npmjs.org` and only `@aetoskia/*` hits
|
||||
the private registry. The auth line must be **scoped to the host**
|
||||
(`//host/:_auth=`), not a bare `_auth=` — modern npm rejects the bare form with
|
||||
`ERR_INVALID_AUTH`. The drone template derives both from the package scope and
|
||||
`NPM_REPO_URL` automatically; see
|
||||
[90 – Drone Pipelines](90_drone_pipelines.md).
|
||||
|
||||
> The Drone pipeline runs each `commands:` list item in a **separate shell**, so
|
||||
> shell variables defined in one item do not survive into the next. Keep the
|
||||
> variable definitions and the commands that use them in the same `|` block.
|
||||
|
||||
### Verdaccio storage permissions
|
||||
|
||||
Verdaccio runs as uid **10001** (`verdaccio`) inside `verdaccio/verdaccio`.
|
||||
The `storage` directory is bind-mounted from the server
|
||||
(`/mnt/omnissiah-vault/data/verdaccio/storage`); if it is owned by `root:root`
|
||||
(mode `755`) the process cannot write to it and every publish fails with a
|
||||
confusing `404 no such package available` (`NotFoundError` from
|
||||
`local-storage`). Ensure the directory — and its `plugins` subdirectory — are
|
||||
owned by `10001:101`:
|
||||
|
||||
```sh
|
||||
sudo chown -R 10001:101 /mnt/omnissiah-vault/data/verdaccio/storage
|
||||
docker restart npm-registry
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- **Hexa** is a full library with its own MCP server on `:8008`: read
|
||||
|
||||
Reference in New Issue
Block a user