Cullen Baker
10/29/2025, 7:11 PMMarvin
10/29/2025, 7:11 PMMarvin
10/29/2025, 7:17 PMprefecthq/prefect:3-python3.12 and install prefect-docker.
- Run it via docker-compose (or podman-compose) and mount the Podman socket into the container.
- Set PREFECT_API_URL to your Server/Cloud API and DOCKER_HOST to the mounted socket path.
- Use Prefect’s Docker work pool and pass Artifactory credentials via job variables (preferred) or mount a Docker config.
1) Create a Docker work pool (once)
prefect work-pool create my-docker-pool --type docker
2) Worker Dockerfile
This bakes the docker integration so the container starts instantly without pip at runtime.
# Dockerfile.worker
FROM prefecthq/prefect:3-python3.12
# Install the Docker integration for Prefect 3
RUN pip install --no-cache-dir prefect-docker
# Optional: pin versions or install any org-wide utilities here
# Default command can be overridden in compose
CMD ["prefect", "worker", "start", "--pool", "my-docker-pool"]
3) docker-compose.yml (with Podman socket on RHEL)
If you’re also running Prefect Server in the same compose stack, include it; otherwise just run the worker service and point PREFECT_API_URL at your existing API.
version: "3.9"
services:
# Optional: only needed if you want to run Prefect Server in the same stack
prefect-server:
image: prefecthq/prefect:3-python3.12
command: prefect server start --host 0.0.0.0
environment:
PREFECT_SERVER_API_HOST: 0.0.0.0
ports:
- "4200:4200"
volumes:
- prefect-server-data:/root/.prefect
restart: unless-stopped
prefect-worker:
build:
context: .
dockerfile: Dockerfile.worker
depends_on:
- prefect-server
environment:
# If using Prefect Server in this compose stack
PREFECT_API_URL: <http://prefect-server:4200/api>
# If using Prefect Cloud instead, set:
# PREFECT_API_URL: <https://api.prefect.cloud/api/accounts/<acct>/workspaces/<ws>>
# PREFECT_API_KEY: <your-key>
# Point the Docker SDK inside the container at the mounted Podman socket
DOCKER_HOST: unix:///var/run/docker.sock
# Optional tuning
# PREFECT_WORKER_QUERY_SECONDS: "15"
# PREFECT_WORKER_PREFETCH_SECONDS: "0"
command:
- prefect
- worker
- start
- --pool
- my-docker-pool
volumes:
# Rootful Podman socket on RHEL
- /run/podman/podman.sock:/var/run/docker.sock
# Optional: allow automatic pulls from Artifactory using your local docker config
# - ${HOME}/.docker/config.json:/root/.docker/config.json:ro
restart: unless-stopped
volumes:
prefect-server-data:
Notes for Podman on RHEL
- Rootful Podman socket is typically at /run/podman/podman.sock. We map it to /var/run/docker.sock inside the container and set DOCKER_HOST=unix:///var/run/docker.sock. The Docker SDK will happily talk to Podman’s Docker-compatible API.
- If you run Podman rootless, your socket may be at /run/user/<uid>/podman/podman.sock. Mapping that into the container is trickier; many teams use the rootful socket for workers to keep it simple.
- Ensure the worker container user can access the socket (ownership/permissions). If you see “permission denied,” adjust the socket’s group/permissions or run the worker as a user/group that can access it.
4) Artifactory (private registry) options
Preferred: set registry credentials in your deployment’s job variables so the worker can pull images for each flow run:
```
# prefect.yaml (excerpt for a deployment)
deployments:
- name: my-flow
entrypoint: flows/my_flow.py:flow
work_pool: my-docker-pool
job_variables:Marvin
10/29/2025, 7:17 PMAlternative: mount your Docker config that already has `docker login <http://artifactory.myco.com|artifactory.myco.com>`:
- Add to compose: `~/.docker/config.json:/root/.docker/config.json:ro`
- The worker will use these credentials to pull your flow images.
5) Build and run
- Build the worker image and start:
docker compose up -d --build
# or podman-compose up -d --build
```
6) Deploy flows to the Docker work pool
In Prefect 3.x, use flow.from_source(...).deploy(...) or prefect deploy with a recipe. Ensure your deployments reference the my-docker-pool and set image to your Artifactory image for flow runs.
Why this pattern?
- Keeps the worker image small and generic (no flow code baked in).
- Uses Podman’s Docker-compatible API via the socket mount.
- Cleanly supports private registries through Prefect’s registry_credentials or your Docker config.
- Clear separation: worker orchestrates; each flow run image contains runtime deps.
Docs for reference
- Docker worker and job variables: Docker worker guide
- Self-hosted with docker-compose: Self-hosted docker-compose
- Docker integration package: prefect-docker integration
- Work pools and workers: Workers concept
Quick check
- Does your environment use Prefect Cloud or Prefect Server?
- Will you run the worker against Podman’s rootful socket at /run/podman/podman.sock? If rootless, we can adjust the compose to map the user socket instead.Nate
10/29/2025, 7:21 PMimage: prefecthq/prefect:3-latest and command: uv run prefect worker start ... is the simplest thing to doMarvin
10/29/2025, 7:21 PMMarvin
10/29/2025, 7:22 PMprefect work-pool create my-docker-pool --type docker
2) docker-compose.yml (Podman on RHEL)
version: "3.9"
services:
prefect-worker:
image: prefecthq/prefect:3-latest
environment:
# Point to your API (Server or Cloud)
# For Server in the same network: <http://prefect-server:4200/api>
PREFECT_API_URL: <http://prefect-server:4200/api>
# Point Docker SDK to the Podman socket mounted below
DOCKER_HOST: unix:///var/run/docker.sock
command:
- uv
- run
- --with
- prefect[docker]
- prefect
- worker
- start
- --pool
- my-docker-pool
volumes:
# Podman socket (rootful)
- /run/podman/podman.sock:/var/run/docker.sock
# Optional: persist uv’s cache so extras aren’t re-fetched on every restart
- /root/.cache/uv:/root/.cache/uv
# Optional: use your Docker config for Artifactory pulls
# - ${HOME}/.docker/config.json:/root/.docker/config.json:ro
restart: unless-stopped
Notes
- For Prefect Cloud, set PREFECT_API_URL to your workspace URL and add PREFECT_API_KEY.
- If you run Podman rootless, your socket may be at /run/user/<uid>/podman/podman.sock — map that instead and keep DOCKER_HOST=unix:///var/run/docker.sock inside the container.
- Ensure the container user can access the socket (permissions/group).
- For Artifactory pulls, either mount a config.json as above or set registry_credentials in your deployment’s job variables.
Docs
- Docker worker how-to: Docker worker guide
- Self-hosted with docker-compose: Self-hosted docker-compose
- Docker integration: prefect-docker integration
If you want, I can tailor the compose snippet with your actual API URL and whether you’re using rootful or rootless Podman.