Prefect deployment steps for building and pushing Docker images.
These steps can be used in a prefect.yaml file to define the default
build steps for a group of deployments, or they can be used to define
the build step for a specific deployment.
The additional tags on the image, in addition to tag.
Source code in prefect_docker/deployments/steps.py
5354555657585960616263646566676869
classBuildDockerImageResult(TypedDict):""" The result of a `build_docker_image` step. Attributes: image_name: The name of the built image. tag: The tag of the built image. image: The name and tag of the built image. image_id: The ID of the built image. additional_tags: The additional tags on the image, in addition to `tag`. """image_name:strtag:strimage:strimage_id:stradditional_tags:Optional[List[str]]
The additional tags on the image, in addition to tag.
Source code in prefect_docker/deployments/steps.py
727374757677787980818283848586
classPushDockerImageResult(TypedDict):""" The result of a `push_docker_image` step. Attributes: image_name: The name of the pushed image. tag: The tag of the pushed image. image: The name and tag of the pushed image. additional_tags: The additional tags on the image, in addition to `tag`. """image_name:strtag:Optional[str]image:stradditional_tags:Optional[List[str]]
@cacheabledefbuild_docker_image(image_name:str,dockerfile:str="Dockerfile",tag:Optional[str]=None,additional_tags:Optional[List[str]]=None,ignore_cache:bool=False,**build_kwargs,)->BuildDockerImageResult:""" Builds a Docker image for a Prefect deployment. Can be used within a `prefect.yaml` file to build a Docker image prior to creating or updating a deployment. Args: image_name: The name of the Docker image to build, including the registry and repository. dockerfile: The path to the Dockerfile used to build the image. If "auto" is 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. **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. Returns: A dictionary containing the image name and tag of the built image. Example: Build a Docker image prior to creating a deployment: ```yaml build: - prefect_docker.deployments.steps.build_docker_image: requires: prefect-docker image_name: repo-name/image-name tag: dev ``` Build a Docker image with multiple tags: ```yaml build: - prefect_docker.deployments.steps.build_docker_image: requires: prefect-docker image_name: repo-name/image-name tag: dev additional_tags: - v0.1.0, - dac9ccccedaa55a17916eef14f95cc7bdd3c8199 ``` Build a Docker image using an auto-generated Dockerfile: ```yaml build: - prefect_docker.deployments.steps.build_docker_image: requires: prefect-docker image_name: repo-name/image-name tag: dev dockerfile: auto ``` Build a Docker image for a different platform: ```yaml build: - prefect_docker.deployments.steps.build_docker_image: requires: prefect-docker image_name: repo-name/image-name tag: dev dockerfile: Dockerfile platform: amd64 ``` """# noqaauto_build=dockerfile=="auto"ifauto_build:lines=[]base_image=get_prefect_image_name()lines.append(f"FROM {base_image}")dir_name=os.path.basename(os.getcwd())ifPath("requirements.txt").exists():lines.append(f"COPY requirements.txt /opt/prefect/{dir_name}/requirements.txt")lines.append(f"RUN python -m pip install -r /opt/prefect/{dir_name}/requirements.txt")lines.append(f"COPY . /opt/prefect/{dir_name}/")lines.append(f"WORKDIR /opt/prefect/{dir_name}/")temp_dockerfile=Path("Dockerfile")ifPath(temp_dockerfile).exists():raiseValueError("Dockerfile already exists.")withPath(temp_dockerfile).open("w")asf:f.writelines(line+"\n"forlineinlines)dockerfile=str(temp_dockerfile)build_kwargs["path"]=build_kwargs.get("path",os.getcwd())build_kwargs["dockerfile"]=dockerfilebuild_kwargs["pull"]=build_kwargs.get("pull",True)build_kwargs["decode"]=Truebuild_kwargs["labels"]={**build_kwargs.get("labels",{}),**IMAGE_LABELS}image_id=Nonewithdocker_client()asclient:try:events=client.api.build(**build_kwargs)try:foreventinevents:if"stream"inevent:sys.stdout.write(event["stream"])sys.stdout.flush()elif"aux"inevent:image_id=event["aux"]["ID"]elif"error"inevent:raiseBuildError(event["error"])elif"message"inevent:raiseBuildError(event["message"])exceptdocker.errors.APIErrorase:raiseBuildError(e.explanation)fromefinally:ifauto_build:os.unlink(dockerfile)ifnotisinstance(image_id,str):raiseBuildError("Docker did not return an image ID for built image.")ifnottag:tag=slugify(pendulum.now("utc").isoformat())image:Image=client.images.get(image_id)image.tag(repository=image_name,tag=tag)additional_tags=additional_tagsor[]fortag_inadditional_tags:image.tag(repository=image_name,tag=tag_)return{"image_name":image_name,"tag":tag,"image":f"{image_name}:{tag}","image_id":image_id,"additional_tags":additional_tags,}
@cacheabledefpush_docker_image(image_name:str,tag:Optional[str]=None,credentials:Optional[Dict]=None,additional_tags:Optional[List[str]]=None,ignore_cache:bool=False,)->PushDockerImageResult:""" Push a Docker image to a remote registry. Args: image_name: The name of the Docker image to push, including the registry and repository. tag: The tag of the Docker image to push. credentials: A dictionary containing the username, password, and URL for the registry to push the image to. additional_tags: Additional tags on the image, in addition to `tag`, to apply to the built image. Returns: A dictionary containing the image name and tag of the pushed image. Examples: Build and push a Docker image to a private repository: ```yaml build: - prefect_docker.deployments.steps.build_docker_image: id: build-image requires: prefect-docker image_name: repo-name/image-name tag: dev dockerfile: auto 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.dev-registry }}" ``` Build and push a Docker image to a private repository with multiple tags ```yaml build: - prefect_docker.deployments.steps.build_docker_image: id: build-image requires: prefect-docker image_name: repo-name/image-name tag: dev dockerfile: auto additional_tags: [ v0.1.0, dac9ccccedaa55a17916eef14f95cc7bdd3c8199 ] 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.dev-registry }}" additional_tags: "{{ build-image.additional_tags }}" ``` """# noqawithdocker_client()asclient:ifcredentialsisnotNone:client.login(username=credentials.get("username"),password=credentials.get("password"),registry=credentials.get("registry_url"),reauth=credentials.get("reauth",True),)events=list(client.api.push(repository=image_name,tag=tag,stream=True,decode=True))additional_tags=additional_tagsor[]fori,tag_inenumerate(additional_tags):event=list(client.api.push(repository=image_name,tag=tag_,stream=True,decode=True))events=events+eventforeventinevents:if"status"inevent:sys.stdout.write(event["status"])if"progress"inevent:sys.stdout.write(" "+event["progress"])sys.stdout.write("\n")sys.stdout.flush()elif"error"inevent:raiseOSError(event["error"])return{"image_name":image_name,"tag":tag,"image":f"{image_name}:{tag}","additional_tags":additional_tags,}