Skip to content
Back to skills

Containerize

ASecurity

Build, scan, sign, and verify Python container images with Trivy and Cosign.

  • 10 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 23, 2026
ai-agentspythongobashdockercode-reviewgitdatabasesecuritydocumentation

Works with

  • cli

Security analysis

A100/100

Pro scans all 6 files and shows the line behind each finding

Scanned October 6, 2026

npx -y skills add fmind/dot --skill containerize --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Containerize?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Containerize
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/fmind-containerize/badge)](https://www.skillsdirectory.com/skills/fmind-containerize)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: containerize
description: "Build, scan, sign, and verify Python container images with Trivy and Cosign."
license: MIT
metadata:
  kind: task
  author: Médéric HURIER (Fmind)
  source: github.com/fmind/dot/tree/main/skills/containerize
  created: "2026-07-04"
  updated: "2026-10-06"
---

# Containerize

Build a reproducible, minimal non-root uv-managed Python image locally, verify its immutable digest, and publish only within the user's authorized registry scope. [cloud-run](../cloud-run/SKILL.md) deploys it, [trivy](../code-security/references/trivy/GUIDE.md) scans it, and the cosign guide below owns provenance; read it only when publication or verification requires signing.

## Workflow

1. **Budget and identify resources**: inspect free space on the workspace and Docker storage filesystems, the selected Docker context, `docker system df`, and `docker buildx ls`. Run `dot doctor --headroom` first, then confirm the projected peak (context, layers, archive export and extraction) still leaves 20 GiB free, per [resource cleanup](references/resource-cleanup.md). Record task-owned names/IDs before creating resources; use a unique Compose project or resource label so concurrent work stays separate.
1. **Adopt the templates**: copy [Dockerfile](templates/Dockerfile) and [.dockerignore](templates/.dockerignore). Replace `<slug>` with the installed Python console script and verify both image digests before use.
1. **Build locally**: emit a Docker archive so the first build and scan require no registry mutation.

   ```bash
   mkdir -p tmp
   docker buildx build --output type=docker,dest=tmp/image.tar .
   ```

1. **Wire the gate** into `mise.toml`; `check:image` scans the exact archive produced by `build:image`.

   ```toml
   [tasks."build:image"]
   description = "Build the Python OCI image locally"
   run = ["mkdir -p tmp", "docker buildx build --output type=docker,dest=tmp/image.tar ."]

   [tasks."check:image"]
   description = "Scan the local OCI image"
   depends = ["build:image"]
   run = "trivy --config trivy.yaml image --skip-dirs '' --input tmp/image.tar"
   ```

1. **Exercise the container**: load it with `docker load --input tmp/image.tar`. For the Python web starter, supply required application settings through a reviewed local environment file, then run `docker run --rm -p 127.0.0.1:8080:8080 --env-file <runtime-env-file> -e HOST=0.0.0.0 -e PORT=8080 -e ENVIRONMENT=production <local-reference>` and request `/health` and `/ready`. For a CLI image, exercise its actual command and exit behavior instead of publishing a port.
1. **Publish when authorized**: push a reviewed tag with `docker buildx build --push --tag "$IMAGE_REPOSITORY:$TAG" --metadata-file tmp/image-metadata.json .`. Parse `containerimage.digest` from that file, require `sha256:` plus 64 lowercase hex characters, and record `$IMAGE_REPOSITORY@$DIGEST`.
1. **Verify the immutable result**: scan the recorded digest, generate a CycloneDX SBOM, sign it, pin the expected certificate identity and issuer during verification, and attest the SBOM per [trivy](../code-security/references/trivy/GUIDE.md) and [cosign](references/cosign.md). For a multi-platform index, scan every child and bind each SBOM to that child's digest before promoting the index; the [CD template](../github-actions/references/ci-cd/templates/cd.yml) implements this sequence.
1. **Tear down temporary resources** on success and failure, preserving requested deliverables and useful failure evidence. Follow [resource cleanup](references/resource-cleanup.md), verify only recorded task resources disappeared, and report any retained disk footprint and reason.

## Gotchas

- **Fail on lock drift with `--locked`**: `uv sync --locked` rejects a missing or stale `uv.lock`; `--frozen` skips freshness checks. The template uses `--locked` so manifest drift fails without rewriting the graph.
- **Run non-root with explicit writable paths**: the template runs as numeric UID/GID 10001 and copies only the locked virtual environment from the build stage. Write temporary data outside the application directory or mount an explicit writable path.
- **Refresh pinned bases together**: both Python and uv use multi-architecture manifest digests. Refresh versions and digests together with [upgrade-tools](../upgrade-tools/SKILL.md).
- **Exclude local state from the context**: keep virtual environments, caches, logs, local databases, Git state, plaintext environment files, and generated `gha-creds-*.json` Workload Identity Federation credentials out through [.dockerignore](templates/.dockerignore). The Cloud Run authentication action creates its credential file before the Docker build; it must not enter a build layer.
- **Digests over tags**: scans, signatures, attestations, deployment, and rollback all use the same immutable digest reference.
- **Authorize every registry write**: pushes, signatures, and attestations require explicit authority; local build and scan do not grant it.
- **Reuse shared build cache under budget**: `--rm` removes a container, not its image, exported archive or build cache. Shared builder cache has no reliable per-agent ownership; reuse it under a reviewed storage budget instead of pruning it at every task end.

## Task guides

<!-- guides:start -->

- [cosign](references/cosign.md): Image signatures, identity verification, and attestations.

<!-- guides:end -->

## Documentation

- [Docker multi-stage builds](https://docs.docker.com/build/building/multi-stage/) · [uv Docker guide](https://docs.astral.sh/uv/guides/integration/docker/)
- [Resource cleanup](references/resource-cleanup.md) · [Build cache garbage collection](https://docs.docker.com/build/cache/garbage-collection/)
- Releases: [Docker Engine](https://docs.docker.com/engine/release-notes/) · [uv changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
- Companion skills: [python-stack](../python-stack/references/foundation/GUIDE.md), [cloud-run](../cloud-run/SKILL.md), [trivy](../code-security/references/trivy/GUIDE.md), [github-actions](../github-actions/references/ci-cd/GUIDE.md), and [code-security](../code-security/references/code-review/GUIDE.md).

Files in this skill

  • SKILL.md918 B
  • references/cosign.md2.7 KB
  • references/image-build/GUIDE.md5.1 KB
  • references/image-build/references/resource-cleanup.md3.1 KB
  • references/image-build/templates/.dockerignore306 B
  • references/image-build/templates/Dockerfile1.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…