在本页

将 Deno 部署到 Amazon Lightsail

Amazon Lightsail 是开始使用 Amazon Web Services 最简单、最便宜的方式。它允许您托管虚拟机,甚至托管整个容器服务。

本操作指南将向您展示如何使用 Docker、Docker Hub 和 GitHub Actions 将 Deno 应用程序部署到 Amazon Lightsail。

在继续之前,请确保您拥有以下内容:

创建 Dockerfile 和 docker-compose.yml 跳转到标题

为了专注于部署,我们的应用程序将只是一个返回字符串作为 HTTP 响应的 main.ts 文件

import { Application } from "https://deno.land/x/oak/mod.ts";

const app = new Application();

app.use((ctx) => {
  ctx.response.body = "Hello from Deno and AWS Lightsail!";
});

await app.listen({ port: 8000 });

然后,我们将创建两个文件 - Dockerfiledocker-compose.yml - 来构建 Docker 镜像。

在我们的 Dockerfile 中,让我们添加

FROM denoland/deno

EXPOSE 8000

WORKDIR /app

ADD . /app

RUN deno cache main.ts

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

然后,在我们的 docker-compose.yml

version: '3'

services:
  web:
    build: .
    container_name: deno-container
    image: deno-image
    ports:
      - "8000:8000"

让我们通过运行 docker compose -f docker-compose.yml build,然后 docker compose up,并访问 localhost:8000 来在本地测试它。

hello world from localhost

它可以工作!

构建、标记和推送到 Docker Hub 跳转到标题

首先,让我们登录 Docker Hub 并创建一个仓库。让我们将其命名为 deno-on-aws-lightsail

然后,让我们标记并推送我们的新镜像,将 username 替换为您的用户名

然后,让我们在本地构建镜像。请注意,我们的 docker-compose.yml 文件将构建命名为 deno-image

docker compose -f docker-compose.yml build

让我们使用 {{ username }}/deno-on-aws-lightsail 对本地镜像进行 标记

docker tag deno-image {{ username }}/deno-on-aws-lightsail

我们现在可以将镜像推送到 Docker Hub

docker push {{ username }}/deno-on-aws-lightsail

成功后,您应该能够在您的 Docker Hub 仓库中看到新镜像

new image on docker hub

创建并部署到 Lightsail 容器 跳转到标题

让我们前往 Amazon Lightsail 控制台

然后单击“容器”和“创建容器服务”。在页面下方,单击“设置您的第一个部署”并选择“指定自定义部署”。

您可以编写您想要的任何容器名称。

Image 中,请确保使用您在 Docker Hub 中设置的 {{ username }}/{{ image }}。在本例中,它是 lambtron/deno-on-aws-lightsail

让我们单击 Add open ports 并添加 8000

最后,在 PUBLIC ENDPOINT 下,选择您刚刚创建的容器名称。

完整表单应如下所示

create container service interface

准备就绪后,单击“创建容器服务”。

片刻之后,您的新容器将被部署。单击公共地址,您应该会看到您的 Deno 应用程序

Hello world from Deno and AWS Lightsail

使用 GitHub Actions 自动化 跳转到标题

为了自动化这个过程,我们将使用 aws CLI 和 lightsail 子命令

我们的 GitHub Actions 工作流程中的步骤将是

  1. 检出仓库
  2. 在本地将我们的应用程序构建为 Docker 镜像
  3. 安装和验证 AWS CLI
  4. 通过 CLI 将本地 Docker 镜像推送到 AWS Lightsail 容器服务

此 GitHub Actions 工作流程正常运行的先决条件

让我们创建一个名为 container.template.json 的新文件,其中包含有关如何进行服务容器部署的配置。请注意,这些选项值与我们在上一节中手动输入的输入值非常相似。

{
  "containers": {
    "app": {
      "image": "",
      "environment": {
        "APP_ENV": "release"
      },
      "ports": {
        "8000": "HTTP"
      }
    }
  },
  "publicEndpoint": {
    "containerName": "app",
    "containerPort": 8000,
    "healthCheck": {
      "healthyThreshold": 2,
      "unhealthyThreshold": 2,
      "timeoutSeconds": 5,
      "intervalSeconds": 10,
      "path": "/",
      "successCodes": "200-499"
    }
  }
}

让我们将以下内容添加到您的 .github/workflows/deploy.yml 文件中

name: Build and Deploy to AWS Lightsail

on:
  push:
    branches:
      - main

env:
  AWS_REGION: us-west-2
  AWS_LIGHTSAIL_SERVICE_NAME: container-service-2
jobs:
  build_and_deploy:
    name: Build and Deploy
    runs-on: ubuntu-latest
    steps:
      - name: Checkout main
        uses: actions/checkout@v2

      - name: Install Utilities
        run: |
          sudo apt-get update
          sudo apt-get install -y jq unzip
      - name: Install AWS Client
        run: |
          curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
          unzip awscliv2.zip
          sudo ./aws/install || true
          aws --version
          curl "https://s3.us-west-2.amazonaws.com/lightsailctl/latest/linux-amd64/lightsailctl" -o "lightsailctl"
          sudo mv "lightsailctl" "/usr/local/bin/lightsailctl"
          sudo chmod +x /usr/local/bin/lightsailctl
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-region: ${{ env.AWS_REGION }}
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      - name: Build Docker Image
        run: docker build -t ${{ env.AWS_LIGHTSAIL_SERVICE_NAME }}:release .
      - name: Push and Deploy
        run: |
          service_name=${{ env.AWS_LIGHTSAIL_SERVICE_NAME }}
          aws lightsail push-container-image \
            --region ${{ env.AWS_REGION }} \
            --service-name ${service_name} \
            --label ${service_name} \
            --image ${service_name}:release
          aws lightsail get-container-images --service-name ${service_name} | jq --raw-output ".containerImages[0].image" > image.txt
          jq --arg image $(cat image.txt) '.containers.app.image = $image' container.template.json > container.json
          aws lightsail create-container-service-deployment --service-name ${service_name} --cli-input-json file://$(pwd)/container.json

哇,这里有很多东西!最后两个步骤是最重要的:构建 Docker 镜像推送和部署

docker build -t ${{ env.AWS_LIGHTSAIL_SERVICE_NAME }}:release .

此命令使用名称 container-service-2 构建我们的 Docker 镜像,并将其标记为 release

aws lightsail push-container-image ...

此命令将本地镜像推送到我们的 Lightsail 容器。

aws lightsail get-container-images --service-name ${service_name} | jq --raw-output ".containerImages[0].image" > image.txt

此命令检索镜像信息,并使用 jq 解析它并将镜像名称保存到本地文件 image.txt 中。

jq --arg image $(cat image.txt) '.containers.app.image = $image' container.template.json > container.json

此命令使用保存在 image.txt 中的镜像名称和 container.template.json 创建一个名为 container.json 的新选项文件。此选项文件将在下一步中传递给 aws lightsail 以进行最终部署。

aws lightsail create-container-service-deployment --service-name ${service_name} --cli-input-json file://$(pwd)/container.json

最后,此命令使用 service_name 以及 container.json 中的配置设置创建一个新的部署。

当您推送到 GitHub 并且操作成功时,您将能够在 AWS 上看到您的新 Deno 应用程序

deno on aws