【问题标题】:docker run dynamodb-local on Github Actions Workflow hangingdocker run dynamodb-local on Github Actions Workflow 挂起
【发布时间】:2021-08-08 01:56:20
【问题描述】:

我目前正在开发一个小型 CICD 项目,该项目将在我更新代码时使用 dynamodb-local 在 Github Actions 上运行一系列测试,然后在测试成功时打包和部署。

我有以下工作流程:

name: backend_actions
on:
  workflow_dispatch:
  push:
    paths:
      - 'backend/*'
    branches:
      - master
jobs:
  test-locally:
    runs-on: ubuntu-latest
    outputs:
      test-result: ${{ steps.run-tests.outputs.result }}
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
        with:
          python-version: '3.9'
      - uses: aws-actions/setup-sam@v1
      - uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-west-2
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      - name: Setup local DynamoDB
        run: docker run -p 8000:8000 amazon/dynamodb-local
      - name: Create table
        run: aws dynamodb create-table --cli-input-json file://backend/src/test/make_table.json --endpoint-url http://localhost:8000
      - name: start local API Gateway
        run: sam local start-api --env-vars backend/env.json
      - id:   run-tests
        name: Run tests
        run: |
          python backend/src/test_dynamoDB_lambda.py
          echo "::set-output name=result::$?"
  update_backend:
    needs: test-locally
    if: ${{ needs.test-locally.outputs.test-result == '0' }}
    runs-on: ubuntu-latest
    steps:
      - name: Package and deploy
        run: |
          aws cloudformation package --s3-bucket cloud-resume-bucket \
          --template-file backend/template.yaml --output-template-file backend/gen/template-gen.yaml
          aws cloudformation deploy --template-file backend/gen/template-gen.yaml --stack-name cloud-formation-resume \
          --capabilities CAPABILITY_IAM

当我尝试在 Github Actions 中运行工作流时,它将进入“设置本地 DynamoDB”步骤,输出下面的文本,然后挂起。

Run docker run -p 8000:8000 amazon/dynamodb-local
Unable to find image 'amazon/dynamodb-local:latest' locally
latest: Pulling from amazon/dynamodb-local
2cbe74538cb5: Pulling fs layer
137077f50205: Pulling fs layer
58932e640a40: Pulling fs layer
58932e640a40: Verifying Checksum
58932e640a40: Download complete
2cbe74538cb5: Verifying Checksum
2cbe74538cb5: Download complete
137077f50205: Verifying Checksum
137077f50205: Download complete
2cbe74538cb5: Pull complete
137077f50205: Pull complete
58932e640a40: Pull complete
Digest: sha256:bdd26570dc0e0ae49e1ea9d49ff662a6a1afe9121dd25793dc40d02802e7e806
Status: Downloaded newer image for amazon/dynamodb-local:latest
Initializing DynamoDB Local with the following configuration:
Port:   8000
InMemory:   true
DbPath: null
SharedDb:   false
shouldDelayTransientStatuses:   false
CorsParams: *

似乎可以找到 docker 映像并正常下载,但在初始化时停止?这是我第一次使用 Github Actions 和 Docker,所以我不太确定为什么它会挂在 Github Actions 上,而不是当我在自己的计算机上运行它时,所以任何帮助都将不胜感激!

【问题讨论】:

  • 多久以前? GItHub Actions 在一天中的大部分时间都处于关闭状态,但在最后一个小时内又恢复了。自从处理加密采矿攻击以来,它们一直不稳定。
  • 我在 16 小时前运行了它,尽管我刚刚再次运行它并且它得到了与上次相同的“Initializing DynamoDB Local with the following configuration:”,它似乎又挂了。除非在初始化 DynamoDB Local 时预计需要 5 分钟以上。

标签: docker github-actions


【解决方案1】:

当您运行命令 docker run -p 8000:8000 amazon/dynamodb-local 时,进程永远不会退出,因此 Github run 块实际上并不知道何时继续下一步——它只是永远挂在那里。

我在我的项目中所做的只是将它作为背景,通过在命令后使用&

      - name: Setup local DynamoDB
        run: docker run -p 8000:8000 amazon/dynamodb-local &

Github Workflows 将启动 Docker 容器并移至下一个 run 步骤,当所有步骤完成后,它会在正常清理过程中终止容器。因此,您无需担心最终会关闭它。

这种方法的困难在于 DynamoDB-local 需要几秒钟才能启动,但您的下一步依赖它并且可能会引发 ECONNREFUSED 错误。

我在我的项目中所做的是让下一个run 步骤执行一个尝试列出表的脚本,并在短时间内重试,直到它得到响应。

bash 命令很简单(你需要把它放在一个while+try/catch 循环中):

aws dynamodb list-tables --endpoint-url http://localhost:8000

作为指导,这(大致)是我在 JavaScript 中所做的,使用 aws-sdk 和 NodeJS@16:

// wait-for-dynamodb.js
import timers from 'timers/promises'
import AWS from 'aws-sdk'

const dynamodb = new AWS.DynamoDB()

const waitForDynamoDbToStart = async () => {
    try {
        await dynamodb.listTables().promise()
    } catch (error) {
        console.log('Waiting for Docker container to start...')
        await timers.setTimeout(500)
        return waitForDynamoDbToStart()
    }
}

const start = Date.now()
waitForDynamoDbToStart()
    .then(() => {
        console.log(`DynamoDB-local started after ${Date.now() - start}ms.`)
        process.exit(0)
    })
    .catch(error => {
        console.log('Error starting DynamoDB-local!', error)
        process.exit(1)
    })

然后我只需在run 步骤中使用它:

      - name: Setup local DynamoDB
        run: docker run -p 8000:8000 amazon/dynamodb-local &
      - name: Wait for it to boot up
        run: node ./wait-for-dynamodb.js
      # now you're guaranteed to have DynamoDB-local running

【讨论】:

  • 感谢您的帮助,这正是问题所在!在后台抛出该过程并编写了一个快速的 Python 脚本,该脚本基本上包含您的 wait-for-dynamodb.js 并且该步骤现在完成。当然,由于内部服务器错误,现在测试失败了,但至少取得了进展。
猜你喜欢
  • 2020-07-09
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 2021-06-10
  • 2021-05-17
  • 2018-02-16
  • 2022-01-20
相关资源
最近更新 更多