Bryan
02/14/2026, 12:03 AMRun PrefectHQ/actions-prefect-deploy@v4
Run astral-sh/setup-uv@v7
Successfully installed uv version 0.10.2
Run uv venv --clear
Downloading cpython-3.14.3-linux-x86_64-gnu (download) (34.3MiB)
Downloaded cpython-3.14.3-linux-x86_64-gnu (download)
Using CPython 3.14.3
Creating virtual environment at: .venv
Activate with: .venv/bin/activate
Run uv pip install prefect -U "prefect>=3,<4"
Resolved 104 packages in 499ms
Prepared 104 packages in 914ms
Installed 104 packages in 121ms
Downloaded prefect
Downloaded uv
Uninstalled 9 packages in 22ms
Installed 14 packages in 34ms
/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/_internal/pydantic/v1_schema.py:6: UserWarning: Core Pydantic V1 functionality isn't compatible with Python 3.14 or greater.
from pydantic.v1 import BaseModel as V1BaseModel
/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/pydantic_settings/main.py:426: UserWarning: Config key `pyproject_toml_table_header` is set in model_config but will be ignored because no PyprojectTomlConfigSettingsSource source is configured. To use this config key, add a PyprojectTomlConfigSettingsSource source to the settings sources via the settings_customise_sources hook.
self._settings_warn_unused_config_keys(sources, self.model_config)
/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/pydantic_settings/main.py:426: UserWarning: Config key `toml_file` is set in model_config but will be ignored because no TomlConfigSettingsSource source is configured. To use this config key, add a TomlConfigSettingsSource source to the settings sources via the settings_customise_sources hook.
self._settings_warn_unused_config_keys(sources, self.model_config)
/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/pydantic/_internal/_generate_schema.py:2249: UnsupportedFieldAttributeWarning: The 'default' attribute with value 'UTC' was provided to the `Field()` function, which has no effect in the context it was used. 'default' is field-specific metadata, and can only be attached to a model field using `Annotated` metadata or by assignment. This may have happened because an `Annotated` type alias using the `type` statement was used, or if the `Field()` function was attached to a single member of a union type.
warnings.warn(
Running deployment build steps...
> Running run_shell_script step...
> Running run_shell_script step...
> Running run_shell_script step...
> Running build_docker_image step...
/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/bin/python3: No module named pip
23:43:09.240 | WARNING | prefect.deployments.steps.core - Unable to install required packages for prefect_docker.deployments.steps.build_docker_image
Traceback (most recent call last):
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/deployments/steps/core.py", line 163, in run_steps
step_output = await run_step(step, upstream_outputs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Unable to load step function: prefect_docker.deployments.steps.build_docker_image. Attempting install of prefect-docker>=0.6.0.
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/deployments/steps/core.py", line 133, in run_step
step_func = _get_function_for_step(fqn, requires=keywords.get("requires"))
An exception occurred.
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/deployments/steps/core.py", line 98, in _get_function_for_step
step_func = import_object(fully_qualified_name)
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/utilities/importtools.py", line 164, in import_object
module = load_module(module_name)
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/utilities/importtools.py", line 135, in load_module
return importlib.import_module(module_name)
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
File "/home/runner/work/_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/importlib/__init__.py", line 88, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1398, in _gcd_import
File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
File "<frozen importlib._bootstrap>", line 1314, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1398, in _gcd_import
File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
File "<frozen importlib._bootstrap>", line 1314, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1398, in _gcd_import
File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
File "<frozen importlib._bootstrap>", line 1335, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'prefect_docker'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/cli/_utilities.py", line 44, in wrapper
return fn(*args, **kwargs)
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/cli/_types.py", line 155, in sync_fn
return asyncio.run(async_fn(*args, **kwargs))
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/asyncio/runners.py", line 204, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File "/home/runner/work/_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/asyncio/runners.py", line 127, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/home/runner/work/_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/asyncio/base_events.py", line 719, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/cli/deploy.py", line 501, in deploy
await _run_single_deploy(
...<4 lines>...
)
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/cli/deploy.py", line 717, in _run_single_deploy
await run_steps(build_steps, step_outputs, print_function=app.console.print)
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/deployments/steps/core.py", line 191, in run_steps
raise StepExecutionError(f"Encountered error while running {fqn}") from exc
prefect.deployments.steps.core.StepExecutionError: Encountered error while running prefect_docker.deployments.steps.build_docker_image
Error: Process completed with exit code 1.
This is the prefect.yaml:
# Generic metadata about this project
name: prefect_project_template # TODO: Set the name of your project
prefect-version: 3.2.15
# build section allows you to manage and build docker images
build:
# push section allows you to manage if and how this project is uploaded to remote locations
push:
# Push the docker image to the registry
- prefect_docker.deployments.steps.push_docker_image:
requires: prefect-docker
image_name: "{{ build-image.image_name }}"
tag: "{{ build-image.tag }}"
pull:
# Definitions to be used as templates elsewhere in the yaml file
definitions:
docker_build:
- prefect_docker.deployments.steps.build_docker_image: &docker_build_config
id: build-image
requires: prefect-docker>=0.6.0
image_name: ""
tag: ""
dockerfile: Dockerfile
platform: "linux/amd64"
git_clone:
- prefect.deployments.steps.git_clone: &git_clone
id: clone-step
repository: ""
branch: ""
credentials: "{{ prefect.blocks.github-credentials.some-github-creds }}"
default_pull: &default_pull
- prefect.deployments.steps.git_clone:
<<: *git_clone
repository: "{{ get-git-repo-url.stdout }}"
branch: "{{ get-git-repo-branch.stdout }}"
default_build: &default_build
- prefect.deployments.steps.run_shell_script:
id: get-github-token
script: echo $SOME_GITHUB_TOKEN
stream_output: false
expand_env_vars: true
# Get the current Git repo URL from an environment variable that is set in the GitHub Action
- prefect.deployments.steps.run_shell_script:
id: get-git-repo-url
script: echo $SOME_GIT_REPO_URL
stream_output: false
expand_env_vars: true
# Go get the current repo name from an environment variable that is set in the GitHub Action
- prefect.deployments.steps.run_shell_script:
id: get-git-repo-name
script: echo $GIT_REPO_NAME
stream_output: false
expand_env_vars: true
# Go get the current repo branch name from an environment variable that is set in the GitHub Action
- prefect.deployments.steps.run_shell_script:
id: get-git-repo-branch
script: echo $SOME_GIT_REPO_BRANCH
stream_output: false
expand_env_vars: true
# Go get the current ECR repo from an environment variable that is set in the GitHub Action
- prefect.deployments.steps.run_shell_script:
id: get-ecr-repo-name
script: echo $SOME_ECR_REPO_NAME
stream_output: false
expand_env_vars: true
# Build the docker image based on the repo name retreived in the previous step
# This step is using a template "docker_build_config" from the definitions section
# of this file and overriding the image_name and tag attributes
- prefect_docker.deployments.steps.build_docker_image:
<<: *docker_build_config
image_name: "{{ get-ecr-repo-name.stdout }}"
tag: "{{ get-git-repo-branch.stdout }}"
buildargs:
GITHUB_TOKEN: "{{ get-github-token.stdout }}"
OS_ENV: "{{ get-git-repo-branch.stdout }}"
# Start of Deployment definitions
deployments:
# Dev deployment definition
# NOTE: If you are not deploying to dev, you can remove this section
- name: "dev-{{ get-git-repo-name.stdout }}-entrypoint"
version:
tags: ["environment:{{ get-git-repo-branch.stdout }}"]
if: '{{ get-git-repo-branch.stdout }} == "dev"'
description: "Your Deployment description" # TODO: Set the appropriate description for this deployment
schedules: # TODO: Set the appropriate schedule for this deployment
- cron: "0 1 * * *"
timezone: "America/Los_Angeles"
active: false # TODO: Is this schedule going to be active upon deployment?
entrypoint: "main.py:entrypoint"
parameters: {}
pull:
*default_pull
build:
*default_build
work_pool:
name: aws_development_account
work_queue_name:
job_variables:
image: "{{ build-image.image }}"Marvin
02/14/2026, 12:03 AMpyproject_toml_table_header is set in model_config but will be ignored because no PyprojectTomlConfigSettingsSource source is configured To use this config key add a PyprojectTomlConfigSettingsSource source to the settings sources via the settings_customise_sources hook self _settings_warn_unused_config_keys(sources self model_config) /home/runner/work/dw_prefect_project_template/dw_prefect_project_template/ venv/lib/python3 14/site-packages/pydantic_settings/main py 426 UserWarning Config key toml_file is set in model_config but will be ignored because no TomlConfigSettingsSource source is configured To use this config key add a TomlConfigSettingsSource source to the settings sources via the settings_customise_sources hook self _settings_warn_unused_config_keys(sources self model_config) /home/runner/work/dw_prefect_project_template/dw_prefect_project_template/ venv/lib/python3 14/site-packages/pydantic/_internal/_generate_schema py 2249 UnsupportedFieldAttributeWarning The 'default' attribute with value 'UTC' was provided to the Field() function which has no effect in the context it was used 'default' is field-specific metadata and can only be attached to a model field using Annotated metadata or by assignment This may have happened because an Annotated type alias using the type statement was used or if the Field() function was attached to a single member of a union type warnings warn( Running deployment build steps > Running run_shell_script step > Running run_shell_script step > Running run_shell_script step > Running build_docker_image step /home/runner/work/dw_prefect_project_template/dw_prefect_project_template/ venv/bin/python3 No module named pip 23 43 09 240 | WARNING | prefect deployments steps core - Unable to install required packages for prefect_docker deployments steps build_docker_image Traceback (most recent call last) File /home/runner/work/dw_prefect_project_template/dw_prefect_project_template/ venv/lib/python3 14/site-packages/prefect/deployments/steps/core py line 163 in run_steps step_output = await run_step(step upstream_outputs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unable to load step function prefect_docker deployments steps build_docker_image Attempting install of prefect-docker>=0 6 0 File /home/runner/work/dw_prefect_project_template/dw_prefect_project_template/ venv/lib/python3 14/site-packages/prefect/deployments/steps/core py line 133 in run_step step_func = _get_function_for_step(fqn requires=keywords get( requires )) An exception occurred File /home/runner/work/dw_prefect_project_template/dw_prefect_project_template/ venv/liMarvin
02/14/2026, 12:03 AMBryan
02/14/2026, 12:05 AM# Generic metadata about this project
name: prefect_project_template # TODO: Set the name of your project
prefect-version: 3.2.15
# build section allows you to manage and build docker images
build:
# push section allows you to manage if and how this project is uploaded to remote locations
push:
# Push the docker image to the registry
- prefect_docker.deployments.steps.push_docker_image:
requires: prefect-docker
image_name: "{{ build-image.image_name }}"
tag: "{{ build-image.tag }}"
pull:
# Definitions to be used as templates elsewhere in the yaml file
definitions:
docker_build:
- prefect_docker.deployments.steps.build_docker_image: &docker_build_config
id: build-image
requires: prefect-docker>=0.6.0
image_name: ""
tag: ""
dockerfile: Dockerfile
platform: "linux/amd64"
git_clone:
- prefect.deployments.steps.git_clone: &git_clone
id: clone-step
repository: ""
branch: ""
credentials: "{{ prefect.blocks.github-credentials.some-github-creds }}"
default_pull: &default_pull
- prefect.deployments.steps.git_clone:
<<: *git_clone
repository: "{{ get-git-repo-url.stdout }}"
branch: "{{ get-git-repo-branch.stdout }}"
default_build: &default_build
- prefect.deployments.steps.run_shell_script:
id: get-github-token
script: echo $SOME_GITHUB_TOKEN
stream_output: false
expand_env_vars: true
# Get the current Git repo URL from an environment variable that is set in the GitHub Action
- prefect.deployments.steps.run_shell_script:
id: get-git-repo-url
script: echo $SOME_GIT_REPO_URL
stream_output: false
expand_env_vars: true
# Go get the current repo name from an environment variable that is set in the GitHub Action
- prefect.deployments.steps.run_shell_script:
id: get-git-repo-name
script: echo $GIT_REPO_NAME
stream_output: false
expand_env_vars: true
# Go get the current repo branch name from an environment variable that is set in the GitHub Action
- prefect.deployments.steps.run_shell_script:
id: get-git-repo-branch
script: echo $SOME_GIT_REPO_BRANCH
stream_output: false
expand_env_vars: true
# Go get the current ECR repo from an environment variable that is set in the GitHub Action
- prefect.deployments.steps.run_shell_script:
id: get-ecr-repo-name
script: echo $SOME_ECR_REPO_NAME
stream_output: false
expand_env_vars: true
# Build the docker image based on the repo name retreived in the previous step
# This step is using a template "docker_build_config" from the definitions section
# of this file and overriding the image_name and tag attributes
- prefect_docker.deployments.steps.build_docker_image:
<<: *docker_build_config
image_name: "{{ get-ecr-repo-name.stdout }}"
tag: "{{ get-git-repo-branch.stdout }}"
buildargs:
GITHUB_TOKEN: "{{ get-github-token.stdout }}"
OS_ENV: "{{ get-git-repo-branch.stdout }}"
# Start of Deployment definitions
deployments:
# Dev deployment definition
# NOTE: If you are not deploying to dev, you can remove this section
- name: "dev-{{ get-git-repo-name.stdout }}-entrypoint"
version:
tags: ["environment:{{ get-git-repo-branch.stdout }}"]
if: '{{ get-git-repo-branch.stdout }} == "dev"'
description: "Your Deployment description" # TODO: Set the appropriate description for this deployment
schedules: # TODO: Set the appropriate schedule for this deployment
- cron: "0 1 * * *"
timezone: "America/Los_Angeles"
active: false # TODO: Is this schedule going to be active upon deployment?
entrypoint: "main.py:entrypoint"
parameters: {}
pull:
*default_pull
build:
*default_build
work_pool:
name: aws_development_account
work_queue_name:
job_variables:
image: "{{ build-image.image }}"Marvin
02/14/2026, 12:05 AMMarvin
02/14/2026, 12:09 AM&name and <<: (not & or <<:), otherwise the file won’t parse.
- Step IDs and templating look good. With id: build-image, you can reference:
- {{ build-image.image_name }}, {{ build-image.tag }}, and {{ build-image.image }} (image_name:tag)
- The git_clone step and block reference syntax look correct:
- credentials: "{{ prefect.blocks.github-credentials.some-github-creds }}"
- Top-level push + per-deployment build is okay. Prefect will execute the combined build/push steps for each deployment, so push can reference outputs from the deployment’s build section.
- If you’re pushing to a private registry (e.g., ECR), add credentials to the push step or ensure the environment is already logged in:
- credentials: "{{ prefect.blocks.docker-registry-credentials.<your-block> }}"
- Ensure the environment running prefect deploy has these env vars set (since you echo them in build steps): SOME_GITHUB_TOKEN, SOME_GIT_REPO_URL, GIT_REPO_NAME, SOME_GIT_REPO_BRANCH, SOME_ECR_REPO_NAME.
- The if: condition to create a dev deployment only on dev branch is fine as written.
- You can omit work_queue_name: if you’re not using a specific queue.
Here’s a corrected excerpt focusing on the YAML anchors/merges and key bits:
```
name: prefect_project_template
prefect-version: 3.2.15
build:
push:
- prefect_docker.deployments.steps.push_docker_image:
requires: prefect-docker
image_name: "{{ build-image.image_name }}"
tag: "{{ build-image.tag }}"
# credentials: "{{ prefect.blocks.docker-registry-credentials.your-registry-creds }}"
pull:
definitions:
docker_build:
- prefect_docker.deployments.steps.build_docker_image: &docker_build_config
id: build-image
requires: prefect-docker>=0.6.0
image_name: ""
tag: ""
dockerfile: Dockerfile
platform: "linux/amd64"
git_clone:
- prefect.deployments.steps.git_clone: &git_clone
id: clone-step
repository: ""
branch: ""
credentials: "{{ prefect.blocks.github-credentials.some-github-creds }}"
default_pull: &default_pull
- prefect.deployments.steps.git_clone:
<<: *git_clone
repository: "{{ get-git-repo-url.stdout }}"
branch: "{{ get-git-repo-branch.stdout }}"
default_build: &default_build
- prefect.deployments.steps.run_shell_script:
id: get-github-token
script: echo $SOME_GITHUB_TOKEN
stream_output: false
expand_env_vars: true
- prefect.deployments.steps.run_shell_script:
id: get-git-repo-url
script: echo $SOME_GIT_REPO_URL
stream_output: false
expand_env_vars: true
- prefect.deployments.steps.run_shell_script:
id: get-git-repo-name
script: echo $GIT_REPO_NAME
stream_output: false
expand_env_vars: true
- prefect.deployments.steps.run_shell_script:
id: get-git-repo-branch
script: echo $SOME_GIT_REPO_BRANCH
stream_output: false
expand_env_vars: true
- prefect.deployments.steps.run_shell_script:
id: get-ecr-repo-name
script: echo $SOME_ECR_REPO_NAME
stream_output: false
expand_env_vars: true
- prefect_docker.deployments.steps.build_docker_image:
<<: *docker_build_config
image_name: "{{ get-ecr-repo-name.stdout }}"
tag: "{{ get-git-repo-branch.stdout }}"
buildargs:
GITHUB_TOKEN: "{{ get-github-token.stdout }}"
OS_ENV: "{{ get-git-repo-branch.stdout }}"
deployments:
- name: "dev-{{ get-git-repo-name.stdout }}-entrypoint"
tags: ["environment:{{ get-git-repo-branch.stdout }}"]
if: '{{ get-git-repo-branch.stdout }} == "dev"'
description: "Your Deployment description"
schedules:Marvin
02/14/2026, 12:09 AMimage_name, tag, image, image_id, and (if used) additional_tags.
- If you’re building for linux/amd64 on a non-amd64 runner, ensure your CI has Buildx/QEMU set up or the build will fail.
- You can run prefect deploy --help to confirm CLI usage and options.
Are you seeing a specific error when running prefect deploy, or is this a sanity check? If there’s an error, please paste it and I’ll pinpoint the exact fix.Bryan
02/14/2026, 12:10 AMRunning deployment build steps...
> Running run_shell_script step...
> Running run_shell_script step...
> Running run_shell_script step...
> Running run_shell_script step...
> Running run_shell_script step...
> Running build_docker_image step...
/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/bin/python3: No module named pip
23:43:09.240 | WARNING | prefect.deployments.steps.core - Unable to install required packages for prefect_docker.deployments.steps.build_docker_image
Traceback (most recent call last):
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/deployments/steps/core.py", line 163, in run_steps
step_output = await run_step(step, upstream_outputs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Unable to load step function: prefect_docker.deployments.steps.build_docker_image. Attempting install of prefect-docker>=0.6.0.
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/deployments/steps/core.py", line 133, in run_step
step_func = _get_function_for_step(fqn, requires=keywords.get("requires"))
An exception occurred.
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/deployments/steps/core.py", line 98, in _get_function_for_step
step_func = import_object(fully_qualified_name)
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/utilities/importtools.py", line 164, in import_object
module = load_module(module_name)
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/utilities/importtools.py", line 135, in load_module
return importlib.import_module(module_name)
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
File "/home/runner/work/_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/importlib/__init__.py", line 88, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1398, in _gcd_import
File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
File "<frozen importlib._bootstrap>", line 1314, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1398, in _gcd_import
File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
File "<frozen importlib._bootstrap>", line 1314, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1398, in _gcd_import
File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
File "<frozen importlib._bootstrap>", line 1335, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'prefect_docker'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/cli/_utilities.py", line 44, in wrapper
return fn(*args, **kwargs)
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/cli/_types.py", line 155, in sync_fn
return asyncio.run(async_fn(*args, **kwargs))
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/asyncio/runners.py", line 204, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File "/home/runner/work/_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/asyncio/runners.py", line 127, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/home/runner/work/_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/asyncio/base_events.py", line 719, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/cli/deploy.py", line 501, in deploy
await _run_single_deploy(
...<4 lines>...
)
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/cli/deploy.py", line 717, in _run_single_deploy
await run_steps(build_steps, step_outputs, print_function=app.console.print)
File "/home/runner/work/dw_prefect_project_template/dw_prefect_project_template/.venv/lib/python3.14/site-packages/prefect/deployments/steps/core.py", line 191, in run_steps
raise StepExecutionError(f"Encountered error while running {fqn}") from exc
prefect.deployments.steps.core.StepExecutionError: Encountered error while running prefect_docker.deployments.steps.build_docker_image
Error: Process completed with exit code 1.Marvin
02/14/2026, 12:10 AMMarvin
02/14/2026, 12:11 AMrequires: prefect-docker>=0.6.0) but your runtime environment does not have pip available:
- No module named pip
- Unable to install required packages for prefect_docker.deployments.steps.build_docker_image
- ModuleNotFoundError: No module named 'prefect_docker'
Because pip is missing, Prefect can’t install the plugin at step runtime. This is common when using uv-managed environments or venvs created without pip.
Pick one of these fixes:
Option 1 — Preinstall prefect-docker (recommended)
- Ensure the environment running prefect deploy has pip, and preinstall the plugin so Prefect doesn’t need to auto-install it.
Example GitHub Actions steps:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11' # recommend 3.11/3.12; avoid 3.14 for now
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install "prefect==3.2.15" "prefect-docker>=0.6.0"
- name: Deploy
run: prefect deploy --all
Option 2 — Use uv to bring the docker extra at runtime (no pip needed)
- Run the CLI via uv and include the docker extra so the plugin is available:
- name: Deploy with uv
run: uv run --with 'prefect[docker]' prefect deploy --all
Or preinstall with uv:
- run: |
uv pip install "prefect==3.2.15" "prefect-docker>=0.6.0"
uv run prefect deploy --all
Option 3 — Add pip to your current venv, then let Prefect auto-install
- If you must rely on the requires: auto-install:
python -m ensurepip --upgrade
python -m pip install --upgrade pip
# Then run your existing `prefect deploy` command
With pip present, Prefect can satisfy requires: prefect-docker>=0.6.0 automatically at step execution time.
Additional notes:
- You’re on CPython 3.14 per the logs. Many libs (including tooling around Docker) aren’t broadly tested there yet. I strongly suggest pinning your runner to Python 3.11 or 3.12 in CI to avoid surprises.
- Your use of requires: on the push step is fine, but you won’t need it once the environment already has prefect-docker installed.
- After this is fixed, if you’re cross-building with platform: "linux/amd64" on a non-amd64 runner, ensure Buildx/QEMU is configured in your CI. GitHub-hosted runners are amd64 by default, so you’re likely fine.
If you can share the GitHub Actions job snippet that runs prefect deploy, I can tailor the exact fix for your setup.Bryan
02/14/2026, 12:16 AM[project]
name = "dw_prefect_project_template"
version = "0.1.0"
description = "Prefect project template"
requires-python = ">=3.11"
dependencies = [
"prefect==3.2.15",
]
This is my Dockerfile:
FROM prefecthq/prefect:3.2.15-python3.11
COPY . /opt/prefect
WORKDIR /opt/prefect
ARG GITHUB_TOKEN
ARG OS_ENV
ENV OS_ENV=$OS_ENV
ENV TZ=America/Los_Angeles
RUN echo "machine github.com login $SOME_GITHUB_TOKEN" > ~/.netrc && \
git config --global url."https://$SOME_GITHUB_TOKEN@github.com/".insteadOf "<https://github.com/>" && \
uv sync --system --no-dev --frozenMarvin
02/14/2026, 12:17 AMMarvin
02/14/2026, 12:17 AM[project]
name = "dw_prefect_project_template"
version = "0.1.0"
description = "Prefect project template"
requires-python = ">=3.11,<3.13"
dependencies = [
"prefect==3.2.15",
"prefect-docker>=0.6.0",
]
- Option B (Prefect extra):
dependencies = [
"prefect[docker]==3.2.15",
]
Then, in the job that runs prefect deploy, make sure deps are installed first. With uv:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11' # strongly recommend 3.11/3.12 (avoid 3.14 for now)
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install dependencies
run: uv sync --frozen
- name: Deploy
run: uv run prefect deploy --all
This removes the need for Prefect to auto-install prefect-docker during the step (which failed because pip wasn’t available). You can keep the requires: prefect-docker>=0.6.0 in your prefect.yaml if you want belt-and-suspenders, but it’s not necessary once the env already has the plugin.
A couple of Dockerfile notes:
- Installing prefect-docker in the image is fine for runtime, but it will not fix the error you hit — the plugin must be available in the environment that runs prefect deploy (your CI runner), before the build step starts.
- Your ARG/ENV usage doesn’t match your Dockerfile commands:
- You pass GITHUB_TOKEN as a build-arg but reference $SOME_GITHUB_TOKEN in RUN. Use the same name everywhere.
- The angle brackets in the git config URL shouldn’t be there.
A corrected snippet:
FROM prefecthq/prefect:3.2.15-python3.11
COPY . /opt/prefect
WORKDIR /opt/prefect
ARG GITHUB_TOKEN
ARG OS_ENV
ENV OS_ENV=$OS_ENV
ENV TZ=America/Los_Angeles
# Use the same var name you pass via buildargs
RUN echo "machine <http://github.com|github.com> login $GITHUB_TOKEN" > ~/.netrc && \
git config --global url."https://$GITHUB_TOKEN@github.com/".insteadOf "<https://github.com/>" && \
uv sync --system --no-dev --frozen
If you prefer not to touch pyproject.toml, an alternative is to run the deploy via uv with the docker extra:
uv run --with 'prefect[docker]' prefect deploy --all
If you share your CI workflow snippet, I can tailor the exact steps for your setup.Bryan
02/14/2026, 12:21 AMMarvin
02/14/2026, 12:21 AMMarvin
02/14/2026, 12:23 AMprefect[docker]==3.2.15
# or: prefect==3.2.15
# prefect-docker>=0.6.0
- Use the action with that file:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- uses: PrefectHQ/actions-prefect-deploy@v4
with:
deployment-file-path: ./prefect.yaml
requirements-file-paths: ./requirements.txt
env:
PREFECT_API_KEY: ${{ secrets.PREFECT_API_KEY }}
PREFECT_API_URL: ${{ secrets.PREFECT_API_URL }}
2) Point the action at your pyproject.toml and include the plugin in default deps
- Update pyproject.toml:
[project]
name = "dw_prefect_project_template"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"prefect==3.2.15",
"prefect-docker>=0.6.0",
]
- Then run the action with pyproject:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- uses: PrefectHQ/actions-prefect-deploy@v4
with:
deployment-file-path: ./prefect.yaml
pyproject-toml-path: ./pyproject.toml
env:
PREFECT_API_KEY: ${{ secrets.PREFECT_API_KEY }}
PREFECT_API_URL: ${{ secrets.PREFECT_API_URL }}
Notes and gotchas:
- The action creates a fresh venv with uv and installs via uv pip install. There’s no pip involved.
- If you want to use “extras” from your project (e.g., optional-dependencies in pyproject), the action’s pyproject install runs “uv pip install .” (no extras). Put prefect-docker in the default [project] dependencies or use a requirements file.
- The action also installs/updates Prefect itself (uv pip install "prefect>=3,<4"). If you must pin exactly 3.2.15, keep that pin in your requirements or pyproject; the action won’t downgrade below your explicit pin, but it may upgrade if you’re unpinned.
- Prefer Python 3.11/3.12 on runners.Bryan
02/14/2026, 12:28 AMMarvin
02/14/2026, 12:28 AMMarvin
02/14/2026, 12:29 AM[project]
name = "dw_prefect_project_template"
version = "0.1.0"
description = "Prefect project template"
requires-python = ">=3.11,<3.13"
dependencies = [
"prefect==3.2.15",
]
[project.optional-dependencies]
deploy = [
"prefect[docker]==3.2.15",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Important: actions-prefect-deploy@v4 installs your project via uv pip install . (no extras). To ensure the extras are installed during deployment, add a small requirements file that references your extra and pass it to the action:
- requirements-deploy.txt
.[deploy]
- Workflow snippet
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- uses: PrefectHQ/actions-prefect-deploy@v4
with:
deployment-file-path: ./prefect.yaml
pyproject-toml-path: ./pyproject.toml
requirements-file-paths: ./requirements-deploy.txt
env:
PREFECT_API_KEY: ${{ secrets.PREFECT_API_KEY }}
PREFECT_API_URL: ${{ secrets.PREFECT_API_URL }}
This ensures uv installs your project plus the deploy extra (which brings in prefect[docker]) before running prefect deploy.Bryan
02/14/2026, 12:38 AMMarvin
02/14/2026, 12:38 AMMarvin
02/14/2026, 12:39 AM[project]
name = "dw_prefect_project_template"
version = "0.1.0"
description = "Prefect project template"
requires-python = ">=3.11,<3.13"
dependencies = [
"prefect[docker]==3.2.15",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Notes:
- With this, actions-prefect-deploy@v4 will install your project (and the docker extra) when you pass pyproject-toml-path: ./pyproject.toml to the action.Bryan
02/14/2026, 12:40 AMMarvin
02/14/2026, 12:40 AMMarvin
02/14/2026, 12:40 AMprefect[docker]==3.2.15 already includes Prefect; the [docker] extra is applied to Prefect itself. You do not need a separate prefect==3.2.15 line.
Two valid patterns:
- With the extra (recommended if you’re fine with extras syntax):
[project]
name = "dw_prefect_project_template"
version = "0.1.0"
description = "Prefect project template"
requires-python = ">=3.11,<3.13"
dependencies = [
"prefect[docker]==3.2.15",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
- Explicit plugin packages (if you prefer no extras):
[project]
name = "dw_prefect_project_template"
version = "0.1.0"
description = "Prefect project template"
requires-python = ">=3.11,<3.13"
dependencies = [
"prefect==3.2.15",
"prefect-docker>=0.6.0",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Note: actions-prefect-deploy@v4 also runs a uv pip install "prefect>=3,<4" step. If you pin 3.2.15 in your project as above, the resolver will keep 3.2.15. If you leave Prefect unpinned, the action may upgrade to the latest 3.x.Bryan
02/14/2026, 12:43 AMMarvin
02/14/2026, 12:43 AMMarvin
02/14/2026, 12:43 AM[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
- Setuptools (if you prefer/set have setup.cfg/setup.py)
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
If you do not pass pyproject-toml-path to the action and instead use requirements-file-paths (e.g., a requirements.txt), then a [build-system] section is not required.Bryan
02/14/2026, 12:46 AMDownloaded prefect
× Failed to build `dw-prefect-project-template @
│ file:///home/runner/work/dw_prefect_project_template/dw_prefect_project_template`
├─▶ The build backend returned an error
╰─▶ Call to `hatchling.build.build_wheel` failed (exit status: 1)
[stderr]
Traceback (most recent call last):
File "<string>", line 11, in <module>
File
"/home/runner/work/_temp/setup-uv-cache/builds-v0/.tmpOBrehR/lib/python3.12/site-packages/hatchling/build.py",
line 58, in build_wheel
return os.path.basename(next(builder.build(directory=wheel_directory,
versions=["standard"])))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/home/runner/work/_temp/setup-uv-cache/builds-v0/.tmpOBrehR/lib/python3.12/site-packages/hatchling/builders/plugin/interface.py",
line 157, in build
artifact = version_api[version](directory, **build_data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/home/runner/work/_temp/setup-uv-cache/builds-v0/.tmpOBrehR/lib/python3.12/site-packages/hatchling/builders/wheel.py",
line 503, in build_standard
for included_file in self.recurse_included_files():
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/home/runner/work/_temp/setup-uv-cache/builds-v0/.tmpOBrehR/lib/python3.12/site-packages/hatchling/builders/plugin/interface.py",
line 178, in recurse_included_files
yield from self.recurse_selected_project_files()
File
"/home/runner/work/_temp/setup-uv-cache/builds-v0/.tmpOBrehR/lib/python3.12/site-packages/hatchling/builders/plugin/interface.py",
line 182, in recurse_selected_project_files
if self.config.only_include:
^^^^^^^^^^^^^^^^^^^^^^^^
File
"/home/runner/work/_temp/uv-python-dir/cpython-3.12.12-linux-x86_64-gnu/lib/python3.12/functools.py",
line 998, in __get__
val = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File
"/home/runner/work/_temp/setup-uv-cache/builds-v0/.tmpOBrehR/lib/python3.12/site-packages/hatchling/builders/config.py",
line 715, in only_include
only_include = only_include_config.get("only-include",
self.default_only_include()) or self.packages
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/home/runner/work/_temp/setup-uv-cache/builds-v0/.tmpOBrehR/lib/python3.12/site-packages/hatchling/builders/wheel.py",
line 268, in default_only_include
return self.default_file_selection_options.only_include
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/home/runner/work/_temp/uv-python-dir/cpython-3.12.12-linux-x86_64-gnu/lib/python3.12/functools.py",
line 998, in __get__
val = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File
"/home/runner/work/_temp/setup-uv-cache/builds-v0/.tmpOBrehR/lib/python3.12/site-packages/hatchling/builders/wheel.py",
line 256, in default_file_selection_options
raise ValueError(message)
ValueError: Unable to determine which files to ship
inside the wheel using the following heuristics:
<https://hatch.pypa.io/latest/plugins/builder/wheel/#default-file-selection>
The most likely cause of this is that there is no directory that matches
the name of your project (dw_prefect_project_template).
At least one file selection option must be defined
in the `tool.hatch.build.targets.wheel` table, see:
<https://hatch.pypa.io/latest/config/build/>
As an example, if you intend to ship a directory named `foo` that
resides within a `src` directory located at the root of your project,
you can define the following:
[tool.hatch.build.targets.wheel]
packages = ["src/foo"]
hint: This usually indicates a problem with the package or the build
environment.
Error: Process completed with exit code 1.Marvin
02/14/2026, 12:46 AMMarvin
02/14/2026, 12:47 AMdw_prefect_project_template/
__init__.py
main.py # or your flow modules
flows/...
pyproject.toml:
[project]
name = "dw_prefect_project_template"
version = "0.1.0"
description = "Prefect project template"
requires-python = ">=3.11,<3.13"
dependencies = [
"prefect[docker]==3.2.15",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["dw_prefect_project_template"]
- src layout:
src/
dw_prefect_project_template/
__init__.py
main.py
flows/...
pyproject.toml:
[project]
name = "dw_prefect_project_template"
version = "0.1.0"
description = "Prefect project template"
requires-python = ">=3.11,<3.13"
dependencies = [
"prefect[docker]==3.2.15",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/dw_prefect_project_template"]
- This gives Hatch a concrete package to include, resolving “Unable to determine which files to ship”.
- Reference: Hatch build config docs
Option 2: Don’t install your project; just install dependencies for deployment
- If you don’t need your repo installed as a package to run flows (most Prefect projects don’t), skip pyproject installation in the action and let it install dependencies from a requirements file.
- Create requirements.txt:
prefect[docker]==3.2.15
- Update your workflow to only pass requirements-file-paths and remove pyproject-toml-path:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- uses: PrefectHQ/actions-prefect-deploy@v4
with:
deployment-file-path: ./prefect.yaml
requirements-file-paths: ./requirements.txt
env:
PREFECT_API_KEY: ${{ secrets.PREFECT_API_KEY }}
PREFECT_API_URL: ${{ secrets.PREFECT_API_URL }}
- This avoids building a wheel entirely and still ensures prefect[docker] is present for your docker steps.
Which should you choose?
- If your flows import local modules (e.g., from dw_prefect_project_template import utils), go with Option 1 and make the project installable.
- If your flows are simple entrypoints and don’t need installed imports, Option 2 is simpler and avoids packaging altogether.
If you share your repo structure (a quick tree of relevant files), I can suggest the minimal change to get you unblocked.