Angular自17版开始对SSR进行了较大的改进,但是如果你尝试在AWS部署你的SSR程序,你会发现在很难找到相关的文档信息。一方面AWS不会管Angular的事情,AWS更偏爱Next.js。另一方面,Angular也不会介绍AWS的部署细节,事实上关于部署方式无论是部署到AWS还是什么别的地方,它们的文档里都是一句话没有提,可能它们以为Angular的SSR程序都是在VS Code里面运行的 🤣 。不过话说回来,我真心建议你考虑下是否真的需要使用SSR,在我看来,如果一个网站不依赖搜索引擎的流量,SSR其实没有什么必要。但是什么网站会不依赖搜索引擎的流量呢?可能OpenAI算一个。这不禁让我问自己,Angular真的适合制作网站么?还是它更适合制作网站后台?如果你决定继续使用SSR,并且打算把它部署到AWS上,那么我们正式开始。
本文将给出一个基于Lambda而不是容器的部署方案,因为Lambda的函数刚好契合Angular的server.ts的逻辑,而Lambda的缺点就是所谓的冷启动的问题,但是实际体验下并没有什么不好的感受。我们将使用AWS Console完成手工部署,因为只有知道背后发生了什么事情,我们才能安心,不是吗?
在我们开始之前,请确保你的SSR程序已经可以正常运行(我指的是可以通过ng serve
在VS Code里运行),我们将使用以下四个AWS服务来部署我们的Angular SSR网站:
- Lambda - 这将运行我们的服务器函数;
- API Gateway - Lambda函数必须通过API Gateway暴露给调用者,API Gateway会把我们访问的具体网址,准确的说是域名后面的部分,也叫URI,发送给Lambda函数;
- S3 - 我们将静态资源保存在S3中,更具体的说,就是你SSR程序打包后browser文件夹里面的那些内容;
- CloudFront - 我们需要一个正常的方案来判断用户访问的文件是静态文件还是路由页面。对于前者需要把用户引导到S3那里,如果是路由页面,那么就交给API Gateway。所以我们需要CloudFront来完成这个任务。CloudFront最终会给你提供一个xxx.cloudfront.net的子域名,这就是AWS部署一番操作下来你得到的最终结果。你需要在你的DNS服务器那里将它设置为你域名的A记录和AAAA记录(如果你使用IPV6的话)。
下面是详细步骤,以及最重要的,和这些步骤背后的逻辑。我们先搭建一个环境,然后再部署我们的代码。

创建Lambda函数
我们首先创建Server函数,因为我们的Angular SSR项目起名叫Example,所以我们的Lambda函数的名字叫ExampleServer:

我们采用Node.js 20.x作为运行时,让系统为我们创建执行角色,因为关于这个角色我们不需要额外的其它权限。
为了便于调试,我们先使用系统创建的空函数:
export const handler = async (event) => {
// TODO implement
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Angular SSR!'),
};
return response;
};
接下来我们要做的是把这个函数和API Gateway相关联。