Madushan Pathirana
09/17/2025, 5:52 AMMarvin
09/17/2025, 5:52 AMMarvin
09/17/2025, 6:08 AMprefect server start
(starts API + services + UI).
- Database URL must use postgresql+asyncpg://
.
- Expose/listen on 4200; clients/workers will use PREFECT_API_URL
to reach the server at http://<host-or-lb>:4200/api
.
Dockerfile (build your Prefect Server image)
# Simple Prefect Server image for Prefect 3.x
FROM python:3.11-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1
# Install Prefect 3 and Postgres driver
RUN pip install --upgrade pip && \
pip install "prefect>=3,<4" asyncpg
# Defaults: override via ECS Task env
ENV PREFECT_SERVER_API_HOST=0.0.0.0 \
PREFECT_SERVER_API_PORT=4200 \
PREFECT_UI_ENABLED=true \
PREFECT_API_DATABASE_MIGRATE_ON_START=true
# Prefect Server listens on 4200
EXPOSE 4200
# Start Prefect Server (API + services + UI)
CMD ["prefect", "server", "start", "--host", "0.0.0.0", "--port", "4200"]
Example ECS Task Definition (EC2 launch type)
- Uses awsvpc networking
- Publishes port 4200 on the host for easy access from your EC2’s SG or an ALB
- Pulls the Postgres URL from Secrets Manager (recommended)
{
"family": "prefect-server",
"networkMode": "awsvpc",
"requiresCompatibilities": [
"EC2"
],
"cpu": "512",
"memory": "1024",
"executionRoleArn": "arn:aws:iam::<account-id>:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::<account-id>:role/prefectServerTaskRole",
"containerDefinitions": [
{
"name": "prefect-server",
"image": "<account-id>.<http://dkr.ecr.ap-southeast-1.amazonaws.com/prefect-server:latest|dkr.ecr.ap-southeast-1.amazonaws.com/prefect-server:latest>",
"essential": true,
"portMappings": [
{
"containerPort": 4200,
"hostPort": 4200,
"protocol": "tcp"
}
],
"environment": [
{
"name": "PREFECT_SERVER_API_HOST",
"value": "0.0.0.0"
},
{
"name": "PREFECT_SERVER_API_PORT",
"value": "4200"
},
{
"name": "PREFECT_UI_ENABLED",
"value": "true"
},
{
"name": "PREFECT_API_DATABASE_MIGRATE_ON_START",
"value": "true"
}
],
"secrets": [
{
"name": "PREFECT_API_DATABASE_CONNECTION_URL",
"valueFrom": "arn:aws:secretsmanager:ap-southeast-1:<account-id>:secret:prefect-db-url-abc123"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/prefect-server",
"awslogs-region": "ap-southeast-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}
What to put in PREFECT_API_DATABASE_CONNECTION_URL
- Example value (store in Secrets Manager and reference via the Task Definition):
- postgresql+asyncpg://<user>:<password>@<rds-endpoint>:5432/<db_name>
- Make sure your ECS task’s security group can reach the RDS SG on port 5432.
How your workers/CLI will reach the API
- Set PREFECT_API_URL
in worker/CLI environments to your reachable server URL:
- Without a load balancer (host port mapping): http://<ec2-instance-private-or-public-ip>:4200/api
- With an ALB / DNS: <https://prefect>.<your-domain>/api
Useful docs
- Prefect settings reference (all env vars): Settings reference
- Self-hosted (Docker/Compose examples): Self-hosted with Docker/Compose
Questions for you
- Do you want the server to run inside ECS on that same EC2 host (above is set up for that), or do you prefer to run it as a plain Docker container (or Docker Compose/systemd) directly on the instance? I can provide a Compose file if that’s closer to your current setup.