dagger / dagger

An engine to run your pipelines in containers
https://dagger.io
Apache License 2.0
10.87k stars 581 forks source link

✨ Import image to local container runtime #8025

Open jedevc opened 1 month ago

jedevc commented 1 month ago

The CLI should support loading images into the local container image store - whether that's docker, containerd through ctr/nerdctl, podman, etc.

Today, this might look something like:

$ dagger call container-echo --string-arg=foo -o ./image.tar
$ docker load -i ./image.tar

However, we should really have a native way to do this - something like:

$ dagger call container-echo --string-arg=foo --load <image>:<tag>

Why?

So how would this work?

Related:

mihaelTBTL commented 1 month ago

Is this also related to #6999? I had a similar use case to #7368, but ultimately didn't manage to get it working as expected.

Even with the described current practice:

$ dagger call container-echo --string-arg=foo -o ./image.tar
$ docker load -i ./image.tar

I'd run into this issue where the image name and tag would not be preserved when loading the tarball. The export method of container didn't seem to behave like docker image save.

verdverm commented 1 month ago

Forgot about the tagging part, for context, here is the code I use in one project

// writes images into docker daemon on host
export default async function build(cfg: Record<string,any>, client: Client) {
    // Dagger Containers
    const imgs = await images(cfg, client)

    const output = async (img: Container, name: string) => {
        const fullName = `${name}:dirty`
        const fullTar = `/tmp/${fullName}.tar`

        // write tar file, triggers actual image building
        await img.export(fullTar)

        // load into docker
        const { stdout } = await exec(`docker load -i ${fullTar}`)
        const sha = stdout.split(":")
        const hash = sha[sha.length-1].trim()

        // tag image
        await exec(`docker tag ${hash} ts/${fullName}`)

        // cleanup tar file
        await exec(`rm ${fullTar}`)
    }

        // doing this in parallel will make your computer warm...
    await Promise.all(cfg.components.map(async (c) => {
        await output(await imgs[c], cfg[c].name)
    }))
}
mihaelTBTL commented 1 month ago

Thanks for sharing, that's nifty.