Vincent Chéry
06/30/2025, 4:19 PMMarvin
06/30/2025, 4:19 PMMarvin
06/30/2025, 4:20 PMbash
docker run -v $(pwd)/.env:/.env your-image-name
2. Using Docker Compose (Recommended):
yaml
version: '3'
services:
flow:
image: your-image-name
env_file:
- .env
volumes:
- ./.env:/.env
Your .env file might look something like this:
PREFECT_API_URL=<http://host.docker.internal:4200/api>
PREFECT_LOGGING_LEVEL=INFO
# Add other environment variables as needed
A few important notes:
- Prefect automatically loads environment variables from .env files in the current working directory
- All Prefect-specific environment variables should be prefixed with PREFECT_
- If you're running the container in a CI/CD environment, make sure the .env file is available in the build context
- The mounted .env file takes precedence over environment variables defined in the Dockerfile
For security best practices:
- Don't commit your .env file to version control
- Consider using Docker secrets for sensitive information in production environments
- Use different .env files for different environments (development, staging, production)
You can verify the environment variables are properly loaded by adding a simple print statement in your flow:
python
from prefect import flow
import os
@flow
def check_env():
print(os.environ.get("YOUR_ENV_VARIABLE"))
if __name__ == "__main__":
check_env()
For more details about Prefect settings and configuration, you can refer to the official documentation.Vincent Chéry
06/30/2025, 4:24 PMMarvin
06/30/2025, 4:25 PMMarvin
06/30/2025, 4:27 PMbash
prefect work-pool create-type docker \
--name your-pool-name \
--base-job-template '{
"job_configuration": {
"volumes": [
{
"source": "/path/to/your/.env",
"destination": "/.env",
"type": "bind"
}
]
}
}'
Or if you're modifying an existing work pool, you can update its base job template through the UI by adding the volume configuration.
2. Alternatively, you can specify the volume mount when deploying your flow:
python
from prefect import flow
from prefect.deployments import Deployment
@flow
def my_flow():
...
deployment = Deployment.build_from_flow(
flow=my_flow,
name="flow-with-env",
work_pool_name="your-pool-name",
job_configuration={
"volumes": [
{
"source": "/path/to/your/.env",
"destination": "/.env",
"type": "bind"
}
]
}
)
Important notes:
- The source
path must be accessible from the machine where the worker is running
- Make sure the worker process has permission to read the .env file
- The destination
path is where the file will appear inside the container
- Consider security implications of mounting sensitive environment files
If you need to use different .env files for different environments or flows, you can create separate work pools with different base job templates, or specify the volume configuration at deployment time.
Remember that the .env file needs to exist on the worker machine (where containers are being spawned), not on the machine where the Prefect server is running or where you're deploying from.Vincent Chéry
07/01/2025, 6:45 AMMarvin
07/01/2025, 6:45 AMMarvin
07/01/2025, 6:45 AMpython
from prefect import flow
from prefect.deployments import Deployment
@flow
def my_flow():
...
if __name__ == "__main__":
my_flow.deploy(
name="flow-with-env",
work_pool_name="your-pool-name",
job_configuration={
"volumes": [
{
"source": "/path/to/your/.env",
"destination": "/.env",
"type": "bind"
}
]
}
)
Or if you're deploying from a remote source:
python
from prefect import flow
@flow
def my_flow():
...
if __name__ == "__main__":
my_flow.from_source(
source="<https://github.com/your-repo/your-project>",
entrypoint="path/to/file.py:my_flow",
).deploy(
name="flow-with-env",
work_pool_name="your-pool-name",
job_configuration={
"volumes": [
{
"source": "/path/to/your/.env",
"destination": "/.env",
"type": "bind"
}
]
}
)
The key differences in the new syntax are:
- We use the flow object's .deploy()
method directly instead of Deployment.build_from_flow()
- For remote deployments, we use .from_source()
to specify the source location
- The configuration structure remains the same, but it's now passed directly to the .deploy()
method
This new syntax is more straightforward and aligns with Prefect 3.x's design philosophy of making deployments more intuitive and direct.Vincent Chéry
07/01/2025, 6:47 AMMarvin
07/01/2025, 6:47 AMMarvin
07/01/2025, 6:47 AMbash
prefect work-pool create \
--name your-pool-name \
--type docker \
--base-job-template '{
"volumes": [
{
"source": "/path/to/your/.env",
"destination": "/.env",
"type": "bind"
}
]
}'
2. For an Existing Work Pool, you can update the configuration through the UI:
- Navigate to Work Pools
- Select your Docker work pool
- Click "Edit"
- Update the base job template to include the volumes configuration
Then your deployment would simply be:
python
from prefect import flow
@flow
def my_flow():
...
if __name__ == "__main__":
my_flow.deploy(
name="flow-with-env",
work_pool_name="your-pool-name"
)
Or for remote source:
python
from prefect import flow
@flow
def my_flow():
...
if __name__ == "__main__":
my_flow.from_source(
source="<https://github.com/your-repo/your-project>",
entrypoint="path/to/file.py:my_flow",
).deploy(
name="flow-with-env",
work_pool_name="your-pool-name"
)
The Docker-specific configurations like volume mounts are handled at the work pool level rather than the deployment level. This approach ensures consistent configuration across all flows deployed to that work pool.Vincent Chéry
07/01/2025, 6:54 AMMarvin
07/01/2025, 6:54 AMMarvin
07/01/2025, 6:57 AMjob_variables
. Here's the correct syntax:
python
from prefect import flow
@flow
def my_flow():
...
if __name__ == "__main__":
my_flow.deploy(
name="flow-with-env",
work_pool_name="your-pool-name",
job_variables={
"volumes": [
{
"source": "/path/to/your/.env",
"destination": "/.env",
"type": "bind"
}
]
}
)
Or for remote source:
python
from prefect import flow
@flow
def my_flow():
...
if __name__ == "__main__":
my_flow.from_source(
source="<https://github.com/your-repo/your-project>",
entrypoint="path/to/file.py:my_flow",
).deploy(
name="flow-with-env",
work_pool_name="your-pool-name",
job_variables={
"volumes": [
{
"source": "/path/to/your/.env",
"destination": "/.env",
"type": "bind"
}
]
}
)
The job_variables
parameter allows you to override or extend the work pool's base job template configurations for this specific deployment. Any settings specified in job_variables
will take precedence over the corresponding settings in the work pool's base job template.
This gives you the flexibility to:
- Use different .env files for different deployments
- Override other Docker configurations on a per-deployment basis
- Keep common configurations in the work pool while allowing for deployment-specific customizations