#"docker build" inside of dag.Container

1 messages · Page 1 of 1 (latest)

thin flare
#

I got it working by running a "service" with docker:dind

dockerLibCache := dag.CacheVolume("docker-lib")
dockerCertCache := dag.CacheVolume("docker-certs")
daemon := dag.Container().
    From("docker:dind").
    WithEnvVariable("DOCKER_TLS_CERTDIR", "/certs").
    WithMountedCache("/var/lib/docker", dockerLibCache, dagger.ContainerWithMountedCacheOpts{}).
    WithMountedCache("/certs", dockerCertCache, dagger.ContainerWithMountedCacheOpts{}).
    WithExposedPort(2376).
    AsService(dagger.ContainerAsServiceOpts{
        InsecureRootCapabilities: true,
    })

and then I can bind my builder container

builder := dag.Container().
    From("golang:1.24-alpine").
    WithServiceBinding("docker", daemon).
    WithMountedCache("/certs", dockerCertCache).
    WithEnvVariable("DOCKER_HOST", "tcp://docker:2376").
    WithEnvVariable("DOCKER_CERT_PATH", "/certs/client").
    WithEnvVariable("DOCKER_TLS_VERIFY", "1").
        WithExec(strings.Fields(buildCommand))

The builder ends up running docker build ... and I can get the image via dag.Container().Import(builder.File("image.tar"))
This works, but Im wondering if using a "service" is the right approach.

NOTE: not feasible to rewrite "buildCommand" as a proper dag.Container build.

#

Another "hacky" thing is getting the final container out of the deamon docker. I ended up doing this

if _, err := builder.WithExec([]string{"docker", "save", fullRef, "-o", "image.tar"}).Sync(ctx); err != nil {
    builder = builder.
        WithExec([]string{"sh", "-c", "docker images --format '{{.Repository}}:{{.Tag}}' --filter 'dangling=false' | head -n 1 > /tmp/latest-image"}).
        WithExec([]string{"sh", "-c", "docker tag $(cat /tmp/latest-image) " + fullRef}).
        WithExec([]string{"docker", "save", fullRef, "-o", "image.tar"})
}
hidden arrow
#

@thin flare this is to work around a limitation of native Directory.dockerBuild?

thin flare
hidden arrow
#

I see, you want to wrap your existing script without modifying it to use dagger itself.

Are you sure using dagger is a good fit then? This will work but you won't get the full benefits of tracing, caching, repeatability etc. within the build script itself