Skip to content

Conversation

@adunne09
Copy link

@adunne09 adunne09 commented Nov 1, 2025

Summary

  • Adds support for using prebuilt Docker images in Cloudflare Container resource
  • Enables image promotion workflows across environments
  • Automatically pulls and pushes external images to Cloudflare registry

Changes

  • Added image property to ContainerProps (mutually exclusive with build)
  • Supports string image references, RemoteImage resources, and Image resources
  • External images are automatically pulled and pushed to Cloudflare's registry since CF Containers only support registry.cloudflare.com
  • Added validation to ensure either image or build is specified (but not both)
  • Updated documentation with usage examples for prebuilt images

Testing

Added 5 new tests covering:

  • Using prebuilt Cloudflare registry images
  • Pulling and pushing external images
  • Using RemoteImage resources
  • Error handling for invalid configurations

Closes #1109

@adunne09 adunne09 force-pushed the alex/support-prebuilt-cloudflare-images branch from fc3a0d1 to 473c416 Compare November 1, 2025 23:03
@sam-goodwin
Copy link
Collaborator

@john-royal can you take a look at this?

Copy link
Collaborator

@john-royal john-royal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments - happy to merge as-is but want to be sure the approach is correct.

/**
* Use a prebuilt image instead of building one.
* Can be a string (image reference), RemoteImage resource, or Image resource.
* Mutually exclusive with `build` property.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is mutually exclusive with build, should we use a union type so you can't accidentally provide both?

Copy link
Author

@adunne09 adunne09 Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opted with the runtime error at L316

tag,
build: props.build,
});
// In local dev mode, always build if build config is provided
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What motivated this when build and image are meant to be mutually exclusive? Does it have to do with the build platform potentially being different?

Copy link
Author

@adunne09 adunne09 Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in d6d8ea7

Comment on lines +369 to +402
if (isCloudflareRegistryLink(imageRef)) {
// Already in CF registry, create a lightweight Image reference
const imageName = extractNameFromImageRef(imageRef);
const imageTag = imageRef.includes(":")
? imageRef.split(":").pop()!.split("@")[0]
: "latest";

image = {
name: imageName,
tag: imageTag,
imageRef: imageRef,
repoDigest: imageRef.includes("@") ? imageRef : undefined,
builtAt: Date.now(),
};
} else {
// External image - automatically push to CF registry
// Cloudflare Containers currently only support images from registry.cloudflare.com
image = await retagAndPushToCloudflare(imageRef, name, tag, api);
}
} else {
// It's an Image or RemoteImage resource
const sourceImage = props.image as Image | RemoteImage;
const sourceImageRef = sourceImage.imageRef;

// Check if it's already in CF registry
if (isCloudflareRegistryLink(sourceImageRef)) {
// Already in CF registry, use as-is
image = sourceImage as Image;
} else {
// Not in CF registry - automatically push to CF registry
// Cloudflare Containers currently only support images from registry.cloudflare.com
image = await retagAndPushToCloudflare(sourceImageRef, name, tag, api);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use the RemoteImage resource here?

Copy link
Author

@adunne09 adunne09 Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my intent was to maintain the previous Image declaration from L235-

const image = await Image(id, {
    name: `${api.accountId}/${name}`,
    tag,
    build: {
      platform: props.build?.platform ?? "linux/amd64",
      ...props.build,
    },
    registry: {
      server: "registry.cloudflare.com",
      username: credentials.username || credentials.user!,
      password: secret(credentials.password),
    },
  });

what would be the advantage of changing to RemoteImage ? I'm not sure what you mean

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cloudflare Containers: support prebuilt/static images (skip rebuilds)

3 participants