Part of https://github.com/pnpm/tasks/issues/191. Wrong claims: - cli: drop the nonexistent `add-user --password` flag and document the terminal/stdin password read; `oci-gc --min-age` and `cache-gc --max-age` are the flags (the `-secs` forms are aliases); `--from` defaults to the `storage` key, not an internal field; `info` and `http` log the same access records; only global and server options have PNPR_* variables. - configuration: `packumentTtl` defaults to 5m; the minimal config now sets `auth.htpasswd.file`, and the auth section says accounts live in memory without it or a backend; grouped hosted registries default their org to `<ecosystem>~<name>`; the handshake is served for any surface; the pipeline surface also satisfies "something must be served"; add `package.update_maintainers` to the audit list. - tls-and-reverse-proxy: remove the invalid `publicUrl:` YAML key and the nonexistent `rate_limiting` setting. - backup-and-restore: `pnpr verify` hashes by default (`--check-hashes` does not exist, `--skip-hashes` skips only the hash comparison); `migrate-storage --verify` compares bytes. - webhooks: audit events do not cover publishes or token creation; the example uses a real action and the `actor` field. - cli: the `RUST_LOG` example keeps `pnpr::audit=info`. - install-acceleration: the `--public-url` host is exempt from the private-address refusal. - shared-side-effects-cache: `pnpm pipeline` publishes workspace-task artifacts. Missing facts: `routes.allowedPrivateNetworks`, the upstream `search` key and canonical `maxAge`, built-in `npm.jsr.io` route, relative path resolution, `log` defaults and `type`, `${VAR:-default}` substitution and the full secret-field list, `oci` defaults, `artifacts.quota` bounds, `migrate-storage` destination rules, `--osv false`, `--packument-ttl` default, S3 `forcePathStyle`/`allowHttp` defaults, grouped org layout, OIDC key table, container image section, `backend:` ignoring the htpasswd and token files. Duplicates and links: health probe bodies, reload procedure, and the resolver allowlist now link to their one home; broken `#secret` anchor fixed; links into the pnpm docs use absolute pnpm.io URLs. Stale history: drop "pnpr v1" and the per-paragraph "Since alpha.N" / "Since pnpm 12.x" prefixes, and the contributor-only extensibility text. Also corrects the `as_filter_directive` doc comment, which claimed `http` quiets the rest of the crate.
104 lines
3.2 KiB
Markdown
104 lines
3.2 KiB
Markdown
---
|
|
id: quick-start
|
|
title: Quick start
|
|
---
|
|
|
|
## Write a config
|
|
|
|
pnpr routes packages through declared
|
|
[registries](configuration.md#registries-and-defaultregistry): every origin
|
|
(a locally-hosted registry, an upstream like npmjs) is declared explicitly and
|
|
claims the package names it serves, and a router resolves each name to exactly
|
|
one of them. Save this as `pnpr.yaml`:
|
|
|
|
```yaml title="pnpr.yaml"
|
|
storage: ./storage
|
|
|
|
auth:
|
|
htpasswd:
|
|
file: ./htpasswd
|
|
# Allow one user to self-register, for the publish step below.
|
|
max_users: 1
|
|
|
|
registries:
|
|
# Packages published to this server. The `packages:` map is this
|
|
# registry's namespace: only these names can live here.
|
|
local:
|
|
type: hosted
|
|
packages:
|
|
'@mycompany/*':
|
|
publish: $authenticated
|
|
|
|
# The public npm registry. No `packages:` map — it serves every name,
|
|
# so it must be the last source in the router below.
|
|
npmjs:
|
|
type: upstream
|
|
url: https://registry.npmjs.org/
|
|
public: true
|
|
|
|
# A package resolves to the first source that claims its name:
|
|
# your scope goes to the local registry, everything else to npm.
|
|
main:
|
|
type: router
|
|
sources: [local, npmjs]
|
|
|
|
# The bare server URL serves the router.
|
|
defaultRegistry: main
|
|
```
|
|
|
|
Replace `@mycompany` with your own scope. There is no fall-through between
|
|
registries: a `@mycompany/*` package that isn't published locally is a
|
|
definitive 404, never a request to npmjs. This is what closes
|
|
dependency confusion.
|
|
|
|
## Start the server
|
|
|
|
```sh
|
|
pnpr -c ./pnpr.yaml
|
|
```
|
|
|
|
It listens on `127.0.0.1:7677`. Running plain `pnpr` with no config works
|
|
too. The bundled config proxies npmjs and provides a local hosted registry at
|
|
`/npm/~local/`, whose packages need a login. It allows no self-registration,
|
|
so create accounts with [`pnpr add-user`](cli.md#add-user).
|
|
|
|
## Point a client at it
|
|
|
|
Configure pnpm (or npm/yarn) to use the local server as its registry:
|
|
|
|
```sh
|
|
pnpm config set registry http://127.0.0.1:7677/npm/
|
|
```
|
|
|
|
Now `pnpm install` fetches packages through pnpr. Packages proxied from the
|
|
upstream are cached, so subsequent installs are served locally.
|
|
|
|
Each registry is also directly addressable at
|
|
`http://127.0.0.1:7677/npm/~<name>/`. For example, you can point only your scope
|
|
at the hosted registry instead of using the router.
|
|
|
|
## Publish a package
|
|
|
|
Create a user and publish:
|
|
|
|
```sh
|
|
pnpm login --registry http://127.0.0.1:7677/npm/
|
|
pnpm publish --registry http://127.0.0.1:7677/npm/
|
|
```
|
|
|
|
The publish routes through the router to the `local` hosted registry.
|
|
Publishing a package that resolves to an upstream, or whose name no registry
|
|
claims, is rejected.
|
|
|
|
## Where to go next
|
|
|
|
- [CLI reference](cli.md): every flag `pnpr` accepts.
|
|
- [Configuration](configuration.md): write your own config, including registries,
|
|
access rules, and auth.
|
|
- [Reverse proxy and TLS](tls-and-reverse-proxy.md): set up Nginx, Caddy, Traefik, or a cloud load balancer for production.
|
|
- [Webhooks and event notifications](webhooks.md): stream audit events and storage notifications to external webhooks.
|
|
- [Backup and restore](backup-and-restore.md): snapshot and restore package storage and user records.
|
|
- [Install acceleration](install-acceleration.md): let pnpr resolve your
|
|
dependency graph to speed up installs.
|
|
|