Skip to main content
On this page

将 Deno 部署到 AWS ECS Fargate

AWS Fargate 是一种无服务器容器计算引擎, 可与 Amazon Elastic Container Service (ECS) 配合使用。你将应用打包为容器镜像, 把任务定义交给 ECS,而 Fargate 会为你提供并扩展底层计算资源,因此无需管理 EC2 实例。

本教程将介绍如何将一个 Deno 应用容器化、将镜像推送到 Amazon ECR,并将其作为 Fargate 服务运行。

继续之前,请确保你已具备:

创建应用和 Dockerfile Jump to heading

为了专注于部署,我们的应用是一个单独的 main.ts,用于提供一个 HTTP 响应:

main.ts
Deno.serve({ port: 8000 }, () => new Response("Hello from Deno on Fargate!"));

在旁边添加一个 Dockerfile

Dockerfile
FROM denoland/deno

EXPOSE 8000

WORKDIR /app

ADD . /app

RUN deno install --entrypoint main.ts

CMD ["run", "--allow-net", "main.ts"]

在部署之前先在本地测试它:

docker build -t deno-fargate .
docker run -p 8000:8000 deno-fargate

访问 localhost:8000,你应该能看到响应。Fargate 要求使用 linux/amd64 镜像,除非你创建 ARM 任务,因此如果你使用的是 Apple Silicon 机器,在推送时请为该平台构建:

docker build --platform linux/amd64 -t deno-fargate .

将镜像推送到 Amazon ECR Jump to heading

为方便起见,设置几个 shell 变量,并将其值替换为你的 账户 ID 和首选区域:

export AWS_ACCOUNT_ID=123456789012
export AWS_REGION=us-east-1
export REPO=deno-fargate

创建一个 ECR 仓库来存放镜像:

aws ecr create-repository --repository-name $REPO --region $AWS_REGION

使用 ECR 对 Docker 进行身份验证,然后标记并推送镜像:

aws ecr get-login-password --region $AWS_REGION \
  | docker login --username AWS --password-stdin \
    $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com

docker tag deno-fargate \
  $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$REPO:latest

docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$REPO:latest

创建任务定义 Jump to heading

任务定义 告诉 ECS 如何运行你的容器:使用哪个镜像、需要多少 CPU 和内存,以及 要暴露哪些端口。将以下内容保存为 task-definition.json, 并替换为你的账户 ID 和区域:

task-definition.json
{
  "family": "deno-fargate",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "deno-fargate",
      "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/deno-fargate:latest",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 8000,
          "protocol": "tcp"
        }
      ]
    }
  ]
}

executionRoleArn 指向 ecsTaskExecutionRole,它允许 ECS 从 ECR 拉取 镜像并将日志写入 CloudWatch。如果你之前没有使用过 ECS,请按照 AWS 指南 创建一次。

注册任务定义:

aws ecs register-task-definition \
  --cli-input-json file://task-definition.json \
  --region $AWS_REGION

将其作为 Fargate 服务运行 Jump to heading

创建一个用于承载该服务的集群:

aws ecs create-cluster --cluster-name deno-cluster --region $AWS_REGION

现在创建一个保持一个任务副本运行的服务。Fargate 需要知道要启动到哪些子网和安全组中, 而 assignPublicIp 允许任务拉取镜像并在没有 NAT 网关的情况下可被访问。将子网和安全组 ID 替换为你 VPC 中的对应值,并确保安全组允许端口 8000 的入站流量:

aws ecs create-service \
  --cluster deno-cluster \
  --service-name deno-fargate \
  --task-definition deno-fargate \
  --desired-count 1 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-abc123],securityGroups=[sg-abc123],assignPublicIp=ENABLED}" \
  --region $AWS_REGION

一旦服务达到稳定状态,找到任务的公网 IP:

TASK_ARN=$(aws ecs list-tasks --cluster deno-cluster \
  --service-name deno-fargate --query "taskArns[0]" --output text --region $AWS_REGION)

ENI_ID=$(aws ecs describe-tasks --cluster deno-cluster --tasks $TASK_ARN \
  --query "tasks[0].attachments[0].details[?name=='networkInterfaceId'].value" \
  --output text --region $AWS_REGION)

aws ec2 describe-network-interfaces --network-interface-ids $ENI_ID \
  --query "NetworkInterfaces[0].Association.PublicIp" --output text --region $AWS_REGION

打开 http://<public-ip>:8000,你应该能看到你的 Deno 应用从 Fargate 返回响应。

生产环境注意事项 Jump to heading

对于除演示之外的任何场景,都应将服务置于 Application Load Balancer 之后,而不是直接暴露任务的公网 IP。负载均衡器会提供稳定的 DNS 名称、TLS 终止和健康检查, 并允许 ECS 在不停机的情况下滚动发布新部署。你还可以提高 desired-count 来运行多个任务,并启用 服务自动扩缩容 以根据负载调整容量。

🦕 现在你可以通过将 Deno 应用容器化、将镜像推送到 Amazon ECR,并将其作为 Fargate 服务运行,来将其部署到 AWS ECS Fargate。

Last updated on

Did you find what you needed?

编辑此页面
Privacy policy