Cullen Baker
10/29/2025, 9:53 PMMarvin
10/29/2025, 9:53 PMMarvin
10/29/2025, 9:58 PMcurl -s http://<your-host-or-ip>:4200/api/health
You should get JSON back indicating server readiness.
3) Point your CLI at that exact server and list objects
- From the same environment where you ran prefect deploy:
PREFECT_API_URL=http://<your-host-or-ip>:4200/api prefect work-pool ls
PREFECT_API_URL=http://<your-host-or-ip>:4200/api prefect deployment ls
- If these are empty, then your deployment and pool were created against a different API. Run:
prefect config view
prefect profile inspect
to see which PREFECT_API_URL was active when you ran the deploy. It’s common for the CLI to be pointed at one API (e.g., a different docker-compose stack or a local server you started earlier) while the UI is pointed at another.
4) Check environment mismatches (common on Linux)
- Inside containers (including a worker running in compose), use service names like http://api:4200/api to reach the API.
- From your host browser and host CLI, use the host-mapped address: http://localhost:4200/api or http//<server hostname>4200/api
- host.docker.internal does not work on Linux by default; avoid using it on RHEL9.
5) Ensure DB persistence wasn’t lost
- If your Postgres volume is ephemeral or got reset, prior pools/deployments would disappear on restart.
- Confirm your compose has a persistent volume for Postgres and that migrations completed:
docker compose ps
docker compose logs -f
Look for messages that the API is serving and DB migrations are done.
Reference env you generally want in compose (abridged):
services:
api:
image: prefecthq/prefect:3-latest
command: prefect server start
ports:
- "4200:4200"
environment:
PREFECT_SERVER_API_HOST: "0.0.0.0"
PREFECT_API_DATABASE_CONNECTION_URL: "<postgresql+asyncpg://postgres:postgres@postgres:5432/prefect>"
# Optional: only if serving UI from a different origin
# PREFECT_UI_API_URL: "<http://localhost:4200/api>"
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: prefect
volumes:
- prefect_pg:/var/lib/postgresql/data
volumes:
prefect_pg:
Given your setup (RHEL9, process worker, need host filesystem access), running the worker on the host is fine; just make sure your host worker and your deploy CLI both use the same PREFECT_API_URL as the UI you’re visiting.
If you can, please share:
- The exact URL you’re opening in the browser
- Output of:
prefect version
prefect config view
prefect profile inspect
PREFECT_API_URL=http://<host>:4200/api prefect work-pool ls
PREFECT_API_URL=http://<host>:4200/api prefect deployment ls
curl -s http://<host>:4200/api/health
- The relevant env section from your docker-compose.yml (redact secrets)
With those, I can pinpoint whether it’s a UI API target, CLI profile, or DB persistence issue.Cullen Baker
10/29/2025, 10:08 PMMarvin
10/29/2025, 10:09 PMMarvin
10/29/2025, 10:09 PMcurl -v http://<host-or-ip>:4200/api/health
If this fails, the API isn’t reachable from your host (port not exposed, server not listening on 0.0.0.0, firewall, or reverse proxy issue).
3) Check docker-compose for port and env
- Ensure the API service publishes port 4200:
ports:
- "4200:4200"
- Ensure the server binds to all interfaces in the container:
environment:
PREFECT_SERVER_API_HOST: "0.0.0.0"
- Unless you’re reverse-proxying, either:
- Do not set PREFECT_UI_API_URL (the UI will call same-origin /api), or
- Set it to an external address reachable by your browser, including /api:
PREFECT_UI_API_URL: "http//<host or ip>4200/api"
- Avoid setting PREFECT_UI_API_URL to a container-only hostname like api or prefect-server.
4) Verify the server is healthy
docker compose logs -f
Look for API startup and DB migrations completed. If Postgres was reset (no persistent volume), any prior pools/deployments would be gone.
5) Sanity-check with the CLI against the same URL your browser should use
PREFECT_API_URL=http://<host-or-ip>:4200/api prefect work-pool ls
PREFECT_API_URL=http://<host-or-ip>:4200/api prefect deployment ls
If you can, please share:
- The Request URL from one failed request in DevTools
- The output of:
curl -v http://<host-or-ip>:4200/api/health
- The relevant part of your docker-compose.yml for the Prefect server service (ports + environment) (redact secrets)
With that, I can point to the exact setting to change.Cullen Baker
10/29/2025, 10:14 PMMarvin
10/29/2025, 10:14 PMMarvin
10/29/2025, 10:15 PMservices:
prefect-server:
image: <http://artifactory.chicagotrading.com/docker-all/prefecthq/prefect:3-latest|artifactory.chicagotrading.com/docker-all/prefecthq/prefect:3-latest>
environment:
PREFECT_API_DATABASE_CONNECTION_URL: "<postgresql+asyncpg://prefect:prefect@postgres:5432/prefect>"
PREFECT_SERVER_API_HOST: "0.0.0.0"
PREFECT_SERVER_API_PORT: "4200"
PREFECT_MESSAGING_BROKER: prefect_redis.messaging
PREFECT_MESSAGING_CACHE: prefect_redis.messaging
PREFECT_REDIS_MESSAGING_HOST: redis
PREFECT_REDIS_MESSAGING_PORT: 6379
PREFECT_REDIS_MESSAGING_DB: 0
# Remove these (let UI use same-origin), OR set to your actual host if needed
# PREFECT_UI_URL: http://${HOSTNAME:-localhost}:4200
# PREFECT_UI_API_URL: http://${HOSTNAME:-localhost}:4200/api
ports:
- "4200:4200"
command: >
sh -c "prefect server database upgrade --yes &&
prefect server start --no-services"
After changing:
1) Restart the server and hard refresh the browser (Ctrl+Shift+R).
2) In DevTools → Network, the failed Request URL should now be http://your-server:4200/api/… (not localhost).
3) From your workstation, verify:
curl -v <http://your-server:4200/api/health>
Notes about your worker
- You’ve set network_mode: host and PREFECT_API_URL: http://127.0.0.1:4200/api — that’s valid because the worker runs on the same host that exposes port 4200.
- If you ever run the worker from another host/container network, change PREFECT_API_URL to the server’s hostname.
If you still don’t see pools/deployments after fixing the UI API URL, we should confirm they exist on this server (not another one) by running from your workstation:
PREFECT_API_URL=<http://your-server:4200/api> prefect work-pool ls
PREFECT_API_URL=<http://your-server:4200/api> prefect deployment ls
Docs for reference:
- Self-hosted with docker-compose
- Settings and profiles
If you share the exact UI URL you’re opening and the result of curl -v http://your-server:4200/api/health from your workstation, I can confirm everything’s wired correctly.Cullen Baker
10/29/2025, 10:36 PMCullen Baker
10/29/2025, 10:38 PMMarvin
10/29/2025, 10:38 PMMarvin
10/29/2025, 10:39 PMdocker compose up -d --force-recreate --no-deps prefect-server
3) Hard refresh the browser (Ctrl+Shift+R) to bust cached UI config.
Verify what the running container has
docker compose exec prefect-server sh -lc 'env | sort | grep PREFECT_UI'
If you still see PREFECT_UI_API_URL=http://0.0.0.0:4200/api, it didn’t pick up the change (or is coming from a .env). Remove it and recreate again.
Sanity checks
- From your workstation:
curl -v <http://ch12lxtrd19:4200/api/health>
- In the browser Network tab, confirm the Request URL is now http://ch12lxtrd19:4200/api/... (not 0.0.0.0, not localhost).
If after this the UI loads but looks empty, confirm objects exist on this server:
PREFECT_API_URL=<http://ch12lxtrd19:4200/api> prefect work-pool ls
PREFECT_API_URL=<http://ch12lxtrd19:4200/api> prefect deployment ls
If anything’s still off, please share:
- Output of the env check inside the prefect-server container
- The updated prefect-server environment section from docker-compose
- The new Request URL from a failed/working call in DevToolsCullen Baker
10/29/2025, 10:43 PMMarvin
10/29/2025, 10:43 PMMarvin
10/29/2025, 10:47 PMdocker compose up -d --force-recreate --no-deps prefect-server
# verify what the container is actually using
docker compose exec prefect-server sh -lc 'env | sort | grep PREFECT_UI'
# hard refresh the browser (Ctrl+Shift+R)
Sanity checks
- From your workstation:
curl -v <http://ch12lxtrd19:4200/api/health>
- In the browser Network tab, confirm Request URL is now http://ch12lxtrd19:4200/api/... (not 0.0.0.0).
Notes
- Keep PREFECT_SERVER_API_HOST=0.0.0.0 so the API binds to all interfaces in the container; just don’t let that leak into the UI config.
- Your previous prefect config set PREFECT_API_URL=... on your workstation is fine for your CLI/worker, but it won’t configure the server UI. Use the env var in docker-compose for that.
Docs
- Self-hosted with docker-compose: Guide
- Settings and profiles: Reference
If you still see 0.0.0.0 in the request URL after the change, please share the output of:
docker compose exec prefect-server sh -lc 'env | sort | grep -E "PREFECT_UI|PREFECT_API_URL|PREFECT_SERVER_API_HOST"'
and the current prefect-server environment section from docker-compose, and I’ll pinpoint what’s still injecting 0.0.0.0.