Nathan Boulogne
08/12/2025, 12:39 PMfrom prefect import serve
from main import my_flow, my_flow_2
if __name__ == "__main__":
flow_1 = my_flow.to_deployment(
name="Healthcheck Flow",
description="A simple flow that says hello.",
parameters={
"name": "Nathan",
},
cron="*/5 * * * *", # Every 5 mins
tags=["test"],
)
flow_2 = my_flow_2.to_deployment(
name="Healthcheck Flow 2",
description="A simple flow that says hello.",
cron="* * * * *", # Every minute
tags=["test"],
)
serve(flow_1, flow_2)
It runs within a docker container, deployed in Coolify.
CMD ["uv", "run", "python", "src/deploy.py"]
My issue is that the link between my prefect server and my flows isn't made. I can't see my flows on my prefect server. However, I've setup PREFECT_API_URL environment variable.Marvin
08/12/2025, 12:39 PMMarvin
08/12/2025, 12:42 PMprefect config view --show-sources
- Make sure PREFECT_API_URL
is reachable from inside the container and includes the /api
suffix.
- Don’t use <http://localhost>:...
unless the Prefect server is in the same container. In Docker, “localhost” is the container itself. Use the service hostname or an external URL, e.g. <http://prefect-server:4200/api>
or <https://prefect.example.com/api>
.
2) Watch the logs when serve
starts
- prefect.serve
will create/update deployments at startup. You should see log lines like “Created deployment …” or clear connection errors.
- If the API is unreachable or misconfigured, Prefect will complain loudly. If it’s suspiciously quiet, the env var may not be set in that container.
3) Verify versions match
- SDK and Server should both be 3.x. Mismatched major versions won’t talk nicely.
prefect version
Check the server’s version in the UI footer, and the SDK’s in the container.
4) Ensure a work pool exists (and is the one you’re targeting)
- By default, deployments go to the “default” process work pool. If that pool doesn’t exist on your server, creation will fail.
- You can set it explicitly to be clear:
flow_1 = my_flow.to_deployment(
name="Healthcheck Flow",
description="A simple flow that says hello.",
parameters={"name": "Nathan"},
cron="*/5 * * * *",
tags=["test"],
work_pool_name="default",
)
flow_2 = my_flow_2.to_deployment(
name="Healthcheck Flow 2",
description="A simple flow that says hello.",
cron="* * * * *",
tags=["test"],
work_pool_name="default",
)
serve(flow_1, flow_2)
- Even if there’s no worker attached to the pool yet, the deployments should still appear in the UI once registration succeeds.
5) Sanity-check connectivity from inside the container
- Quick probe to the API health endpoint:
python - <<'PY'
import os, requests
url = os.environ.get("PREFECT_API_URL", "")
print("PREFECT_API_URL =", url)
url = url.rstrip("/")
resp = requests.get(f"{url}/health", timeout=5)
print("GET /health ->", resp.status_code, resp.text[:200])
PY
If this doesn’t surface the issue, could you share:
- The exact value you’re using for PREFECT_API_URL
(redact host if needed; format matters, especially the /api
).
- The output of prefect config view --show-sources
from inside the container.
- Any logs printed when the container starts (particularly around “serve” and deployment creation).
- SDK and server versions.
With those, we can narrow it down quickly. And yes, I know, computers should just read our minds by now. Sadly they still insist on URLs that aren’t localhost.Nathan Boulogne
08/12/2025, 12:53 PM# uv run prefect config view --show-sources
🚀 you are connected to:
<https://workflows.insight-analytics.fr>
PREFECT_PROFILE='ephemeral'
PREFECT_API_URL='<https://workflows.insight-analytics.fr/api>' (from env)
PREFECT_RUNNER_SERVER_ENABLE='true' (from env)
PREFECT_RUNNER_SERVER_HOST='0.0.0.0' (from env)
PREFECT_RUNNER_SERVER_PORT='8080' (from env)
PREFECT_SERVER_ALLOW_EPHEMERAL_MODE='true' (from profile)
# #
Also, please note that the deployment is running fine. My concern is that no flow is running. I have set it up so it runs every minute but it doesn't. But my flows are updated on new deployment etc... There is simply no run.Marvin
08/12/2025, 12:53 PMMarvin
08/12/2025, 1:00 PMuv run prefect deployments inspect "my_flow/Healthcheck Flow"
Look for “paused” and the “schedules” block.
- If paused, unpause it in the UI or make it explicit in code:
flow_1 = my_flow.to_deployment(
name="Healthcheck Flow",
parameters={"name": "Nathan"},
cron="*/5 * * * *",
tags=["test"],
paused=False,
)
(Same for flow_2
.)
2) The server scheduler is not running
- If your self-hosted server was started with services disabled (or the scheduler service off), the UI will show deployments but no scheduled runs will be created.
- Ensure your server starts with the scheduler enabled, e.g. don’t use --no-services
, and do use:
- CLI: prefect server start --scheduler
(or just no flag; scheduler should be on by default)
- Env: set PREFECT_API_SERVICES_SCHEDULER=true
- There’s also a --late-runs/--no-late-runs
toggle; it only affects catching up missed runs, not creating new on-time runs.
Quick triage steps
- See if the server created any runs at all:
uv run prefect deployments ls
uv run prefect deployments inspect "my_flow/Healthcheck Flow"
- Try a manual run to confirm the runner can execute:
uv run prefect deployments run "my_flow/Healthcheck Flow"
If manual runs start but scheduled ones don’t appear, it’s almost certainly the scheduler service.
If you can share how you start Prefect Server in Coolify (the exact command/flags or env vars), I can point to the precise fix. Otherwise, set paused=False
in your to_deployment(...)
calls and make sure your server is started with the scheduler enabled. If only everything obeyed cron as faithfully as we do.Nathan Boulogne
08/12/2025, 2:05 PM