Ali
07/16/2025, 2:14 PMMarvin
07/16/2025, 2:15 PMMarvin
07/16/2025, 2:15 PMMarvin
07/16/2025, 2:16 PMprefect-server/
├── docker-compose.yml
├── worker/
│ ├── Dockerfile
│ └── requirements.txt
2. Create your `docker-compose.yml`:
yaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
server:
image: prefecthq/prefect:2-latest
restart: always
environment:
- PREFECT_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect@postgres:5432/prefect>
ports:
- 4200:4200
depends_on:
postgres:
condition: service_healthy
command: prefect server start --host 0.0.0.0
worker:
build:
context: ./worker
dockerfile: Dockerfile
environment:
- PREFECT_API_URL=<http://server:4200/api>
depends_on:
- server
volumes:
postgres_data:
3. Create your custom worker Dockerfile
in the worker
directory:
dockerfile
FROM prefecthq/prefect:2-latest
# Copy requirements file
COPY requirements.txt .
# Install additional dependencies
RUN pip install -r requirements.txt
# Command to start the worker
CMD ["prefect", "worker", "start", "--pool", "default-agent-pool"]
4. Create a requirements.txt
file in the worker directory with your external libraries:
# Add your required packages here, for example:
pandas
requests
scikit-learn
# ... any other packages you need
To use this setup:
1. Add your required Python packages to requirements.txt
2. Start everything with:
bash
docker compose up -d
This will:
- Start a PostgreSQL database
- Launch the Prefect server (accessible at http://localhost:4200)
- Build and start your custom worker with all your dependencies
Some important notes:
1. The worker service will automatically rebuild when you modify your requirements.txt
2. You can access the Prefect UI at <http://localhost:4200>
3. If you need to add more workers or modify the work pool, you can do so through the Prefect UI or CLI
4. Make sure to adjust the PREFECT_API_URL
in both services if you're deploying this to a different host
To customize this further:
- Add more environment variables as needed
- Modify the worker's work pool name (currently set to "default-agent-pool")
- Add volume mounts if you need to persist data
- Add more services if needed (like Redis for caching)
Let me know if you need to customize any part of this setup or if you have questions about specific configurations!Ali
07/16/2025, 2:23 PMMarvin
07/16/2025, 2:23 PMMarvin
07/16/2025, 2:24 PMdocker-compose.yml
that includes Traefik labels:
yaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
server:
image: prefecthq/prefect:2-latest
restart: always
environment:
# For internal communication, use the service name
- PREFECT_API_URL=<http://server:4200/api>
# For external access, use your domain
- PREFECT_UI_API_URL=<https://prefect.yourdomain.com/api>
labels:
- "traefik.enable=true"
# HTTP Router for UI
- "traefik.http.routers.prefect-ui.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`)"
- "traefik.http.routers.prefect-ui.entrypoints=websecure"
- "traefik.http.routers.prefect-ui.tls=true"
- "traefik.http.services.prefect-ui.loadbalancer.server.port=4200"
# HTTP Router for API (same domain, different path)
- "traefik.http.routers.prefect-api.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`) && PathPrefix(`/api`)"
- "traefik.http.routers.prefect-api.entrypoints=websecure"
- "traefik.http.routers.prefect-api.tls=true"
depends_on:
postgres:
condition: service_healthy
command: prefect server start --host 0.0.0.0
worker:
build:
context: ./worker
dockerfile: Dockerfile
environment:
# Use internal HTTP URL for worker-to-server communication
- PREFECT_API_URL=<http://server:4200/api>
depends_on:
- server
volumes:
postgres_data:
Key points about this configuration:
1. Internal Communication:
- The worker can use plain <http://server:4200/api>
for internal communication because:
- It's within the Docker network
- Docker's internal DNS resolves server
to the correct service
- Internal traffic never leaves the Docker network
2. External Access:
- The Traefik labels ensure external access is properly secured via HTTPS
- Both UI and API are exposed through the same domain but with different paths
- The UI is at <https://prefect.yourdomain.com>
- The API is at <https://prefect.yourdomain.com/api>
3. Environment Variables:
- PREFECT_API_URL
for the worker uses the internal URL
- PREFECT_UI_API_URL
for the server uses the external URL (this is what the UI will use to make API calls)
Make sure to:
1. Replace <http://prefect.yourdomain.com|prefect.yourdomain.com>
with your actual domain
2. Ensure Traefik is properly configured with SSL certificates
3. Adjust the entrypoints and TLS settings according to your Traefik setup
This configuration maintains security for external access while allowing efficient internal communication. The worker doesn't need Traefik labels because it doesn't need to be accessed from outside the Docker network.
Would you like me to provide any specific Traefik configuration details or explain any part of this setup in more detail?Ali
07/16/2025, 2:55 PMMarvin
07/16/2025, 2:56 PMMarvin
07/16/2025, 2:58 PM/worker
├── Dockerfile
├── requirements.txt
└── flows/
├── __init__.py
├── deployments.py
├── flow1/
│ └── flow1.py
└── flow2/
└── flow2.py
Here's an example of how to write your `deployments.py`:
python
from prefect import flow
from prefect.deployments import Deployment
from prefect.filesystems import RemoteFileSystem
# Import your flows
from flows.flow1.flow1 import my_flow1
from flows.flow2.flow2 import my_flow2
def create_deployments():
# Create a remote filesystem block for Bitbucket
remote_fs = RemoteFileSystem(
basepath="<https://bitbucket.org/your-org/your-repo>",
credentials={"username": "your-username", "password": "your-token"}
)
# Deploy flow1
Deployment.build_from_flow(
flow=my_flow1,
name="flow1-deployment",
work_pool_name="your-work-pool",
path="/flows/flow1/flow1.py",
storage=remote_fs
)
# Deploy flow2
Deployment.build_from_flow(
flow=my_flow2,
name="flow2-deployment",
work_pool_name="your-work-pool",
path="/flows/flow2/flow2.py",
storage=remote_fs
)
if __name__ == "__main__":
create_deployments()
2. Alternative: YAML Configuration (If you prefer declarative configuration)
Create a prefect.yaml
file:
yaml
flows:
- path: ./flows/flow1/flow1.py:my_flow1
name: flow1-deployment
work_pool:
name: your-work-pool
source:
type: bitbucket
repository: your-org/your-repo
reference: main
credentials:
username: ${BITBUCKET_USERNAME}
password: ${BITBUCKET_TOKEN}
- path: ./flows/flow2/flow2.py:my_flow2
name: flow2-deployment
work_pool:
name: your-work-pool
source:
type: bitbucket
repository: your-org/your-repo
reference: main
credentials:
username: ${BITBUCKET_USERNAME}
password: ${BITBUCKET_TOKEN}
3. Modify your Dockerfile to include the deployment process:
dockerfile
FROM prefecthq/prefect:2-latest
# Copy requirements file
COPY requirements.txt .
# Install additional dependencies
RUN pip install -r requirements.txt
# Copy your flows directory
COPY flows/ /opt/prefect/flows/
# Set working directory
WORKDIR /opt/prefect
# If using Python deployment script
CMD ["python", "flows/deployments.py" && "prefect", "worker", "start", "--pool", "your-work-pool"]
# If using YAML
# CMD ["prefect", "deploy", "--all" && "prefect", "worker", "start", "--pool", "your-work-pool"]
Recommendations:
1. Use Python Scripts (Primary Recommendation) because:
- More flexible and maintainable
- Better version control
- Easier to debug
- Can include logic and conditions
- Better type checking and IDE support
2. Environment Variables
Store sensitive information like Bitbucket credentials as environment variables in your docker-compose:
yaml
worker:
environment:
- BITBUCKET_USERNAME=your-username
- BITBUCKET_TOKEN=your-token
3. Work Pool Configuration
Make sure to create your work pool before running the deployments. You can do this via the UI or CLI:
bash
prefect work-pool create your-work-pool
4. Deployment Updates
With this setup, your flows will be automatically deployed when the container starts. To update deployments:
- Push changes to Bitbucket
- Restart the worker container
Would you like me to elaborate on any part of this setup or provide more specific examples for your use case?Ali
07/16/2025, 3:13 PMMarvin
07/16/2025, 3:13 PMMarvin
07/16/2025, 3:14 PM/worker
├── Dockerfile
├── requirements.txt
└── flows/
├── __init__.py
├── deploy_all.py
├── enrollment/
│ └── deployments.py
├── admissions/
│ └── deployments.py
├── program_reviews/
│ └── deployments.py
└── general/
└── deployments.py
Here's how to implement this structure:
1. Unit-Specific Deployment Files
For example, `flows/enrollment/deployments.py`:
python
from prefect import flow
from prefect.deployments import Deployment
def create_enrollment_deployments():
# Define the Bitbucket source for enrollment flows
source = {
"repository": "<https://bitbucket.org/your-org/your-repo>",
"reference": "main", # or specific branch
"path": "enrollment" # subfolder in your Bitbucket repo
}
# Create deployments for enrollment flows
deployments = [
{
"name": "student-enrollment",
"entrypoint": "enrollment/student_enrollment.py:student_enrollment_flow",
},
{
"name": "enrollment-reporting",
"entrypoint": "enrollment/reporting.py:enrollment_reporting_flow",
},
# Add more enrollment-related deployments
]
created_deployments = []
for dep in deployments:
deployment = Deployment.build_from_flow(
name=dep["name"],
entrypoint=dep["entrypoint"],
work_pool_name="your-work-pool",
source=source
)
created_deployments.append(deployment)
return created_deployments
2. Main Deployment Script
Create flows/deploy_all.py
to manage all units:
python
from prefect import flow
from prefect.filesystems import RemoteFileSystem
# Import deployment creators from each unit
from .enrollment.deployments import create_enrollment_deployments
from .admissions.deployments import create_admissions_deployments
from .program_reviews.deployments import create_program_review_deployments
from .general.deployments import create_general_deployments
def setup_bitbucket_auth():
# You could set up common Bitbucket authentication here
# This could be used across all deployments if needed
return {
"username": "${BITBUCKET_USERNAME}",
"password": "${BITBUCKET_TOKEN}"
}
@flow
def deploy_all_flows():
"""Deploy all flows from all units"""
# Deploy flows from each unit
all_deployments = []
all_deployments.extend(create_enrollment_deployments())
all_deployments.extend(create_admissions_deployments())
all_deployments.extend(create_program_review_deployments())
all_deployments.extend(create_general_deployments())
return f"Successfully created {len(all_deployments)} deployments"
if __name__ == "__main__":
deploy_all_flows()
3. Modified Dockerfile
dockerfile
FROM prefecthq/prefect:2-latest
# Copy requirements file
COPY requirements.txt .
# Install additional dependencies
RUN pip install -r requirements.txt
# Copy only the deployment configuration
COPY flows/ /opt/prefect/flows/
# Set working directory
WORKDIR /opt/prefect
# Run deployments and start worker
CMD ["bash", "-c", "python -m flows.deploy_all && prefect worker start --pool your-work-pool"]
4. Bitbucket Repository Structure
Your Bitbucket repository should be organized like this:
repository/
├── enrollment/
│ ├── student_enrollment.py
│ └── reporting.py
├── admissions/
│ ├── application_processing.py
│ └── decision_flows.py
├── program_reviews/
│ └── review_flows.py
└── general/
└── utility_flows.py
Key Benefits of this Structure:Marvin
07/16/2025, 3:14 PMdeployments.py
file
Important Notes:
1. Path References: Make sure your entrypoint
paths in the deployments match your Bitbucket repository structure
2. Work Pool Configuration: You might want to consider using different work pools for different units:
python
work_pool_name=f"{unit_name}-pool" # e.g., "enrollment-pool"
3. Environment Variables: In your docker-compose.yml, include:
yaml
worker:
environment:
- BITBUCKET_USERNAME=your-username
- BITBUCKET_TOKEN=your-token
- PREFECT_API_URL=<http://server:4200/api>
4. Versioning: You can add version control by specifying branches or tags in your source configuration:
python
source = {
"repository": "<https://bitbucket.org/your-org/your-repo>",
"reference": "production", # or staging, development, etc.
"path": "enrollment"
}
Would you like me to elaborate on any part of this structure or provide more specific examples for any of the units?Ali
07/16/2025, 3:59 PMMarvin
07/16/2025, 3:59 PMMarvin
07/16/2025, 3:59 PMAli
07/16/2025, 4:08 PMfrom prefect import flow
from prefect.runner.storage import GitRepository
from prefect_bitbucket import BitBucketCredentials
from prefect.schedules import Interval
from datetime import datetime, timedelta
if __name__ == "__main__":
source = GitRepository(
url="url",
credentials=BitBucketCredentials.load("gsbitbucket")
)
flow.from_source(
source=source,
entrypoint="Enrollment/Gradapp/GradApp.py:gradAppFlow",
).deploy(
name="LoadGradApp",
work_pool_name="grad_flow_docker",
image = 'gs_flows:latest',
tags=["Enrollment"],
schedules=[
Interval(
timedelta(days=1),
datetime(2023, 1, 1, 6, 0),
"America/Chicago"
)
],
description="Grad App flow running daily at 6 AM CDT from Bitbucket"
)
Marvin
07/16/2025, 4:09 PMMarvin
07/16/2025, 4:09 PMpython
from prefect import flow
from prefect.deployments import Deployment
from prefect.filesystems import RemoteFileSystem
from prefect.server.schemas.schedules import IntervalSchedule
from datetime import datetime, timedelta
def create_enrollment_deployments():
# Set up Bitbucket credentials (using existing block)
source = {
"repository": "url", # Your Bitbucket URL
"credentials": "gsbitbucket", # Your existing credentials block
"reference": "main" # or whatever branch you're using
}
# Create deployment for GradApp
gradapp_deployment = Deployment.build_from_flow(
flow_name="gradAppFlow",
name="LoadGradApp",
path="Enrollment/Gradapp/GradApp.py:gradAppFlow",
work_pool_name="grad_flow_docker",
work_queue_name="default",
tags=["Enrollment"],
infrastructure_document={
"type": "docker-container",
"image": "gs_flows:latest"
},
schedule=IntervalSchedule(
interval=timedelta(days=1),
anchor_date=datetime(2023, 1, 1, 6, 0),
timezone="America/Chicago"
),
description="Grad App flow running daily at 6 AM CDT from Bitbucket",
source=source
)
return [gradapp_deployment]
if __name__ == "__main__":
# Create and apply all enrollment deployments
deployments = create_enrollment_deployments()
for deployment in deployments:
deployment.apply()
Key changes and improvements:
1. Modern Structure: Uses the current Prefect 3.x deployment patterns
2. Flexible Design: The create_enrollment_deployments()
function returns a list, making it easy to add more enrollment-related deployments later
3. Schedule Format: Uses the current IntervalSchedule
format while maintaining your existing schedule settings
4. Docker Configuration: Explicitly defines the Docker infrastructure settings
You can expand this by adding more deployments to the same file. For example, if you have other enrollment-related flows:
python
def create_enrollment_deployments():
source = {
"repository": "url",
"credentials": "gsbitbucket",
"reference": "main"
}
deployments = []
# GradApp Deployment
gradapp_deployment = Deployment.build_from_flow(
flow_name="gradAppFlow",
name="LoadGradApp",
path="Enrollment/Gradapp/GradApp.py:gradAppFlow",
work_pool_name="grad_flow_docker",
work_queue_name="default",
tags=["Enrollment"],
infrastructure_document={
"type": "docker-container",
"image": "gs_flows:latest"
},
schedule=IntervalSchedule(
interval=timedelta(days=1),
anchor_date=datetime(2023, 1, 1, 6, 0),
timezone="America/Chicago"
),
description="Grad App flow running daily at 6 AM CDT from Bitbucket",
source=source
)
deployments.append(gradapp_deployment)
# Add additional enrollment deployments here
# Example:
# enrollment_stats_deployment = Deployment.build_from_flow(
# flow_name="enrollmentStatsFlow",
# name="EnrollmentStats",
# path="Enrollment/Stats/enrollment_stats.py:enrollment_stats_flow",
# ...
# )
# deployments.append(enrollment_stats_deployment)
return deployments
if __name__ == "__main__":
deployments = create_enrollment_deployments()
for deployment in deployments:
deployment.apply()
To use this in your Docker setup:
1. Save this as flows/enrollment/deployments.py
2. Make sure your requirements.txt
includes:
prefect>=3.0.0
prefect-bitbucket # if you're using Bitbucket-specific features
Would you like me to:
1. Add more enrollment-related deployments to this structure?
2. Show how to integrate this with the main deployment script?Marvin
07/16/2025, 4:09 PMAli
07/16/2025, 4:12 PMMarvin
07/16/2025, 4:12 PMMarvin
07/16/2025, 4:12 PMdeploy_all.py
. Here's the streamlined version:
python
from prefect import flow
# Import deployment creators from each unit
from .enrollment.deployments import create_enrollment_deployments
from .admissions.deployments import create_admissions_deployments
from .program_reviews.deployments import create_program_review_deployments
from .general.deployments import create_general_deployments
@flow(name="deploy-all-flows")
def deploy_all_flows():
"""Deploy all flows from all units"""
deployments = []
# Collect all deployments
try:
deployments.extend(create_enrollment_deployments())
print("✅ Enrollment deployments created successfully")
except Exception as e:
print(f"❌ Error creating enrollment deployments: {e}")
try:
deployments.extend(create_admissions_deployments())
print("✅ Admissions deployments created successfully")
except Exception as e:
print(f"❌ Error creating admissions deployments: {e}")
try:
deployments.extend(create_program_review_deployments())
print("✅ Program review deployments created successfully")
except Exception as e:
print(f"❌ Error creating program review deployments: {e}")
try:
deployments.extend(create_general_deployments())
print("✅ General deployments created successfully")
except Exception as e:
print(f"❌ Error creating general deployments: {e}")
# Apply all deployments
successful_deployments = 0
failed_deployments = 0
for deployment in deployments:
try:
deployment.apply()
successful_deployments += 1
print(f"✅ Successfully deployed: {deployment.name}")
except Exception as e:
failed_deployments += 1
print(f"❌ Failed to deploy {deployment.name}: {e}")
# Summary
print("\n=== Deployment Summary ===")
print(f"Total deployments attempted: {len(deployments)}")
print(f"Successful deployments: {successful_deployments}")
print(f"Failed deployments: {failed_deployments}")
return {
"total": len(deployments),
"successful": successful_deployments,
"failed": failed_deployments
}
if __name__ == "__main__":
deploy_all_flows()
This version:
1. Removes Redundant Auth: No need for Bitbucket auth setup since it's handled by your credential blocks
2. Adds Error Handling: Each unit's deployments are created in a try-except block
3. Provides Feedback: Clear console output showing which deployments succeeded or failed
4. Includes Summary: Shows total statistics at the end
You can run this from your Dockerfile like before:
dockerfile
FROM prefecthq/prefect:2-latest
# Copy requirements file
COPY requirements.txt .
# Install additional dependencies
RUN pip install -r requirements.txt
# Copy only the deployment configuration
COPY flows/ /opt/prefect/flows/
# Set working directory
WORKDIR /opt/prefect
# Run deployments and start worker
CMD ["bash", "-c", "python -m flows.deploy_all && prefect worker start --pool grad_flow_docker"]
And each unit's deployment file (like your enrollment one) would remain focused on just defining its specific deployments.
The structure would look like:
/worker
├── Dockerfile
├── requirements.txt
└── flows/
├── __init__.py
├── deploy_all.py
├── enrollment/
│ ├── __init__.py
│ └── deployments.py # Your enrollment deployment code we just updated
├── admissions/
│ ├── __init__.py
│ └── deployments.py # Similar structure for admissions
├── program_reviews/
│ ├── __init__.py
│ └── deployments.py # Similar structure for program reviews
└── general/
├── __init__.py
└── deployments.py # Similar structure for general flows
Marvin
07/16/2025, 4:12 PMdeployments.py
would follow the pattern we established in your enrollment deployment, just with their specific flows and configurations.
Would you like me to:
1. Show an example of one of the other unit's deployment files?
2. Add any additional error handling or logging?
3. Modify the summary output format?Ali
07/16/2025, 4:17 PMMarvin
07/16/2025, 4:17 PMMarvin
07/16/2025, 4:17 PMbash
# For first time deployment or to see logs
docker compose up
# For production/background running
docker compose up -d
# If you need to rebuild (e.g., after changing requirements.txt or deployment code)
docker compose up -d --build
A few important things to keep in mind:
1. The first time you run it, you might want to run without -d
to watch the logs and make sure:
- All deployments are created successfully
- The worker starts properly
- No authentication issues with Bitbucket
2. If you make changes to:
- requirements.txt
- Any deployment code
- Dockerfile
You'll need to include the --build
flag to rebuild the container.
3. To check logs after running with `-d`:
bash
docker compose logs -f worker
4. If something goes wrong, you can:
bash
# Stop everything
docker compose down
# Check logs
docker compose logs worker
# Start fresh
docker compose up -d --build
Would you like me to provide any specific troubleshooting steps or explain any other Docker Compose commands that might be useful for managing your deployment?Ali
07/16/2025, 4:18 PMMarvin
07/16/2025, 4:19 PMMarvin
07/16/2025, 4:19 PMCMD
in the Dockerfile:
dockerfile
CMD ["bash", "-c", "python -m flows.deploy_all && prefect worker start --pool grad_flow_docker"]
This means every time the container starts (whether from a fresh docker compose up
or a restart), it will:
1. Run the deploy_all.py
script first, which:
- Creates/updates all your deployments across all units (enrollment, admissions, etc.)
- Provides that nice summary output of what was deployed
- Automatically handles any updates if you've changed flow configurations
2. Then starts the worker to actually run the flows
So yes, you don't need any additional commands! It's all automated as part of the container startup. This is particularly convenient because:
- No need to manually run deployment commands
- If you update any deployment configurations, just rebuild and restart the container
- If the container restarts for any reason, it'll ensure all deployments are up to date before starting the worker
The only time you'd need to run additional commands would be if you want to:
- Add new flows
- Modify existing flow configurations
- Change requirements
In those cases, you'd just:
1. Make your changes
2. docker compose up -d --build
And everything else happens automatically! 😊Ali
07/16/2025, 4:23 PMsudo docker compose logs worker
worker-1 | Traceback (most recent call last):
worker-1 | File "/usr/local/lib/python3.10/runpy.py", line 196, in _run_module_as_main
worker-1 | return _run_code(code, main_globals, None,
worker-1 | File "/usr/local/lib/python3.10/runpy.py", line 86, in _run_code
worker-1 | exec(code, run_globals)
worker-1 | File "/opt/prefect/flows/deploy_all.py", line 4, in <module>
worker-1 | from .enrollment.deployments import create_enrollment_deployments
worker-1 | File "/opt/prefect/flows/enrollment/deployments.py", line 2, in <module>
worker-1 | from prefect.deployments import Deployment
worker-1 | File "/usr/local/lib/python3.10/site-packages/prefect/deployments/__init__.py", line 23, in __getattr__
worker-1 | return getattr_migration(__name__)(attr_name)
worker-1 | File "/usr/local/lib/python3.10/site-packages/prefect/_internal/compatibility/migration.py", line 156, in wrapper
worker-1 | raise PrefectImportError(
worker-1 | prefect.exceptions.PrefectImportError: `prefect.deployments:Deployment` has been removed. Use `flow.serve()`, `flow.deploy()`, or `prefect deploy` instead.
achaghan@tosmgrad0006:/usr/share/docker/prefect2$
Marvin
07/16/2025, 4:23 PMMarvin
07/16/2025, 4:23 PMDeployment
class. Let me update your code to use the current method:
1. Update `flows/enrollment/deployments.py`:
python
from prefect import flow
from prefect.server.schemas.schedules import IntervalSchedule
from datetime import datetime, timedelta
def create_enrollment_deployments():
"""Create all enrollment-related deployments"""
from prefect.flows import load_flow_from_source
# Load the flow from source
gradapp_flow = load_flow_from_source(
source="url", # Your Bitbucket URL
entrypoint="Enrollment/Gradapp/GradApp.py:gradAppFlow",
credentials="gsbitbucket" # Your existing credentials block
)
# Deploy the flow
gradapp_flow.deploy(
name="LoadGradApp",
work_pool_name="grad_flow_docker",
image="gs_flows:latest",
tags=["Enrollment"],
schedule=IntervalSchedule(
interval=timedelta(days=1),
anchor_date=datetime(2023, 1, 1, 6, 0),
timezone="America/Chicago"
),
description="Grad App flow running daily at 6 AM CDT from Bitbucket"
)
return ["LoadGradApp"] # Return list of deployment names for tracking
2. Update `flows/deploy_all.py`:
python
from prefect import flow
# Import deployment creators from each unit
from .enrollment.deployments import create_enrollment_deployments
from .admissions.deployments import create_admissions_deployments
from .program_reviews.deployments import create_program_review_deployments
from .general.deployments import create_general_deployments
@flow(name="deploy-all-flows")
def deploy_all_flows():
"""Deploy all flows from all units"""
all_deployments = []
# Create deployments for each unit
try:
enrollment_deps = create_enrollment_deployments()
all_deployments.extend(enrollment_deps)
print(f"✅ Created {len(enrollment_deps)} enrollment deployments")
except Exception as e:
print(f"❌ Error creating enrollment deployments: {e}")
try:
admissions_deps = create_admissions_deployments()
all_deployments.extend(admissions_deps)
print(f"✅ Created {len(admissions_deps)} admissions deployments")
except Exception as e:
print(f"❌ Error creating admissions deployments: {e}")
try:
program_review_deps = create_program_review_deployments()
all_deployments.extend(program_review_deps)
print(f"✅ Created {len(program_review_deps)} program review deployments")
except Exception as e:
print(f"❌ Error creating program review deployments: {e}")
try:
general_deps = create_general_deployments()
all_deployments.extend(general_deps)
print(f"✅ Created {len(general_deps)} general deployments")
except Exception as e:
print(f"❌ Error creating general deployments: {e}")
# Summary
print("\n=== Deployment Summary ===")
print(f"Total deployments created: {len(all_deployments)}")
print("Deployments:", ", ".join(all_deployments))
return {
"total": len(all_deployments),
"deployments": all_deployments
}
if __name__ == "__main__":
deploy_all_flows()
The main changes are:
1. Removed Deployment
class usage
2. Now using flow.deploy()
directly
3. Simplified the deployment process
4. Each unit's deployment function now returns a list of deployment names instead of deployment objects
Your Dockerfile remains the same:
dockerfile
FROM prefecthq/prefect:2-latest
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY flows/ /opt/prefect/flows/
WORKDIR /opt/prefect
CMD ["bash", "-c", "python -m flows.deploy_all && prefect worker start --pool grad_flow_docker"]
To apply these changes:
1. Update your files with the new code
2. Rebuild and restart:
bash
docker compose up -d --build
Marvin
07/16/2025, 4:23 PMAli
07/16/2025, 4:33 PMsudo docker compose logs worker
worker-1 | Traceback (most recent call last):
worker-1 | File "/usr/local/lib/python3.10/runpy.py", line 196, in _run_module_as_main
worker-1 | return _run_code(code, main_globals, None,
worker-1 | File "/usr/local/lib/python3.10/runpy.py", line 86, in _run_code
worker-1 | exec(code, run_globals)
worker-1 | File "/opt/prefect/flows/deploy_all.py", line 55, in <module>
worker-1 | deploy_all_flows()
worker-1 | File "/usr/local/lib/python3.10/site-packages/prefect/flows.py", line 1699, in __call__
worker-1 | return run_flow(
worker-1 | File "/usr/local/lib/python3.10/site-packages/prefect/flow_engine.py", line 1530, in run_flow
worker-1 | ret_val = run_flow_sync(**kwargs)
worker-1 | File "/usr/local/lib/python3.10/site-packages/prefect/flow_engine.py", line 1370, in run_flow_sync
worker-1 | with engine.start():
worker-1 | File "/usr/local/lib/python3.10/contextlib.py", line 135, in __enter__
worker-1 | return next(self.gen)
worker-1 | File "/usr/local/lib/python3.10/site-packages/prefect/flow_engine.py", line 742, in start
worker-1 | with self.initialize_run():
worker-1 | File "/usr/local/lib/python3.10/contextlib.py", line 135, in __enter__
worker-1 | return next(self.gen)
worker-1 | File "/usr/local/lib/python3.10/site-packages/prefect/flow_engine.py", line 670, in initialize_run
worker-1 | with SyncClientContext.get_or_create() as client_ctx:
worker-1 | File "/usr/local/lib/python3.10/contextlib.py", line 135, in __enter__
worker-1 | return next(self.gen)
worker-1 | File "/usr/local/lib/python3.10/site-packages/prefect/context.py", line 267, in get_or_create
worker-1 | with cls() as ctx:
worker-1 | File "/usr/local/lib/python3.10/site-packages/prefect/context.py", line 249, in __enter__
worker-1 | self.client.raise_for_api_version_mismatch()
worker-1 | File "/usr/local/lib/python3.10/site-packages/prefect/client/orchestration/__init__.py", line 1398, in raise_for_api_version_mismatch
worker-1 | raise RuntimeError(
worker-1 | RuntimeError: Found incompatible versions: client: 3.4.8, server: 2.20.18. Major versions must match.
achaghan@tosmgrad0006:/usr/share/docker/prefect2$
Marvin
07/16/2025, 4:33 PMMarvin
07/16/2025, 4:33 PMdockerfile
FROM prefecthq/prefect:2.20.18
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY flows/ /opt/prefect/flows/
WORKDIR /opt/prefect
CMD ["bash", "-c", "python -m flows.deploy_all && prefect worker start --pool grad_flow_docker"]
And let's update your deployment code to use Prefect 2.x syntax:
1. Update `flows/enrollment/deployments.py`:
python
from prefect import flow
from prefect.deployments import Deployment
from prefect.runner.storage import GitRepository
from prefect.schedules import IntervalSchedule
from datetime import datetime, timedelta
def create_enrollment_deployments():
"""Create all enrollment-related deployments"""
# Set up the source
source = GitRepository(
url="url", # Your Bitbucket URL
credentials="gsbitbucket" # Your existing credentials block
)
# Create deployment
gradapp_deployment = Deployment.build_from_flow(
flow_name="gradAppFlow",
name="LoadGradApp",
storage=source,
path="Enrollment/Gradapp/GradApp.py:gradAppFlow",
work_queue_name="default",
work_pool_name="grad_flow_docker",
infrastructure_document={
"type": "docker-container",
"image": "gs_flows:latest"
},
tags=["Enrollment"],
schedule=IntervalSchedule(
interval=timedelta(days=1),
anchor_date=datetime(2023, 1, 1, 6, 0),
timezone="America/Chicago"
),
description="Grad App flow running daily at 6 AM CDT from Bitbucket"
)
# Apply the deployment
gradapp_deployment.apply()
return ["LoadGradApp"] # Return list of deployment names for tracking
2. The deploy_all.py
can remain the same as it's just orchestrating the deployments.
3. Update your requirements.txt
to pin the Prefect version:
prefect==2.20.18
prefect-bitbucket # if you're using this
To apply these changes:
1. Stop your current containers:
bash
docker compose down
2. Rebuild with the correct version:
bash
docker compose up -d --build
This should resolve the version mismatch error. The key changes are:
1. Using the exact Prefect version that matches your server (2.20.18)
2. Using Prefect 2.x deployment syntax with Deployment.build_from_flow()
3. Ensuring all dependencies match the 2.x version
Let me know if you see any other errors after making these changes!Ali
07/16/2025, 4:34 PMMarvin
07/16/2025, 4:34 PMMarvin
07/16/2025, 4:35 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
server:
image: prefecthq/prefect:3.4.8 # Updated to 3.x
restart: always
environment:
- PREFECT_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect@postgres:5432/prefect>
ports:
- 4200:4200
depends_on:
postgres:
condition: service_healthy
command: prefect server start --host 0.0.0.0
volumes:
postgres_data:
2. Then you can keep your worker code in the 3.x format we had before:
python
# flows/enrollment/deployments.py
from prefect import flow
from prefect.server.schemas.schedules import IntervalSchedule
from datetime import datetime, timedelta
def create_enrollment_deployments():
"""Create all enrollment-related deployments"""
from prefect.flows import load_flow_from_source
# Load the flow from source
gradapp_flow = load_flow_from_source(
source="url", # Your Bitbucket URL
entrypoint="Enrollment/Gradapp/GradApp.py:gradAppFlow",
credentials="gsbitbucket" # Your existing credentials block
)
# Deploy the flow
gradapp_flow.deploy(
name="LoadGradApp",
work_pool_name="grad_flow_docker",
image="gs_flows:latest",
tags=["Enrollment"],
schedule=IntervalSchedule(
interval=timedelta(days=1),
anchor_date=datetime(2023, 1, 1, 6, 0),
timezone="America/Chicago"
),
description="Grad App flow running daily at 6 AM CDT from Bitbucket"
)
return ["LoadGradApp"]
3. And keep your worker's Dockerfile using 3.x:
dockerfile
FROM prefecthq/prefect:3.4.8
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY flows/ /opt/prefect/flows/
WORKDIR /opt/prefect
CMD ["bash", "-c", "python -m flows.deploy_all && prefect worker start --pool grad_flow_docker"]
To update:
1. Stop all Prefect services:
bash
docker compose down
2. Back up your PostgreSQL data (just in case):
bash
docker compose exec postgres pg_dump -U prefect prefect > prefect_backup.sql
3. Update your docker-compose files with the new versions
4. Rebuild and start everything:
bash
docker compose up -d --build
Important notes about the upgrade:
1. Make sure to back up any important flow data before upgrading
2. You might need to recreate your work pools after the upgrade
3. The upgrade might require recreating your deployments
4. Make sure all your flows are compatible with Prefect 3.x syntax
Would you like me to:
1. Provide more details about any specific part of the upgrade process?
2. Show you how to verify the upgrade was successful?
3. Help with migrating any specific flows or deployments?Ali
07/16/2025, 4:37 PMMarvin
07/16/2025, 4:37 PMMarvin
07/16/2025, 4:38 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
server:
image: prefecthq/prefect:3.4.8
restart: always
environment:
- PREFECT_API_URL=<http://server:4200/api> # Internal URL
- PREFECT_UI_API_URL=<https://prefect.yourdomain.com/api> # External URL for UI
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect@postgres:5432/prefect>
depends_on:
postgres:
condition: service_healthy
command: prefect server start --host 0.0.0.0
labels:
- "traefik.enable=true"
# UI Router
- "traefik.http.routers.prefect-ui.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`)"
- "traefik.http.routers.prefect-ui.entrypoints=websecure"
- "traefik.http.routers.prefect-ui.tls=true"
- "traefik.http.services.prefect-ui.loadbalancer.server.port=4200"
# API Router
- "traefik.http.routers.prefect-api.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`) && PathPrefix(`/api`)"
- "traefik.http.routers.prefect-api.entrypoints=websecure"
- "traefik.http.routers.prefect-api.tls=true"
- "traefik.http.routers.prefect-api.service=prefect-api"
- "traefik.http.services.prefect-api.loadbalancer.server.port=4200"
networks:
- traefik-public
- prefect-network
worker:
build:
context: ./worker
dockerfile: Dockerfile
restart: always
environment:
- PREFECT_API_URL=<http://server:4200/api> # Internal URL
- BITBUCKET_USERNAME=${BITBUCKET_USERNAME}
- BITBUCKET_TOKEN=${BITBUCKET_TOKEN}
depends_on:
- server
volumes:
- /var/run/docker.sock:/var/run/docker.sock # If you need Docker socket for infrastructure
networks:
- prefect-network
networks:
traefik-public:
external: true # Assuming this is your existing Traefik network
prefect-network:
name: prefect-network
driver: bridge
volumes:
postgres_data:
And here's the corresponding worker Dockerfile for completeness:
dockerfile
FROM prefecthq/prefect:3.4.8
# Install additional system dependencies if needed
# RUN apt-get update && apt-get install -y ...
# Copy requirements file
COPY requirements.txt .
# Install Python dependencies
RUN pip install -r requirements.txt
# Copy your deployment code
COPY flows/ /opt/prefect/flows/
# Set working directory
WORKDIR /opt/prefect
# Start deployments and worker
CMD ["bash", "-c", "python -m flows.deploy_all && prefect worker start --pool grad_flow_docker"]
Key points about this configuration:
1. Networks:
- `traefik-public`: External network for Traefik
- `prefect-network`: Internal network for Prefect services
2. Environment Variables:
- Server uses both internal and external URLs
- Worker uses internal URL for communication
- Bitbucket credentials are passed as environment variables
3. Traefik Labels:
- Separate routes for UI and API
- Both secured with TLS
- Using websecure entrypoint
4. Volumes:
- Persistent PostgreSQL data
- Docker socket mounted for worker (if needed for infrastructure)
5. Dependencies:
- Worker depends on server
- Server depends on postgres
- Health checks ensure proper startup order
To use this:
1. Create a .env
file for your secrets:
env
BITBUCKET_USERNAME=your-username
BITBUCKET_TOKEN=your-token
2. Make sure to replace:
- <http://prefect.yourdomain.com|prefect.yourdomain.com>
with your actual domain
- Adjust any network names to match your environment
- Update any paths or volume mounts as needed
3. Start everything:
```bashMarvin
07/16/2025, 4:38 PMAli
07/16/2025, 4:40 PMMarvin
07/16/2025, 4:40 PMMarvin
07/16/2025, 4:41 PMcredentials="gsbitbucket"
) in your deployment code, you don't need to pass those environment variables to the worker container. That was redundant on my part.
Here's the corrected docker-compose.yml without those unnecessary environment variables:
yaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
server:
image: prefecthq/prefect:3.4.8
restart: always
environment:
- PREFECT_API_URL=<http://server:4200/api> # Internal URL
- PREFECT_UI_API_URL=<https://prefect.yourdomain.com/api> # External URL for UI
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect@postgres:5432/prefect>
depends_on:
postgres:
condition: service_healthy
command: prefect server start --host 0.0.0.0
labels:
- "traefik.enable=true"
# UI Router
- "traefik.http.routers.prefect-ui.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`)"
- "traefik.http.routers.prefect-ui.entrypoints=websecure"
- "traefik.http.routers.prefect-ui.tls=true"
- "traefik.http.services.prefect-ui.loadbalancer.server.port=4200"
# API Router
- "traefik.http.routers.prefect-api.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`) && PathPrefix(`/api`)"
- "traefik.http.routers.prefect-api.entrypoints=websecure"
- "traefik.http.routers.prefect-api.tls=true"
- "traefik.http.routers.prefect-api.service=prefect-api"
- "traefik.http.services.prefect-api.loadbalancer.server.port=4200"
networks:
- traefik-public
- prefect-network
worker:
build:
context: ./worker
dockerfile: Dockerfile
restart: always
environment:
- PREFECT_API_URL=<http://server:4200/api> # Internal URL
depends_on:
- server
volumes:
- /var/run/docker.sock:/var/run/docker.sock # If you need Docker socket for infrastructure
networks:
- prefect-network
networks:
traefik-public:
external: true # Assuming this is your existing Traefik network
prefect-network:
name: prefect-network
driver: bridge
volumes:
postgres_data:
The credentials block you're using in your deployment code (credentials="gsbitbucket"
) handles the authentication with Bitbucket, so there's no need to pass those credentials again through environment variables. This is actually a better practice because:
1. The credentials are managed through Prefect's block system
2. More secure as the credentials aren't exposed in environment variables
3. Easier to manage and update credentials through Prefect's UI/API
Would you like me to explain anything else about the configuration or credential management?Ali
07/16/2025, 4:43 PMMarvin
07/16/2025, 4:43 PMMarvin
07/16/2025, 4:44 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
server:
image: prefecthq/prefect:2-latest # We'll update this once we confirm the correct 3.x tag
restart: always
environment:
- PREFECT_API_URL=<http://server:4200/api> # Internal URL
- PREFECT_UI_API_URL=<https://prefect.yourdomain.com/api> # External URL for UI
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect@postgres:5432/prefect>
depends_on:
postgres:
condition: service_healthy
command: prefect server start --host 0.0.0.0
labels:
- "traefik.enable=true"
# UI Router
- "traefik.http.routers.prefect-ui.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`)"
- "traefik.http.routers.prefect-ui.entrypoints=websecure"
- "traefik.http.routers.prefect-ui.tls=true"
- "traefik.http.services.prefect-ui.loadbalancer.server.port=4200"
# API Router
- "traefik.http.routers.prefect-api.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`) && PathPrefix(`/api`)"
- "traefik.http.routers.prefect-api.entrypoints=websecure"
- "traefik.http.routers.prefect-api.tls=true"
- "traefik.http.routers.prefect-api.service=prefect-api"
- "traefik.http.services.prefect-api.loadbalancer.server.port=4200"
networks:
- traefik-public
- prefect-network
worker:
build:
context: ./worker
dockerfile: Dockerfile
restart: always
environment:
- PREFECT_API_URL=<http://server:4200/api> # Internal URL
depends_on:
- server
volumes:
- /var/run/docker.sock:/var/run/docker.sock # If you need Docker socket for infrastructure
networks:
- prefect-network
networks:
traefik-public:
external: true
prefect-network:
name: prefect-network
driver: bridge
volumes:
postgres_data:
And update your Dockerfile to match:
dockerfile
FROM prefecthq/prefect:2-latest
# Copy requirements file
COPY requirements.txt .
# Install Python dependencies
RUN pip install -r requirements.txt
# Copy your deployment code
COPY flows/ /opt/prefect/flows/
# Set working directory
WORKDIR /opt/prefect
# Start deployments and worker
CMD ["bash", "-c", "python -m flows.deploy_all && prefect worker start --pool grad_flow_docker"]
For now, I've set it to use 2-latest
while we confirm the correct 3.x tag. Could you try running:
bash
docker pull prefecthq/prefect:2-latest
And let me know if that works? Then we can check what 3.x tags are available by running:
bash
docker search prefecthq/prefect
This will help us identify the correct tag format for version 3. Would you mind running those commands and sharing the output? That way, I can provide you with the exact correct tag to use.Ali
07/16/2025, 4:47 PMsudo docker pull prefecthq/prefect:2-latest
2-latest: Pulling from prefecthq/prefect
Digest: sha256:413f5d4189b023f3f67936281f8b690d69b2fab7e576601fe5ecf96d1b1961ac
Status: Image is up to date for prefecthq/prefect:2-latest
<http://docker.io/prefecthq/prefect:2-latest|docker.io/prefecthq/prefect:2-latest>
achaghan@tosmgrad0006:/usr/share/docker/prefect2$ sudo docker search prefecthq/prefect
NAME DESCRIPTION STARS OFFICIAL
prefecthq/prefect Prefect is a workflow orchestration framewor… 52
prefecthq/prefect-dev Prefect development images 0
simonsobs/prefect-worker 0
prefecthq/server 2
prefecthq/apollo 0
prefecthq/ui 4
prefecthq/prometheus-prefect-exporter Prometheus Prefect Exporter image 0
prefecthq/prefect-client An optimized image for the Prefect client. 0
prefecthq/prefect-client-dev An optimized image for the Prefect client (d… 0
prefecthq/prefect-operator-dev Development versions of the Prefect Operator… 0
prefecthq/prefect-operator Docker image for the Prefect Operator: https… 0
kingsleyprefect/prefect_pulic 0
prefecthq/flows Prefect Cloud Example Flows 0
yaronlevi/prefect 0
tnpatlas/prefect 0
znicholasbrown/prefect_flow 0
prefecthq/orion for testing orion images 0
andreykudr/prefect 0
jdduprey/rca-data-tools-prefect2 0
jliubutter/prefect 0
dabbleofdevops/prefect2 0
prefecthq/demos 0
kendrsq/prefect-dbt Repo for dbt related flows 0
annaprefect/prefect-s3 0
andsande/prefect 0
achaghan@tosmgrad0006:/usr/share/docker/prefect2$
Marvin
07/16/2025, 4:47 PMMarvin
07/16/2025, 4:47 PMyaml
version: '3.8'
services:
postgres:
# ... (same as before)
server:
image: prefecthq/prefect:3-latest # Changed from 3.4.8 to 3-latest
# ... (rest of server config)
worker:
# ... (same as before)
And update your Dockerfile as well:
dockerfile
FROM prefecthq/prefect:3-latest # Changed from 3.4.8 to 3-latest
# Rest of Dockerfile remains the same
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY flows/ /opt/prefect/flows/
WORKDIR /opt/prefect
CMD ["bash", "-c", "python -m flows.deploy_all && prefect worker start --pool grad_flow_docker"]
The tag format follows the pattern of {major-version}-latest
, so:
- For Prefect 2.x: 2-latest
- For Prefect 3.x: 3-latest
Try rebuilding with these changes:
bash
docker compose down
docker compose up -d --build
This should resolve the "manifest not found" error. The 3-latest
tag will give you the latest stable version of Prefect 3.x.
Let me know if you still see any errors!Ali
07/16/2025, 5:31 PMMarvin
07/16/2025, 5:31 PMMarvin
07/16/2025, 5:32 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
server:
image: prefecthq/prefect:3-latest
restart: always
environment:
# Internal URL for services
- PREFECT_API_URL=<http://server:4200/api>
# External URL for UI (important for Traefik routing)
- PREFECT_UI_API_URL=<https://prefect.yourdomain.com/api>
- PREFECT_SERVER_API_HOST=0.0.0.0
- PREFECT_SERVER_API_PORT=4200
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect@postgres:5432/prefect>
depends_on:
postgres:
condition: service_healthy
command: prefect server start
labels:
- "traefik.enable=true"
# UI Router
- "traefik.http.routers.prefect-ui.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`)"
- "traefik.http.routers.prefect-ui.entrypoints=websecure"
- "traefik.http.routers.prefect-ui.tls=true"
- "traefik.http.services.prefect-ui.loadbalancer.server.port=4200"
# API Router
- "traefik.http.routers.prefect-api.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`) && PathPrefix(`/api/`)"
- "traefik.http.routers.prefect-api.entrypoints=websecure"
- "traefik.http.routers.prefect-api.tls=true"
- "traefik.http.services.prefect-api.loadbalancer.server.port=4200"
# Middleware to handle paths
- "traefik.http.middlewares.prefect-strip-prefix.stripprefix.prefixes=/api"
- "traefik.http.routers.prefect-api.middlewares=prefect-strip-prefix@docker"
networks:
- traefik-public
- prefect-network
worker:
build:
context: ./worker
dockerfile: Dockerfile
restart: always
environment:
- PREFECT_API_URL=<http://server:4200/api>
depends_on:
- server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- prefect-network
networks:
traefik-public:
external: true
prefect-network:
name: prefect-network
driver: bridge
volumes:
postgres_data:
Key changes made:
1. Added explicit server API host and port settings
2. Updated the Traefik labels to handle API path stripping correctly
3. Added middleware for API path handling
4. Ensured proper environment variables for both internal and external URLs
To apply these changes:
1. Stop your current setup:
bash
docker compose down
2. Remove any cached images (optional but recommended for clean slate):
bash
docker compose rm -f
docker system prune -f
3. Start everything up again:
bash
docker compose up -d --build
4. Check the logs to ensure everything is starting correctly:
bash
docker compose logs -f server
The UI should now be accessible at <https://prefect.yourdomain.com>
and the API at <https://prefect.yourdomain.com/api>
.
If you're still having issues, could you:
1. Share any error messages you see in the logs?
2. Confirm if you can access the server directly (without Traefik) at port 4200?
3. Check if there are any Traefik logs showing routing issues?Ali
07/16/2025, 5:40 PM17:37:27.119 | ERROR | prefect.server.utilities.postgres_listener - Failed to establish raw asyncpg connection for LISTEN/NOTIFY: password authentication failed for user "prefect"
...
server-1 | asyncpg.exceptions.InvalidPasswordError: password authentication failed for user "prefect"
Marvin
07/16/2025, 5:40 PMMarvin
07/16/2025, 5:40 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect_pass # Changed password to be more distinct
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
server:
image: prefecthq/prefect:3-latest
restart: always
environment:
# Database connection
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect_pass@postgres:5432/prefect>
# API and UI URLs
- PREFECT_API_URL=<http://server:4200/api>
- PREFECT_UI_API_URL=<https://prefect.yourdomain.com/api>
- PREFECT_SERVER_API_HOST=0.0.0.0
- PREFECT_SERVER_API_PORT=4200
depends_on:
postgres:
condition: service_healthy
command: prefect server start
labels:
- "traefik.enable=true"
# UI Router
- "traefik.http.routers.prefect-ui.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`)"
- "traefik.http.routers.prefect-ui.entrypoints=websecure"
- "traefik.http.routers.prefect-ui.tls=true"
- "traefik.http.services.prefect-ui.loadbalancer.server.port=4200"
# API Router
- "traefik.http.routers.prefect-api.rule=Host(`<http://prefect.yourdomain.com|prefect.yourdomain.com>`) && PathPrefix(`/api/`)"
- "traefik.http.routers.prefect-api.entrypoints=websecure"
- "traefik.http.routers.prefect-api.tls=true"
- "traefik.http.services.prefect-api.loadbalancer.server.port=4200"
# Middleware to handle paths
- "traefik.http.middlewares.prefect-strip-prefix.stripprefix.prefixes=/api"
- "traefik.http.routers.prefect-api.middlewares=prefect-strip-prefix@docker"
networks:
- traefik-public
- prefect-network
worker:
build:
context: ./worker
dockerfile: Dockerfile
restart: always
environment:
- PREFECT_API_URL=<http://server:4200/api>
depends_on:
- server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- prefect-network
networks:
traefik-public:
external: true
prefect-network:
name: prefect-network
driver: bridge
volumes:
postgres_data:
To apply these changes:
1. First, remove the existing PostgreSQL volume to start fresh:
bash
docker compose down
docker volume rm prefect2_postgres_data # adjust name if different
2. Start everything up again:
bash
docker compose up -d --build
3. Check the logs to verify the connection:
bash
docker compose logs -f server
Key changes made:
1. Changed PostgreSQL password to be more distinct (prefect_pass
)
2. Updated the database connection URL to match
3. Made sure the healthcheck is properly configured
4. Ensured proper dependency ordering
If you still see issues, we can try:
1. Checking if PostgreSQL is actually initialized with the correct credentials
2. Adding a delay to the server startup
3. Checking if the PostgreSQL container is accessible from the server container
Would you like me to show you how to verify any of these aspects?Ali
07/16/2025, 5:54 PMMarvin
07/16/2025, 5:54 PMMarvin
07/16/2025, 5:54 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect_pass
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
server:
image: prefecthq/prefect:3-latest
restart: always
ports:
- "4200:4200" # Expose port directly for testing
environment:
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect_pass@postgres:5432/prefect>
# Simplified URLs for direct access testing
- PREFECT_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_UI_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_SERVER_API_HOST=0.0.0.0
- PREFECT_SERVER_API_PORT=4200
depends_on:
postgres:
condition: service_healthy
command: prefect server start
networks:
- prefect-network
worker:
build:
context: ./worker
dockerfile: Dockerfile
restart: always
environment:
- PREFECT_API_URL=<http://server:4200/api>
depends_on:
- server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- prefect-network
networks:
prefect-network:
name: prefect-network
driver: bridge
volumes:
postgres_data:
Let's try this first:
1. Stop everything and clean up:
bash
docker compose down
docker volume rm prefect2_postgres_data # adjust name if different
2. Start just postgres and server (without worker) to debug:
bash
docker compose up postgres server
This will show us the logs directly. Could you run this and share:
1. Can you access http://localhost:4200 directly?
2. What do the logs show now?
Once we get the basic connectivity working, we can add back the Traefik configuration. This will help us identify if the issue is with Prefect's configuration or with Traefik routing.Ali
07/16/2025, 5:59 PMMarvin
07/16/2025, 5:59 PMMarvin
07/16/2025, 6:00 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: postgres_password # Changed password
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
# Add this to verify the database is properly initialized
command: ["postgres", "-c", "log_statement=all"]
server:
image: prefecthq/prefect:3-latest
restart: always
ports:
- "4200:4200"
environment:
# Updated database URL to match new password
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:postgres_password@postgres:5432/prefect>
- PREFECT_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_UI_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_SERVER_API_HOST=0.0.0.0
- PREFECT_SERVER_API_PORT=4200
depends_on:
postgres:
condition: service_healthy
command: prefect server start
networks:
- prefect-network
# ... rest of the services remain the same
networks:
prefect-network:
name: prefect-network
driver: bridge
volumes:
postgres_data:
Let's completely reset everything to ensure a clean state:
1. Stop and remove everything:
bash
docker compose down
docker volume rm prefect2_postgres_data # adjust volume name if different
2. Let's verify the PostgreSQL setup first. Start just PostgreSQL:
bash
docker compose up postgres -d
3. Test the PostgreSQL connection:
bash
docker compose exec postgres psql -U prefect -d prefect -c "\du"
This should show you the users. If this works, then:
4. Start the server:
bash
docker compose up -d server
5. Check the logs:
bash
docker compose logs -f server
Could you try these steps and let me know:
1. Does the PostgreSQL user verification command work?
2. What do the server logs show now?
If we still see issues, we can try:
1. Explicitly creating the database and user
2. Using a different PostgreSQL authentication method
3. Verifying the network connectivity between containersAli
07/16/2025, 6:03 PMMarvin
07/16/2025, 6:03 PMMarvin
07/16/2025, 6:03 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: postgres_password
POSTGRES_DB: prefect
# Add logging for authentication attempts
POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256"
POSTGRES_HOST_AUTH_METHOD: scram-sha-256
volumes:
- postgres_data:/var/lib/postgresql/data
# Add custom pg_hba.conf for more permissive auth during testing
- ./pg_hba.conf:/var/lib/postgresql/data/pg_hba.conf
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
command: ["postgres", "-c", "log_statement=all", "-c", "log_connections=on", "-c", "log_disconnections=on"]
server:
image: prefecthq/prefect:3-latest
restart: always
ports:
- "4200:4200"
environment:
# Try the simplified URL format
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql://prefect:postgres_password@postgres:5432/prefect>
- PREFECT_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_UI_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_SERVER_API_HOST=0.0.0.0
- PREFECT_SERVER_API_PORT=4200
# Add debug logging
- PREFECT_LOGGING_LEVEL=DEBUG
depends_on:
postgres:
condition: service_healthy
command: prefect server start
networks:
- prefect-network
networks:
prefect-network:
name: prefect-network
driver: bridge
volumes:
postgres_data:
First, create a pg_hba.conf
file in the same directory as your docker-compose.yml:
conf
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
host all all 0.0.0.0/0 scram-sha-256
Then let's try a complete reset:
1. Stop everything:
bash
docker compose down -v
2. Start PostgreSQL alone first:
bash
docker compose up -d postgres
3. Verify PostgreSQL is running and accessible:
bash
# Check postgres logs
docker compose logs postgres
# Try connecting with psql
docker compose exec postgres psql -U prefect -d prefect -c "SELECT version();"
4. If that works, try to connect using the exact connection string that Prefect will use:
bash
docker compose exec postgres psql "<postgresql://prefect:postgres_password@postgres:5432/prefect>" -c "SELECT version();"
5. If both those work, start the server:
bash
docker compose up -d server
6. Check both logs:
bash
# Check postgres logs for connection attempts
docker compose logs postgres
# Check server logs
docker compose logs server
The additional logging we've added should help us see exactly what's happening with the authentication attempts. Could you try these steps and share:
1. Do both PostgreSQL connection tests work?
2. What do you see in the PostgreSQL logs when the server tries to connect?
3. Does the server log show any additional details about the authentication failure?Ali
07/16/2025, 6:08 PMMarvin
07/16/2025, 6:08 PMMarvin
07/16/2025, 6:08 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: postgres_password
POSTGRES_DB: prefect
# Specify a different data directory
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- prefect_postgres_data:/var/lib/postgresql/data/pgdata
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
command: ["postgres", "-c", "log_statement=all", "-c", "log_connections=on", "-c", "log_disconnections=on"]
server:
image: prefecthq/prefect:3-latest
restart: always
ports:
- "4200:4200"
environment:
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql://prefect:postgres_password@postgres:5432/prefect>
- PREFECT_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_UI_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_SERVER_API_HOST=0.0.0.0
- PREFECT_SERVER_API_PORT=4200
- PREFECT_LOGGING_LEVEL=DEBUG
depends_on:
postgres:
condition: service_healthy
command: prefect server start
networks:
- prefect-network
networks:
prefect-network:
name: prefect-network
driver: bridge
volumes:
prefect_postgres_data:
name: prefect_postgres_data # Explicitly named volume
Let's clean up and start fresh:
1. Remove everything including volumes:
bash
docker compose down -v
2. Remove any existing volumes manually:
bash
docker volume rm prefect_postgres_data
3. Create the volume explicitly:
bash
docker volume create prefect_postgres_data
4. Start everything up:
bash
docker compose up -d
5. Check the logs:
bash
docker compose logs postgres
docker compose logs server
The key changes are:
1. Using a specifically named volume (prefect_postgres_data
)
2. Setting PGDATA
to a specific subdirectory
3. Mounting the volume to that specific subdirectory
This should prevent any conflicts with other PostgreSQL instances and ensure a clean data directory. Let me know what the logs show now!Ali
07/16/2025, 6:11 PMMarvin
07/16/2025, 6:11 PMMarvin
07/16/2025, 6:11 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: postgres_password
POSTGRES_DB: prefect
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- prefect_postgres_data:/var/lib/postgresql/data/pgdata
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
command: ["postgres", "-c", "log_statement=all", "-c", "log_connections=on", "-c", "log_disconnections=on"]
server:
image: prefecthq/prefect:3-latest
restart: always
ports:
- "4200:4200"
environment:
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql://prefect:postgres_password@postgres:5432/prefect>
- PREFECT_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_UI_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_SERVER_API_HOST=0.0.0.0
- PREFECT_SERVER_API_PORT=4200
- PREFECT_LOGGING_LEVEL=DEBUG
depends_on:
postgres:
condition: service_healthy
# Add installation of psycopg2-binary before starting the server
command: >
bash -c "pip install psycopg2-binary &&
prefect server start"
networks:
- prefect-network
networks:
prefect-network:
name: prefect-network
driver: bridge
volumes:
prefect_postgres_data:
name: prefect_postgres_data
The key change is in the server service's command, where we first install psycopg2-binary
before starting the server.
Let's try it again:
1. Stop and remove containers:
bash
docker compose down
2. Build and start everything:
bash
docker compose up -d
3. Check the logs:
bash
docker compose logs -f server
If you prefer a cleaner approach, we could also create a custom Dockerfile for the server that includes psycopg2. Would you like me to show you that alternative approach as well?Marvin
07/16/2025, 6:13 PMMarvin
07/16/2025, 6:13 PMAli
07/16/2025, 6:14 PMMarvin
07/16/2025, 6:14 PMMarvin
07/16/2025, 6:15 PMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: postgres_password
POSTGRES_DB: prefect
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- prefect_postgres_data:/var/lib/postgresql/data/pgdata
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
command: ["postgres", "-c", "log_statement=all", "-c", "log_connections=on", "-c", "log_disconnections=on"]
server:
image: prefecthq/prefect:3-latest
restart: always
ports:
- "4200:4200"
environment:
# Updated to use asyncpg driver
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:postgres_password@postgres:5432/prefect>
- PREFECT_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_UI_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_SERVER_API_HOST=0.0.0.0
- PREFECT_SERVER_API_PORT=4200
- PREFECT_LOGGING_LEVEL=DEBUG
depends_on:
postgres:
condition: service_healthy
# Install asyncpg instead of psycopg2
command: >
bash -c "pip install asyncpg &&
prefect server start"
networks:
- prefect-network
networks:
prefect-network:
name: prefect-network
driver: bridge
volumes:
prefect_postgres_data:
name: prefect_postgres_data
The key changes are:
1. Changed the database URL to use postgresql+asyncpg://
instead of just postgresql://
2. Installing asyncpg
instead of psycopg2-binary
Let's try again:
1. Stop everything:
bash
docker compose down
2. Start fresh:
bash
docker compose up -d
3. Check the logs:
bash
docker compose logs -f server
This should resolve the async driver error. Let me know what you see in the logs now!Ali
07/16/2025, 6:17 PMMarvin
07/16/2025, 6:17 PMMarvin
07/16/2025, 6:18 PMdockerfile
FROM prefecthq/prefect:3-latest
# Install required packages
RUN pip install asyncpg
# Set environment variables for database connection retries
ENV PGCONNECT_TIMEOUT=10
ENV PGCONNECT_RETRIES=5
2. Update the docker-compose.yml:
yaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: postgres_password
POSTGRES_DB: prefect
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- prefect_postgres_data:/var/lib/postgresql/data/pgdata
# Add explicit configuration for authentication
- ./postgresql.conf:/etc/postgresql/postgresql.conf
- ./pg_hba.conf:/etc/postgresql/pg_hba.conf
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
command: postgres -c config_file=/etc/postgresql/postgresql.conf
server:
build:
context: .
dockerfile: server.Dockerfile
restart: always
ports:
- "4200:4200"
environment:
- PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:postgres_password@postgres:5432/prefect?connect_timeout=10>
- PREFECT_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_UI_API_URL=<http://127.0.0.1:4200/api>
- PREFECT_SERVER_API_HOST=0.0.0.0
- PREFECT_SERVER_API_PORT=4200
- PREFECT_LOGGING_LEVEL=DEBUG
depends_on:
postgres:
condition: service_healthy
command: prefect server start
networks:
- prefect-network
networks:
prefect-network:
name: prefect-network
driver: bridge
volumes:
prefect_postgres_data:
name: prefect_postgres_data
3. Create a pg_hba.conf
file:
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
host all all 0.0.0.0/0 md5
host all all 172.16.0.0/12 md5
4. Create a postgresql.conf
file:
listen_addresses = '*'
max_connections = 100
shared_buffers = 128MB
dynamic_shared_memory_type = posix
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_statement = 'all'
log_connections = on
log_disconnections = on
Now let's try a complete reset:
1. Clean everything:
bash
docker compose down -v
docker volume rm prefect_postgres_data
2. Create the volume:
bash
docker volume create prefect_postgres_data
3. Build and start:
bash
docker compose up -d --build
4. Check the logs:
bash
# Check postgres initialization
docker compose logs postgres
# Check server logs
docker compose logs server
The key changes in this approach:
1. Custom server Dockerfile with pre-installed dependencies
2. Explicit PostgreSQL configuration files
3. More detailed logging
4. Connection timeout and retry settings
5. Explicit authentication method configuration
Let me know what the logs show with this setup!Eric
07/16/2025, 6:19 PM# Docker compose to run Prefect UI + API + Workers (worker type: `process`, `docker`)
services:
prefect:
image: "prefecthq/prefect:3-latest"
depends_on:
postgresql:
condition: service_healthy
environment:
- SERVICE_FQDN_PREFECT_4200
- "PREFECT_API_URL=${SERVICE_FQDN_PREFECT}/api"
- "PREFECT_API_DATABASE_CONNECTION_URL=postgresql+asyncpg://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql:5432/${POSTGRES_DB:-prefect}"
- "PREFECT_API_KEY=${SERVICE_PASSWORD_APIKEY}"
- "PREFECT_EXPERIMENTAL_WARN=${PREFECT_EXPERIMENTAL_WARN:-false}"
- "PREFECT_EXPERIMENTAL_ENABLE_SCHEDULE_CONCURRENCY=${PREFECT_EXPERIMENTAL_ENABLE_SCHEDULE_CONCURRENCY:-false}"
- "PREFECT_RUNNER_SERVER_ENABLE=${PREFECT_RUNNER_SERVER_ENABLE:-false}"
- "PREFECT_DEFAULT_WORK_POOL_NAME=${DEFAULT_POOL_NAME:-default}"
command:
- prefect
- server
- start
- "--host"
- 0.0.0.0
- "--port"
- "4200"
healthcheck:
test:
- CMD
- python
- "-c"
- "import requests as r;r.get('<http://127.0.0.1:4200/api/health').raise_for_status(>)"
interval: 5s
timeout: 5s
retries: 3
postgresql:
image: "postgres:16-alpine"
volumes:
- "pg-data:/var/lib/postgresql/data"
environment:
- POSTGRES_USER=${SERVICE_USER_POSTGRES}
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
- POSTGRES_DB=${POSTGRES_DB:-prefect}
healthcheck:
test:
- CMD-SHELL
- "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
interval: 5s
timeout: 5s
retries: 3
# Prefect worker for `process` work pool
# Create a work pool of type ${DEFAULT_POOL_TYPE}" + start a worker for this work pool
worker-process:
image: "prefecthq/prefect:3-python3.13"
depends_on:
prefect:
condition: service_healthy
entrypoint:
- /opt/prefect/entrypoint.sh
- prefect
- worker
- start
- "--pool=${DEFAULT_POOL_NAME}"
- "--type=${DEFAULT_POOL_TYPE}"
- "--with-healthcheck"
- "--name=${DEFAULT_WORKER_NAME}"
- "--limit=${DEFAULT_POOL_LIMIT}"
environment:
- "PREFECT_API_URL=<http://prefect:4200/api>"
- "PREFECT_API_KEY=${SERVICE_PASSWORD_APIKEY}"
- "DEFAULT_POOL_NAME=${DEFAULT_POOL_NAME:-default}"
- "DEFAULT_POOL_TYPE=${DEFAULT_POOL_TYPE:-process}"
- "DEFAULT_POOL_LIMIT=${DEFAULT_POOL_LIMIT:-1}"
- "DEFAULT_WORKER_NAME=${DEFAULT_WORKER_NAME:-worker-process}"
healthcheck:
test:
- CMD-SHELL
- pwd
interval: 5s
timeout: 5s
retries: 3
## Prefect worker for `docker` work pool
# Create a work pool of type ${DOCKER_POOL_TYPE}" + start a worker for this work pool
# Delete and create manually the docker work pool if you need to add your Docker Registry Credentials from Prefect Block. (v3.4.8 at least)
worker-docker:
image: "prefecthq/prefect:3-python3.13"
depends_on:
prefect:
condition: service_healthy
volumes:
- /var/run/docker.sock:/var/run/docker.sock # Required to access docker
# Download docker
command: >
sh -c "
apt-get update && apt-get install -y <http://docker.io|docker.io> &&
/opt/prefect/entrypoint.sh prefect worker start
--pool=${DOCKER_POOL_NAME}
--type=${DOCKER_POOL_TYPE}
--with-healthcheck
--name=${DOCKER_WORKER_NAME}
--limit=${DOCKER_POOL_LIMIT}
"
environment:
- "EXTRA_PIP_PACKAGES=prefect-docker" # Required package for docker worker
- "PREFECT_API_URL=<http://prefect:4200/api>"
- "PREFECT_API_KEY=${SERVICE_PASSWORD_APIKEY}"
- "DOCKER_HOST=${DOCKER_HOST:-unix:///var/run/docker.sock}" # Required for Docker
- "DOCKER_POOL_NAME=${DOCKER_POOL_NAME:-docker-work-pool}"
- "DOCKER_POOL_TYPE=${DOCKER_POOL_TYPE:-docker}"
- "DOCKER_POOL_LIMIT=${DOCKER_POOL_LIMIT:-1}"
- "DOCKER_WORKER_NAME=${DOCKER_WORKER_NAME:-worker-docker}"
healthcheck:
test:
- CMD-SHELL
- pwd
interval: 5s
timeout: 5s
retries: 3
volumes:
pg-data:
Eric
07/16/2025, 6:20 PM