不用 Docker 也能跑 AI Agent | OpenClaw + Podman + EC2 Graviton + ECR 容器化部署全攻略
Docker 装不上?公司不让用 Docker Desktop?或者就是想要更安全的容器方案?OpenClaw 2026.3.28 简化了 Podman 部署流程------rootless 用户直接跑,配合 Amazon EC2 Graviton 实例和 Amazon ECR 镜像托管,一套组合拳把 AI Agent 搬到云上生产环境。
这篇从零开始:开 EC2 实例、构建镜像推到 ECR、Podman rootless 部署、systemd 开机自启,全套走一遍。
为什么选 Podman + EC2 Graviton
先说 Podman 和 Docker 的区别:
| 对比 | Docker | Podman |
|---|---|---|
| 守护进程 | 需要 dockerd(root) | 不需要守护进程 |
| 权限 | 默认 root | 默认 rootless |
| 兼容性 | OCI 标准 | OCI 标准,兼容 Docker CLI |
| systemd | 需要额外配置 | 原生 Quadlet 支持 |
| 安全 | 依赖 dockerd | 无特权进程 |
再说为什么选 Graviton:Amazon EC2 Graviton 是亚马逊云科技自研的 Arm 处理器,跑容器工作负载性价比很高。根据 AWS 官方数据,Graviton 实例相比同类 x86 实例最多可节省 40% 的成本,同时提供更好的能效。对于 OpenClaw 这种 AI Agent 网关服务,CPU 占用不高但需要长期运行,Graviton 是很合适的选择。
推荐实例:t4g.small(2 vCPU,2 GiB,Graviton2),月费约 $12。跑 OpenClaw Gateway 绑绑有余。
第一步:开 EC2 Graviton 实例
bash
# 用 AWS CLI 启动 Graviton 实例
aws ec2 run-instances \
--image-id ami-0abcdef1234567890 \
--instance-type t4g.small \
--key-name my-key-pair \
--security-group-ids sg-0123456789abcdef0 \
--subnet-id subnet-0123456789abcdef0 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=openclaw-agent}]'
安全组记得开:
18789:Gateway 端口(API + Web UI)18790:Bridge 端口(Node 配对用)22:SSH
SSH 进去后装 Podman:
bash
# Ubuntu/Debian
sudo apt update && sudo apt install -y podman
# Amazon Linux 2023
sudo dnf install -y podman
Amazon Linux 2023 原生支持 Podman,不用折腾。
第二步:构建镜像并推送到 Amazon ECR
Amazon ECR(Elastic Container Registry)是亚马逊云科技的容器镜像托管服务,支持私有仓库 + IAM 权限控制 + 镜像漏洞扫描。把 OpenClaw 镜像推到 ECR,方便多台实例拉取,也方便做版本管理。
创建 ECR 仓库
bash
aws ecr create-repository \
--repository-name openclaw \
--image-scanning-configuration scanOnPush=true \
--region us-east-1
scanOnPush=true 开启镜像扫描------每次推送新镜像自动检查安全漏洞,这是 ECR 的内置能力。
构建并推送
bash
# 登录 ECR
aws ecr get-login-password --region us-east-1 | \
podman login --username AWS --password-stdin \
123456789012.dkr.ecr.us-east-1.amazonaws.com
# 克隆 OpenClaw
git clone https://github.com/openclaw/openclaw.git
cd openclaw
# 构建镜像(Graviton 上直接构建 arm64 镜像)
podman build -t openclaw .
# 打标签
podman tag openclaw:latest \
123456789012.dkr.ecr.us-east-1.amazonaws.com/openclaw:latest
# 推送
podman push \
123456789012.dkr.ecr.us-east-1.amazonaws.com/openclaw:latest
在 Graviton 实例上构建天然就是 arm64 镜像,不需要交叉编译。
ECR 生命周期策略
镜像多了会占空间。配个生命周期策略自动清理旧版本:
json
{
"rules": [{
"rulePriority": 1,
"description": "保留最近 10 个镜像",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 10
},
"action": { "type": "expire" }
}]
}
bash
aws ecr put-lifecycle-policy \
--repository-name openclaw \
--lifecycle-policy-text file://lifecycle-policy.json
第三步:Podman Rootless 部署
一键部署
bash
# 一键设置(创建用户、构建镜像、安装启动脚本)
./setup-podman.sh
这个脚本做了三件事:
- 创建专用系统用户
openclaw(nologin,不能交互登录) - 构建 OpenClaw 容器镜像
- 安装启动脚本到
~openclaw/run-openclaw-podman.sh
如果镜像在 ECR
从 ECR 拉取而不是本地构建:
bash
# 先登录 ECR
aws ecr get-login-password --region us-east-1 | \
podman login --username AWS --password-stdin \
123456789012.dkr.ecr.us-east-1.amazonaws.com
# 拉取
podman pull 123456789012.dkr.ecr.us-east-1.amazonaws.com/openclaw:latest
# 打本地标签
podman tag 123456789012.dkr.ecr.us-east-1.amazonaws.com/openclaw:latest openclaw:latest
启动 Gateway
bash
./scripts/run-openclaw-podman.sh launch
运行配置向导
bash
./scripts/run-openclaw-podman.sh launch setup
然后打开 http://127.0.0.1:18789/,用 ~openclaw/.openclaw/.env 里的 Token 登录。
Systemd 开机自启(Quadlet)
生产环境必须配 systemd,EC2 实例重启后 Agent 自动恢复:
bash
# 带 Quadlet 的一键安装
./setup-podman.sh --quadlet
管理命令:
bash
# 启动
sudo systemctl --machine openclaw@ --user start openclaw.service
# 停止
sudo systemctl --machine openclaw@ --user stop openclaw.service
# 查看状态
sudo systemctl --machine openclaw@ --user status openclaw.service
# 看日志
sudo journalctl --machine openclaw@ --user -u openclaw.service -f
这样 EC2 实例重启后 OpenClaw Gateway 自动拉起,不需要手动干预。
安全配置
openclaw 专用用户
setup-podman.sh 创建的用户有几个安全特性:
- nologin Shell:不能交互式登录,减少攻击面
- 独立 Home :
/home/openclaw/,只有 openclaw 和 root 能访问 - subuid/subgid:rootless Podman 需要用户命名空间映射
如果系统没自动分配 subuid/subgid:
bash
echo "openclaw:100000:65536" | sudo tee -a /etc/subuid
echo "openclaw:100000:65536" | sudo tee -a /etc/subgid
EC2 安全组
最小权限原则:
bash
# 只开必要端口
aws ec2 authorize-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--protocol tcp --port 18789 \
--cidr 你的IP/32
# Bridge 端口只开给需要配对的 Node IP
aws ec2 authorize-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--protocol tcp --port 18790 \
--cidr Node的IP/32
IAM 角色
EC2 实例绑 IAM 角色,让 Podman 能拉 ECR 镜像 + 调用 Amazon Bedrock:
json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": "arn:aws:bedrock:*::foundation-model/*"
}
]
}
这样 OpenClaw 在容器里就能直接调 Amazon Bedrock 的模型(Claude、Nova 等),不需要在环境变量里配 AK/SK。
网络
默认只绑定 loopback(127.0.0.1)。要暴露到局域网:
bash
# 在 .env 里设置
OPENCLAW_GATEWAY_BIND=lan
环境变量
在 ~openclaw/.openclaw/.env 里设置:
bash
OPENCLAW_GATEWAY_TOKEN=your-token-here
# 如果用 IAM 角色调 Bedrock,不需要配 API Key
# 如果用第三方模型,配对应 Key
GROQ_API_KEY=your-key
自定义镜像
构建时可以加额外依赖:
bash
# 加 apt 包
OPENCLAW_DOCKER_APT_PACKAGES="ffmpeg imagemagick" ./setup-podman.sh
# 预装扩展
OPENCLAW_EXTENSIONS="diagnostics-otel matrix" ./setup-podman.sh
常见问题
EACCES 权限错误:检查 bind-mount 的目录所有者是否是运行 Podman 的用户。
ECR 登录过期:ECR 的 token 12 小时过期。配个 cron 定期刷新:
bash
# /etc/cron.d/ecr-login
0 */6 * * * openclaw aws ecr get-login-password --region us-east-1 | podman login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
Graviton 兼容性:OpenClaw 的 npm 依赖都支持 arm64。如果自定义插件用了 native module,确认有 arm64 预编译。
Quadlet 服务找不到 :运行 daemon-reload。Quadlet 需要 cgroups v2,用 podman info --format '{{.Host.CgroupsVersion}}' 检查。
Amazon EC2 Graviton:aws.amazon.com/cn/ec2/grav... Amazon ECR 文档:docs.aws.amazon.com/AmazonECR/l... OpenClaw Podman 文档:docs.openclaw.ai/install/pod... GitHub:github.com/openclaw/op...