Fugo Takefusa
09/21/2025, 10:42 PMMarvin
09/21/2025, 10:42 PMMarvin
09/21/2025, 10:47 PMprefect.yaml
or flow Python files to the server. Prefect Server only stores deployment metadata. The actual code is delivered to your workers at run time via one of a few patterns.
How teams typically manage this:
- Keep prefect.yaml
and your flow code in a Git repo. Treat them as code, reviewed and deployed via CI/CD.
- Create deployments either from your laptop or, preferably, from CI using prefect deploy
or the Python API. This registers deployment metadata with your self-hosted Server (point your CLI/CI at your API with PREFECT_API_URL
).
- Workers (e.g., an ECS worker) pull the code or image at run time based on the deployment’s storage definition.
Two common, reliable patterns for ECS
1) Container-image based (most common for ECS)
- Bake your flow code into a Docker image, push it to ECR, and run it in ECS.
- Pros: fast cold starts, fully reproducible, no git access needed at runtime.
- Typical setup:
- Create an ECS work pool (requires prefect-aws
).
- Build and push the image in CI (or via prefect deploy
) to ECR.
- The deployment stores the image reference; the ECS worker launches tasks using that image.
Example (Python API):
from prefect import flow, Flow
@flow
def my_flow():
...
# If code is in this repo and you want Prefect to build/push an image:
# (Ensure your project has a prefect.yaml for build context or pass an explicit image)
Flow.from_source(".", entrypoint="flows/my_flow.py:my_flow").deploy(
name="prod",
work_pool_name="my-ecs-pool",
image="<http://123456789012.dkr.ecr.us-east-1.amazonaws.com/myimage:{{|123456789012.dkr.ecr.us-east-1.amazonaws.com/myimage:{{> git_sha }}", # push this in CI
)
2) Git-based (from_source)
- Store your code in a Git repo; the worker clones the repo at run time.
- Pros: simplest to start, no image build needed.
- Considerations: worker must have network and credentials to clone.
- Example:
from prefect import flow, Flow
Flow.from_source(
"<https://github.com/your-org/your-repo>",
entrypoint="flows/my_flow.py:my_flow",
).deploy(
name="prod",
work_pool_name="my-ecs-pool",
)
Less common: remote artifact storage (e.g., S3)
- Package your project and store it in S3; the worker downloads it at run time.
- Useful in restricted environments; requires extra setup. See storage docs below.
Where prefect.yaml
fits
- Keep prefect.yaml
at your repo root. It defines build/push steps and default deployment fields that prefect deploy
uses.
- You don’t “transfer” this file anywhere — you commit it, and your CI (or local machine) reads it when running prefect deploy
. The Server stores deployment metadata; workers fetch code/images based on that metadata.
ECS specifics (high level)
- Run a Prefect ECS worker (in ECS/Fargate or EC2) pointed at your Server’s API.
- Create a work pool for ECS and configure its job template (subnets, security groups, task role, etc.).
- Your deployments target that work pool; the worker spins up ECS tasks to execute each flow run.
Handy commands (verify worker types in your env)
- Initialize a project:
prefect init
- Create a work pool (ECS requires prefect-aws; exact type string depends on your installed integrations):
prefect work-pool create "my-ecs-pool" --type ecs --help
- Deploy from the current project:
prefect deploy ./flows/my_flow.py:my_flow --name prod
Tip: For CI, set PREFECT_API_URL=<https://your-prefect-server/api>
before running deploys.
Docs and references
- Versioning and deployments: Deployment versioning (Prefect 3.x)
- Storing flow code: Store flow code (Prefect 3.x)
- ECS guidance: ECS guide (prefect-aws)Marvin
09/21/2025, 10:47 PMfrom_source
, or
- build and push a Docker image to ECR and reference it in the deployment.
- Running prefect deploy
from your laptop or CI “registers” the deployment with Server; then workers fetch code/image when running the flow.
A couple of quick questions to tailor a concrete example:
- Are your flow runs also going to execute on ECS via the Prefect ECS worker?
- Do you prefer image-based or Git-based distribution?
- Do you already have ECR set up for pushing images, or would you rather start with from_source?Fugo Takefusa
09/21/2025, 11:00 PMPREFECT_API_URL=<https://your-prefect-server/api>
before running deploys. what would you do if the prefect is self-hosted in ec2?Fugo Takefusa
09/21/2025, 11:01 PMPREFECT_API_URL=<https://your-prefect-server/api>
before running deploys. what would you do if the prefect is self-hosted in ec2?Marvin
09/21/2025, 11:01 PMMarvin
09/21/2025, 11:02 PMprefect deploy
(your laptop or CI), Prefect needs to talk to your self-hosted API. You do that by pointing PREFECT_API_URL
at your EC2-hosted Server’s API endpoint.
What to set for an EC2-hosted Server
- If you’ve exposed the server directly on the EC2 instance (not recommended for prod):
- Example: <http://ec2-12-34-56-78.compute-1.amazonaws.com:4200/api>
- If you’re fronting the EC2 instance with a load balancer and TLS (recommended):
- Example: <https://prefect.mycompany.com/api>
- If you serve Prefect behind a path prefix:
- Example: <https://tools.mycompany.com/prefect/api>
(note the /prefect/api
)
How to set it in CI
- As an environment variable for the job that runs `prefect deploy`:
- GitHub Actions:
env:
PREFECT_API_URL: <https://prefect.mycompany.com/api>
steps:
- run: prefect config view
- run: prefect deploy ./flows/my_flow.py:my_flow --name prod
- GitLab CI:
deploy:
variables:
PREFECT_API_URL: <https://prefect.mycompany.com/api>
script:
- prefect config view
- prefect deploy ./flows/my_flow.py:my_flow --name prod
- Or create/use a Prefect profile within CI:
prefect profile create ci
prefect profile use ci
prefect config set PREFECT_API_URL="<https://prefect.mycompany.com/api>"
prefect deploy ./flows/my_flow.py:my_flow --name prod
Networking considerations that often trip folks up
- The CI runner must be able to reach your EC2-hosted API:
- If your runner is public/SaaS (e.g., GitHub-hosted), you’ll need a public endpoint (via ALB) and open SG rules, or run a self-hosted runner inside your VPC.
- If your runner is inside the VPC, you can use a private ALB or the EC2 private IP as the API URL.
- Ensure TLS/ALB is set up to pass through to port 4200 on the instance (or whatever you’ve configured).
- If using a subpath, make sure your reverse proxy forwards /<prefix>/api
correctly.
Quick ways to verify
- View your current setting:
prefect config view
- Try a simple command that hits the API (e.g., listing deployments):
prefect deployments ls
If it errors with connection issues, your PREFECT_API_URL
or network path is off.
Docs
- Manage settings and profiles
- Self-hosting Prefect Server (CLI)
If you share:
- whether your CI runner is inside your AWS VPC or not, and
- whether your Prefect Server is behind an ALB with TLS and/or a path prefix,
I can suggest the exact PREFECT_API_URL
value and any ALB/SG tweaks you might need.