> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boat.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Private registries

> Log in to private npm, pip, uv and Docker registries in every sandbox with environment variables and secret files.

Put the registry token in the environment. Every new sandbox then installs from your private registry with no extra step.

| Registry | What to set | Path inside the sandbox |
| - | - | - |
| npm, pnpm | Variable `NPM_TOKEN` and secret file `.npmrc` | `/home/user/.npmrc` |
| pip | Secret file `.config/pip/pip.conf`, or variable `PIP_INDEX_URL` | `/home/user/.config/pip/pip.conf` |
| uv | Variable `UV_DEFAULT_INDEX`, or `UV_INDEX_<NAME>_USERNAME` and `UV_INDEX_<NAME>_PASSWORD` | Environment only |
| Docker | Secret file `.docker/config.json`, or `docker login` in a setup script | `/home/user/.docker/config.json` |

Secret file paths are relative to `/home/user`. Read [Secrets, env vars and .env files](/environments/secrets).

<Warning>
  An environment that is [safe for third parties](/environments/access#safe-for-third-parties) gets none of these values. Check with `boat exec <id> 'echo "[$NPM_TOKEN]"'`.
</Warning>

## npm and pnpm

npm replaces `${NPM_TOKEN}` in `.npmrc` with the variable. So the file itself holds no secret.

```bash theme={null}
boat env set-var base NPM_TOKEN=npm_xxxxxxxx
printf '@acme:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${NPM_TOKEN}\n' \
  | boat env set-file base .npmrc
```

Check it in a new sandbox:

```bash theme={null}
boat exec <id> 'npm whoami --registry https://npm.pkg.github.com'
```

## pip

Use one variable:

```bash theme={null}
boat env set-var base PIP_INDEX_URL=https://user:token@pypi.example.com/simple
```

Or use a config file:

```bash theme={null}
printf '[global]\nindex-url = https://user:token@pypi.example.com/simple\n' \
  | boat env set-file base .config/pip/pip.conf
```

## uv

```bash theme={null}
boat env set-var base UV_DEFAULT_INDEX=https://pypi.example.com/simple
boat env set-var base UV_INDEX_ACME_USERNAME=user
boat env set-var base UV_INDEX_ACME_PASSWORD=token
```

`ACME` is the uppercase name of the index in your `pyproject.toml`.

## Docker

The user `user` runs `docker` without `sudo`. Docker reads logins from `/home/user/.docker/config.json`.

Option 1: send the config file of a machine that is already logged in. The file must hold the login itself, not a `credsStore` entry.

```bash theme={null}
boat env set-file base .docker/config.json --from ./docker-config.json
```

Option 2: log in at each start. Keep the token in a variable, and add this [repository setup script](/setup#repository-setup-scripts):

```bash theme={null}
echo "$GHCR_TOKEN" | docker login ghcr.io --username acme-bot --password-stdin
```

<Note>
  A [named snapshot](/snapshots/templates) keeps `/home/user/.docker/config.json` like every other file. Do not save a named snapshot from a sandbox that holds a login that others must not use.
</Note>

## Related

* [Secrets, env vars and .env files](/environments/secrets)
* [Setup scripts](/setup)
* [Access and credentials](/environments/access)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.