我去年年底在一台刚装好 Ubuntu 24.04 的机器上折腾 AWS SAM CLI,本来以为跑两条命令就能完事,结果硬是被 Python 版本、PATH 环境变量、还有 Docker 权限这几个问题轮番教做人。事后我复盘了一下,其实不是 SAM 本身多难装,而是它依赖的链路过长,任何一个环节出了偏差,报错信息都容易把人带偏。这篇文章我打算把整个过程拆开揉碎,从装 AWS CLI 到跑通第一个 hello world,把每一步的原理和坑都说清楚,特别是那些官方文档里不会写的细节。
1. 安装前必须想明白的事:SAM 到底跑在什么上
很多人以为安装 AWS SAM 就是装一个命令行工具,其实它只是整个工具链的一个前端。真正干活的还有 AWS CLI、Docker、Python 运行时这几个组件。理解它们的分工,后面遇到问题才知道该查哪里。
1.1 SAM CLI、AWS CLI 和 Docker 的各自角色
SAM(Serverless Application Model)本质上是一个基于 CloudFormation 的模板规范和配套的 CLI 工具。模板文件让你用简洁的语法定义 Lambda 函数、API Gateway、DynamoDB 表等资源,CLI 工具负责把模板转换成 CloudFormation 的完整 JSON,然后帮你打包、部署。
这个转换依赖 AWS CLI 的底层能力,所以 AWS CLI 是必须的,两者版本之间还有兼容要求。
Docker 则是本地调试的基石。你可以用 sam local start-api 在本地起一个 API 服务,让 Lambda 函数在 Docker 容器里模拟运行。这样不用部署到云端就能测逻辑,也是 SAM 最实用的功能之一。如果你只打算直接 sam deploy 推送远程,不搞本地调试,Docker 可以暂时不装。但说实话,不装 Docker 的 SAM 跟折了一条腿差不多,还是建议一起装。
1.2 Ubuntu 版本和 Python 版本的影响
SAM CLI 本身是用 Python 写的,安装时它对 Python 版本有要求。较早的版本支持 Python 3.7,现在主流版本要求 Python 3.8 到 3.12 之间。Ubuntu 20.04 默认的 Python 3.8 能跑,Ubuntu 24.04 默认是 Python 3.12 也没问题。问题通常出在用户自己去折腾 Pyenv 或者系统里装了多个 Python 版本,导致 pip 装到了某个解释器下,PATH 里又是另一个解释器在前面。
我的建议是:用 Ubuntu 系统自带的 Python 版本,别用 PPA 或者编译安装的版本。系统自带的虽然旧,但跟系统组件兼容性最好,SAM 跑在上面反而不容易出事。如果你已经装了多版本 Python,安装前先用 python3 --version 确认默认解释器版本,再用 which python3 看它的路径,做到心里有数。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 前置工具安装:AWS CLI 与 Docker 的完整步骤
我习惯把前置工具先全部搞定,再装 SAM。这样每一步的依赖都是清晰的,出了问题也好定位。
2.1 官方推荐的 AWS CLI 安装方法
AWS CLI 目前分 v1 和 v2 两个大版本。SAM 虽然没有强制要求 v2,但强烈建议用 v2。因为 v2 是独立打包的二进制文件,不依赖系统的 Python 环境,也不容易被 pip 升级误伤。
安装 v2 的标准流程是这样:
bash复制cd /tmp
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
安装完成后验证一下:
bash复制aws --version
如果看到类似 aws-cli/2.17.13 Python/3.11.8 Linux/5.15.0-... 的输出,就说明 v2 装好了。这里需要留个心眼:报错里出现的 Python 版本只是 AWS CLI 自带的运行时,不是你系统的 Python,不用去纠结。
2.2 Docker 安装和当前用户的组权限配置
Docker 在 Ubuntu 上安装最省心的方式是使用官方脚本:
bash复制curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
脚本会帮我们把 Docker Engine、containerd、还有 compose 插件一起装上,比手动加仓库省事得多。
装完 Docker 之后有个非常关键的步骤是大多数教程不会强调的:把当前用户加入 docker 用户组,否则每次执行 docker 命令都要加 sudo,而 SAM 调用 Docker 时不会给你加 sudo 的机会,会直接报权限错误。
bash复制sudo usermod -aG docker $USER
newgrp docker
newgrp docker 是让当前终端会话立即生效的方式,省得注销重新登录。退出并重新登录也是可以的,看你习惯。
然后验证一下:
bash复制docker run hello-world
这一步能跑通,说明 Docker 的基本链路没问题。如果出现 permission denied 类似的提示,多半是 docker 组没有生效,确认一下 id 输出里有没有 docker。
2.3 安装过程中的小检查清单
在我动手装 SAM 之前,通常先跑一遍这个清单,确认所有前置都是绿的:
| 检查项 | 命令 | 期望结果 |
|---|---|---|
| Ubuntu 版本 | lsb_release -a |
20.04 / 22.04 / 24.04 |
| Python 版本 | python3 --version |
3.8 以上 |
| AWS CLI | aws --version |
2.x 版本 |
| Docker | docker --version |
24.x 或更新 |
| Docker 权限 | docker ps |
不报权限错误 |
四个全是绿,就可以进行下一步了。有一个红的就先解决那个,不要带着问题往下走。
3. SAM CLI 安装:三种方式对比与我踩过的坑
SAM CLI 官方提供的安装方式有好几种,我在 Ubuntu 上实际试过三条路:Homebrew、Linux 二进制包、pip。各有利弊,我按推荐度排序来说。
3.1 Linuxbrew 安装:管理省心但引入额外依赖
如果你之前已经装了 Linuxbrew(也就是 Homebrew 的 Linux 版本),那安装 SAM 非常轻松:
bash复制brew tap aws/tap
brew install aws-sam-cli
这条路的优点是升级方便,brew upgrade aws-sam-cli 一条命令搞定。缺点也明显——为了装一个 SAM,得先维护一整套 Homebrew 环境,对于普通 Ubuntu 用户来说有点重。如果只是为了 SAM 去装 Linuxbrew,我不太建议,性价比不高。
3.2 官方二进制包安装:最干净的路线,推荐
我最推荐的是下载官方编译好的二进制包,不依赖任何包管理器。思路其实比 yum/apt 安装还简单:
bash复制cd /tmp
wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip
unzip aws-sam-cli-linux-x86_64.zip -d sam-install
sudo ./sam-install/install
它会默认把 sam 可执行文件放到 /usr/local/bin/sam,这个目录通常在 PATH 里,装完就能直接调用。
验证:
bash复制sam --version
如果能输出版本号,比如 SAM CLI, version 1.111.0,安装就成功了。
这里有几个容易被忽略的点需要提醒:
- 如果你的系统不是 x86_64 架构(比如 ARM 的 AWS Graviton 实例或者树莓派),下载链接要换成
aws-sam-cli-linux-arm64.zip。用uname -m先确认架构,别抄错。 - 用
wget下载 GitHub 文件时,如果提示证书错误,多半是系统缺少 ca-certificates 包,执行sudo apt install ca-certificates -y再试。
3.3 用 pip 安装的注意事项
社区里很多人习惯用 pip 装 SAM,官方其实也支持,只是不再作为推荐方式。命令是:
bash复制pip3 install --user aws-sam-cli
这里有个大坑:如果用 pip 装,SAM 就会和你系统里的 Python 环境绑定在一起。以后你升级了系统 Python 或者卸载了某些依赖,SAM 可能就坏了。更麻烦的是,如果你用 sudo pip3 install 装到系统 Python,很可能触发 Ubuntu 的 externally-managed-environment 保护机制(PEP 668),直接报错不让装。解决办法是用 --user 安装或者创建虚拟环境,但说实话,这样折腾下来的复杂度比二进制包高多了,不推荐新手走这条路。
3.4 为什么我不建议绕过官网用 apt 装
在 Ubuntu 软件源里搜不到 aws-sam-cli 这个包,但网上有些教程会引导你添加第三方 PPA 仓库去装。我不推荐这么做。第三方 PPA 里的 SAM 版本更新滞后,而且你无法确认打包的人是否做了手脚。安装开发工具这种事,还是官方渠道最稳。
4. 凭证配置与本地调试环境验证
装好 SAM 之后,最重要的一步是配置 AWS 凭证。没有凭证,sam deploy 完全跑不动,sam local invoke 如果需要访问 AWS 资源也会有问题。
4.1 IAM 用户创建与凭证文件配置
先到 IAM 控制台创建一个程序化访问的用户,权限方面,开发环境可以用 AdministratorAccess 省事,但生产环境应该严格按最小权限来。最少需要:
cloudformation:*:管理 CloudFormation 栈lambda:*:管理 Lambda 函数iam:PassRole:将角色传递给 Lambdas3:*:SAM 部署时需要 S3 桶存放构建产物s3:GetObject/s3:PutObject:读写 S3 对象logs:*:CloudWatch Logs 相关操作apigateway:*(如果要用 API Gateway)dynamodb:*(如果要用 DynamoDB)
创建好用户后,你会拿到 Access Key ID 和 Secret Access Key。然后把它们写入凭证文件:
bash复制aws configure
它交互式地提问,依次输入 Access Key ID、Secret Access Key、默认区域(比如 us-east-1)、默认输出格式(通常填 json)。配置会写到 ~/.aws/credentials 和 ~/.aws/config 两个文件里。
验证凭证是否有效:
bash复制aws sts get-caller-identity
能返回你的账号 ID 和 ARN,就说明凭证没问题。
4.2 sam --version 之外的安装验证
命令行能输出版本号,不代表整个工具链都是通的。我一般再做两步验证:
第一步,检查 SAM 对 Docker 的感知:
bash复制sam local invoke --help
如果 Docker 不可用或权限有问题,sam local 命令会在运行时提示,而不是在 help 输出里报错。所以这个命令只是验证 CLI 本身没有缺依赖。
第二步,用 sam init 创建一个最小模板来测全过程。这一步放在下一节详说,因为它是 SAM 安装正确性的终极验证。
4.3 环境变量替代方式的适用场景
aws configure 写文件的方式适合个人开发机。如果是 CI/CD 环境,更推荐用环境变量:
bash复制export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_DEFAULT_REGION=us-east-1
SAM 和 AWS CLI 都会自动读取这些环境变量,优先级高于配置文件。在脚本或 CI 流水线里用这种方式更安全,凭证不会落地到磁盘。
5. 跑通第一个 SAM 应用:用 sam init 做端到端验证
安装的终极验证,是让 SAM 完整地走一遍创建、构建、打包、部署的流程。而 sam init 是官方提供的脚手架命令,能帮你把示例项目生成了一个结构严谨的模板工程。它既能验证模板格式是否正确,也能顺便检查构建和部署命令是否可用。
5.1 选择模板类型与运行时
运行命令:
bash复制sam init --runtime python3.12
然后按照提示选择一个模板。我建议新手选 Hello World 示例,因为它的结构足够简单,又完整包含了 SAM 模板、Lambda 函数代码、事件源定义和单元测试。
--runtime 参数要跟你 Lambda 函数实际使用的运行时一致。SAM CLI 本身对 Python 版本有要求,但模板生成的 Lambda 运行时是另外一回事,两者不冲突。比如你用 Python 3.12 生成模板,本地 SAM CLI 是用 Python 3.10 安装的,完全没问题,因为 SAM 只负责打包和调用,不负责执行 Lambda 内部代码。
5.2 构建与本地调用
在项目目录下执行:
bash复制sam build
它会读取 template.yaml,把函数代码连同依赖一起打包到一个 .aws-sam/build 目录里。这个过程会临时创建一个隔离的 Python 环境去解析依赖要求,所以能看到很多 pip 相关的输出,别慌,这是正常的。
构建成功后再本地调用:
bash复制sam local invoke HelloWorldFunction --event events/event.json
注意,第一次执行 sam local invoke 时,SAM 会先从 Docker Hub 拉取 Lambda 执行环境的镜像。这个拉取可能需要几分钟,取决于网速。如果镜像拉取失败,先确认 Docker 服务是否在运行:
bash复制systemctl status docker
如果显示 inactive,就启动它:
bash复制sudo systemctl start docker
sudo systemctl enable docker
enable 让它开机自启,这是很多教程容易漏掉的。
本地调用如果输出了返回值,说明 SAM CLI、Docker、模板、代码这几个环节全部打通了。这时候你才可以说,SAM 安装是真正成功的。
5.3 部署到云端验证
本地调用通过后,还可以用以下命令部署到云端:
bash复制sam deploy --guided
它会询问一堆配置问题,比如堆栈名称、区域、是否允许创建 IAM 角色。如果你想跳过交互,可以这样:
bash复制sam deploy --guided --parameter-overrides ParameterKey=Stage,ParameterValue=dev
不过说实话,首次部署我还是建议手动跑一下 --guided,因为部署在云端是真实付费的动作,走到这一步时,输出的每一个提示都看清楚再回车,能避免误操作。等熟悉了,再去写自动化脚本也不迟。
6. 高频报错与解决路线:照着这个顺序排查
折腾 SAM 安装和运行,难免会碰到报错。我把最常见的几个错误分类整理一下,并附上排查顺序。
6.1 与 Docker 相关的权限或连接失败
这类错误最典型的表现是:
text复制Error: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
排查顺序:
- 确认 Docker 服务运行状态:
systemctl status docker - 确认当前用户在 docker 组里:
id - 如果刚加入 docker 组,确认当前会话是否已生效:
newgrp docker
这三点按顺序检查一遍,大部分权限类问题都能解决。
6.2 与 Python 版本有关的兼容问题
如果报错里出现 Runtime.ImportModuleError 或者 pip 安装依赖时失败,先检查 SAM CLI 的运行环境:
bash复制sam --version
如果 SAM 是用 pip 装的,而系统 Python 后来升级过,SAM CLI 有可能直接坏掉。解决方法是重新安装,或者干脆用官方二进制包安装,一劳永逸。
6.3 AWS CLI 版本过旧导致的转换失败
sam deploy 时如果出现 CloudFormation 模板校验错误,但模板本身检查过没问题,那大概率是 AWS CLI 版本太旧。更新 AWS CLI:
bash复制sudo ./aws/install --update
这个命令会覆盖安装最新版。之后再试部署,问题通常就消失了。
6.4 权限不足的报错
部署时报 AccessDenied,十有八九是 IAM 策略没配够。先在本地执行:
bash复制aws sts get-caller-identity
确认你在用哪个身份操作,再去 IAM 控制台比对权限。别急着删了重建用户,先看是不是策略少了一项。
6.5 网络原因导致的镜像拉取失败
如果你身处网络环境受限的环境,Docker Hub 拉取镜像可能会失败。解决办法是给 Docker 配置镜像加速器。如果你遇到的是别的网络限制,那就用代理,但要注意,这是环境层面的问题,不是 SAM 本身的问题。
7. 一些提高日常使用效率的配置思路
安装完 SAM 不算结束,真正提高效率的是后续的配置习惯。
7.1 使用 AWS SAM 配置文件管理多环境
在项目根目录维护一个 samconfig.toml 文件,可以省去每次部署时的交互提问。比如:
toml复制version = 0.1
[default.deploy.parameters]
stack_name = "my-app-dev"
s3_bucket = "my-app-deploy-bucket"
s3_prefix = "dev"
region = "us-east-1"
confirm_changeset = false
capabilities = "CAPABILITY_IAM"
这样之后执行 sam deploy 时,它会直接从配置文件里读取参数,不再逐个询问,自动化的时候非常方便。
7.2 与 CodeDeploy 配合做灰度发布
SAM 模板里可以配置 AutoPublishAlias 和 DeploymentPreference,让 Lambda 部署自动走 CodeDeploy 的灰度流程。第一次配置的时候感觉有点复杂,但一旦跑通,之后的发布体验会很顺畅,风险也小很多。这部分和安装本身不是一回事,但值得提前了解。
7.3 保持工具版本更新的习惯
AWS 的服务更新很快,SAM CLI 也是高频发布。建议每个月跑一次:
bash复制sudo ./sam-install/install
重新执行安装脚本可以自动覆盖更新到最新版。如果你忘了之前下载到哪个目录,就重新下载一次再跑。
8. 写在最后的两个提醒
我在多个 Ubuntu 版本上装过 SAM,包括 20.04、22.04、24.04,整体体验是越来越顺的。官方在依赖处理和安装脚本上做了不少优化,如今二进制包安装已经能做到一次成功。但有两个提醒值得说:
第一个是不要贪图省事跳过前置检查。我曾经在一台缺少 Docker 的干净机器上直接跑 sam local invoke,浪费时间去找一个跟 SAM 本身无关的 Docker 问题。现在我的固定流程是先把 aws --version、docker ps、python3 --version 全部跑一遍,再动 SAM。
第二个是善用 sam --help 和 sam deploy --guided 的交互提示。这个工具的提示信息写得相对友好,不像某些工具给出一串晦涩的 error code 就跑路,遇到不懂的选项,先看 help 再决定,不要盲目回车。尤其是 capabilities 这个参数,一定要明确知道它在授予什么权限,再确认。
按这个流程走下来,从零开始装好 SAM 并跑通一个本地示例,熟练以后大概十五分钟。第一次的话,预留半小时到一小时比较稳妥,主要是 Docker 镜像拉取的时间不可控。装好之后,日常工作就会顺很多。
