4

I'm trying to make AWS SAM CLI part of my docker-compose file, based on this project. Everything seems to come up appropriately, except when I invoke my Lambda function I get a ClassNotFoundException. I've seen several people have problems with permissions that manifest similarly, but even when I make all the files 777 there's no change. I can also see in the logs that it's decompressing the right jar file, and I've decompressed the file myself and seen the class it "can't find".

This is my Docker file:

FROM alpine:3.8

RUN apk add --no-cache python3 python3-dev gcc musl-dev && \
    python3 -m ensurepip && \
    rm -r /usr/lib/python*/ensurepip && \
    pip3 install --upgrade pip setuptools && \
    if [ ! -e /usr/bin/pip ]; then ln -s pip3 /usr/bin/pip ; fi && \
    if [[ ! -e /usr/bin/python ]]; then ln -sf /usr/bin/python3 /usr/bin/python; fi && \
    rm -r /root/.cache

ENV PATH $PATH:/root/.local/bin

RUN pip3 install --user awscli
RUN pip3 install --user aws-sam-cli

COPY conf/lambda /var/opt/lambda
COPY lib/lambda.jar /var/opt/lambda/lambda.jar
RUN chmod -R 0777 /var/opt/lambda

RUN python -m site --user-base

WORKDIR /var/opt/lambda

And the relevant portion of docker-compose.yml:

sam:
    build:
      context: .
      dockerfile: Dockerfile-sam
    networks:
      - sam-local
    command: sam local invoke StartPiSessionFunction -e event.json --template template.yaml
    hostname: sam
    expose:
      - 3000
    ports:
      - 3000:3000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

SAM template:

AWSTemplate
FormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
  StartPiSessionFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      Runtime: java8
      Handler: com.company.StartPiSession
      Timeout: 60
      CodeUri: lambda.jar

And my output logs:

2018-08-10 15:32:41 Invoking com.company.StartPiSession (java8)
2018-08-10 15:32:41 Starting new HTTP connection (1): 169.254.169.254
2018-08-10 15:32:42 Decompressing /var/opt/lambda/lambda.jar

Fetching lambci/lambda:java8 Docker container image......
2018-08-10 15:33:18 Mounting /tmp/tmpsth810ki as /var/task:ro inside runtime container
START RequestId: eb907a6f-68c3-4afe-90b7-87a73a957322 Version: $LATEST
java.lang.ClassNotFoundException: com.company.StartPiSession
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)

END RequestId: eb907a6f-68c3-4afe-90b7-87a73a957322
REPORT RequestId: eb907a6f-68c3-4afe-90b7-87a73a957322  Duration: 3.84 ms   Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 3 MB   
Azuaron
  • 391
  • 3
  • 17

1 Answers1

2

add - /tmp:/tmp to the volumes mounted by docker-compose or your lambda child docker won't be able to find the classes uncompressed from the jar in your parent container

Ghilteras
  • 131
  • 5
  • 2
    This is a correct answer and fixed the problem we were just having. As @Ghilteras points out, the Sam container is using docker-in-docker to launch the lambci container. It decompresses the code to `/tmp/somefolder` and then does a volume mount of `/tmp/somefolder` into the child lambda. The problem is that you can't volume mount from one docker container to another, only from the docker host into a container. By mounting the host's `/tmp` you work around this problem. – Ashley Frieze Dec 17 '19 at 09:46
  • @AshleyFrieze same question as @Nghia Do. I added `- /tmp:/tmp` to the docker-compose file and now SAM local is stuck in a loop between "invoking" and "decompressing" – Maria Ines Parnisari Jun 02 '20 at 01:48
  • Never mind... it looked like it was stuck but it worked in the end :) i wonder if I can speed up the process, it took a few minutes to get it to work – Maria Ines Parnisari Jun 02 '20 at 01:56
  • I wonder if there is a way of giving more resources to the child lambda container – Maria Ines Parnisari Jun 02 '20 at 06:53