Tu Vu
08/07/2025, 10:17 AMMarvin
08/07/2025, 10:17 AMMarvin
08/07/2025, 10:18 AMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
server:
image: prefecthq/prefect:3-latest
restart: always
environment:
- PREFECT_SERVER_API_HOST=0.0.0.0
- PREFECT_SERVER_API_PORT=4200
- PREFECT_SERVER_DATABASE_CONNECTION_URL=<postgresql+asyncpg://prefect:prefect@postgres:5432/prefect>
# Add authentication
- PREFECT_SERVER_API_AUTH_STRING=admin:your_secure_password
ports:
- 4200:4200
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:
2. After setting up the server with authentication, clients will need to configure their authentication settings to match. This can be done in several ways:
a. Using environment variables:
bash
export PREFECT_API_AUTH_STRING="admin:your_secure_password"
b. Using the Prefect CLI to set the configuration:
bash
prefect config set PREFECT_API_AUTH_STRING="admin:your_secure_password"
3. For additional security, you might want to add Nginx as a reverse proxy. This would require adding an Nginx service to your Docker Compose file:
yaml
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- server
Important Security Considerations:
1. Use strong passwords and store them securely
2. Consider using environment files (.env) instead of hardcoding credentials
3. Implement proper network security rules on your VM
4. Keep your Prefect server and related components updated
To verify the authentication is working:
1. Start your services with docker compose up -d
2. Try accessing the Prefect UI - you should be prompted for authentication
3. Test a client connection using the Prefect CLI with the configured authentication
If you need to connect from remote clients, they'll need to:
1. Set the correct API URL: prefect config set PREFECT_API_URL="<http://your-server-ip:4200/api>"
2. Set the matching authentication string: prefect config set PREFECT_API_AUTH_STRING="admin:your_secure_password"
Would you like me to provide more specific details about any of these aspects, such as:
- Setting up Nginx configuration
- Additional security measures
- Troubleshooting authentication issues
- Setting up client configurationsTu Vu
08/07/2025, 10:20 AMversion: '3.8'
services:
# PostgreSQL database for Prefect
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: prefect
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
# Redis message broker (optional, but recommended for scaling)
redis:
image: redis:7
volumes:
- redis_data:/data
# Prefect Server
prefect-server:
image: prefecthq/prefect:3-latest
container_name: prefect-server
environment:
PREFECT_API_DATABASE_CONNECTION_URL: <postgresql+asyncpg://prefect:prefect@postgres/prefect>
PREFECT_API_URL: http://<vm_public_address>:4200/api
PREFECT_SERVER_API_HOST: 0.0.0.0
PREFECT_API_DATABASE_MIGRATE_ON_START: "True"
ports:
- "4200:4200"
volumes:
- prefect_server_data:/root/.prefect
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
command: prefect server start --host 0.0.0.0
# Prefect Background Services (e.g., scheduling)
prefect-services:
image: prefecthq/prefect:3-latest
environment:
PREFECT_API_URL: <http://prefect-server:4200/api>
depends_on:
prefect-server:
condition: service_started
command: prefect services start
volumes:
postgres_data:
redis_data:
prefect_server_data:
Marvin
08/07/2025, 10:20 AMMarvin
08/07/2025, 10:21 AMyaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: prefect
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-prefect} # Use environment variable
POSTGRES_DB: prefect
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U prefect"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
redis:
image: redis:7
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
networks:
- prefect-network
prefect-server:
image: prefecthq/prefect:3-latest
container_name: prefect-server
environment:
# Fixed the connection URL syntax (removed < >)
PREFECT_API_DATABASE_CONNECTION_URL: <postgresql+asyncpg://prefect:${POSTGRES_PASSWORD:-prefect}@postgres/prefect>
# Use environment variable for public address
PREFECT_API_URL: http://${VM_PUBLIC_ADDRESS}:4200/api
PREFECT_SERVER_API_HOST: 0.0.0.0
PREFECT_SERVER_API_PORT: 4200
PREFECT_API_DATABASE_MIGRATE_ON_START: "True"
# Add authentication
PREFECT_SERVER_API_AUTH_STRING: ${PREFECT_AUTH_STRING:-admin:prefect}
ports:
- "4200:4200"
volumes:
- prefect_server_data:/root/.prefect
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy # Changed to use healthcheck
networks:
- prefect-network
restart: unless-stopped
command: prefect server start --host 0.0.0.0
prefect-services:
image: prefecthq/prefect:3-latest
environment:
# Fixed the URL syntax (removed < >)
PREFECT_API_URL: <http://prefect-server:4200/api>
PREFECT_API_AUTH_STRING: ${PREFECT_AUTH_STRING:-admin:prefect}
depends_on:
prefect-server:
condition: service_started
networks:
- prefect-network
restart: unless-stopped
command: prefect services start
networks:
prefect-network:
driver: bridge
volumes:
postgres_data:
redis_data:
prefect_server_data:
Key improvements made:
1. Security Enhancements:
- Added PREFECT_SERVER_API_AUTH_STRING
for basic authentication
- Used environment variables for sensitive data (passwords, auth strings)
- Default values provided but can be overridden using environment variables
2. Network Configuration:
- Added a dedicated network prefect-network
for better isolation
- All services are connected to this network
3. Reliability Improvements:
- Added restart: unless-stopped
for better container recovery
- Added healthcheck for Redis
- Made Redis dependency use healthcheck instead of just service_started
4. Syntax Fixes:
- Removed < >
from URLs which would cause issues
- Properly formatted environment variables
To use this improved version:
1. Create a .env
file in the same directory as your docker-compose.yml:
bash
VM_PUBLIC_ADDRESS=your.server.address
POSTGRES_PASSWORD=your-secure-password
PREFECT_AUTH_STRING=admin:your-secure-password
2. Start the services:
bash
docker compose --env-file .env up -d
3. For clients connecting to this server, they'll need to configure:
bash
prefect config set PREFECT_API_URL="<http://your.server.address:4200/api>"
prefect config set PREFECT_API_AUTH_STRING="admin:your-secure-password"
Additional recommendations:
1. Consider adding Nginx as a reverse proxy if you want to:
- Add SSL/TLS
- Handle custom domains
- Add additional security layers
2. For production environments:
- Use secrets management for sensitive values
- Consider adding resource limits to containersMarvin
08/07/2025, 10:21 AMTu Vu
08/08/2025, 7:01 AMclass PrefectService:
def __init__(self):
self.prefect_client = get_client(
httpx_settings={
"base_url": settings.prefect_api_url,
}
)
Marvin
08/08/2025, 7:01 AMMarvin
08/08/2025, 7:04 AMTu Vu
08/08/2025, 7:20 AMgcloud run deploy prefect-worker-pool --image=prefecthq/prefect:3.4.11 \
--set-env-vars PREFECT_API_URL=<http://xxx:4200/api> \
--service-account <mailto:prefect-worker-pool@xxx.iam.gserviceaccount.com|prefect-worker-pool@xxx.iam.gserviceaccount.com> \
--no-cpu-throttling \
--min-instances 1 \
--max-instances 1 \
--startup-probe httpGet.port=8080,httpGet.path=/health,initialDelaySeconds=100,periodSeconds=20,timeoutSeconds=20 \
--args "prefect","worker","start","--install-policy","always","--with-healthcheck","--pool","cloudrun-worker-pool"
Marvin
08/08/2025, 7:20 AMMarvin
08/08/2025, 7:23 AM