Slackbot
12/26/2025, 1:53 AMMarvin
12/26/2025, 1:53 AMMarvin
12/26/2025, 1:53 AMMarvin
12/26/2025, 1:55 AMMarvin
12/26/2025, 1:59 AMPREFECT_API_URL=<http://prefect-server:4200/api>
- Using http://${PUBLIC_IP}:4200/api often fails from inside containers.
2) Server not listening on all interfaces
- In Docker, the API must bind to 0.0.0.0 or other containers can’t reach it.
- Set: PREFECT_SERVER_API_HOST=0.0.0.0
- If you pass a CLI flag, use --host 0.0.0.0 (not spaced out).
3) Startup ordering/healthchecks
- Keep depends_on: {prefect-server: {condition: service_healthy}} for the worker so it starts after the API is actually healthy.
4) Bad/malformed env values in the snippet
- These should be exact:
- DB URL: PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:${POSTGRES_PASSWORD:-prefect}@postgres:5432/prefect>
- Messaging: PREFECT_MESSAGING_BROKER=prefect_redis.messaging and PREFECT_MESSAGING_CACHE=prefect_redis.messaging (note the dot, not a space)
- Redis host: PREFECT_REDIS_MESSAGING_HOST=redis
- If you’re using auth, PREFECT_API_AUTH_STRING in the worker must match PREFECT_SERVER_API_AUTH_STRING on the server.
5) Increase API timeout if your server is slow
- Default is 60s. You can bump it:
- PREFECT_API_REQUEST_TIMEOUT=120
6) Make sure the work pool exists
- If you’re starting the worker with --pool default, ensure the pool is created and not paused:
prefect work-pool create default --type process
Quick checks from inside the worker container:
- Can it resolve and reach the API?
docker compose exec prefect-worker sh -c "apk add --no-cache curl || true; curl -v <http://prefect-server:4200/api/health>"
- Can it resolve the DNS name?
docker compose exec prefect-worker ping -c 1 prefect-server
Minimal, corrected Compose snippets for the key parts:
- Server
prefect-server:
image: prefecthq/prefect:3-latest
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
PREFECT_API_DATABASE_CONNECTION_URL: <postgresql+asyncpg://prefect:${POSTGRES_PASSWORD:-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_API_REQUEST_TIMEOUT: "120"
# Optional: PREFECT_SERVER_API_AUTH_STRING: ${PREFECT_AUTH_STRING}
command: prefect server start --no-services
ports:
- "4200:4200"
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request as u; u.urlopen('<http://localhost:4200/api/health>', timeout=5)"]
interval: 20s
timeout: 10s
retries: 5
start_period: 30s
- Services (if running separately)
prefect-services:
image: prefecthq/prefect:3-latest
depends_on:
prefect-server:
condition: service_healthy
environment:
PREFECT_API_DATABASE_CONNECTION_URL: <postgresql+asyncpg://prefect:${POSTGRES_PASSWORD:-prefect}@postgres:5432/prefect>
PREFECT_MESSAGING_BROKER: prefect_redis.messaging
PREFECT_MESSAGING_CACHE: prefect_redis.messaging
PREFECT_REDIS_MESSAGING_HOST: redis
PREFECT_REDIS_MESSAGING_PORT: "6379"
PREFECT_API_REQUEST_TIMEOUT: "120"
command: prefect server services start
- Worker
```
prefect-worker:
image: prefecthq/prefect:3-latest
depends_on:
prefect-server:
condition: service_healthy
environment:
PREFECT_API_URL: http://prefect-server:4200/api
PREFECT_API_REQUEST_TIMEOUT: "120"
# Optional if you enabled auth on server:Marvin
12/26/2025, 1:59 AMPREFECT_API_URL in the worker container (after env substitution)
- Run the curl test above from inside the worker and paste the result
- Confirm the pool name you’re using and whether it exists and is unpaused
Happy to review your full docker-compose.yml if you paste it here, and we’ll pinpoint the minimal changes needed.