> ## 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.

# Environment, setup script or named snapshot?

> Pick the right tool for what a new sandbox needs: settings and secrets, commands at each start, or a disk with your tools already installed.

Each tool does one job. Most setups use two or three of them together.

| You want | Use | It holds | When it applies |
| - | - | - | - |
| The same secrets, repositories and credentials in every sandbox | [Environment](/environments) | Settings only, no disk | At each start |
| Packages, tools or data already installed | [Named snapshot](/snapshots/templates) | A full copy of a sandbox disk | When you create a sandbox with `--from` |
| Commands that must run at each start, for example `git pull` or `npm install` | [Repository setup script](/setup#repository-setup-scripts) | A script, attached to a repository in an environment | At each start: create, resume and fork |
| Commands for one sandbox only | [`--setup-file`](/setup#per-sandbox-setup-file) | A script, given at create | Once, at create |

Rules:

* Put slow installs in a named snapshot. A setup script repeats them at every start.
* Put secrets in an environment, never in a named snapshot. A named snapshot keeps every file on its disk.
* Boat has no custom image and no Dockerfile build. A named snapshot does that job: install your tools in a sandbox, then save it.

## Example 1: a web app with a database URL

You want each sandbox to have your repository, its dependencies and a `DATABASE_URL`.

1. Add the repository and the variable to an environment:

   ```bash theme={null}
   boat env add-repo base acme/web-app
   boat env set-var base DATABASE_URL=postgres://db.example.com/app
   ```

2. Add the repository setup script `npm install` in [Dashboard > Environment](https://boat.dev/dashboard?tab=environment).

3. Create sandboxes with `boat new`. Each one clones the repository, gets the variable and runs `npm install`.

## Example 2: heavy tools installed once

You need Python ML packages, a large dataset and Playwright browsers. They take 10 minutes to install.

1. Create one sandbox and install everything in it:

   ```bash theme={null}
   boat new --type large
   boat ssh <id> -- bash -s < ./install-tools.sh
   ```

2. Save the disk as a named snapshot:

   ```bash theme={null}
   boat snapshot <id> ml-stack
   ```

3. Create each new sandbox from it. The tools are already there:

   ```bash theme={null}
   boat new --from ml-stack
   ```

The environment still adds your secrets at each start. Read [Named snapshots](/snapshots/templates).

## Example 3: one task file per sandbox

Each sandbox works on a different customer ticket. The setup differs per sandbox.

```bash theme={null}
boat new --from ml-stack --setup-file ./ticket-4211.sh
boat info <id>   # setupStatus: pending, running, done or failed
```

The `--setup-file` script runs once, as the user `user`. A fork does not run it again. Read [Per-sandbox setup file](/setup#per-sandbox-setup-file).


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