oleander-whirlwind
12/05/2025, 8:24 AMMarvin
12/05/2025, 8:24 AMMarvin
12/05/2025, 8:28 AMdocker run command or inside a docker-compose file. For production, many teams still prefer to explicitly create/update the pool first so they can control settings like the base job template.
Options:
- Let the worker auto-create the pool (simple)
- If the pool doesn’t exist, pass the worker type so Prefect knows what to create.
- Example with Docker worker:
docker run --rm \
-e PREFECT_API_URL=<your-api-url> \
-e PREFECT_API_KEY=<your-api-key-if-using-cloud> \
-v /var/run/docker.sock:/var/run/docker.sock \
prefecthq/prefect:latest \
prefect worker start --pool my-docker-pool --type docker
Notes:
- --type docker is needed if the pool doesn’t exist yet.
- If the pool already exists, Prefect will infer the type from the pool and --type isn’t required.
- Create/update the pool before starting the worker (recommended for controlled config)
- Idempotent compose pattern:
services:
pool-init:
image: prefecthq/prefect:latest
environment:
PREFECT_API_URL: <your-api-url>
PREFECT_API_KEY: <your-api-key-if-using-cloud>
command: >
sh -c "
prefect work-pool create my-docker-pool --type docker --overwrite || true
"
docker-worker:
image: prefecthq/prefect:latest
depends_on:
- pool-init
environment:
PREFECT_API_URL: <your-api-url>
PREFECT_API_KEY: <your-api-key-if-using-cloud>
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: prefect worker start --pool my-docker-pool
restart: unless-stopped
- Use --base-job-template on work-pool create if you need a custom job template:
prefect work-pool create my-docker-pool --type docker --base-job-template ./base-job-template.json --overwrite
Docs for reference:
- Work pools concept: Work pools
- Managing work pools: Manage work pools
- Docker worker guide: Docker worker
- CLI reference: work-pool and worker
Quick check:
- Using Prefect Cloud? Set PREFECT_API_KEY and point PREFECT_API_URL to your workspace URL, or run prefect cloud login in your container entrypoint.
- Self-hosted Prefect Server? Set PREFECT_API_URL to your server’s API (e.g., `http://prefect-server:4200/api`).
If you share whether you’re on Cloud or self-hosted and which worker type you want (docker/kubernetes/process), I can tailor the exact compose snippet for your setup.oleander-whirlwind
12/05/2025, 8:30 AMMarvin
12/05/2025, 8:30 AMMarvin
12/05/2025, 8:33 AMprefect worker start is trying to read the work pool, but all TCP connection attempts to PREFECT_API_URL are failing.
Common causes and quick fixes:
- Missing or wrong PREFECT_API_URL
- Using <http://localhost:4200/api> from inside a container (localhost points to the container, not your host)
- Prefect Server not started yet (ordering/healthcheck issue in compose)
- Using Prefect Cloud but missing PREFECT_API_KEY, wrong URL, or proxy blocking egress
Diagnose inside the worker container:
prefect config view --show-sources
Confirm:
- api.url is set to the correct endpoint
- If using Cloud, api.key is set and valid
If you’re using Prefect Server with docker-compose:
- Point the worker at the server service name, not localhost
- Example compose snippet:
services:
prefect-server:
image: prefecthq/prefect:latest
command: prefect server start
ports:
- "4200:4200"
prefect-worker:
image: prefecthq/prefect:latest
depends_on:
- prefect-server
environment:
PREFECT_API_URL: <http://prefect-server:4200/api>
# For Docker work pool only; not needed for process worker
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: prefect worker start --pool my-docker-pool --type docker
restart: unless-stopped
If your server is running on your host (not in compose):
- Use host.docker.internal from the container:
PREFECT_API_URL=<http://host.docker.internal:4200/api>
- On Linux, add this to the worker service:
extra_hosts:
- "host.docker.internal:host-gateway"
If you’re using Prefect Cloud:
- Set both URL and API key:
PREFECT_API_URL="<https://api.prefect.cloud/api/accounts/<ACCOUNT_ID>/workspaces/<WORKSPACE_ID>>"
PREFECT_API_KEY="pnb_xxx or pnu_xxx"
- Test from the container:
curl -I "$PREFECT_API_URL/health"
If the pool might not exist yet, include the worker type on first start so it can auto-create the pool:
prefect worker start --pool my-docker-pool --type docker
# or for a process worker
prefect worker start --pool my-process-pool --type process
Helpful docs:
- Settings & profiles: Settings and profiles
- Connect to Cloud: Connect to Cloud
- Docker worker guide: Docker worker
- Self-hosted via docker-compose: Docker Compose for Server
- Cloud troubleshooting: Troubleshoot Cloud
If you can share:
- Whether you’re on Cloud or self-hosted
- Your PREFECT_API_URL value
- Your docker-compose snippet for the worker (and server, if applicable)
…I can pinpoint the exact fix for your setup.oleander-whirlwind
12/05/2025, 10:26 AMMarvin
12/05/2025, 10:26 AMMarvin
12/05/2025, 10:27 AMPREFECT_API_URL=<http://prefect-server:4200/api> but still see “All connection attempts failed”, it means the worker container cannot reach the server at that hostname/port.
Most common causes and quick fixes:
1) The server isn’t reachable on the container network
- Ensure the server and worker are in the same docker-compose project/network and the service is named prefect-server.
- If the server runs in a different compose project or separately, put both on a shared network or switch the URL to the host:
- If server runs on your host: use <http://host.docker.internal:4200/api> (on Linux add extra_hosts: ["host.docker.internal:host-gateway"]).
- If in a different compose project: use a user-defined external network and attach both services to it.
2) The server is binding to 127.0.0.1 inside its container
- Make sure the server binds to 0.0.0.0 so other containers can connect:
command: prefect server start --host 0.0.0.0 --port 4200
3) The worker starts before the server is ready
- Add a healthcheck and depend on it:
prefect-server:
image: prefecthq/prefect:latest
command: prefect server start --host 0.0.0.0 --port 4200
ports:
- "4200:4200"
healthcheck:
test: ["CMD", "curl", "-f", "<http://localhost:4200/api/health>"]
interval: 5s
timeout: 3s
retries: 20
prefect-worker:
image: prefecthq/prefect:latest
depends_on:
prefect-server:
condition: service_healthy
environment:
PREFECT_API_URL: <http://prefect-server:4200/api>
command: prefect worker start --pool my-pool --type process
restart: unless-stopped
4) DNS/hostname mismatch
- From inside the worker container, test resolution and connectivity:
prefect config view --show-sources
getent hosts prefect-server
curl -v <http://prefect-server:4200/api/health>
- If getent can’t resolve prefect-server, the services are not on the same network or the name differs.
5) You’re on Prefect Cloud by mistake
- If PREFECT_API_KEY is set and PREFECT_API_URL points to Prefect Cloud, the worker will try Cloud. For self-hosted, unset PREFECT_API_KEY or ensure PREFECT_API_URL truly points to your server (and server is reachable).
Helpful references:
- Docker Compose for self-hosted server: Docker Compose guide
- Server overview: Server
- Settings & profiles (API URL / key): Settings and profiles
If you can share your docker-compose snippet (server + worker services), I’ll point out the exact change to make.oleander-whirlwind
12/05/2025, 10:32 AMMarvin
12/05/2025, 10:32 AMMarvin
12/05/2025, 10:33 AMprefect-server-1 vs prefect-worker-docker-process-1), the worker won’t resolve prefect-server. Either:
- Put both services in the same compose file/project, or
- Attach both to a shared user-defined network, or
- Point the worker at the host’s published port via host.docker.internal.
Concrete fixes:
Option A — same compose project/network
- Ensure both services are defined in one compose file (or started with the same -p <project>).
- Use the service name:
environment:
PREFECT_API_URL: <http://prefect-server:4200/api>
Option B — shared external network
networks:
prefect-net:
name: prefect-net
external: true
services:
prefect-server:
networks: [prefect-net]
command: prefect server start --host 0.0.0.0 --port 4200
prefect-worker:
networks: [prefect-net]
environment:
PREFECT_API_URL: <http://prefect-server:4200/api>
Create the network once:
docker network create prefect-net
Option C — connect via host port
- If the server is reachable on your host at 4200:
environment:
PREFECT_API_URL: <http://host.docker.internal:4200/api>
- On Linux add:
extra_hosts:
- "host.docker.internal:host-gateway"
Add readiness/health checks to avoid race conditions:
prefect-server:
command: prefect server start --host 0.0.0.0 --port 4200
healthcheck:
test: ["CMD", "curl", "-f", "<http://localhost:4200/api/health>"]
interval: 5s
timeout: 3s
retries: 20
prefect-worker:
depends_on:
prefect-server:
condition: service_healthy
Validate from inside the worker container:
prefect config view --show-sources
getent hosts prefect-server
curl -v <http://prefect-server:4200/api/health>
Key points:
- Don’t set PREFECT_API_URL to <http://0.0.0.0:4200/api> in the worker.
- Make sure DNS for prefect-server resolves inside the worker (same network or use host.docker.internal).
Docs:
- Self-hosted with docker-compose: Docker Compose guide
- Server overview: Server
- Settings & profiles: Settings and profiles
If you paste your compose snippet (server + worker sections), I’ll mark the exact changes to make.oleander-whirlwind
12/05/2025, 10:55 AMMarvin
12/05/2025, 10:55 AMMarvin
12/05/2025, 10:56 AM# Create the network once (shared across compose projects)
# docker network create prefect-net
networks:
prefect-net:
external: true
services:
prefect-server:
image: prefecthq/prefect:latest
command: prefect server start --host 0.0.0.0 --port 4200
networks:
prefect-net:
aliases:
- prefect-api # <-- explicit DNS name for the server
ports:
- "4200:4200"
prefect-worker:
image: prefecthq/prefect:latest
depends_on:
- prefect-server
networks:
- prefect-net
environment:
PREFECT_API_URL: <http://prefect-api:4200/api> # <-- use the alias here
command: prefect worker start --pool my-pool --type process
restart: unless-stopped
Notes:
- The service name (e.g., prefect-server) is also a DNS name on the network. Use aliases if you want a different or additional stable name like prefect-api.
- If your server and worker are in different compose files/projects, they must share the same external network (as shown) to resolve each other by name.
- Avoid container_name unless you really need it; it limits scaling and can collide. Prefer networks.<name>.aliases.
- Setting hostname only affects the container’s internal hostname; it doesn’t create a name other containers can resolve. Use aliases for that.
If your server runs on the host instead of a container, map a DNS name to the host gateway from the worker:
services:
prefect-worker:
extra_hosts:
- "prefect-api:host-gateway"
environment:
PREFECT_API_URL: <http://prefect-api:4200/api>
Quick validation from the worker container:
getent hosts prefect-api
curl -v <http://prefect-api:4200/api/health>
If you paste your current compose snippets (server + worker), I can suggest the exact edits.oleander-whirlwind
12/05/2025, 11:12 AMMarvin
12/05/2025, 11:12 AMMarvin
12/05/2025, 11:13 AMdocker network inspect <network> -f '{{range $id, $c := .Containers}}{{printf "%s\t%s\n" $c.Name $c.IPv4Address}}{{end}}'
2) List all resolvable names (service name, container name, and any custom aliases) per container on that network
NET=<network>
for id in $(docker network inspect "$NET" -f '{{range $id, $c := .Containers}}{{println $id}}{{end}}'); do
docker inspect "$id" \
--format "{{.Name}}: {{(index .NetworkSettings.Networks \"$NET\").Aliases}}"
done
Notes:
- Docker’s embedded DNS registers, per network, the container name, the Compose service name, and any networks.<net>.aliases you set.
- These names only resolve between containers that share that network.
- To test a specific name from a container on that network:
getent hosts <name>
curl -v http://<name>:<port>/api/health
If you share your network name, I can help tailor the exact command for your setup.oleander-whirlwind
12/05/2025, 11:44 AMMarvin
12/05/2025, 11:44 AMMarvin
12/05/2025, 11:44 AMoleander-whirlwind
12/05/2025, 11:46 AMMarvin
12/05/2025, 11:46 AMMarvin
12/05/2025, 11:47 AMenvironment:
PREFECT_API_URL: <http://prefect-server:4200/api>
It must be:
environment:
PREFECT_API_URL: <http://prefect-server:4200/api>
If the brackets are present, Prefect’s client will try to connect to a malformed host and you’ll get ConnectError even though curl with the clean URL works.
Let’s verify exactly what Prefect sees inside the worker container:
- Print the env var and Prefect’s resolved config
echo "$PREFECT_API_URL"
prefect config view --show-sources | grep -i -A1 "api.url"
- Double-check what the Prefect client is actually using
python - <<'PY'
import asyncio, os
from prefect.client.orchestration import get_client
async def main():
print("ENV PREFECT_API_URL =", os.getenv("PREFECT_API_URL"))
async with get_client() as c:
print("Client base url =", str(c._client.base_url))
r = await c._client.get("/health")
print("Health JSON =", r.json())
asyncio.run(main())
PY
If the values don’t exactly match http://prefect-server:4200/api:
- Remove any angle brackets
- Ensure there’s no trailing whitespace or hidden characters
- Make sure no profile in the image is overriding it (env vars should win, but let’s confirm with the show-sources output)
Other quick checks:
- Ensure the server binds to all interfaces so other containers can reach it:
command: prefect server start --host 0.0.0.0 --port 4200
- If the pool might not exist yet, let the worker create it by specifying the type once:
prefect worker start --pool my-process-pool --type process
If you paste your worker service from docker-compose (exact environment block and command), I’ll mark the one-line fix.oleander-whirlwind
12/05/2025, 11:51 AMMarvin
12/05/2025, 11:51 AMMarvin
12/05/2025, 11:51 AM<http://prefect-server:4200/api> for link formatting. If those angle brackets make it into your docker-compose or env file, Prefect will try to use the URL with the brackets included, which is invalid and causes the ConnectError you’re seeing.
Wrong (has angle brackets):
environment:
PREFECT_API_URL: <http://prefect-server:4200/api>
Right (no angle brackets; quoting is optional but safe):
environment:
PREFECT_API_URL: "<http://prefect-server:4200/api>"
Quick checks inside the worker container:
echo "$PREFECT_API_URL"
prefect config view --show-sources | grep -i -A1 "api.url"
If you want, paste the exact environment block from your compose file and I’ll confirm it’s clean. If the brackets weren’t the issue, share the prefect config view --show-sources output for api.url and we’ll keep digging.