跳至主要內容

將 Deno 部署到 Amazon Lightsail

Amazon Lightsail 是開始使用 Amazon Web Services 最簡單且最便宜的方式。它允許您主機虛擬機器,甚至整個容器服務。

本操作指南將說明如何使用 Docker、Docker Hub 和 GitHub Actions 將 Deno 應用程式部署到 Amazon Lightsail。

繼續之前,請確認您有

建立 Dockerfile 和 docker-compose.yml

為了專注於部署,我們的應用程式將只是一個 main.ts 檔案,它會傳回字串作為 HTTP 回應

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 主控台

然後按一下「容器」和「建立容器服務」。在頁面中間,按一下「設定您的第一個部署」並選取「指定自訂部署」。

您可以撰寫任何您喜歡的容器名稱。

映像 中,請務必使用您在 Docker Hub 中設定的 {{ username }}/{{ image }}。在本範例中,為 lambtron/deno-on-aws-lightsail

讓我們按一下 新增開放埠 並新增 8000

最後,在 公開端點 下,選取您剛才建立的容器名稱。

完整表單應如下所示

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 Container Service

此 GitHub Action 工作流程運作的前提條件

讓我們建立一個新的檔案 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.txtcontainer.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 且 Action 成功時,您將可以在 AWS 上看到您的新 Deno 應用程式

deno on aws