使用 Podman 部署 Prefect 服务器
前言
Prefect 是一个现代的工作流编排平台,用于构建、调度和监控数据流水线。本文将介绍如何使用 Podman 部署 Prefect 服务器。
前置要求
在开始之前,请确保您已安装:
- Podman 4.0 或更高版本
- systemd(用于管理 Quadlet 服务)
- 足够的系统资源(建议至少 2CPU + 4GB 内存)
- Rootless 模式已启用
第一步:验证 Podman 环境
首先,确认 Podman 已正确安装:
podman --version
podman info第二步:配置 Quadlet
Quadlet 是 Podman 的 systemd 集成功能,可以使用 unit 文件来管理容器。
将 Quadlet 配置文件复制到 systemd 用户目录~/.config/containers/systemd/,没有则创建一个:
mkdir -p ~/.config/containers/systemd
cp prefect-server.container ~/.config/containers/systemd/重新加载 systemd 配置并启用服务:
sudo systemctl daemon-reload
sudo systemctl restart prefect-server.service查看服务状态:
systemctl status prefect-server.service创建 Prefect 的 Quadlet 配置文件prefect-server.container:
[Unit]
Description=Prefect Server (Standalone)
[Container]
Image=docker.io/prefecthq/prefect:3-latest
ContainerName=prefect-server
# Format: host_path:container_path:Z (Z handles SELinux/Permissions)
Volume=%h/prefect-data/server:/root/.prefect
# Networking: Expose UI to the VPS Public IP
PublishPort=127.0.0.1:4200:4200
# Server Config
Environment=PREFECT_API_URL=http://127.0.0.1:4200/api
Environment=PREFECT_SERVER_API_HOST=0.0.0.0
Environment=PREFECT_UI_API_URL=http://127.0.0.1:4200/api
Exec=prefect server start --host 0.0.0.0
# Healthcheck using Python
HealthCmd=python3 -c "import urllib.request; exit(0 if urllib.request.urlopen('http://127.0.0.1:4200/api/health').read() == b'true' else 1)"
HealthInterval=10s
HealthStartPeriod=10s
[Service]
Restart=always
[Install]
WantedBy=default.target第三步:验证部署以及排错
访问 Prefect UI
服务启动后,可以通过 http://localhost:4200/ 访问 Prefect UI。如果无法访问,说明服务未启动或配置错误。
查看 systemd 的 unit 文件
systemctl --user list-units | grep prefect如果 unit 文件都没有生成使用以下命令,查看 container 相关文件设置设置是否正确。
/usr/libexec/podman/quadlet --user -dryrun检查 systemd 服务状态
systemctl --user status prefect-server.service如果服务未启动,可以用 journalctl 查看日志:
journalctl --user -xeu prefect-server.service检查 Podman 容器运行状态
podman ps按照 container 文件中的设置,10 秒钟左右,容器应该进入 healthy 状态。如果仍为 starting 状态,可能PREFECT_API_URL设置有问题。可以尝试以下命令:
curl http://127.0.0.1:4200/api/health如果返回true,说明服务正常运行。
第四步:创建 Podman 网络
为 Prefect 服务创建一个专用的网络,便于容器间通信。
创建网络配置文件
创建prefect.network文件:
[Network]
Name=prefect-network让 Prefect Server 使用网络
在prefect-server.container中添加网络配置:
[Container]
Network=prefect.network # 文件名部署网络
# 复制网络配置文件
cp prefect.network ~/.config/containers/systemd/
# 重新加载 systemd 配置
systemctl --user daemon-reload
# 查看网络状态
podman network inspect prefect-network第五步:配置 Valkey 作为任务队列
Valkey 是 Redis 的一个分支,可用于 Prefect 的任务队列和缓存。
创建 Valkey Quadlet 配置
创建prefect-valkey.container文件:
[Unit]
Description=Valkey for Prefect
[Container]
Image=docker.io/valkey/valkey:9.0.3-alpine
ContainerName=prefect-valkey
Volume=%h/prefect-data/valkey:/data
PublishPort=127.0.0.1:6379:6379
Network=prefect.network
Exec=redis-server --appendonly yes
# Healthcheck
HealthCmd=redis-cli ping
HealthInterval=10s
HealthStartPeriod=5s
[Service]
Restart=always
[Install]
WantedBy=default.target部署 Valkey
cp prefect-valkey.container ~/.config/containers/systemd/
systemctl --user daemon-reload
systemctl --user start prefect-valkey.service验证 Valkey
systemctl --user status prefect-valkey.service
podman exec -it prefect-valkey redis-cli ping第六步:配置 PostgreSQL 作为元数据库
PostgreSQL 用于存储 Prefect 的元数据,如流程定义、运行历史等。
创建 PostgreSQL Quadlet 配置
创建prefect-postgres.container文件:
[Unit]
Description=PostgreSQL for Prefect
[Container]
Image=docker.io/library/postgres:18-alpine
ContainerName=prefect-postgres
Volume=%h/prefect-data/postgres:/var/lib/postgresql/data
PublishPort=127.0.0.1:5432:5432
Network=prefect.network
Environment=POSTGRES_DB=prefect
Environment=POSTGRES_USER=prefect
Environment=POSTGRES_PASSWORD=prefect
# Healthcheck
HealthCmd=pg_isready -U prefect
HealthInterval=10s
HealthStartPeriod=10s
[Service]
Restart=always
[Install]
WantedBy=default.target部署 PostgreSQL
cp prefect-postgres.container ~/.config/containers/systemd/
systemctl --user daemon-reload
systemctl --user start prefect-postgres.service验证 PostgreSQL
systemctl --user status prefect-postgres.service
podman exec -it prefect-postgres psql -U prefect -d prefect -c "SELECT 1;"第七步:更新 Prefect Server 配置
现在需要更新prefect-server.container文件,让 Prefect 使用外部的 Valkey 和 PostgreSQL:
[Unit]
Description=Prefect Server
Requires=prefect-valkey.service prefect-postgres.service
After=prefect-valkey.service prefect-postgres.service
[Container]
Image=docker.io/prefecthq/prefect:3-latest
ContainerName=prefect-server
# Persistence
Volume=%h/prefect-data/server:/root/.prefect
# Networking
PublishPort=127.0.0.1:4200:4200
Network=prefect.network
# Server Config
Environment=PREFECT_API_URL=http://127.0.0.1:4200/api
Environment=PREFECT_SERVER_API_HOST=0.0.0.0
Environment=PREFECT_UI_API_URL=http://127.0.0.1:4200/api
# PostgreSQL Configuration
Environment=PREFECT_API_DATABASE_CONNECTION_URL=postgresql+asyncpg://prefect:prefect@prefect-postgres:5432/prefect
# Valkey Configuration
Environment=PREFECT_MESSAGING_BROKER=prefect_redis.messaging
Environment=PREFECT_MESSAGING_CACHE=prefect_redis.messaging
Environment=PREFECT_REDIS_MESSAGING_HOST=prefect-valkey
Environment=PREFECT_REDIS_MESSAGING_PORT=6379
Environment=PREFECT_REDIS_MESSAGING_DB=0
Exec=prefect server start --no-services --host 0.0.0.0
# Healthcheck
HealthCmd=python3 -c "import urllib.request; exit(0 if urllib.request.urlopen('http://127.0.0.1:4200/api/health').read() == b'true' else 1)"
HealthInterval=30s
HealthTimeout=10s
HealthStartPeriod=60s
[Service]
Restart=always
[Install]
WantedBy=default.target重新部署 Prefect Server
systemctl --user daemon-reload
systemctl --user restart prefect-server.service