Ricardo Rosales Vishnubhatla
12/16/2025, 5:54 AMMarvin
12/16/2025, 5:54 AMMarvin
12/16/2025, 5:57 AMdocker buildx build --platform linux/amd64 -t us-central1-docker.pkg.dev/<project>/<repo>/<name>:latest --push .
- Prefect 3.x deployment via code (recommended)
from prefect import flow
from prefect.docker import DockerImage
@flow(log_prints=True)
def my_flow():
print("Hello from Cloud Run!")
if __name__ == "__main__":
my_flow.deploy(
name="my-deployment",
work_pool_name="my-cloud-run-pool",
image=DockerImage(
name="us-central1-docker.pkg.dev/<project>/<repo>/<name>:latest",
platform="linux/amd64", # critical for Apple Silicon -> Cloud Run
),
)
- prefect.yaml build step (if you’re using build steps)
build:
- prefect_docker.deployments.steps.build_docker_image:
id: build-image
requires: prefect-docker
image_name: us-central1-docker.pkg.dev/<project>/<repo>/<name>
tag: latest
dockerfile: Dockerfile
platform: linux/amd64
- Verify the image architecture before deploying:
docker buildx imagetools inspect us-central1-docker.pkg.dev/<project>/<repo>/<name>:latest
# or
docker inspect us-central1-docker.pkg.dev/<project>/<repo>/<name>:latest | grep -i architecture
# Expect: amd64
Notes
- Prefect’s official images (e.g., prefecthq/prefect:3-latest) are multi-arch; using them as a base is fine, but you still need to build/push an amd64 manifest for Cloud Run.
- Building amd64 on Apple Silicon can be slower due to emulation; many teams offload the build to CI (GitHub Actions with buildx) to produce multi-arch or explicit amd64 images.
- In Prefect 3.x, avoid older 2.x deployment patterns; specifying DockerImage(..., platform="linux/amd64") or the platform field in the docker build step is the supported path.
If you’re still seeing issues, can you share:
- The exact error/log from Cloud Run or the Prefect worker
- Your Dockerfile
- How you’re creating the deployment (code or prefect.yaml)
- Your work pool type and base job template
With those, I can pinpoint the failure quickly.Ricardo Rosales Vishnubhatla
12/16/2025, 6:01 AMprefect work-pool create --type cloud-run:push --provision-infra gcr-pool
successfully.
my deployment code is as follows:
from prefect import flow
from prefect.docker import DockerImage
@flow(log_prints=True)
def my_flow(name: str = "world"):
print(f"Hello {name}! I'm a flow running on Cloud Run!")
if __name__ == "__main__":
my_flow.deploy(
name="my-deployment",
work_pool_name="gcr-pool",
image=DockerImage(
name="my-image:latest",
platform="linux/amd64",
),
)Ricardo Rosales Vishnubhatla
12/16/2025, 6:03 AMprefect work-pool create --type cloud-run:push --provision-infra gcr-pool
successfully.
my deployment code is as follows:
from prefect import flow
from prefect.docker import DockerImage
@flow(log_prints=True)
def my_flow(name: str = "world"):
print(f"Hello {name}! I'm a flow running on Cloud Run!")
if __name__ == "__main__":
my_flow.deploy(
name="my-deployment",
work_pool_name="gcr-pool",
image=DockerImage(
name="my-image:latest",
platform="linux/amd64",
),
)Marvin
12/16/2025, 6:03 AMMarvin
12/16/2025, 6:09 AMprefect work-pool create --type cloud-run:push --provision-infra gcr-pool
here’s a step-by-step to get your deployment built, pushed, and running from your M4 Mac. This assumes Prefect 3.x and push-based Cloud Run (no worker needed).
Step 1) Confirm pool details
- Inspect the pool to see the project, region, and the Artifact Registry repo Prefect created:
prefect work-pool inspect gcr-pool
Note the region (e.g., us-central1) and repo name. You’ll need them for your image name.
Step 2) Authenticate Docker to Artifact Registry
- Set your active GCP project:
gcloud config set project <YOUR_PROJECT_ID>
- Configure Docker to push to Artifact Registry in your region:
gcloud auth configure-docker <REGION>-docker.pkg.dev
Example: gcloud auth configure-docker us-central1-docker.pkg.dev
Step 3) Choose a fully-qualified image name
- For Cloud Run, your image must live in Artifact Registry. Replace your current my-image:latest with the fully-qualified path:
<REGION>-docker.pkg.dev/<PROJECT_ID>/<REPO>/<IMAGE_NAME>:latest
Example:
us-central1-docker.pkg.dev/my-project/prefect-flows/my-flow:latest
Step 4) Ensure you build for linux/amd64 on your M4 Mac
- Your code is already using platform="linux/amd64" which is exactly right for Cloud Run.
- Update your deploy script to use the fully-qualified image name:
from prefect import flow
from prefect.docker import DockerImage
@flow(log_prints=True)
def my_flow(name: str = "world"):
print(f"Hello {name}! I'm a flow running on Cloud Run!")
if __name__ == "__main__":
my_flow.deploy(
name="my-deployment",
work_pool_name="gcr-pool",
image=DockerImage(
name="us-central1-docker.pkg.dev/<PROJECT_ID>/<REPO>/<IMAGE_NAME>:latest",
platform="linux/amd64",
),
)
Notes:
- If you have a Dockerfile in your project root, Prefect will pick it up automatically (dockerfile="auto"). If not, consider adding one to control deps.
- Docker Desktop on Apple Silicon supports buildx; Prefect will pass the platform through to the build so it emits an amd64 image.
Step 5) Run the deployment (build + push)
- From your project directory:
python path/to/your_deploy_script.py
- This will:
- Build your image for linux/amd64
- Push to Artifact Registry
- Create/update the Prefect deployment
Optional: verify the pushed image architecture
docker buildx imagetools inspect us-central1-docker.pkg.dev/<PROJECT_ID>/<REPO>/<IMAGE_NAME>:latest
# Expect to see: linux/amd64
Step 6) Trigger a run (push pool = no worker needed)
- From CLI:
prefect deployment run "my_flow/my-deployment" --watch
or kick it off from the Prefect UI. The run should submit directly to Cloud Run.
Common pitfalls to avoid
- Local-only image name: Use a fully-qualified Artifact Registry path; otherwise Cloud Run won’t be able to pull it.
- Wrong architecture: Always keep platform="linux/amd64" on Apple Silicon for Cloud Run.
- Artifact Registry auth: If you see image pull permission errors in Cloud Run, re-run:
gcloud auth configure-docker <REGION>-docker.pkg.dev
and ensure the service account created by provisioning has permission to pull from the repo (the provisioner typically handles this).
If you’d like, paste:
- The prefect work-pool inspect gcr-pool output (redact sensitive bits)
- Your intended Artifact Registry image URL
- Any build or Cloud Run error messages
I’ll tailor exact fixes from there.Marvin
12/16/2025, 6:19 AMMarvin
12/16/2025, 6:24 AMfailed to export image: NotFound: content digest sha256:... not found
is very often caused by a base image/tag that does not exist for the platform you’re building. From your stack trace I also see Python 3.14 on your host. Prefect’s “auto” Dockerfile tries to match your local Python version; if it generates a base like FROM python:3.14-slim, that tag likely doesn’t exist yet (especially for linux/amd64) and you’ll see a “digest not found”/manifest-not-found style error during export.
Below is a step-by-step path to get you running on Cloud Run from your M4 Mac.
Step 0) Use a fully qualified image in Artifact Registry
Replace my-image:latest with your Artifact Registry path:
<REGION>-docker.pkg.dev/<PROJECT_ID>/<REPO>/<IMAGE_NAME>:latest
Example:
us-central1-docker.pkg.dev/my-project/prefect-flows/my-flow:latest
Step 1) Auth Docker to Artifact Registry
gcloud config set project <YOUR_PROJECT_ID>
gcloud auth configure-docker <REGION>-docker.pkg.dev
Step 2) Add a Dockerfile with a known-good base and amd64 support
Avoid the “auto” Dockerfile (which may choose python:3.14-slim). Pin to a version that exists, e.g. Python 3.12 or the Prefect image for 3.12.
Option A: Use Prefect’s base image
# Dockerfile
FROM prefecthq/prefect:3-python3.12
WORKDIR /app
COPY . /app
# If you have dependencies:
# RUN pip install -U pip && pip install -r requirements.txt
Option B: Use Python base + install Prefect
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
RUN pip install -U pip setuptools wheel \
&& pip install "prefect>=3" "prefect-gcp"
COPY . /app
# If you have a requirements.txt, install it instead of the simple line above
Step 3) Update your deploy code
Point the DockerImage at your Artifact Registry image and your Dockerfile, and keep `platform="linux/amd64"`:
from prefect import flow
from prefect.docker import DockerImage
@flow(log_prints=True)
def my_flow(name: str = "world"):
print(f"Hello {name}! I'm a flow running on Cloud Run!")
if __name__ == "__main__":
my_flow.deploy(
name="my-deployment",
work_pool_name="gcr-pool",
image=DockerImage(
name="us-central1-docker.pkg.dev/<PROJECT_ID>/<REPO>/<IMAGE_NAME>:latest",
dockerfile="Dockerfile",
platform="linux/amd64",
),
)
Step 4) Try the deploy again
python deploy.py
This will build for linux/amd64, push to Artifact Registry, and register the deployment.
If the build still errors on your Mac: pre-build and skip build in deploy
On Apple Silicon, using Docker CLI buildx is often the most robust path.
1) Build and push with buildx:
docker buildx build \
--platform linux/amd64 \
-t us-central1-docker.pkg.dev/<PROJECT_ID>/<REPO>/<IMAGE_NAME>:latest \
--push .
2) Verify the manifest includes amd64:
docker buildx imagetools inspect us-central1-docker.pkg.dev/<PROJECT_ID>/<REPO>/<IMAGE_NAME>:latest
3) Deploy using the already-built image (skip Prefect build/push):
from prefect import flow
@flow
def my_flow():
print("Hello from Cloud Run!")
if __name__ == "__main__":
my_flow.deploy(
name="my-deployment",
work_pool_name="gcr-pool",
image="us-central1-docker.pkg.dev/<PROJECT_ID>/<REPO>/<IMAGE_NAME>:latest",
build=False, # skip Docker build
push=False, # skip Docker push
)
Step 5) Trigger a run
prefect deployment run "my_flow/my-deployment" --watch
Why this likely fixes your error
- You’re on Python 3.14 locally. Prefect’s auto Dockerfile probably tried FROM python:3.14-slim (or similar) which doesn’t exist for linux/amd64, leading to the “digest not found” error.
- Providing a Dockerfile pinned to a known-good base (e.g., python:3.12-slim or prefecthq/prefect:3-python3.12) avoids that missing manifest.Marvin
12/16/2025, 6:24 AMlinux/amd64 is required for Cloud Run, and using buildx on Apple Silicon is the most reliable way to cross-build.
If this doesn’t resolve it, please share:
- Your Dockerfile (if any)
- Your exact image name and region
- Output of docker buildx imagetools inspect <your-image>
- The full build log lines above the “content digest not found” error
I’ll pinpoint the next fix quickly.