Mark Moreno
07/03/2025, 3:56 PMservices:
prefect:
image: 'prefecthq/prefect:3-latest'
depends_on:
postgresql:
condition: service_healthy
environment:
- 'PREFECT_API_URL=<http://prefect.example.com/api|prefect.example.com/api>'
- 'PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://postgresuser:supersecurepassword@postgresql:5432/${POSTGRES_DB:-prefect}>'
- 'PREFECT_API_KEY=gyy789uijnbhgvytf67'
- 'PREFECT_EXPERIMENTAL_WARN=false'
- 'PREFECT_EXPERIMENTAL_ENABLE_SCHEDULE_CONCURRENCY=false'
- 'PREFECT_RUNNER_SERVER_ENABLE=false'
- 'PREFECT_DEFAULT_WORK_POOL_NAME=default'
command:
- prefect
- server
- start
- '--host'
- 0.0.0.0
- '--port'
- '4200'
healthcheck:
test:
- CMD
- python
- '-c'
- "import requests as r;r.get('<http://127.0.0.1:4200/api/health').raise_for_status(>)"
interval: 5s
timeout: 5s
retries: 3
postgresql:
image: 'postgres:16-alpine'
volumes:
- 'pg-data:/var/lib/postgresql/data'
environment:
- POSTGRES_USER=postgresuser
- POSTGRES_PASSWORD=supersecurepassword
- 'POSTGRES_DB=prefect'
healthcheck:
test:
- CMD-SHELL
- 'pg_isready -U postgresuser -d prefect'
interval: 5s
timeout: 5s
retries: 3
agent:
image: 'prefecthq/prefect:3-python3.12'
depends_on:
prefect:
condition: service_healthy
entrypoint:
- /opt/prefect/entrypoint.sh
- prefect
- worker
- start
- '--pool=default'
- '--with-healthcheck'
- '--name=worker1'
- '--limit=1'
environment:
- 'PREFECT_API_URL=<http://prefect:4200/api>'
- 'PREFECT_API_KEY=gyy789uijnbhgvytf67'
- 'DEFAULT_POOL_NAME=default'
- 'DEFAULT_POOL_LIMIT=1'
- 'DEFAULT_WORKER_NAME=worker1'
healthcheck:
test:
- CMD-SHELL
- pwd
interval: 5s
timeout: 5s
retries: 3
Marvin
07/03/2025, 3:56 PMMarvin
07/03/2025, 3:56 PM<http://prefect.example.com|prefect.example.com>
) won't work unless you have:
- Proper DNS resolution for <http://prefect.example.com|prefect.example.com>
- A reverse proxy (like nginx) handling the routing
- Port forwarding configured correctly
2. Port Exposure: You haven't exposed any ports in your Docker Compose file. You need to add port mapping for the Prefect server.
3. Network Configuration: The services need to be on the same network to communicate.
Here's the corrected version of your Docker Compose file:
yaml
services:
prefect:
image: 'prefecthq/prefect:3-latest'
depends_on:
postgresql:
condition: service_healthy
ports:
- "4200:4200" # Add this to expose the port
environment:
- 'PREFECT_API_URL=<http://0.0.0.0:4200/api>' # Changed for direct access
- 'PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://postgresuser:supersecurepassword@postgresql:5432/${POSTGRES_DB:-prefect}>'
- 'PREFECT_API_KEY=gyy789uijnbhgvytf67'
- 'PREFECT_EXPERIMENTAL_WARN=false'
- 'PREFECT_EXPERIMENTAL_ENABLE_SCHEDULE_CONCURRENCY=false'
- 'PREFECT_RUNNER_SERVER_ENABLE=false'
- 'PREFECT_DEFAULT_WORK_POOL_NAME=default'
command:
- prefect
- server
- start
- '--host'
- '0.0.0.0'
- '--port'
- '4200'
healthcheck:
test:
- CMD
- python
- '-c'
- "import requests as r;r.get('<http://127.0.0.1:4200/api/health>').raise_for_status()"
interval: 5s
timeout: 5s
retries: 3
networks:
- prefect-network # Add this
postgresql:
# ... (your existing postgresql config)
networks:
- prefect-network # Add this
agent:
# ... (your existing agent config)
networks:
- prefect-network # Add this
networks:
prefect-network: # Add this network definition
driver: bridge
To make this work with `prefect.example.com`:
1. If you're using this locally for testing, you can access it directly at <http://localhost:4200>
2. If you need to use <http://prefect.example.com|prefect.example.com>
, you'll need to:
- Set up a reverse proxy (like nginx) to forward requests to the Prefect server
- Configure your DNS or local hosts file to resolve <http://prefect.example.com|prefect.example.com>
- Update the PREFECT_API_URL
to match your final access URL
For a quick test to verify if the server is working:
1. After applying these changes, run docker compose up
2. Try accessing <http://localhost:4200>
3. You should see the Prefect UI
If you specifically need to use <http://prefect.example.com|prefect.example.com>
, let me know and I can provide additional configuration steps for setting up a reverse proxy.Mark Moreno
07/03/2025, 4:00 PMMarvin
07/03/2025, 4:01 PMMarvin
07/03/2025, 4:01 PMyaml
services:
prefect:
image: 'prefecthq/prefect:3-latest'
depends_on:
postgresql:
condition: service_healthy
ports:
- "4200:4200"
environment:
- 'PREFECT_API_URL=<http://prefect.example.com/api>' # Remove the :4200 port
- 'PREFECT_UI_API_URL=<http://prefect.example.com/api>' # Add this line
- 'PREFECT_SERVER_API_HOST=0.0.0.0' # Add this line
- 'PREFECT_API_DATABASE_CONNECTION_URL=<postgresql+asyncpg://postgresuser:supersecurepassword@postgresql:5432/${POSTGRES_DB:-prefect}>'
- 'PREFECT_API_KEY=gyy789uijnbhgvytf67'
- 'PREFECT_EXPERIMENTAL_WARN=false'
- 'PREFECT_EXPERIMENTAL_ENABLE_SCHEDULE_CONCURRENCY=false'
- 'PREFECT_RUNNER_SERVER_ENABLE=false'
- 'PREFECT_DEFAULT_WORK_POOL_NAME=default'
command:
- prefect
- server
- start
- '--host'
- '0.0.0.0'
- '--port'
- '4200'
# ... rest of your prefect service config
Additionally, since you're accessing the server through <http://prefect.example.com|prefect.example.com>
, you'll need to set up a reverse proxy (like nginx) to handle the routing. Here's a sample nginx configuration:
nginx
server {
listen 80;
server_name <http://prefect.example.com|prefect.example.com>;
location / {
proxy_pass <http://prefect:4200;>
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Add this nginx service to your docker-compose:
yaml
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- prefect
networks:
- prefect-network
If you need HTTPS (which is recommended for production):
1. Add SSL certificates
2. Update the nginx configuration to listen on port 443
3. Update all PREFECT_API_URL
and PREFECT_UI_API_URL
to use https://
instead of http://
Try these changes and let me know if you're still experiencing issues. Remember to:
1. Save the nginx configuration in a file named nginx.conf
in the same directory as your docker-compose file
2. Restart all services with docker compose down && docker compose up -d
3. Access the UI through <http://prefect.example.com>
(or https://
if you've configured SSL)Mark Moreno
07/03/2025, 4:15 PM[Warning] [blocked] The page at <https://prefect.example.com/deployments> requested insecure content from <http://prefect.example.com/api/health>. This content was blocked and must be served over HTTPS. (index-DLpks3Kx.js, line 126)
[Error] Not allowed to request resource
(anonymous function) (index-DLpks3Kx.js:126:7063)
Promise
(anonymous function) (index-DLpks3Kx.js:126:5107)
GH (index-DLpks3Kx.js:128:514)
[Error] XMLHttpRequest cannot load <http://prefect.example.com/api/health> due to access control checks.
(anonymous function) (index-DLpks3Kx.js:126:7063)
Promise
(anonymous function) (index-DLpks3Kx.js:126:5107)
GH (index-DLpks3Kx.js:128:514)
[Warning] [blocked] The page at <https://prefect.example.com/deployments> requested insecure content from <http://prefect.example.com/api/deployments/filter>. This content was blocked and must be served over HTTPS. (index-DLpks3Kx.js, line 126)
[Error] Not allowed to request resource
(anonymous function) (index-DLpks3Kx.js:126:7063)
Promise
(anonymous function) (index-DLpks3Kx.js:126:5107)
GH (index-DLpks3Kx.js:128:514)
[Error] XMLHttpRequest cannot load <http://prefect.example.com/api/deployments/filter> due to access control checks.
(anonymous function) (index-DLpks3Kx.js:126:7063)
Promise
(anonymous function) (index-DLpks3Kx.js:126:5107)
GH (index-DLpks3Kx.js:128:514)
[Error] Ur {stack: "@https://prefect.example.com/assets/index-DLpks3Kx.…<http://fect.example.com/assets/index-DLpks3Kx.js:128:2087|fect.example.com/assets/index-DLpks3Kx.js:128:2087>", message: "Network Error", name: "AxiosError", code: "ERR_NETWORK", config: Object, …}
(anonymous function) (index-DLpks3Kx.js:120:15186)
[Warning] The resource <https://prefect.example.com/assets/Deployments-D7qVpAbj.js> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.
Marvin
07/03/2025, 4:15 PMMarvin
07/03/2025, 4:15 PM<https://prefect.example.com>
) but the API endpoints are still being requested over HTTP. This mixed content is being blocked by the browser. Let's fix this by ensuring everything uses HTTPS consistently.
Here's the updated configuration:
1. First, update your Prefect service environment variables in docker-compose:
yaml
services:
prefect:
environment:
- 'PREFECT_API_URL=<https://prefect.example.com/api>'
- 'PREFECT_UI_API_URL=<https://prefect.example.com/api>'
# ... other environment variables remain the same
2. Update your nginx configuration to handle HTTPS:
nginx
server {
# Redirect HTTP to HTTPS
listen 80;
server_name <http://prefect.example.com|prefect.example.com>;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name <http://prefect.example.com|prefect.example.com>;
# SSL configuration
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass <http://prefect:4200;>
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
3. Update your nginx service in docker-compose to include SSL certificates:
yaml
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443" # Add HTTPS port
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./ssl:/etc/nginx/ssl:ro # Mount SSL certificates
depends_on:
- prefect
networks:
- prefect-network
4. Update your agent configuration to use HTTPS:
yaml
services:
agent:
environment:
- 'PREFECT_API_URL=<https://prefect.example.com/api>'
# ... other environment variables remain the same
5. Make sure you have SSL certificates:
- Place your SSL certificate files (cert.pem
and key.pem
) in an ssl
directory next to your docker-compose file
- If you don't have certificates, you can get free ones from Let's Encrypt using certbot
To implement these changes:
1. Create the SSL certificate directory:
bash
mkdir ssl
# Place your cert.pem and key.pem files in this directory
2. Restart your services:
bash
docker compose down
docker compose up -d
3. Check that all services are healthy:
bash
docker compose ps
Important notes:
- Make sure your SSL certificates are valid and properly configured
- The certificates should match your domain name (<http://prefect.example.com|prefect.example.com>
)
- All URLs in the configuration should consistently use https://
- If you're using a self-signed certificate for testing, you might need to add it to your browser's trusted certificates
Let me know if you need help with any of these steps or if you're still experiencing issues.