Running flows with Docker¶
In the Deployments tutorial, we looked at creating configuration that enables creating flow runs via the API and with code that was uploaded to a remotely accessible location.
In this guide, we will "bake" your code directly into a Docker image. This will allow for easy storage and allow you to deploy flow code without the need for a storage block. Then, we'll configure the deployment so flow runs are executed in a Docker container based on that image. We'll run our Docker instance locally, but you can extend this guide to run it on remote machines.
In this guide we'll:
- Create a Docker image that stores your Prefect flow code.
- Configure a build step which will build a docker image on our behalf.
- Build and register a new
log_flow.py
deployment that uses the new image. - Create a flow run from this deployment that spins up a Docker container and executes, logging a message.
Prerequisites¶
To run a deployed flow in a Docker container, you'll need the following:
- We'll use the flow script and deployment from the Deployments tutorial.
- You must run a standalone Prefect server (
prefect server start
) or use Prefect Cloud. - You'll need Docker Engine installed and running on the same machine as your agent.
Docker Desktop works fine for local testing if you don't already have Docker Engine configured in your environment.
Run a Prefect server
This guide assumes you're already running a Prefect server with prefect server start
, as described in the Deployments tutorial.
If you shut down the server, you can start it again by opening another terminal session and starting the Prefect server with the prefect server start
CLI command.
Storing Prefect Flow Code in a Docker Image¶
First let's create a directory to work from, docker-tutorial
.
In this directory, you will create a sub-directory named flows
and put your flow script from the Deployments tutorial. In this case, I've named the flow docker-tutorial-flow.py
.
The next file you will add to the docker-tutorial
directory is a requirements.txt
. In this file make sure to include all dependencies that are required for your docker-tutorial-flow.py
script.
Next, you will create a Dockerfile
that will be used to create a Docker image that will also store the flow code. This Dockerfile
should look similar to the following:
FROM prefecthq/prefect:2-python3.9
COPY requirements.txt .
RUN pip install -r requirements.txt --trusted-host pypi.python.org --no-cache-dir
ADD flows /opt/prefect/flows
Finally, we build this image by running:
docker build -t docker-tutorial-image .
This will create a Docker image in your Docker repository with your Prefect flow stored in the image.
Prefect.yaml File¶
Now that you have created a Docker image that stores your Prefect flow code, you're going to make use of Prefect's deployment recipes. In your terminal, run:
prefect init --recipe docker
You will see a prompt to input values for image name and tag, lets use:
image_name: docker-tutorial-image
tag: latest
This will create a prefect.yaml
file for us populated with some fields. By default, it will look like this:
# Welcome to your prefect.yaml file! You can use this file for storing and managing
# configuration for deploying your flows. We recommend committing this file to source
# control along with your flow code.
# Generic metadata about this project
name: docker-tutorial
prefect-version: 2.10.16
# build section allows you to manage and build docker images
build:
- prefect_docker.deployments.steps.build_docker_image:
id: build_image
requires: prefect-docker>=0.3.0
image_name: docker-tutorial-image
tag: latest
dockerfile: auto
push: true
# push section allows you to manage if and how this project is uploaded to remote locations
push: null
# pull section allows you to provide instructions for cloning this project in remote locations
pull:
- prefect.deployments.steps.set_working_directory:
directory: /opt/prefect/docker-tutorial
# the deployments section allows you to provide configuration for deploying flows
deployments:
- name: null
version: null
tags: []
description: null
schedule: {}
flow_name: null
entrypoint: null
parameters: {}
work_pool:
name: null
work_queue_name: null
job_variables:
image: '{{ build_image.image }}'
Once you have made any updates you would like to this prefect.yaml
file, in your terminal run:
prefect deploy
The Prefect deployment wizard will walk you through the deployment experience to deploy your flow in either Prefect Cloud or your local Prefect Server. Once the flow is deployed, you can even save the configuration to your prefect.yaml
file for faster deployment in the future.
Cleaning up¶
When you're finished, just close the Prefect UI tab in your browser, and close the terminal sessions running the Prefect server and agent.