Problem
azd core does not provide a service target with a way to declare that a configured container image must be passed directly to the target without running the core image lifecycle.
For a service with a top-level image, core currently selects the Docker framework. When no local build artifact exists, the framework package phase treats the configured image as an external source image and performs local image processing:
The image may subsequently be copied or published to another registry.
This processing happens before the service target package phase:
framework service Build
framework service Package
service target Package
service target Publish
service target Deploy
As a result, a service target cannot prevent core from pulling and tagging an image that the target intends to deploy directly by reference.
Required scenarios
Some service targets do not own the image build or publish lifecycle. They pass an existing image reference to a destination platform, and that platform pulls the image using its own identity or registry connection.
One example is BYO ACR support in the azure.ai.agents extension:
services:
hosted-agent:
host: azure.ai.agent
image: customer.azurecr.io/agents/hosted-agent:1.0
registryConnectionId: customer-acr-connection
kind: hosted
name: hosted-agent
In this scenario:
- the image is already built and published;
- azd should not copy it into another registry;
- Foundry pulls the image directly;
- registry authentication belongs to Foundry and its project connection;
- the local Docker client may not have access to the registry;
- Docker or Podman should not be required.
The same requirement applies to other extension targets that deploy an existing image by reference and delegate image retrieval to the destination platform.
Current behavior
Without another Docker setting, azd deploy reaches the core framework package phase and attempts to pull the private image locally:
Packaging
Pulling container source image
ERROR: pulling source container image:
Error response from daemon:
Head "https://customer.azurecr.io/v2/.../manifests/1.0":
Authentication is required
The extension service target has not run its package operation at this point, so it cannot classify the image as a deployment-by-reference artifact before the pull occurs.
This behavior may be masked when the local Docker client happens to have cached registry credentials. In that case, azd still performs an unnecessary pull and tag.
Current azure.ai.agents workaround
The azure.ai.agents extension currently relies on:
docker:
remoteBuild: true
to suppress the core local Build and Package operations.
The extension then:
- classifies the configured image as prebuilt;
- creates a remote container artifact for the original image;
- skips extension Publish;
- sends the image reference directly to Foundry.
Because extension Publish is skipped, the ACR Tasks build associated with remoteBuild does not run.
This is an accidental and semantically incorrect use of remoteBuild.
docker.remoteBuild means that azd should build and push a new image using ACR Tasks. It does not mean that an existing image should bypass pull, tag, copy, and publish.
The workaround is problematic because:
- generated configuration misrepresents the intended lifecycle;
- users may reasonably expect an ACR Tasks build;
- telemetry and diagnostics identify the service as a remote-build service;
- a change in package or publish selection could unexpectedly invoke ACR Tasks;
- remote-build fallback behavior may invoke the local container lifecycle;
- hand-authored declarative configurations do not inherit the workaround automatically.
Expected core capability
Core needs an explicit service-level signal, separate from docker.remoteBuild, for the following lifecycle:
- use the configured top-level
image as the final remote image reference;
- do not require Docker or Podman;
- do not build the image;
- do not pull the image;
- do not tag the image;
- do not authenticate to its registry;
- do not copy or publish the image;
- pass the unchanged image reference to the service target.
The existing behavior must remain the default for Container Apps, AKS, App Service, and other scenarios that intentionally pull and copy an external source image into a deployment registry.
Related work
This problem was confirmed while implementing and testing:
The E2E covered both an existing BYO registry connection and a declaratively provisioned registry connection. Foundry successfully pulled and ran the private image using its own connection once the core local image lifecycle was bypassed.
Problem
azd core does not provide a service target with a way to declare that a configured container image must be passed directly to the target without running the core image lifecycle.
For a service with a top-level
image, core currently selects the Docker framework. When no local build artifact exists, the framework package phase treats the configured image as an external source image and performs local image processing:The image may subsequently be copied or published to another registry.
This processing happens before the service target package phase:
As a result, a service target cannot prevent core from pulling and tagging an image that the target intends to deploy directly by reference.
Required scenarios
Some service targets do not own the image build or publish lifecycle. They pass an existing image reference to a destination platform, and that platform pulls the image using its own identity or registry connection.
One example is BYO ACR support in the
azure.ai.agentsextension:In this scenario:
The same requirement applies to other extension targets that deploy an existing image by reference and delegate image retrieval to the destination platform.
Current behavior
Without another Docker setting,
azd deployreaches the core framework package phase and attempts to pull the private image locally:The extension service target has not run its package operation at this point, so it cannot classify the image as a deployment-by-reference artifact before the pull occurs.
This behavior may be masked when the local Docker client happens to have cached registry credentials. In that case, azd still performs an unnecessary pull and tag.
Current
azure.ai.agentsworkaroundThe
azure.ai.agentsextension currently relies on:to suppress the core local Build and Package operations.
The extension then:
Because extension Publish is skipped, the ACR Tasks build associated with
remoteBuilddoes not run.This is an accidental and semantically incorrect use of
remoteBuild.docker.remoteBuildmeans that azd should build and push a new image using ACR Tasks. It does not mean that an existing image should bypass pull, tag, copy, and publish.The workaround is problematic because:
Expected core capability
Core needs an explicit service-level signal, separate from
docker.remoteBuild, for the following lifecycle:imageas the final remote image reference;The existing behavior must remain the default for Container Apps, AKS, App Service, and other scenarios that intentionally pull and copy an external source image into a deployment registry.
Related work
This problem was confirmed while implementing and testing:
The E2E covered both an existing BYO registry connection and a declaratively provisioned registry connection. Foundry successfully pulled and ran the private image using its own connection once the core local image lifecycle was bypassed.