> For the complete documentation index, see [llms.txt](https://docs.sealsecurity.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sealsecurity.io/setup-apps-os/cli-in-cicd/dockerfile.md).

# Running the CLI inside a Dockerfile

When the entire build is wrapped inside `docker build` with no separate CI step where the Seal CLI could run, the CLI runs inside the Dockerfile itself: install the CLI in an intermediate layer, run `seal fix` after the dependency-install step, finish the build.

## Sketch

```dockerfile
# syntax=docker/dockerfile:1.4

FROM node:20
WORKDIR /app
COPY . .
RUN npm ci

# Install the Seal CLI in an intermediate layer.
ADD https://github.com/seal-community/cli/releases/download/latest/seal-linux-amd64-latest /usr/local/bin/seal
RUN chmod +x /usr/local/bin/seal

# Run seal fix with the token mounted as a build-time secret.
ARG SEAL_PROJECT=my-project-id
RUN --mount=type=secret,id=SEAL_TOKEN,env=SEAL_TOKEN \
    seal fix --mode all --remove-cli

RUN npm run build
```

The seal step runs after `npm ci` (so the packages are on disk to be replaced) and before `npm run build` (so the build sees the sealed versions). The same shape applies to every ecosystem; swap `npm ci` for `mvn install`, `pip install -r requirements.txt`, `go mod download`, and so on.

`--remove-cli` deletes the CLI binary at the end of the run, so the final image does not ship with it. Drop the flag if you have a reason to keep the binary in the image.

## Passing the token

The example uses **BuildKit secrets** to mount `SEAL_TOKEN` only for the duration of the seal step. It does not appear in image history or layer metadata. Invoke the build with:

```bash
SEAL_TOKEN=$SEAL_TOKEN docker build --secret id=SEAL_TOKEN,env=SEAL_TOKEN -t my-app .
```

BuildKit secrets are available from Docker 18.09 onward with BuildKit enabled (the default on modern Docker versions). If your build runs on an older Docker without BuildKit, fall back to `--build-arg SEAL_TOKEN=$SEAL_TOKEN` — it works, but the token may appear in image history; rotate the token after the build if that matters for your environment.

## Notes

* `--mode all`, `--mode remote`, and `--mode local` all work inside a Dockerfile. Pick the one that matches your [deployment method](/setup-apps-os/choosing-deployment-method.md).
* BuildKit aggressively caches `RUN` steps. If `seal fix` is being skipped on re-runs when you expect it to re-execute, see the [BuildKit caching note](/setup-apps-os/cli-in-cicd/common-issues.md#platform-specific-gotchas).

## Related

* [Installing the Seal CLI](/setup-apps-os/cli-in-cicd/installing-the-cli.md): the install methods for non-Dockerfile contexts.
* [The CLI fix mode](/setup-apps-os/cli-in-cicd/cli-fix-mode.md): the meaning of `--mode all`.
