Javier King
09/05/2025, 4:44 PMprefect.deployments.steps.load_dotenv
pull step, but this... isn't a thingMarvin
09/05/2025, 4:44 PMNate
09/05/2025, 4:45 PMNate
09/05/2025, 4:45 PMNate
09/05/2025, 4:45 PMJavier King
09/05/2025, 4:46 PMNate
09/05/2025, 4:46 PMJavier King
09/05/2025, 4:46 PMNate
09/05/2025, 4:48 PMMarvin
09/05/2025, 4:54 PMprefect.deployments.steps.load_dotenv
step in Prefect 3.x. That recommendation was for something that doesn’t exist.
Good news: there are cleaner patterns to avoid listing tens of env vars in each deployment. The best choice depends on your worker/infrastructure (Docker, Kubernetes, Process, etc.). If you can share which work pool type you’re using, I can tailor an example.
Here are the common approaches:
1) Kubernetes work pool: use envFrom with ConfigMaps/Secrets (no clutter in deployments)
- Put your env in a ConfigMap/Secret and reference it in the work pool’s base job template via envFrom
. Your deployments don’t need to list anything.
- Steps:
- Export the default template:
prefect work-pool get-default-base-job-template --type kubernetes > k8s-template.json
- Edit k8s-template.json
to add something like:
{
"pod": {
"spec": {
"containers": [
{
"name": "flow",
"envFrom": [
{
"configMapRef": {
"name": "my-config"
}
},
{
"secretRef": {
"name": "my-secrets"
}
}
]
}
]
}
}
}
- Apply it:
prefect work-pool update "my-k8s-pool" --base-job-template k8s-template.json
- This keeps env management in Kubernetes and out of prefect.yaml
.
- Docs: Customize job variables, prefect.yaml guide
2) Docker work pool: mount an env file or use a startup script
- The Docker worker’s job_variables.env
is a dict and does not support an env_file
parameter directly. To avoid listing everything:
- Mount a file containing env vars into the container and use a custom entrypoint/cmd to source it before starting the flow.
- Example job_variables
(simplified idea):
job_variables:
image: your-image:tag
volumes:
- /host/path/app.env:/opt/prefect/app.env:ro
command: >
/bin/sh -lc "set -a; . /opt/prefect/app.env; set +a; exec prefect runner"
- Or, build a custom image whose entrypoint sources a known env file that you mount at runtime.
- Docs: Customize job variables
3) Load dotenv in your flow code (works across worker types)
- If you just want “read many vars from one file” with minimal YAML clutter, add python-dotenv to your project and load a file in your flow module:
# pip install python-dotenv
import os
from dotenv import load_dotenv, find_dotenv
# Load from a specific path provided by a single env var
dotenv_path = os.getenv("DOTENV_PATH", find_dotenv())
if dotenv_path:
load_dotenv(dotenv_path, override=False)
- Then you only set a single env var per deployment (or at the work pool): DOTENV_PATH=/opt/prefect/app.env
, and mount/place the file appropriately (K8s Secret volume, Docker volume, etc.). No need to enumerate every variable in prefect.yaml
.
4) Keep in mind: Prefect’s own .env loading is for PREFECT_* settings only
- Prefect will read .env
files for Prefect settings (e.g., PREFECT_API_URL
, PREFECT_API_KEY
) but it won’t load arbitrary application env vars for your flows by default. For app envs, use one of the strategies above.
- Docs: Settings and profiles
5) About “pull steps”
- There is no load_dotenv
pull step. Built-in pull steps are things like git_clone
, pull_from_remote_storage
, etc.
- You can see available steps here: utility steps and the pull steps in code: prefect.deployments.steps.pull.git_clone
, set_working_directory
, etc.Marvin
09/05/2025, 4:54 PMNate
09/05/2025, 4:55 PMJavier King
09/05/2025, 4:55 PMNate
09/05/2025, 4:55 PMJavier King
09/05/2025, 5:05 PM