I have a pipeline that produces multi-stage images, where image C is FROM B, B is FROM A, and all three A B & C should be usable in docker run. I can't see any way to assign a tag either before or after Directory.dockerBuild() a la docker build -t something .. Currently, I have something like
const runEnvironment_imageRef = await client
.host()
.directory(`RunEnvironment`)
.dockerBuild()
.withRegistryAuth(runEnvironment_imageUrl, configuration.containerRegistry_user, containerRegistry_password)
.publish(runEnvironment_imageUrl)
const buildEnvironment_imageRef = await client
.directory()
.withDirectory("/", gitDirectory)
.dockerBuild({
dockerfile: `Dagger/BuildEnvironment/Dockerfile`,
buildArgs: [{ name: `RunEnvironment_ImageRef`, value: runEnvironment_imageRef }]
})
.withRegistryAuth(buildEnvironment_imageUrl, configuration.containerRegistry_user, containerRegistry_password)
.publish(buildEnvironment_imageUrl)
Build args using the output of publish are used to force a dependency between the two (avoid having the build environment build from an outdated run environment while the new run environment is still building). There are several problems with using the shared registry URL as this intermediate:
- If there are problems with the container registry, my local testing is interrupted (running into this right now!).
- I should be able to test this out locally without pushing anything to the shared registry.
- One of these containers is necessarily big, and uploading can take a long time. But C shouldn't have to wait for B to finish uploading, before it begins building - the two operations should, ideally, occur simultaneously.
- For each subsequent stage, Docker downloads the previous one from the registry, which it had just uploaded. This doesn't happen with
docker build -t.
Using localhost or a plain tag name in publish doesn't work (they're treated as hostnames).