<@ULVA73B9P> How can I deploy a flow (using `myFlo...
# ask-marvin
s
@Marvin How can I deploy a flow (using
myFlow.deploy()
) to a work-pool whose type is "process" ? I'm running workers with docker compose. When I try to deploy the flows, it says it requires either an image or a source of code: with the "process" type, shouldn't it simply start a new process ?
m
thought for 386.9 seconds
Great question — and the error you’re seeing makes sense in Prefect 3.x. Short answer - A Process worker does “just start a new process”, but it still needs a way to get your flow code into the runtime environment. - In Prefect 3.x, deployments must specify either: - a code source (e.g., Git URL or a local path the worker can read), or - a container image (used by Docker/Kubernetes work pools, not Process) Since you’re using a Process work pool with workers running in Docker Compose, you have two good options. Option A: Keep Process work pool and provide a code source - If your worker container has your repo mounted (via docker-compose volume), point the deployment at that path inside the container:
Copy code
from prefect import flow, Flow

@flow
def my_flow():
    ...

Flow.from_source(
    source="/opt/app",                             # path inside the worker container
    entrypoint="flows/my_flow.py:my_flow",         # file:callable
).deploy(
    name="prod",
    work_pool_name="my-process-pool",
)
- If you’d rather pull from Git (recommended when not mounting code), use a Git URL:
Copy code
from prefect import flow, Flow

@flow
def my_flow():
    ...

Flow.from_source(
    source="<https://github.com/acme/prefect-project>",
    entrypoint="flows/my_flow.py:my_flow",
).deploy(
    name="prod",
    work_pool_name="my-process-pool",
)
Notes: - The path or repo must be accessible from inside the worker container. - With Process workers, your worker container must already have all Python dependencies installed; Prefect does not build an image per deployment for Process pools. Option B: Switch to a Docker work pool and use an image - If you prefer to bake code and dependencies into an image per deployment, use a Docker or Kubernetes work pool instead of Process and pass
image=...
to
.deploy(...)
. This is not used by Process pools. Why the error? -
Flow.deploy()
requires Prefect to know how the worker will load your code at run time. For Process pools, that means the worker must be able to import your flow from a specified “source”; for Docker/K8s pools, an image is required. Hence the “image or source” requirement. Helpful links - Create deployments in Prefect 3 - Work pools and workers overview (blog) - Agents to Workers migration (context) Quick check - Are you mounting your repo into the worker container via docker-compose? If so, what is the mount path inside the container? I can tailor the
from_source(..., entrypoint=...)
snippet to match your layout. - If you’re using a private Git repo, do you already have credentials configured in the worker container environment?
s
@Marvin it worked, I've been able to create the flow in the deployment. However the process ended afterwards. How can I run these processes and keep them ready ?
m
thought for 149.1 seconds
Congrats on getting the deployment created! One important distinction in Prefect 3.x: - Creating a deployment just registers your flow + entrypoint with the API. - To keep execution “ready,” you need long-running workers that poll for work. Since you’re using a Process work pool and Docker Compose, you’ll typically have two long-running components: 1) A flow worker for your deployments - This worker polls your Process work pool and spawns a new subprocess for each flow run. - Start it as a long-running service:
Copy code
prefect work-pool create my-process-pool --type process   # if not created
prefect worker start --pool my-process-pool
Example docker-compose service:
Copy code
services:
  prefect-flow-worker:
    image: prefecthq/prefect:3-latest
    command: bash -lc "prefect worker start --pool my-process-pool"
    environment:
      - PREFECT_API_URL=${PREFECT_API_URL}
      - PREFECT_API_KEY=${PREFECT_API_KEY}
    volumes:
      - ./app:/opt/app    # if your deployments use a local path source
- Scale by running more replicas of this service:
Copy code
docker compose up -d --scale prefect-flow-worker=3
2) Task workers for background tasks created with .delay() - Background tasks are executed by task workers, which you run as long-lived processes using
prefect.task_worker.serve
. - Create a small runner script and run it as a service: worker_task.py:
Copy code
from prefect.task_worker import serve
from my_package.tasks import task_a, task_b  # import the task objects you call with .delay()

if __name__ == "__main__":
    serve(task_a, task_b, limit=20)  # limit = max concurrent tasks per worker
docker-compose service:
Copy code
services:
  prefect-task-worker:
    image: prefecthq/prefect:3-latest
    working_dir: /opt/app
    command: bash -lc "python worker_task.py"
    environment:
      - PREFECT_API_URL=${PREFECT_API_URL}
      - PREFECT_API_KEY=${PREFECT_API_KEY}
    volumes:
      - ./app:/opt/app
- Scale task capacity by running more replicas or increasing `limit`:
Copy code
docker compose up -d --scale prefect-task-worker=5
Notes for your setup - For Process workers, your code must be available inside the worker container. If you used
Flow.from_source("/opt/app", entrypoint=...)
, keep that path mounted. If you pointed at a Git URL, ensure the container can reach the repo (and any credentials). - For background tasks, make sure the exact Task objects you call with
.delay()
are the ones passed to
serve(...)
. If you’re dynamically renaming tasks via
.with_options(name=...)
, that creates new task definitions. If you need per-run naming while keeping a stable task identity, consider using a task-run naming callback instead of changing the task’s name. Helpful links - Create deployments in Prefect 3 - Work pools and workers overview If you can share your docker-compose snippet and how you’re calling
.delay()
, I can tailor the services and
serve(...)
call to match your layout and scaling goals.
s
@Marvin is there a python equivalent call to
prefect worker start --pool my-pool
?
m
thought for 60.2 seconds
Yes. You can start a Process worker programmatically. Minimal example:
Copy code
from prefect.workers import ProcessWorker

if __name__ == "__main__":
    worker = ProcessWorker(
        work_pool_name="my-pool",
        # optional:
        # work_queues=["high-priority"],
        # name="my-python-worker",
        # limit=5,  # max concurrent flow runs this worker will execute
        # create_pool_if_not_found=True,
    )
    worker.start(with_healthcheck=True)  # runs forever, polling the pool
Notes: - This is the programmatic equivalent of
prefect worker start --pool my-pool
. - The worker must run in an environment where your flow code is available (e.g., your Docker Compose volume or the Git source you used in
Flow.from_source(...)
) and where `PREFECT_API_URL`/`PREFECT_API_KEY` are set if using Cloud. -
limit
controls concurrency for flow runs on this worker. -
with_healthcheck=True
starts a healthcheck server; you can omit it if you don’t need one. If you want a quick Docker Compose snippet using Python:
Copy code
services:
  process-worker:
    image: prefecthq/prefect:3-latest
    working_dir: /opt/app
    command: bash -lc "python start_worker.py"
    environment:
      - PREFECT_API_URL=${PREFECT_API_URL}
      - PREFECT_API_KEY=${PREFECT_API_KEY}
    volumes:
      - ./app:/opt/app
Where
start_worker.py
is the script above.