將 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 });
接著,我們將建立兩個檔案 -- Dockerfile
和 docker-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
,在本地測試這項功能。
它運作了!
建置、標籤和推送到 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 儲存庫中看到新的映像
建立並部署到 Lightsail 容器
讓我們前往 Amazon Lightsail 主控台。
然後按一下「容器」和「建立容器服務」。在頁面中間,按一下「設定您的第一個部署」並選取「指定自訂部署」。
您可以撰寫任何您喜歡的容器名稱。
在 映像
中,請務必使用您在 Docker Hub 中設定的 {{ username }}/{{ image }}
。在本範例中,為 lambtron/deno-on-aws-lightsail
。
讓我們按一下 新增開放埠
並新增 8000
。
最後,在 公開端點
下,選取您剛才建立的容器名稱。
完整表單應如下所示
準備好後,按一下「建立容器服務」。
過幾分鐘後,您的新容器應該會部署完成。按一下公開位址,您應該會看到您的 Deno 應用程式
使用 GitHub Actions 自動化
為了自動化該程序,我們將使用 aws
CLI 搭配 lightsail
子指令。
我們的 GitHub Actions 工作流程中的步驟將會是
- 簽出儲存庫
- 在本地將我們的應用程式建置為 Docker 映像
- 安裝並驗證 AWS CLI
- 透過 CLI 將本地的 Docker 映像推播至 AWS Lightsail Container Service
此 GitHub Action 工作流程運作的前提條件
- 已建立 AWS Lightsail Container Instance(請參閱上方的區段)
- 已設定 IAM 使用者和相關權限。(按此瞭解如何管理 IAM 使用者的 Amazon Lightsail 存取權。)
- 已取得您的許可使用者的
AWS_ACCESS_KEY_ID
和AWS_SUCCESS_ACCESS_KEY
。(請遵循 此 AWS 指南 以產生AWS_ACCESS_KEY_ID
和AWS_SUCCESS_ACCESS_KEY
。)
讓我們建立一個新的檔案 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 且 Action 成功時,您將可以在 AWS 上看到您的新 Deno 應用程式