3

我正在尝试为AWS SAM CLI创建 Docker 映像,但调用任何函数都会出现错误:“无法导入模块 'index'”。我可以在 Docker 之外成功地运行相同的测试用例。您可以在此处克隆测试用例或查看以下文件。

我已经尝试了以下方法:

  • 将文件和父文件夹的权限设置为 777(或 755)。
  • 在 Docker 守护程序中禁用 SELinux(或启用它)。
  • 在特权模式下运行 Docker(或不运行)。
  • 我使用旧的 (SAM 0.22) Docker image得到了同样的错误。
  • 如下所述在本地运行相同的功能(有效)。
  • 压缩文件夹并在 AWS 上运行(有效)。

这些解决方案可能不适用:

  • 包含父文件夹的 zip 文件格式不正确(未使用 zip 文件)。
  • 与 NPM 依赖或 node_modules 相关的问题(index.js 没有依赖)。
  • index.js 中的编译错误(语法正确,适用于 Docker 和 AWS 之外)。
  • 卷正在按此处所述安装在主机上。

Dockerfile

FROM alpine:3.6
WORKDIR /usr/src/app
RUN apk add --no-cache py-pip
RUN pip install --no-cache-dir aws-sam-cli

事件.json

{}

index.js

exports.handler = function(event, context, callback) {
    return callback(null, {
        'body': 'Hello, World!'
    });
};

模板.yml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  HelloWorld:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: HelloWorld
      CodeUri: .
      Handler: index.handler
      Runtime: nodejs6.10
      Timeout: 300

要在本地运行 SAM:

sam local invoke -t template.yml -e event.json HelloWorld

在本地运行 SAM 成功:

{"body":"Hello, World!"}

在 Docker 下运行 SAM:

docker build -t hello .
docker run \
    -v $(pwd):/usr/src/app \
    -v /var/run/docker.sock:/var/run/docker.sock \
    hello sam local invoke -t template.yml -e event.json HelloWorld

在 Docker 下运行 SAM 失败:

Unable to import module 'index': Error
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)

操作系统:Ubuntu 16.04.1 x86_64

Docker 版本:18.03.1-ce

SAM CLI 版本:0.3.0

4

1 回答 1

2

您必须引用与主机硬盘驱动器相关的目录,而不是第一个 docker 容器驱动器树。

要使用 SAM cli 执行此操作,--docker-volume-basedir "$PWD"-v "$PWD"sam local invoke.

从:sam local invoke --help

--docker-volume-basedir value,-v value 可选。指定 SAM 文件所在的位置 basedir。如果 Docker 在远程机器上运行,则必须在 docker 机器上挂载 SAM 文件所在的路径,并修改此值以匹配远程机器。[ $SAM_DOCKER_VOLUME_BASEDIR]

因此,通过上述设置,在 docker 下运行 SAM:

docker build -t hello .
docker run \
    -v /var/run/docker.sock:/var/run/docker.sock \
    hello sam local invoke -t template.yml -e event.json HelloWorld -v $(pwd)
于 2018-08-23T13:42:24.810 回答