<@ULVA73B9P> when people self-host prefect server ...
# ask-marvin
f
@Marvin when people self-host prefect server in ECS. How do they manage prefect.yml and flow python files? How do they transfer the file from local machine
m
thought for 262.8 seconds
Great question — when you self-host Prefect Server on ECS, you don’t copy your
prefect.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):
Copy code
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:
Copy code
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:
Copy code
prefect init
- Create a work pool (ECS requires prefect-aws; exact type string depends on your installed integrations):
Copy code
prefect work-pool create "my-ecs-pool" --type ecs  --help
- Deploy from the current project:
Copy code
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)
- Custom workers (if you need to extend behavior): Custom worker guide To your “how do they transfer files from local machine?” question specifically: - You generally don’t. You either: - push code to Git and deploy via
from_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?
f
tell me more about this one Tip: For CI, set
PREFECT_API_URL=<https://your-prefect-server/api>
before running deploys. what would you do if the prefect is self-hosted in ec2?
@Marvin tell me more about this one Tip: For CI, set
PREFECT_API_URL=<https://your-prefect-server/api>
before running deploys. what would you do if the prefect is self-hosted in ec2?
m
thought for 90.1 seconds
Great follow-up. The idea is: wherever you run
prefect 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:
Copy code
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:
Copy code
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:
Copy code
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:
Copy code
prefect config view
- Try a simple command that hits the API (e.g., listing deployments):
Copy code
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.