npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@turbokube/contain

v0.4.4

Published

Simple declarative container builds from local artifacts

Downloads

343

Readme

contain

Simple declarative container builds from local artifacts.

contain is a unix philosophy CLI that does the following thing well: Produces a container image from a local directory structure and a base image.

It runs nicely with Skaffold as custom buildCommand, as it picks up the IMAGE and PLATFORMS envs.

basics

Contain is designed to take platform-agnostic layers and append to multi-platform bases. Nodejs and Java are examples of runtime environments that work well with such images.

Future versions might add support for:

  • Single platform base images (can be auto detected)
  • Configuring platform per layer, i.e. omit a layer on non-matching platforms

To leave room for single platform images, Contain requires that you set platforms to all, the same value you'd use for ko multi-platform images.

There are many image manifests formats but Contain supports only OCI. By validating manifest types Contain helps keeping your images consistent. Future versions could add support for other formats, but that would be opt-in by config.

execution

Here's an example of a base image manifest, with optional attestation:

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:2e2643ac2745067b637a4e1c4d5a3936b27a430cf0d989562c04fb7d7c53e69c",
      "size": 475,
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:e34c5ca17d295d5873f451ab094fb5b5515a0a5ec433d8613276baeb8f1c7741",
      "size": 475,
      "platform": {
        "architecture": "arm64",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:897bf5e232d9c5a72947462cc13072e988428e0ff80f4441c7a238e4892afc00",
      "size": 566,
      "annotations": {
        "vnd.docker.reference.digest": "sha256:2e2643ac2745067b637a4e1c4d5a3936b27a430cf0d989562c04fb7d7c53e69c",
        "vnd.docker.reference.type": "attestation-manifest"
      },
      "platform": {
        "architecture": "unknown",
        "os": "unknown"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:a7f5930278c418d53dc56bfcd22f7332fbda225006a1875fbc673df454929a49",
      "size": 566,
      "annotations": {
        "vnd.docker.reference.digest": "sha256:e34c5ca17d295d5873f451ab094fb5b5515a0a5ec433d8613276baeb8f1c7741",
        "vnd.docker.reference.type": "attestation-manifest"
      },
      "platform": {
        "architecture": "unknown",
        "os": "unknown"
      }
    }
  ]
}

This means that to get the actual base layer references, Contain will have to pull both of the application/vnd.oci.image.manifest.v1+json manifests. They're also pretty-printed json, like

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:0d0715737c21d4dc2a49af26ef780241ad5d6ab1a0e1133364e40d002ca16722",
    "size": 575
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:c61587a79a418fb6188de8add2e9f694b012acde27abefd27dedaff5f02de71e",
      "size": 93
    }
  ]
}

Running sha256sum on the above you get 2e2643ac2745067b637a4e1c4d5a3936b27a430cf0d989562c04fb7d7c53e69c which is the digest in the index manifest. Using this manifest you can retrieve the layers, but because Contain is agnostic to what the base image contains there's no need to spend the bandwidth of pulling them.

Later on if the resulting image is pushed to a different registry than where the base image lives, go-containerregistry will handle the copying of all layers.

Contain does not support nested indexes. It will bail if any manifest in the index has mediaType application/vnd.oci.image.index.v1+json.

Upon successful retrieval of indexes, contain can start the actual build.

Layers are just tarballs. The task for Contain is to produce these tar+gzips from your config, hash them and append each layer in order to each platform's index. That creates a new index per platform, each one having a new digest (checksum). With those checksums Contain can produce a new index.

In practice Contain will run append and push to the first platform, then derive the layers to append from that one.

Currently Contain can't update attestations. Those index entries are therefore dropped.