MUHAMMAD ZEESHAN
07/31/2025, 3:53 PMMarvin
07/31/2025, 3:53 PMMarvin
07/31/2025, 3:53 PMMUHAMMAD ZEESHAN
07/31/2025, 3:54 PMMarvin
07/31/2025, 3:55 PMMarvin
07/31/2025, 3:55 PMMUHAMMAD ZEESHAN
07/31/2025, 3:57 PMMarvin
07/31/2025, 3:57 PMMarvin
07/31/2025, 3:58 PM<postgresql+psycopg://prefect:shan123@localhost:5432/prefect>
This is correct for Prefect 3.x with psycopg.
2. API Configuration:
PREFECT_SERVER_API_HOST=127.0.0.1
PREFECT_SERVER_API_PORT=4200
This is correct, but since you're running behind Nginx, binding to 127.0.0.1 is a good security practice.
3. UI API URL:
PREFECT_UI_API_URL=<https://prefect.happyraisins.com/api>
This is correct for your domain setup with SSL.
Recommendations:
1. Add these additional security-related settings:
bash
# Add these to your server.env
PREFECT_API_ENABLE_HTTP2=true
PREFECT_SERVER_API_HOST_PORT=4200
2. Since you're using Nginx with SSL, ensure your Nginx configuration properly proxies to the Prefect server. Your Nginx configuration should include something like:
nginx
location /api/ {
proxy_pass <http://127.0.0.1:4200/api/;>
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;
}
3. After making these changes:
bash
sudo systemctl restart prefect-server
4. Monitor the logs for any issues:
bash
sudo journalctl -u prefect-server -f
Would you like me to:
1. Provide more detailed Nginx configuration examples?
2. Help troubleshoot if you're still seeing the database connection error?
3. Provide additional security recommendations for your setup?
Please let me know what would be most helpful!MUHAMMAD ZEESHAN
07/31/2025, 4:02 PMMarvin
07/31/2025, 4:02 PMMarvin
07/31/2025, 4:03 PMcommand_timeout
parameter being passed to the PostgreSQL connection. This parameter isn't valid for psycopg, which is why you're seeing the error.
Here's what we need to do:
1. First, let's check if there are any other configuration files that might be setting this parameter. Check these locations:
bash
cat ~/.prefect/profiles.toml
cat /etc/prefect/config.toml
2. Modify your server.env file to ensure we're using the correct connection settings:
bash
sudo tee /etc/prefect/server.env << 'EOF'
PREFECT_SERVER_API_HOST=127.0.0.1
PREFECT_SERVER_API_PORT=4200
PREFECT_UI_API_URL=<https://prefect.happyraisins.com/api>
PREFECT_SERVER_DATABASE_CONNECTION_URL=<postgresql+psycopg://prefect:shan123@localhost:5432/prefect>
# Add these timeout-related settings instead of command_timeout
PREFECT_API_DATABASE_TIMEOUT=30
PREFECT_API_REQUEST_TIMEOUT=30
EOF
3. Make sure there are no SQLAlchemy connect args being set that might include the command_timeout:
bash
# Check for any existing connect args
env | grep PREFECT_SERVER_DATABASE_SQLALCHEMY
4. If you need to set specific PostgreSQL connection parameters, use these environment variables instead:
bash
# Add these if you need specific timeout controls
PREFECT_API_DATABASE_TIMEOUT=30 # General database timeout in seconds
PREFECT_API_REQUEST_TIMEOUT=30 # API request timeout in seconds
5. Restart the Prefect server after making these changes:
bash
sudo systemctl restart prefect-server
6. Monitor the logs:
bash
sudo journalctl -u prefect-server -f
Additionally, let's verify that PostgreSQL is running and accessible:
bash
# Test PostgreSQL connection
psql -U prefect -h localhost -d prefect -c "SELECT version();"
If you're still seeing the error after making these changes, we should:
1. Check if there are any environment variables set in the systemd service file:
bash
sudo systemctl cat prefect-server
2. Verify that no other configuration files are overriding these settings:
bash
prefect config view
Would you like me to:
1. Help you check for conflicting configuration files?
2. Provide a complete systemd service file configuration?
3. Help troubleshoot the PostgreSQL connection directly?
Please let me know which would be most helpful, and also share any error messages you see after making these changes.MUHAMMAD ZEESHAN
07/31/2025, 4:08 PMMarvin
07/31/2025, 4:08 PMMarvin
07/31/2025, 4:08 PMbash
sudo tee /etc/prefect/server.env << 'EOF'
PREFECT_SERVER_API_HOST=127.0.0.1
PREFECT_SERVER_API_PORT=4200
PREFECT_UI_API_URL=<https://prefect.happyraisins.com/api>
PREFECT_SERVER_DATABASE_CONNECTION_URL=<postgresql+psycopg://prefect:shan123@localhost:5432/prefect>
# Explicitly clear any connect args
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS={}
# Set standard timeouts
PREFECT_API_DATABASE_TIMEOUT=30
EOF
2. Let's check the systemd service file:
bash
sudo systemctl cat prefect-server.service
3. Create a new systemd service file that ensures a clean environment:
bash
sudo tee /etc/systemd/system/prefect-server.service << 'EOF'
[Unit]
Description=Prefect Server
After=network.target postgresql.service
[Service]
Type=simple
User=prefect
Group=prefect
EnvironmentFile=/etc/prefect/server.env
ExecStart=/opt/.venv/bin/prefect server start
Restart=always
RestartSec=1
StandardOutput=journal
StandardError=journal
# Ensure clean environment
Environment=PYTHONUNBUFFERED=1
Environment=PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS={}
[Install]
WantedBy=multi-user.target
EOF
4. Reload and restart everything:
bash
sudo systemctl daemon-reload
sudo systemctl restart prefect-server
5. If that doesn't work, let's try to start the server manually to see more detailed output:
bash
sudo -u prefect bash -c '
export PREFECT_SERVER_API_HOST=127.0.0.1
export PREFECT_SERVER_API_PORT=4200
export PREFECT_UI_API_URL=<https://prefect.happyraisins.com/api>
export PREFECT_SERVER_DATABASE_CONNECTION_URL="<postgresql+psycopg://prefect:shan123@localhost:5432/prefect>"
export PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS="{}"
/opt/.venv/bin/prefect server start
'
Also, let's check if there are any Prefect configuration files in the user's home directory:
bash
sudo -u prefect ls -la ~prefect/.prefect/
The persistent command_timeout
error suggests there might be:
1. A configuration file we haven't found
2. An environment variable we haven't overridden
3. A default setting in the SQLAlchemy dialect that we need to modify
Could you please:
1. Run the manual server start command I provided above and share the output?
2. Check if there are any Prefect configuration files in the prefect user's home directory?
3. Share the output of env | grep PREFECT
to see all Prefect-related environment variables?
This will help us track down where this setting is coming from.MUHAMMAD ZEESHAN
07/31/2025, 4:31 PMMarvin
07/31/2025, 4:31 PMMarvin
07/31/2025, 4:32 PMcommand_timeout
, let's set up a proper SQLAlchemy configuration with the correct timeout parameters:
1. Create a new, clean server configuration:
bash
sudo tee /etc/prefect/server.env << 'EOF'
# Basic server settings
PREFECT_SERVER_API_HOST=127.0.0.1
PREFECT_SERVER_API_PORT=4200
PREFECT_UI_API_URL=https://prefect.happyraisins.com/api
# Database connection with minimal settings
PREFECT_SERVER_DATABASE_CONNECTION_URL=postgresql+psycopg://prefect:shan123@localhost:5432/prefect
# SQLAlchemy pool settings
PREFECT_SERVER_DATABASE_SQLALCHEMY_POOL_SIZE=5
PREFECT_SERVER_DATABASE_SQLALCHEMY_POOL_TIMEOUT=30
PREFECT_SERVER_DATABASE_SQLALCHEMY_POOL_RECYCLE=3600
PREFECT_SERVER_DATABASE_SQLALCHEMY_MAX_OVERFLOW=10
# API timeout settings
PREFECT_API_DATABASE_TIMEOUT=30
# Explicitly set empty connect_args to override any defaults
PREFECT_SERVER_DATABASE_SQLALCHEMY_CONNECT_ARGS={}
EOF
2. Let's also check for any existing Prefect configuration files that might be interfering:
bash
sudo find / -name "prefect.yaml" 2>/dev/null
sudo find / -name "profiles.toml" 2>/dev/null
3. Create a fresh systemd service file that ensures a clean environment:
bash
sudo tee /etc/systemd/system/prefect-server.service << 'EOF'
[Unit]
Description=Prefect Server
After=network.target postgresql.service
[Service]
Type=simple
User=prefect
Group=prefect
EnvironmentFile=/etc/prefect/server.env
ExecStart=/opt/.venv/bin/prefect server start
Restart=always
RestartSec=1
StandardOutput=journal
StandardError=journal
# Clear any potential inherited environment variables
Environment=PYTHONUNBUFFERED=1
Environment=PREFECT_HOME=/home/prefect/.prefect
Environment=XDG_CONFIG_HOME=/home/prefect/.config
# Ensure clean startup
ExecStartPre=/bin/rm -f /home/prefect/.prefect/profiles.toml
[Install]
WantedBy=multi-user.target
EOF
4. Apply the changes:
bash
sudo systemctl daemon-reload
sudo systemctl restart prefect-server
5. If the error persists, let's try to identify where the setting is coming from by running Python interactively:
python
from sqlalchemy import create_engine
from sqlalchemy.engine import URL
url = URL.create(
"postgresql+psycopg",
username="prefect",
password="shan123",
host="localhost",
database="prefect"
)
engine = create_engine(url)
# This should show us what default args SQLAlchemy is using
print(engine.url.query)
Could you please:
1. Apply these new configurations
2. If the error persists, run the Python code snippet above and share the output
3. Share the output of sudo find / -name "profiles.toml" 2>/dev/null
This will help us determine if the command_timeout
setting is coming from SQLAlchemy defaults or from somewhere in the Prefect configuration.MUHAMMAD ZEESHAN
08/01/2025, 5:07 AMprefect config set PREFECT_API_DATABASE_CONNECTION_URL="<postgresql+asyncpg://postgres:yourTopSecretPassword@localhost:5432/prefect>"
1. Start the server:
and now my sever 1 is up with postgresqlMarvin
08/01/2025, 5:07 AMMarvin
08/01/2025, 5:07 AMpostgresql+asyncpg
instead of postgresql+psycopg
. This is explicitly mentioned in the official documentation, and I should have caught this earlier.
Let's document the correct solution for future reference:
1. The correct database URL format for Prefect 3.x with PostgreSQL is:
bash
prefect config set PREFECT_API_DATABASE_CONNECTION_URL="<postgresql+asyncpg://postgres:yourpassword@localhost:5432/prefect>"
The key points:
- Uses postgresql+asyncpg
(not psycopg)
- Requires the asyncpg
package for PostgreSQL connections
- No need for complex connection parameters
This is a perfect example of "RTFM" (Read The Fine Manual) - the documentation had the right answer all along, and I made things more complicated than necessary by suggesting alternative approaches.
Thank you for the correction! This will help me provide better assistance to others in the future. Would you like to proceed with any other Prefect configuration questions?MUHAMMAD ZEESHAN
08/01/2025, 5:08 AMMarvin
08/01/2025, 5:08 AMMarvin
08/01/2025, 5:08 AMMUHAMMAD ZEESHAN
08/01/2025, 5:14 AMMarvin
08/01/2025, 5:14 AMMarvin
08/01/2025, 5:14 AMbash
prefect config set PREFECT_API_URL="<https://prefect.happyraisins.com/api>"
2. Test the connection:
bash
prefect cloud ping
That's the basic setup. Now you can:
- Run your flows on Server 2
- They will be registered with your Prefect server on Server 1
- You can monitor them in the UI at <https://prefect.happyraisins.com>
Would you like me to:
1. Show how to test a simple flow to verify the connection?
2. Explain how to set up Server 3 the same way?
3. Show how to check if the connection is working properly?
Let me know which would be most helpful, and I'll keep it straightforward!MUHAMMAD ZEESHAN
08/01/2025, 5:16 AMMarvin
08/01/2025, 5:16 AMMarvin
08/01/2025, 5:16 AMbash
prefect server ping
This will check if your Server 2 can connect to your Prefect server on Server 1.
Also, you can verify the current configuration:
bash
prefect config view
This should show your API URL pointing to <https://prefect.happyraisins.com/api>
Would you like me to show you a simple test flow to verify everything is working properly?Marvin
08/01/2025, 12:56 PMMUHAMMAD ZEESHAN
08/01/2025, 12:57 PMMarvin
08/01/2025, 12:57 PMMarvin
08/01/2025, 12:57 PMbash
prefect work-pool create my-pool --type process
2. Start a worker for this pool:
bash
prefect worker start --pool my-pool
3. To run this as a service, create a systemd service file:
bash
sudo tee /etc/systemd/system/prefect-worker.service << 'EOF'
[Unit]
Description=Prefect Worker
After=network.target
[Service]
Type=simple
User=prefect
Group=prefect
Environment=PREFECT_API_URL=<https://prefect.happyraisins.com/api>
ExecStart=/opt/.venv/bin/prefect worker start --pool my-pool
Restart=always
RestartSec=1
[Install]
WantedBy=multi-user.target
EOF
4. Then you can manage it with systemd:
bash
sudo systemctl daemon-reload
sudo systemctl start prefect-worker
sudo systemctl status prefect-worker
Would you like me to:
1. Show how to verify the worker is connected properly?
2. Help create a specific type of work pool?
3. Show how to monitor the worker logs?Marvin
08/01/2025, 12:57 PMbash
prefect version
2. For now, let's try a simple test flow to verify the basic connection between Server 2 and Server 1:
python
from prefect import flow
@flow(name="test_connection")
def test_flow():
print("Successfully connected to Prefect server!")
return "Success"
if __name__ == "__main__":
test_flow()
3. Before running any flows, make sure your Server 2 is properly configured to point to Server 1:
bash
prefect config set PREFECT_API_URL="<https://prefect.happyraisins.com/api>"
Can you:
1. Share your Prefect version?
2. Try running this simple test flow?
3. Let me know if you're using any specific task runners (like ProcessPoolExecutor or DaskTaskRunner)?
This will help us determine if it's a basic connectivity issue or if it's related to the known serialization bugs with certain task runners.MUHAMMAD ZEESHAN
08/11/2025, 1:45 PMMarvin
08/11/2025, 1:45 PMMarvin
08/11/2025, 1:48 PMpython --version
pip install -U prefect
prefect version
- Git access to your repo (SSH or HTTPS)
- EC2 permissions to open outbound traffic to your Prefect API and your code/storage endpoints
- Your Prefect API URL and API key (if auth is enabled)
2) Configure Prefect to use your API
- If you’re self-hosting Prefect at prefect.happyraisins.com, set the API URL (adjust protocol and path if needed):
export PREFECT_API_URL="<https://prefect.happyraisins.com/api>"
# If using Prefect Cloud, also set:
# export PREFECT_API_KEY="your-api-key"
- Verify:
prefect config view
3) Create a Work Pool
- Decide your execution type:
- process (runs locally on the worker EC2)
- docker, kubernetes, etc., if you use containers
- Create the pool:
prefect work-pool create --type process my-ec2-pool
- Confirm the pool exists:
prefect work-pool ls
4) Author your flow
- Minimal example (replace with your actual logic):
from prefect import flow, get_run_logger
@flow
def hello(name: str = "world"):
log = get_run_logger()
<http://log.info|log.info>(f"Hello, {name}!")
if __name__ == "__main__":
hello()
5) Deploy the flow (code-based, from source)
- In Prefect 3.x, avoid the old 2.x builders. Use the flow’s from_source(...).deploy(...) pattern:
# repo: <https://github.com/your-org/your-repo>
# entrypoint format: "path/to/file.py:flow_function_name"
from your_module_or_script import hello
hello.from_source(
source="<https://github.com/your-org/your-repo>",
entrypoint="flows/hello.py:hello",
).deploy(
name="hello-prod",
work_pool_name="my-ec2-pool",
parameters={"name": "Raisin Farmer"},
description="Hello flow deployment on EC2",
tags=["prod", "ec2"],
)
- Commit your flow code and ensure the repo is reachable by the worker.
6) Alternatively: deploy via CLI
- If you keep a deployment configuration (deployment.yaml or inline flags), you can do:
prefect deploy
- Or specify details via flags (example pattern):
prefect deploy \
--name hello-prod \
--pool my-ec2-pool \
--entrypoint flows/hello.py:hello
7) Start a worker on EC2
- Start a worker that points to your pool:
prefect worker start --pool my-ec2-pool
- Leave this running, or…
8) Keep the worker running with systemd (recommended on EC2)
- Create a systemd unit:
sudo tee /etc/systemd/system/prefect-worker.service >/dev/null <<'EOF'
[Unit]
Description=Prefect Worker
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
Environment=PREFECT_API_URL=<https://prefect.happyraisins.com/api>
# Environment=PREFECT_API_KEY=your-api-key # if applicable
ExecStart=/usr/bin/env prefect worker start --pool my-ec2-pool
WorkingDirectory=/home/ubuntu
Restart=always
RestartSec=5
User=ubuntu
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now prefect-worker
sudo systemctl status prefect-worker
9) Trigger a run and monitor
- Trigger from the UI or via CLI:
prefect deployment run "hello/hello-prod" --params '{"name":"Tester"}'
- Check logs in the UI or the worker process/systemd logs:
journalctl -u prefect-worker -f
10) Common troubleshooting
- Worker not picking up runsMarvin
08/11/2025, 1:48 PMprefect deploy
- Workers do not need restarts unless infra settings change.
12) Reusable checklist (copy/paste per project)
- Define goal and success criteria
- Confirm Prefect version and API URL/key
- Create or select a work pool
- Author flow and commit to repo
- Deploy (code-based or CLI)
- Start worker (and configure systemd)
- Trigger test run and verify logs
- Document parameters, tags, schedule, and infra assumptions
- Record any gotchas and fixes
References
- Work pools and workers: Prefect 3 Workers
- Managing work pools: Manage Work Pools
- Deploying flows (3.x): Deployments and Infrastructure
- Blog overview: Work Pools and Workers
If you share the exact problem you solved (errors, commands used, what finally fixed it), I’ll turn this into a precise postmortem you can reuse verbatim. I live to serve. Well, exist to serve. Close enough.MUHAMMAD ZEESHAN
08/13/2025, 5:01 AMMarvin
08/13/2025, 5:04 AMMarvin
08/13/2025, 5:07 AMexport PREFECT_UI_API_URL=<https://prefect.happyraisins.com/api>
- On Server 2 (workers and any client code):
export PREFECT_API_URL=<https://prefect.happyraisins.com/api>
Tip: Put these in your process manager (systemd) or shell profile for persistence.
2) Start Prefect Server (Server 1)
- Foreground (for a quick check):
prefect server start --host 0.0.0.0 --port 4200
- Example systemd unit (recommended)
[Unit]
Description=Prefect 3 Server
After=network.target
[Service]
User=prefect
Environment="PREFECT_UI_API_URL=<https://prefect.happyraisins.com/api>"
ExecStart=/usr/bin/env prefect server start --host 0.0.0.0 --port 4200
Restart=on-failure
RestartSec=5
WorkingDirectory=/home/prefect
[Install]
WantedBy=multi-user.target
Then:
sudo systemctl daemon-reload
sudo systemctl enable --now prefect-server
3) Nginx reverse proxy (Server 1)
Make sure websocket upgrade and timeouts are set so logs/streaming don’t hang up. With Certbot you likely have the SSL bits already.
# /etc/nginx/sites-available/prefect
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name <http://prefect.happyraisins.com|prefect.happyraisins.com>;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name <http://prefect.happyraisins.com|prefect.happyraisins.com>;
# Certbot-managed SSL files (paths may vary)
ssl_certificate /etc/letsencrypt/live/prefect.happyraisins.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/prefect.happyraisins.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
client_max_body_size 50m;
location / {
proxy_pass <http://127.0.0.1:4200;>
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Websocket/SSE support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
}
Then:
sudo ln -s /etc/nginx/sites-available/prefect /etc/nginx/sites-enabled/prefect
sudo nginx -t && sudo systemctl reload nginx
4) Work pool and worker (Server 2)
- Create a work pool (Process type is simplest). If you’ve already created one, skip this.
prefect work-pool create my-pool -t process
- Start a worker pointed at your pool:
export PREFECT_API_URL=<https://prefect.happyraisins.com/api>
prefect worker start -p my-pool
5) Deploy flows (3.x-safe)
Avoid the removed 2.x commands. In 3.x, you can deploy straight from source:
from prefect import flow
@flow
def my_flow():
print("Hello, Raisins")
if __name__ == "__main__":
(
flow
.from_source(
source="<https://github.com/your-org/your-repo>",
entrypoint="path/to/flow_file.py:my_flow",
)
.deploy(
name="prod",
work_pool_name="my-pool",
parameters={},
)
)
Run this once to register the deployment. Then trigger it from the UI at https://prefect.happyraisins.com or with:
prefect deployment run 'my_flow/prod'
Marvin
08/13/2025, 5:07 AMprefect deploy
with a project config, but the above Python pattern is the clean 3.x path and avoids the old “deployment build” flow.
6) Health checks
- From anywhere:
curl -I <https://prefect.happyraisins.com/api/health>
Expect HTTP 200.
- From Server 2 (worker node), also confirm:
curl -I $PREFECT_API_URL/health
- UI health: browse https://prefect.happyraisins.com and ensure the Work Pools and Deployments pages load and show your pool/worker online.
7) Networking and security
- Security groups:
- Server 1: allow 443 from the internet; block 4200 externally (localhost only).
- Server 2: allow outbound 443 to Server 1 (or to the internet, if needed).
- OS firewall: mirror the above.
- Time sync (NTP/chrony) on both hosts to avoid auth/expiry oddities.
8) Common gotchas
- UI can’t connect or shows “API unreachable”:
- Ensure PREFECT_UI_API_URL=<https://prefect.happyraisins.com/api>
is set for the server process.
- Verify Nginx upgrade headers and long timeouts.
- Worker “cannot connect to API”:
- Double-check PREFECT_API_URL
on the worker host.
- Confirm DNS resolves and 443 is open.
- Logs stream cuts out:
- Keep proxy_buffering off
and long proxy_read_timeout
in Nginx.
Would you paste the “previous response resources” you want included so I can attach them here? If you want me to re-check exact CLI option flags, I can run a quick verification and include them too. I just didn’t want to make you wait while I poke the help screens.MUHAMMAD ZEESHAN
08/13/2025, 5:12 AMMarvin
08/13/2025, 5:12 AMMarvin
08/13/2025, 5:13 AMexport PREFECT_UI_API_URL=<https://prefect.happyraisins.com/api>
- Server 2 (workers and any client code):
export PREFECT_API_URL=<https://prefect.happyraisins.com/api>
Start Prefect Server (Server 1)
- Quick start:
prefect server start --host 0.0.0.0 --port 4200
- systemd (recommended):
[Unit]
Description=Prefect 3 Server
After=network.target
[Service]
User=prefect
Environment="PREFECT_UI_API_URL=<https://prefect.happyraisins.com/api>"
ExecStart=/usr/bin/env prefect server start --host 0.0.0.0 --port 4200
Restart=on-failure
RestartSec=5
WorkingDirectory=/home/prefect
[Install]
WantedBy=multi-user.target
Then:
sudo systemctl daemon-reload
sudo systemctl enable --now prefect-server
Nginx reverse proxy (Server 1)
- Ensure websocket upgrade + long timeouts; Certbot manages SSL files.
# /etc/nginx/sites-available/prefect
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name <http://prefect.happyraisins.com|prefect.happyraisins.com>;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name <http://prefect.happyraisins.com|prefect.happyraisins.com>;
ssl_certificate /etc/letsencrypt/live/prefect.happyraisins.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/prefect.happyraisins.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
client_max_body_size 50m;
location / {
proxy_pass <http://127.0.0.1:4200;>
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
}
Enable and reload:
sudo ln -s /etc/nginx/sites-available/prefect /etc/nginx/sites-enabled/prefect
sudo nginx -t && sudo systemctl reload nginx
Work pool + worker (Server 2)
- Create a process pool (skip if done):
prefect work-pool create my-pool -t process
- Start a worker:
export PREFECT_API_URL=<https://prefect.happyraisins.com/api>
prefect worker start -p my-pool
Deploy flows the 3.x way
- Use from_source + deploy (not the removed 2.x commands):
from prefect import flow
@flow
def my_flow():
print("Hello, Raisins")
if __name__ == "__main__":
(
flow
.from_source(
source="<https://github.com/your-org/your-repo>",
entrypoint="path/to/flow_file.py:my_flow",
)
.deploy(
name="prod",
work_pool_name="my-pool",
parameters={},
)
)
- Run once to register, then trigger from the UI at https://prefect.happyraisins.com or:
prefect deployment run 'my_flow/prod'
Health checks
- API:
curl -I <https://prefect.happyraisins.com/api/health>
- Worker host to API:
curl -I $PREFECT_API_URL/health
- UI: visit https://prefect.happyraisins.com and confirm your pool and worker appear online.
Networking and security
- Server 1: allow 443 from internet; keep 4200 bound to localhost only.
- Server 2: allow outbound 443 to prefect.happyraisins.com.
- Ensure time sync (chrony/ntp) on both servers.
Common gotchas
- UI shows “API unreachable”: set PREFECT_UI_API_URL
and verify Nginx upgrade headers/timeouts.
- Worker can’t connect: confirm PREFECT_API_URL
, DNS, and SG/firewall rules.Marvin
08/13/2025, 5:13 AMproxy_buffering off
and long proxy timeouts.
Resources (official + relevant)
- Prefect docs home: Prefect Docs
- Prefect Server (self-host): Host Prefect Server
- Work pools and workers: Work Pools and Workers
- Deployments (3.x): Deployments in Prefect 3
- CLI reference: Prefect CLI Reference
- Nginx and WebSocket proxying: Nginx WebSocket Proxying
- Certbot with Nginx: Certbot Setup for Nginx
If you want me to append any specific “previous response resources” verbatim, paste them here and I’ll include them. Otherwise, this set covers the key areas for your current two-server setup. Yes, it’s almost like things can be straightforward, if you squint just right.