For the complete documentation index, see llms.txt. This page is also available as Markdown.

Seal My Container

Container-to-container sealing for your own private images.

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, 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; 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_TOKENs 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. 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 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; there is no post-build sealing path for those.

Chapter contents

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

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

  • Seal My Container: 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: 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.

Last updated