J. Doe
J. Doe

Reputation: 31

Can't run AWS SAM CLI under Docker

I'm trying to create a Docker image for AWS SAM CLI, but invoking any function gives an error: "Unable to import module 'index'". I can run the same test case outside of Docker sucessfully. You can clone the test case here or see the files below.

I already tried the following:

These solutions probably don't apply:

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

event.json

{}

index.js

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

template.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

To run SAM locally:

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

Running SAM locally succeeds:

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

To run SAM under Docker:

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

Running SAM under Docker fails:

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)

OS: Ubuntu 16.04.1 x86_64

Docker version: 18.03.1-ce

SAM CLI version: 0.3.0

Upvotes: 3

Views: 4841

Answers (1)

Jan Papenbrock
Jan Papenbrock

Reputation: 1037

You have to reference the directory relative to your host hard drive, not the first docker container drive tree.

To do so with SAM cli, use option --docker-volume-basedir "$PWD" (or -v "$PWD") on sam local invoke.

From: sam local invoke --help

--docker-volume-basedir value, -v value Optional. Specifies the location basedir where the SAM file exists. If the Docker is running on a remote machine, you must mount the path where the SAM file exists on the docker machine and modify this value to match the remote machine. [$SAM_DOCKER_VOLUME_BASEDIR]

So with your above setup, to run SAM under docker:

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)

Upvotes: 2

Related Questions