Image class

Image builds a Docker image and pushes it Docker and OCI compatible registries. This resource enables running Docker builds as part of a Pulumi deployment.

Note: We recommend you migrate your images to the more modern Docker Build provider to get the best possible support, features, and performance.

Note: This resource does not delete tags, locally or remotely, when destroyed.

Image name

The Image resource uses imageName to refer to a fully qualified Docker image name, by the format repository:tag. Note that this does not include any digest information and thus will not cause any updates when passed to dependencies, even when using latest tag. To trigger such updates, e.g. when referencing pushed images in container orchestration and management resources, please use the repoDigest Output instead, which is of the format repository@<algorithm>:<hash> and unique per build/push. As of Docker v4.4, repoDigest is now available for local Images.

Cross-platform builds

The Image resource supports cross-platform builds when the Docker engine has cross-platform support enabled via emulators. The Image resource currently supports providing only a single operating system and architecture in the platform field, e.g.: linux/amd64. To enable this support, you may need to install the emulators in the environment running your Pulumi program.

If you are using Linux, you may be using Docker Engine or Docker Desktop for Linux, depending on how you have installed Docker. The FAQ for Docker Desktop for Linux describes the differences and how to select which Docker context is in use.

  • For local development using Docker Desktop, this is enabled by default.
  • For systems using Docker Engine, install the QEMU binaries and register them with using the docker image from github.com/tonistiigi/binfmt:
  docker run --privileged --rm tonistiigi/binfmt --install all
  • In a GitHub Actions workflow, the docker/setup-qemu-action can be used instead by adding this step to your workflow file. Example workflow usage:
  name: Pulumi
  on:
    push:
      branches:
        - master
  jobs:
    up:
      name: Preview
      runs-on: ubuntu-latest
      steps:
          # This is the step added:
        - name: Set up QEMU
          uses: docker/setup-qemu-action@v2
          # The ordinary pulumi/actions workflow:
        - uses: actions/checkout@v3
        - uses: pulumi/actions@v4
          with:
            command: preview
            stack-name: org-name/stack-name
          env:
            PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}

{{% examples %}}

Example Usage

{{% example %}}

A Docker image build

import * as pulumi from "@pulumi/pulumi";
import * as docker from "@pulumi/docker";

const demoImage = new docker.Image("demo-image", {
    build: {
        context: ".",
        dockerfile: "Dockerfile",
        platform: "linux/amd64",
    },
    imageName: "username/image:tag1",
    skipPush: true,
}, {
    version: "v4.4.0",
});
export const imageName = demoImage.imageName;
import pulumi
import pulumi_docker as docker

demo_image = docker.Image("demo-image",
    build={
        "context": ".",
        "dockerfile": "Dockerfile",
        "platform": "linux/amd64",
    },
    image_name="username/image:tag1",
    skip_push=True,
    opts = pulumi.ResourceOptions(version="v4.4.0"))
pulumi.export("imageName", demo_image.image_name)
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Docker = Pulumi.Docker;

return await Deployment.RunAsync(() =>
{
    var demoImage = new Docker.Image("demo-image", new()
    {
        Build = new Docker.Inputs.DockerBuildArgs
        {
            Context = ".",
            Dockerfile = "Dockerfile",
            Platform = "linux/amd64",
        },
        ImageName = "username/image:tag1",
        SkipPush = true,
    }, new CustomResourceOptions
    {
        Version = "v4.4.0",
    });

    return new Dictionary<string, object?>
    {
        ["imageName"] = demoImage.ImageName,
    };
});

package main

import (
	"github.com/pulumi/pulumi-docker/sdk/v4/go/docker"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		demoImage, err := docker.NewImage(ctx, "demo-image", &docker.ImageArgs{
			Build: &docker.DockerBuildArgs{
				Context:    pulumi.String("."),
				Dockerfile: pulumi.String("Dockerfile"),
				Platform:   pulumi.String("linux/amd64"),
			},
			ImageName: pulumi.String("username/image:tag1"),
			SkipPush:  pulumi.Bool(true),
		}, pulumi.Version("v4.4.0"))
		if err != nil {
			return err
		}
		ctx.Export("imageName", demoImage.ImageName)
		return nil
	})
}
config: {}
description: A Docker image build
name: image-yaml
outputs:
    imageName: ${demo-image.imageName}
resources:
    demo-image:
        options:
            version: v4.4.0
        properties:
            build:
                context: .
                dockerfile: Dockerfile
                platform: linux/amd64
            imageName: username/image:tag1
            skipPush: true
        type: docker:Image
runtime: yaml
variables: {}
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.docker.Image;
import com.pulumi.docker.ImageArgs;
import com.pulumi.docker.inputs.DockerBuildArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var demoImage = new Image("demoImage", ImageArgs.builder()
            .build(DockerBuildArgs.builder()
                .context(".")
                .dockerfile("Dockerfile")
                .platform("linux/amd64")
                .build())
            .imageName("username/image:tag1")
            .skipPush(true)
            .build(), CustomResourceOptions.builder()
                .version("v4.4.0")
                .build());

        ctx.export("imageName", demoImage.imageName());
    }
}

{{% /example %}} {{% example %}}

A Docker image build and push

import * as pulumi from "@pulumi/pulumi";
import * as docker from "@pulumi/docker";

const demoPushImage = new docker.Image("demo-push-image", {
    build: {
        context: ".",
        dockerfile: "Dockerfile",
    },
    imageName: "docker.io/username/push-image:tag1",
}, {
    version: "v4.4.0",
});
export const imageName = demoPushImage.imageName;
export const repoDigest = demoPushImage.repoDigest;
import pulumi
import pulumi_docker as docker

demo_push_image = docker.Image("demo-push-image",
    build={
        "context": ".",
        "dockerfile": "Dockerfile",
    },
    image_name="docker.io/username/push-image:tag1",
    opts = pulumi.ResourceOptions(version="v4.4.0"))
pulumi.export("imageName", demo_push_image.image_name)
pulumi.export("repoDigest", demo_push_image.repo_digest)
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Docker = Pulumi.Docker;

return await Deployment.RunAsync(() =>
{
    var demoPushImage = new Docker.Image("demo-push-image", new()
    {
        Build = new Docker.Inputs.DockerBuildArgs
        {
            Context = ".",
            Dockerfile = "Dockerfile",
        },
        ImageName = "docker.io/username/push-image:tag1",
    }, new CustomResourceOptions
    {
        Version = "v4.4.0",
    });

    return new Dictionary<string, object?>
    {
        ["imageName"] = demoPushImage.ImageName,
        ["repoDigest"] = demoPushImage.RepoDigest,
    };
});

package main

import (
	"github.com/pulumi/pulumi-docker/sdk/v4/go/docker"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		demoPushImage, err := docker.NewImage(ctx, "demo-push-image", &docker.ImageArgs{
			Build: &docker.DockerBuildArgs{
				Context:    pulumi.String("."),
				Dockerfile: pulumi.String("Dockerfile"),
			},
			ImageName: pulumi.String("docker.io/username/push-image:tag1"),
		}, pulumi.Version("v4.4.0"))
		if err != nil {
			return err
		}
		ctx.Export("imageName", demoPushImage.ImageName)
		ctx.Export("repoDigest", demoPushImage.RepoDigest)
		return nil
	})
}
config: {}
description: A Docker image build and push
name: image-push-yaml
outputs:
    imageName: ${demo-push-image.imageName}
    repoDigest: ${demo-push-image.repoDigest}
resources:
    demo-push-image:
        options:
            version: v4.4.0
        properties:
            build:
                context: .
                dockerfile: Dockerfile
            imageName: docker.io/username/push-image:tag1
        type: docker:Image
runtime: yaml
variables: {}
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.docker.Image;
import com.pulumi.docker.ImageArgs;
import com.pulumi.docker.inputs.DockerBuildArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var demoPushImage = new Image("demoPushImage", ImageArgs.builder()
            .build(DockerBuildArgs.builder()
                .context(".")
                .dockerfile("Dockerfile")
                .build())
            .imageName("docker.io/username/push-image:tag1")
            .build(), CustomResourceOptions.builder()
                .version("v4.4.0")
                .build());

        ctx.export("imageName", demoPushImage.imageName());
        ctx.export("repoDigest", demoPushImage.repoDigest());
    }
}

{{% /example %}} {{% example %}}

Docker image build using caching with AWS Elastic Container Registry

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as docker from "@pulumi/docker";

const ecrRepository = new aws.ecr.Repository("ecr-repository", {name: "docker-repository"});
const authToken = aws.ecr.getAuthorizationTokenOutput({
    registryId: ecrRepository.registryId,
});
const myAppImage = new docker.Image("my-app-image", {
    build: {
        args: {
            BUILDKIT_INLINE_CACHE: "1",
        },
        cacheFrom: {
            images: [pulumi.interpolate`${ecrRepository.repositoryUrl}:latest`],
        },
        context: "app/",
        dockerfile: "app/Dockerfile",
    },
    imageName: pulumi.interpolate`${ecrRepository.repositoryUrl}:latest`,
    registry: {
        password: pulumi.secret(authToken.password),
        server: ecrRepository.repositoryUrl,
        username: authToken.userName,
    },
}, {
    version: "v4.1.2",
});
export const imageName = myAppImage.imageName;
import pulumi
import pulumi_aws as aws
import pulumi_docker as docker

ecr_repository = aws.ecr.Repository("ecr-repository", name="docker-repository")
auth_token = aws.ecr.get_authorization_token_output(registry_id=ecr_repository.registry_id)
my_app_image = docker.Image("my-app-image",
    build={
        "args": {
            "BUILDKIT_INLINE_CACHE": "1",
        },
        "cache_from": {
            "images": [ecr_repository.repository_url.apply(lambda repository_url: f"{repository_url}:latest")],
        },
        "context": "app/",
        "dockerfile": "app/Dockerfile",
    },
    image_name=ecr_repository.repository_url.apply(lambda repository_url: f"{repository_url}:latest"),
    registry={
        "password": pulumi.Output.secret(auth_token.password),
        "server": ecr_repository.repository_url,
        "username": auth_token.user_name,
    },
    opts = pulumi.ResourceOptions(version="v4.1.2"))
pulumi.export("imageName", my_app_image.image_name)
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
using Docker = Pulumi.Docker;

return await Deployment.RunAsync(() =>
{
    var ecrRepository = new Aws.Ecr.Repository("ecr-repository", new()
    {
        Name = "docker-repository",
    });

    var authToken = Aws.Ecr.GetAuthorizationToken.Invoke(new()
    {
        RegistryId = ecrRepository.RegistryId,
    });

    var myAppImage = new Docker.Image("my-app-image", new()
    {
        Build = new Docker.Inputs.DockerBuildArgs
        {
            Args =
            {
                { "BUILDKIT_INLINE_CACHE", "1" },
            },
            CacheFrom = new Docker.Inputs.CacheFromArgs
            {
                Images = new[]
                {
                    ecrRepository.RepositoryUrl.Apply(repositoryUrl => $"{repositoryUrl}:latest"),
                },
            },
            Context = "app/",
            Dockerfile = "app/Dockerfile",
        },
        ImageName = ecrRepository.RepositoryUrl.Apply(repositoryUrl => $"{repositoryUrl}:latest"),
        Registry = new Docker.Inputs.RegistryArgs
        {
            Password = Output.CreateSecret(authToken.Apply(getAuthorizationTokenResult => getAuthorizationTokenResult.Password)),
            Server = ecrRepository.RepositoryUrl,
            Username = authToken.Apply(getAuthorizationTokenResult => getAuthorizationTokenResult.UserName),
        },
    }, new CustomResourceOptions
    {
        Version = "v4.1.2",
    });

    return new Dictionary<string, object?>
    {
        ["imageName"] = myAppImage.ImageName,
    };
});

package main

import (
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ecr"
	"github.com/pulumi/pulumi-docker/sdk/v4/go/docker"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		ecrRepository, err := ecr.NewRepository(ctx, "ecr-repository", &ecr.RepositoryArgs{
			Name: pulumi.String("docker-repository"),
		})
		if err != nil {
			return err
		}
		authToken := ecr.GetAuthorizationTokenOutput(ctx, ecr.GetAuthorizationTokenOutputArgs{
			RegistryId: ecrRepository.RegistryId,
		}, nil)
		myAppImage, err := docker.NewImage(ctx, "my-app-image", &docker.ImageArgs{
			Build: &docker.DockerBuildArgs{
				Args: pulumi.StringMap{
					"BUILDKIT_INLINE_CACHE": pulumi.String("1"),
				},
				CacheFrom: &docker.CacheFromArgs{
					Images: pulumi.StringArray{
						ecrRepository.RepositoryUrl.ApplyT(func(repositoryUrl string) (string, error) {
							return fmt.Sprintf("%v:latest", repositoryUrl), nil
						}).(pulumi.StringOutput),
					},
				},
				Context:    pulumi.String("app/"),
				Dockerfile: pulumi.String("app/Dockerfile"),
			},
			ImageName: ecrRepository.RepositoryUrl.ApplyT(func(repositoryUrl string) (string, error) {
				return fmt.Sprintf("%v:latest", repositoryUrl), nil
			}).(pulumi.StringOutput),
			Registry: &docker.RegistryArgs{
				Password: pulumi.ToSecret(authToken.Password()).(pulumi.StringPtrOutput),
				Server:   ecrRepository.RepositoryUrl,
				Username: authToken.UserName(),
			},
		}, pulumi.Version("v4.1.2"))
		if err != nil {
			return err
		}
		ctx.Export("imageName", myAppImage.ImageName)
		return nil
	})
}
config: {}
description: Docker image build using caching with AWS Elastic Container Registry
name: image-caching-yaml
outputs:
    imageName: ${my-app-image.imageName}
resources:
    ecr-repository:
        properties:
            name: docker-repository
        type: aws:ecr:Repository
    my-app-image:
        options:
            version: v4.1.2
        properties:
            build:
                args:
                    BUILDKIT_INLINE_CACHE: "1"
                cacheFrom:
                    images:
                        - ${ecr-repository.repositoryUrl}:latest
                context: app/
                dockerfile: app/Dockerfile
            imageName: ${ecr-repository.repositoryUrl}:latest
            registry:
                password:
                    fn::secret: ${authToken.password}
                server: ${ecr-repository.repositoryUrl}
                username: ${authToken.userName}
        type: docker:Image
runtime: yaml
variables:
    authToken:
        fn::aws:ecr:getAuthorizationToken:
            registryId: ${ecr-repository.registryId}
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ecr.Repository;
import com.pulumi.aws.ecr.RepositoryArgs;
import com.pulumi.aws.ecr.EcrFunctions;
import com.pulumi.aws.ecr.inputs.GetAuthorizationTokenArgs;
import com.pulumi.docker.Image;
import com.pulumi.docker.ImageArgs;
import com.pulumi.docker.inputs.DockerBuildArgs;
import com.pulumi.docker.inputs.CacheFromArgs;
import com.pulumi.docker.inputs.RegistryArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var ecrRepository = new Repository("ecrRepository", RepositoryArgs.builder()
            .name("docker-repository")
            .build());

        final var authToken = EcrFunctions.getAuthorizationToken(GetAuthorizationTokenArgs.builder()
            .registryId(ecrRepository.registryId())
            .build());

        var myAppImage = new Image("myAppImage", ImageArgs.builder()
            .build(DockerBuildArgs.builder()
                .args(Map.of("BUILDKIT_INLINE_CACHE", "1"))
                .cacheFrom(CacheFromArgs.builder()
                    .images(ecrRepository.repositoryUrl().applyValue(_repositoryUrl -> String.format("%s:latest", _repositoryUrl)))
                    .build())
                .context("app/")
                .dockerfile("app/Dockerfile")
                .build())
            .imageName(ecrRepository.repositoryUrl().applyValue(_repositoryUrl -> String.format("%s:latest", _repositoryUrl)))
            .registry(RegistryArgs.builder()
                .password(authToken.applyValue(_authToken -> _authToken.password()).asSecret())
                .server(ecrRepository.repositoryUrl())
                .username(authToken.applyValue(_authToken -> _authToken.userName()))
                .build())
            .build(), CustomResourceOptions.builder()
                .version("v4.1.2")
                .build());

        ctx.export("imageName", myAppImage.imageName());
    }
}

{{% /example %}} {{% /examples %}}

Constructors

Image(String name, {ImageArgs? args, CustomResourceOptions? options})
Creates a new Image. name The Pulumi resource name. args Arguments used to configure this Image. The set of arguments for Image. options Resource options controlling this resource's behavior.
Image.reference(String urn)
Creates a typed reference to an existing Image resource.

Properties

baseImageName ↔ Output<String>
The fully qualified image name that was pushed to the registry.
latefinal
childResources → Set<Resource>
finalinherited
completionSources ↔ Map<String, IOutputCompletionSource>
latefinalinherited
context ↔ Output<String>
The path to the build context to use.
latefinal
dockerfile ↔ Output<String>
The location of the Dockerfile relative to the docker build context.
latefinal
hashCode → int
The hash code for this object.
no setterinherited
id ↔ Output<String>
getter/setter pairinherited
imageName ↔ Output<String>
The fully qualified image name
latefinal
isCustom → bool
Returns whether this resource is provider-managed.
no setterinherited
isProtected → bool
Returns whether this resource is protected from deletion.
no setterinherited
isRemote → bool
Whether this resource is registered as remote.
no setterinherited
isResourceReference → bool
Whether this instance represents a resource value returned over RPC.
finalinherited
platform ↔ Output<String?>
The image's architecture and OS
latefinal
registryServer ↔ Output<String>
The name of the registry server hosting the image.
latefinal
repoDigest ↔ Output<String>
For pushed images: The manifest digest of an image pushed to a registry, of the format repository@<algorithm>:<hash>, e.g. username/demo-image@sha256:a6ae6dd8d39c5bb02320e41abf00cd4cb35905fec540e37d306c878be8d38bd3. This reference is unique per image build and push. Only available for images pushed to a registry. Use when passing a reference to a pushed image to container management resources.
latefinal
resourceTransforms → List<ResourceTransform>
Inherited/explicit async transforms.
no setterinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
transformations → List<ResourceTransformation>
Inherited/explicit legacy transformations.
no setterinherited
urn ↔ Output<String>
latefinalinherited

Methods

failId(Object error) → void
Completes this resource ID with an error when registration fails.
inherited
failOutputs(Object error) → void
Completes all output properties with error.
inherited
failUrn(Object error) → void
Completes this resource URN with an error when registration fails.
inherited
getProvider(String moduleMember) → ProviderResource?
Returns provider for moduleMember's package, if configured.
inherited
getResourceName() → String
Returns this resource's logical name.
inherited
getResourceType() → String
Returns this resource's Pulumi type token.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
registerOutput<T>(String propertyName, {Object? decoder(Object?)?, bool isSecret = false}) → Output<T>
Registers a dynamic output property for this resource.
inherited
resolveId(String? value, {required bool isKnown}) → void
Resolves the provider-assigned ID for this resource.
inherited
resolveOutputs(Struct outputs) → void
Resolves all output properties from a monitor response payload.
inherited
resolveUrn(String value) → void
Resolves this resource's URN once assigned by the engine.
inherited
serializeProperties(Map<String, dynamic> properties) → Future<Struct>
Serializes resource properties for RPC transmission.
inherited
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited