Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ def build_docker_image(
tag: str | None = None,
additional_tags: list[str] | None = None,
ignore_cache: bool = False,
persist_dockerfile: bool = False,
dockerfile_output_path: str = "Dockerfile.generated",
**build_kwargs: Any,
) -> BuildDockerImageResult:
"""
Expand All @@ -142,6 +144,10 @@ def build_docker_image(
passed, a temporary Dockerfile will be created to build the image.
tag: The tag to apply to the built image.
additional_tags: Additional tags on the image, in addition to `tag`, to apply to the built image.
persist_dockerfile: If True and dockerfile="auto", the generated Dockerfile will be saved
instead of deleted after the build.
dockerfile_output_path: Optional path where the auto-generated Dockerfile should be saved
(e.g., "Dockerfile.generated"). Only used if `persist_dockerfile` is True.
**build_kwargs: Additional keyword arguments to pass to Docker when building
the image. Available options can be found in the [`docker-py`](https://docker-py.readthedocs.io/en/stable/images.html#docker.models.images.ImageCollection.build)
documentation.
Expand Down Expand Up @@ -187,6 +193,17 @@ def build_docker_image(
dockerfile: Dockerfile
platform: amd64
```
Save the auto-generated Dockerfile to disk:
```yaml
build:
- prefect_docker.deployments.steps.build_docker_image:
requires: prefect-docker
image_name: repo-name/image-name
tag: dev
dockerfile: auto
persist_dockerfile: true
dockerfile_output_path: Dockerfile.generated
```
""" # noqa

namespace, repository = split_repository_path(image_name)
Expand Down Expand Up @@ -221,6 +238,18 @@ def build_docker_image(
with Path(temp_dockerfile).open("w") as f:
f.writelines(line + "\n" for line in lines)

if persist_dockerfile:
logger.info(
f"Persisting auto-generated Dockerfile to {dockerfile_output_path or 'Dockerfile.generated'}. Please update your 'dockerfile' value to use this Dockerfile for subsequent runs."
)
output_path = Path(dockerfile_output_path or "Dockerfile.generated")
with output_path.open("w") as out_file:
out_file.writelines(line + "\n" for line in lines)
else:
logger.info(
"Deleting auto-generated Dockerfile after build. Consider using `persist_dockerfile` to save it."
)

dockerfile = str(temp_dockerfile)

build_kwargs["path"] = build_kwargs.get("path", os.getcwd())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,23 @@ def mock_datetime(monkeypatch: pytest.MonkeyPatch):
},
"registry/repo:mytag",
),
(
{
"image_name": "registry/repo",
"dockerfile": "auto",
"persist_dockerfile": True,
},
f"registry/repo:{FAKE_DEFAULT_TAG}",
),
(
{
"image_name": "registry/repo",
"dockerfile": "auto",
"persist_dockerfile": True,
"dockerfile_output_path": "Dockerfile.test",
},
f"registry/repo:{FAKE_DEFAULT_TAG}",
),
],
)
@pytest.mark.usefixtures("mock_datetime")
Expand All @@ -160,6 +177,8 @@ def test_build_docker_image(
auto_build = False
image_name = kwargs.get("image_name")
dockerfile = kwargs.get("dockerfile", "Dockerfile")
persist_dockerfile = kwargs.get("persist_dockerfile", False)
dockerfile_output_path = kwargs.get("dockerfile_output_path", None)
tag = kwargs.get("tag", FAKE_DEFAULT_TAG)
additional_tags = kwargs.get("additional_tags", None)
path = kwargs.get("path", os.getcwd())
Expand Down Expand Up @@ -202,7 +221,10 @@ def test_build_docker_image(
mock_docker_client.images.get.assert_called_once_with(FAKE_CONTAINER_ID)

if auto_build:
assert not Path("Dockerfile").exists()
if persist_dockerfile:
assert Path(dockerfile_output_path or "Dockerfile.generated").exists()
else:
assert not Path("Dockerfile").exists()


def test_build_docker_image_raises_with_auto_and_existing_dockerfile():
Expand Down