dagger / dagger

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

✨ Import image to local container runtime #8025

Open jedevc opened 3 months ago

jedevc commented 3 months 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:

ghost commented 3 months 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 3 months 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)
    }))
}
ghost commented 3 months ago

Thanks for sharing, that's nifty.

VasiliyS commented 6 days ago

That would be a much welcomed feature!

In my case, I'd like to automate the container workflow for local dev and testing for a library I'm developing. In a nutshell, the library is a client which interacts with a server. This server is under active development and therefore a functionality is needed to automate bootstrapping dev/test/demo environment against various git refs.

Also, the users of the library will benefit from the ability to have all bootstrapping done for them for learning and development.

Currently, I'm exporting and loading a tarball, but it's slow and feels kind of wasteful.

BTW, to deal with tagging, one can simply annotate the container with io.containerd.image.name prior to asTarball call. docker load -i picks up the annotation, including the tag.