> 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-containers/seal-my-container.md).

# Seal My Container

Seal My Container is for the case where the container you want sealed is one **you built**, not a public upstream image. The customer's existing image-build pipeline produces an image with vulnerable OS-level packages (and possibly application artifacts) inside. Seal My Container takes that built image, replaces the vulnerable packages, and pushes the sealed result back to the same tag — overwriting the original. From the perspective of every deployment that already pulls `your-registry/your-app:1.2.3`, the tag is the same; only the contents are now sealed.

The mechanism is a single CLI command: `seal image fix`. It pulls the source image, rebuilds it as a one-stage `FROM <source>` `Dockerfile` with the seal step inside, and pushes the result back to the same tag (or to a different tag, if you pass `--tag`). From the rest of your pipeline's perspective, it's a post-build step that takes an image in and returns a sealed image out, in place.

## When to use this

The Seal product lineup distinguishes three container-shaped products:

* **Seal Base Images** when the image you want sealed is a public upstream that Seal has already sealed (Python, OpenJDK, Elasticsearch, and so on). You pull the sealed counterpart, your build uses it. Lowest friction; no per-image work.
* **Seal My Container** (this chapter) when the image is one you built yourself. The image is private to your tenant, not a public upstream, and you need the OS packages inside it sealed without rewriting your `Dockerfile` or migrating distributions.
* **Seal Vendor Apps** when the image is one a vendor ships and you run as-is (a Kafka image from Confluent, a database image from Oracle). Seal cannot redistribute a copy because of licensing; the workflow is different.

For application packages inside your own image, the canonical path is still to seal at build time using the [Seal CLI in CI/CD](/setup-apps-os/cli-in-cicd.md), where each ecosystem's package manager and lockfile are present. `seal image fix` also seals JAR files anywhere in the image's filesystem alongside the OS layer, which makes it the right tool for cases where the JARs are already built and you cannot reach back into the source build (vendor-shipped JARs, third-party deliveries, and so on).

## How `seal image fix` works

```
your CI / a scheduled runner / a developer
                |
        seal image fix <image>
                |
   ┌──────────────────────────────────────────────────────┐
   │  docker pull <image>                                 │  from the registry
   │  generate seal.dockerfile                            │  FROM <image>, RUN seal fix --os, RUN seal fix --fs java /
   │  docker build -t <same-tag>                          │  both seal steps run inside this build
   │  docker push <same-tag>                              │  overwrite the original tag
   └──────────────────────────────────────────────────────┘
```

The CLI orchestrates a small set of `docker` calls (pull, build, push, plus an inspect to capture metadata) on the host it runs on. Docker must be installed on that host; the CLI invokes the `docker` binary directly. The seal steps themselves run **inside** the build, in layers added on top of the pulled image. The OS-layer step is the same `seal fix --os` logic documented in [Seal OS in CI/CD](/setup-apps-os/seal-os-cicd.md); the JAR-sealing step runs `seal fix --fs java /` to recursively rewrite any vulnerable JAR files anywhere in the image. Both are wrapped in a generated `Dockerfile` so the build context is reproducible.

The generated `Dockerfile` uses BuildKit's secret-mount feature to keep `SEAL_TOKEN` out of the resulting image's layers. BuildKit is enabled by default in recent Docker releases; on older Docker daemons, set `DOCKER_BUILDKIT=1` in the environment before running `seal image fix`.

The token is plumbed in through `--secret id=SEAL_TOKEN,env=SEAL_TOKEN`. The two `SEAL_TOKEN`s refer to two different things and just happen to share the name: the first is the BuildKit secret's ID (the handle the inner `RUN` step references), and the second is the host environment variable BuildKit reads the value from. Using the same name for both is the conventional setup.

## What it covers

`seal image fix` seals two layers of a container image:

* **OS packages** installed through `apk`, `apt` / `dpkg`, or `dnf` / `yum`. The package families and per-distribution mechanics are the same as the standalone `seal fix --os` documented under [Seal OS in CI/CD](/setup-apps-os/seal-os-cicd.md). Distroless images are supported too — the CLI uses a filesystem-level mechanism to seal packages in images where the package-manager binary itself was stripped out.
* **JAR files** anywhere in the image's filesystem, sealed via `seal fix --fs java /` as the second step of the generated build.

Python wheels can also be sealed inside a container, via `seal fix --fs python <path>`. The default `seal image fix` flow does not scan for them automatically; reach for the custom-`Dockerfile` pattern documented in [Seal Vendor Apps](/setup-containers/seal-vendor-apps.md) when an image carries wheels you want sealed.

For npm dependencies and Go binaries, seal at the application's own build time using the [Seal CLI in CI/CD](/setup-apps-os/cli-in-cicd.md); there is no post-build sealing path for those.

## Chapter contents

This chapter is the canonical setup home for Seal My Container.

* [Authenticating with your container registry](/setup-containers/seal-my-container/authenticating-registry.md): the source-registry and destination-registry credentials Docker needs on the host where `seal image fix` runs.
* [The `seal image fix` command and flags](/setup-containers/seal-my-container/seal-image-fix-reference.md): the full reference, including the required `--platform` flag and the optional `--tag`.
* [Implementing the centralized re-seal pipeline](/setup-containers/seal-my-container/centralized-pipeline.md): the most common production pattern — a single automation that triggers on registry pushes, seals the image, and pushes the sealed result back.
* [Renaming packages inside containers](/setup-containers/seal-my-container/renaming.md): the recommended default — rename sealed packages inside the image so external scanners do not flag them.
* [Common issues](/setup-containers/seal-my-container/common-issues.md): the failures that come up most often.

## Before you start

* A built container image. The image is typically based on an `apk`, `apt`, or `dnf` / `yum`-managed Linux distribution; distroless images are also supported.
* Docker installed on the host where `seal image fix` runs. The CLI invokes the `docker` binary directly. BuildKit is the build engine used; it is the default in current Docker releases.
* The host authenticated to the registry holding the image; see [Authenticating with your container registry](/setup-containers/seal-my-container/authenticating-registry.md). The typical setup uses one registry for both pull and push.
* The Seal CLI installed on the host. The same binary used elsewhere in Seal; no separate install.
* `SEAL_TOKEN` and `SEAL_PROJECT` set in the host's environment.

## Related

* [Seal My Container](/introduction/product-family/seal-my-container.md): the product-family page that frames where this fits among the five Seal products.
* Working with Seal My Container: the day-2 operating rhythm once the pipeline is in place. (Documented under "Using the Seal Platform.")
* [Seal OS in CI/CD](/setup-apps-os/seal-os-cicd.md): the parallel chapter that runs the same seal step inside a `Dockerfile` you wrote yourself, rather than inside a generated wrapper around a pre-built image.
