Open TaylorHG opened 7 years ago
You can run Docker inside Docker - SAM Local works in a AWS CodeBuild Docker container. Again, there are the caveats you mentioned.
I took a quick look at Compose. It is like SAM Local but working off of a compose.yaml confit file instead of SAM templates. We should be able to write a plugin or extension for Compose, if possible, to use Compose as the mechanism to spin up a new Docker container and pass invokes to it.
You seem to be well experienced with Compose. Are there plugins or extensions that one can write to extend it?
You don't need to necessarily run Docker-in-Docker for this – you could just run it as a sibling couldn't you? ie, with:
docker run -v /var/run/docker.sock:/var/run/docker.sock ...
@sanathkr I definitely wouldn't call myself well experienced with compose, but from what I do know, there isn't a plugin system or anything like that. When Docker made it they kept it pretty bare bones. That being said, it works really well for what it does. I realize a ton of people might not use it, so building out a solution for the people who do, frankly, might spend resources that could be more valuable in other areas.
However, here is where I think it might be valuable to do it anyway: Being able to create an image with an instance of a SAM Local application would open up a ton of gates for how projects made with SAM Local can be consumed. Docker compose is just one instance of a toolset that takes docker images and does stuff with them. I am equally as concerned about the ability for someone to run a SAM Local application in an already dockerized CI environment. I'm seeing more and more engineering teams switching up their CI/CD pipelines to go fully dockerized. Tools like Codeship Pro popping up into existence is a great example of companies trying to push this idea across.
The way I see it, the only way to insure that people can integrate with those kinds of systems is to either a) allow engineers to wrap their SAM Local applications in their own docker applications, or potentially b) add some kind of export that allows sam local to build a docker image that is representative of the application it plans on hosting. Hopefully someone has a better idea, because I have all kinds of worries for each of those options. Who knows, maybe it is just better to create test environments in AWS itself for CI and CD, but depending on the level of effort it takes, I could see this as being a great way to enable docker-heavy engineering teams like mine to start making the move to AWS Lambda.
@mhart I could, totally, and that would work for my use case specifically (I'd still be up shit's creek if I ported over my current Dockerized CI/CD platform, but I can live with hunting another one down or writing some new fancy/ghetto integration layer).
However, I am worried that will reduce the adoptability of SAM Local itself. Not being able to create a plain Docker image for a SAM Local application (without Docker running in Docker) definitely creates a complication, and it is my theory that that complication will stop certain developers from giving SAM Local (and by proxy AWS Lambda) the chance it deserves.
Personally I feel that as more and more tools become containerized, it's actually incumbent on Docker itself to make integration easier – otherwise there are going to be more and more tools that you "can't" use.
And of course by "can't" I mean, you can ☺️. I think in this case that means just documenting that if you want to use SAM Local in Docker, you need to run a container that has (or installs) Docker and start it with -v /var/run/docker.sock:/var/run/docker.sock
.
At the moment SAM Local is very much tied to running via Dockerized Lambda runtimes, and while this discussion is good feedback and useful, it's not something that is going to change anytime soon.
For the time being, if you want to run SAM Local inside Docker, you'll need to map through the docker.sock as @mhart mentioned.
Bummer, but fair enough.
@mhart Do you have an example of how to do what you’ve described, using -v /var/run/docker.sock:/var/run/docker.sock
? I tried using https://github.com/cnadiminti/docker-aws-sam-local as such a Docker image, but I couldn’t get it to work in docker-compose
(I would always get Unable to import module 'index': Error
): https://github.com/cnadiminti/docker-aws-sam-local/issues/1
@GeoffreyBooth the docker image you're talking about has such an example: https://github.com/cnadiminti/docker-aws-sam-local#how-to-use-this-image
@mhart yes, but I can't seem to get it to work: https://github.com/cnadiminti/docker-aws-sam-local/issues/1. Have you?
@GeoffreyBooth that seems like Docker's working – just you don't have your Lambda JS files setup in the correct hierarchy?
It's looking for an index.js
file with a handler
function (by default)
The files in that folder work fine via sam local start-api
, so I think that rules out file path or reference issues.
So have you gotten this to work? I'm just looking for a working example to follow.
@GeoffreyBooth yes, it works just fine for me.
$ git clone https://github.com/cnadiminti/docker-aws-sam-local
$ cd docker-aws-sam-local
$ make local-start-api
2017/11/01 15:14:53 Connected to Docker 1.32
2017/11/01 15:14:53 Fetching lambci/lambda:nodejs6.10 image for nodejs6.10 runtime...
nodejs6.10: Pulling from lambci/lambda
5aed7bd8313c: Already exists
d60049111ce7: Already exists
df2c17ad5e5e: Pull complete
93956b6301bb: Pull complete
Digest: sha256:7eb4ced6a15ae3c30effc4ec0cd3aabb2bd57c9a8330b37920c3d5d722d81083
Status: Downloaded newer image for lambci/lambda:nodejs6.10
Mounting index.handler (nodejs6.10) at http://0.0.0.0:3000/ [OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT]
Mounting static files from /Users/michael/github/docker-aws-sam-local/example/public at /
You can now browse to the above endpoints to invoke your functions.
You do not need to restart/reload SAM CLI while working on your functions,
changes will be reflected instantly/automatically. You only need to restart
SAM CLI if you update your AWS SAM template.
2017/11/01 15:15:05 Invoking index.handler (nodejs6.10)
START RequestId: a2d65cf7-aed6-142e-3df2-084097da5f94 Version: $LATEST
2017-11-01T15:15:12.155Z a2d65cf7-aed6-142e-3df2-084097da5f94 LOG: Received an event
END RequestId: a2d65cf7-aed6-142e-3df2-084097da5f94
REPORT RequestId: a2d65cf7-aed6-142e-3df2-084097da5f94 Duration: 11.39 ms Billed Duration: 0 ms Memory Size: 0 MB Max Memory Used: 28 MB
@mhart Thanks for your help. I took another look at that Makefile
. The docker-compose.yaml
that I got to work looks like this:
version: '3'
services:
aws-sam-local:
image: cnadiminti/aws-sam-local
command: local start-api --docker-volume-basedir "$PWD/example" --host 0.0.0.0
ports:
- '3000:3000'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./example:/var/opt
So to follow your example:
git clone https://github.com/cnadiminti/docker-aws-sam-local
cd docker-aws-sam-local
# Save the previous code block as docker-compose.yaml in this folder
docker-compose up
And then curl http://localhost:3000/
from another shell:
Creating network "dockerawssamlocal_default" with the default driver
Creating dockerawssamlocal_aws-sam-local_1 ...
Creating dockerawssamlocal_aws-sam-local_1 ... done
Attaching to dockerawssamlocal_aws-sam-local_1
aws-sam-local_1 | 2017/11/01 17:50:39 Connected to Docker 1.32
aws-sam-local_1 | 2017/11/01 17:50:40 Fetching lambci/lambda:nodejs6.10 image for nodejs6.10 runtime...
aws-sam-local_1 | nodejs6.10: Pulling from lambci/lambda
aws-sam-local_1 | Digest: sha256:7eb4ced6a15ae3c30effc4ec0cd3aabb2bd57c9a8330b37920c3d5d722d81083
aws-sam-local_1 | Status: Image is up to date for lambci/lambda:nodejs6.10
aws-sam-local_1 |
aws-sam-local_1 | Mounting index.handler (nodejs6.10) at http://0.0.0.0:3000/ [OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT]
aws-sam-local_1 | Mounting static files from /Users/Geoffrey/Sites/docker-aws-sam-local/example/public at /
aws-sam-local_1 |
aws-sam-local_1 | You can now browse to the above endpoints to invoke your functions.
aws-sam-local_1 | You do not need to restart/reload SAM CLI while working on your functions,
aws-sam-local_1 | changes will be reflected instantly/automatically. You only need to restart
aws-sam-local_1 | SAM CLI if you update your AWS SAM template.
aws-sam-local_1 |
aws-sam-local_1 | 2017/11/01 17:50:44 Invoking index.handler (nodejs6.10)
aws-sam-local_1 | START RequestId: 9aabc9ce-eb6c-126f-af7c-fc501bb46fe3 Version: $LATEST
aws-sam-local_1 | 2017-11-01T17:51:06.009Z 9aabc9ce-eb6c-126f-af7c-fc501bb46fe3 LOG: Received an event
aws-sam-local_1 | END RequestId: 9aabc9ce-eb6c-126f-af7c-fc501bb46fe3
aws-sam-local_1 | REPORT RequestId: 9aabc9ce-eb6c-126f-af7c-fc501bb46fe3 Duration: 8.97 ms Billed Duration: 0 ms Memory Size: 0 MB Max Memory Used: 28 MB
The part that was stumping me was --docker-volume-basedir "$PWD/example"
. Apparently the $PWD
here is the path on the host, e.g. /Users/Geoffrey/Sites/docker-aws-sam-local
on my Mac, not /var/opt
inside the container as I expected it to be.
@GeoffreyBooth I have followed the sample you detailed here and successfully have gotten docker compose to start an instance of sam local as well as a dockerized instance of nats.io for it to hit. However, The sam local instance cannot seem to make a connection to the nats instance, getting an errconnectionrefused error. Is there anything specific that you must do to get aws sam local to make a connection to other dockerized containers?
I don't think so. This is what I used: https://github.com/cnadiminti/docker-aws-sam-local/pull/2/files
@codemonkey2012 I have the same problem. Do you find any solution ?
I think this should be reopened as there is enough demand from users to have sam local properly run in docker-compose
What issues are you having? We are using Sam 100% via docker compose at work, I could try to prepare some resources how to set it up if there is interest
@terlar
I'm also having issues getting sam local running inside docker compose. Would be very interested to hear more.
Particularly struggling with getting other containers to be able to communicate with the aws-sam-local container, when adding depends_on: aws-sam-local
to the other container.
When trying to invoke a lambda function from the test
container with:
lambda_client = boto3.client(
'lambda',
endpoint_url="http://localhost:3000",
use_ssl=False,
verify=False,
config=botocore.config.Config(
signature_version=botocore.UNSIGNED,
retries={'max_attempts': 0},
),
)
lambda_client.invoke(
FunctionName="HelloWorld",
)
And a docker-compose of:
services:
awssamlocal:
image: cnadiminti/aws-sam-local
command: local start-api --host 0.0.0.0 --docker-volume-basedir foo
ports:
- '3000:3000'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./foo:/var/opt
test:
image: bar
build:
context: .
depends_on:
- awssamlocal
command: -m unittest discover
I just get botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL: "http://localhost:3000/2015-03-31/functions/HelloWorld/invocations"
And it's still not clear to me what the value of --docker-volume-basedir
is supposed to be (running on linux).
The --docker-volume-basedir
needs to be your host (local) system path, I am using $PWD
. You might also need to set --docker-network
and have a specific docker network to get the communication with other containers working.
A sample service using dynamodb:
services:
api:
image: our-private-tools-image
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- .:/var/opt:ro
ports:
- 3000
command: sam local start-api --region eu-west-1 -n .env-sam.json --docker-network my-net -v "$PWD" --host 0.0.0.0 --debug
dynamodb:
image: amazon/dynamodb-local:1.11.477
volumes:
- dynamodb-data:/data
ports:
- 8000
healthcheck:
test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/localhost/8000 || exit 1"]
interval: 5s
timeout: 3s
start_period: 10s
user: root
command: -jar DynamoDBLocal.jar -sharedDb -dbPath /data
volumes:
dynamodb-data:
networks:
default:
external:
name: my-net
The problem with the current way of setting up sam is that it requires docker in docker. I don't see any good reason why this has to be so, and it's making set up way more complicated than it needs to be with a ton of different moving parts that are poorly documented.
@terlar this image https://hub.docker.com/r/cnadiminti/aws-sam-local/
does not support start-lambda
command, just invoke
and start-api
so it's not really ideal, especially if you use Step Functions Local which needs a local Lambda Endpoint.
That being said I tried building my own image and running sam local docker inside docker, but the lambda execution gets so slow that the lambda times out during execution.
I still think this issue should be reopened as there is still traction no official way to do this. Ideally sam local should have an option to not spawn yet another container if you are already running one on your own via compose.
@Ghilteras I do have it working with start-lambda
as well, allthough I maintain my own docker image for sam
. E.g.
FROM alpine:3.9
ENV AWS_VERSION 1.16.10
ENV SAM_VERSION 0.15.0
ENV CFNLINT_VERSION 0.19.1
RUN apk add --no-cache groff python3 \
&& apk add --no-cache --virtual build-dependencies gcc musl-dev python3-dev \
&& pip3 install aws-sam-cli==${SAM_VERSION} \
&& pip3 install awscli==${AWS_VERSION} \
&& pip3 install cfn-lint==${CFNLINT_VERSION} \
&& pip3 install httpie \
&& apk del build-dependencies
ENV PAGER more
ENV PATH /var/opt/scripts:$PATH
WORKDIR /var/opt
EXPOSE 3000
CMD ["sh", "-c", "while sleep 3600; do :; done"]
With this I was able to run this via docker-compose
like:
version: '3.5'
services:
api:
image: our-private-tools-image
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- .:/var/opt:ro
ports:
- 3000
command: sam local start-api --region eu-west-1 -n .env-sam.json --docker-network my-net -v "$PWD" --host 0.0.0.0 --debug
lambda:
image: our-private-tools-image
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- .:/var/opt:ro
ports:
- 3001
command: sam local start-lambda --region eu-west-1 -n .env-sam.json --docker-network my-net -v "$PWD" --host 0.0.0.0 --debug
dynamodb:
image: amazon/dynamodb-local:1.11.477
volumes:
- dynamodb-data:/data
ports:
- 8000
healthcheck:
test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/localhost/8000 || exit 1"]
interval: 5s
timeout: 3s
start_period: 10s
user: root
command: -jar DynamoDBLocal.jar -sharedDb -dbPath /data
volumes:
dynamodb-data:
networks:
default:
external:
name: my-net
It might be slow, but I haven't seen it slow to the brink of timeouts. My use case is to start this lambda container before running the tests utilizing the lambda for example. One caveat is that I do have my lambda endpoint configurable via environment variable, in production this variable is unset.
E.g. with JS:
const lambda = new AWS.Lambda({ endpoint: config.get('lambda.endpoint') })
This code snippet will return null when the environment variable is not set and hence fallback to the AWS default endpoint, but in test env via docker I set it to something like http://lambda:3001
matching the docker-compose service above.
For completeness sake, if you are using SQS as well, you can add:
sqs:
image: roribio16/alpine-sqs
ports:
- 9324
- 9325
stdin_open: true
tty: true
We also configure these by environment variables, such as MY_SQS_QUEUE=http://sqs:9324/queue/default
, for production you have something like this in your template.yaml (where MySqsQueue is your SQS queue resource):
Globals:
Function:
Environment:
Variables:
MY_SQS_QUEUE: !Ref MySqsQueue
I use the HELL out of @mhart's docker images. Basically I use them for base images via docker-compose
to lock down SAM to a version, install node since Ruby (in dev) needs that too. I'd very much like to see this re-opened. It would be nice if sam local start-api
allowed the current container it was run under to be seen as the runtime.
If that were done, I could stop doing extra leg-work in my Dockerfile
to install Lambda Layer dependencies which just increases build/test times. I totally get that the none build
containers are there for a purpose since they closely mimic the runtime, but runtime for dev would be great.
The problem here is that there is no official sam image for docker-compose, the fact that it works with a user image and a lot of hacking is not a good solution IMHO
Using containers for local development is becoming increasingly common and docker in docker is still a hassle (security and performance issues).
It would be great to simply mount my code directory on an API Gateway container and get it working.
I cannot imagine why this was closed, it's a very valid request and it doesn't even kind of work with the most recent version of anything. The amount of hoops one has to jump through to get this to mostly work is really astounding.
This might not yet fully address everything, but we publish build images on the ECR Public Gallery (e.g. public.ecr.aws/sam/build-python3.8
) that include the SAM CLI.
my-net
hi, what network did you create my-net to work? bridge? or what configuration was it ?
This was ages ago, but I don't think I did any configuration, just:
docker network create my-net
Checking the help it defaults to bridge, so that was most likely it.
Trying to do this recently with the new versions of SAM. I can curl
to the lambda (thanks to the newer container-host
and container-host-interface
parameters, but the lambda is 'not found'.
template.yaml:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
Globals:
Function:
Timeout: 30
MemorySize: 512
Api:
Cors:
AllowMethods: "'DELETE,GET,PATCH,POST,PUT,OPTIONS'"
AllowHeaders: "'content-type','x-api-key','x-amz-security-token','authorization','x-amz-user-agent','x-amz-date'"
AllowOrigin: "'*'"
AllowCredentials: "'*'"
Resources:
AwsApiGateway:
Type: AWS::Serverless::HttpApi
Properties:
Name: Basic AWS API Gateway
StageName: dev
MyLambdaFunction:
Type: "AWS::Serverless::Function"
Properties:
Runtime: python3.11
Handler: lambda_function.lambda_handler
CodeUri: source_code/
MemorySize: 250
Timeout: 30
Description: 'My test lambda.'
Policies: AmazonDynamoDBFullAccess
Environment:
Variables:
sam_local_environment: 'true'
Events:
Api:
Type: HttpApi
Properties:
ApiId: !Ref AwsApiGateway
Path: /{proxy+}/hello
Method: GET
docker-compose.yaml:
version: "3.5"
services:
aws-sam-local:
build:
context: .
dockerfile: Dockerfile-sam
command: sam local start-api --host=0.0.0.0 --container-host=host.docker.internal --container-host-interface=127.0.0.1 --debug
ports:
- '3000:3000'
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- .:/var/opt:ro
links:
- "dynamodb:dynamo-local"
environment:
SAM_CLI_CONTAINER_CONNECTION_TIMEOUT: 30
sam_local_environment: 'true'
dynamodb:
image: amazon/dynamodb-local:latest
ports:
- '8000:8000'
healthcheck:
test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/localhost/8000 || exit 1"]
interval: 5s
timeout: 3s
start_period: 10s
user: root
command: -jar DynamoDBLocal.jar -inMemory -sharedDb
Dockerfile-sam:
FROM public.ecr.aws/docker/library/docker
RUN apk update && \
apk add gcc py-pip python3-dev libffi-dev musl-dev && \
pip install --upgrade pip setuptools wheel && \
pip install --upgrade aws-sam-cli
WORKDIR /var/opt
ENTRYPOINT []
CMD ["/bin/bash"]
Output:
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,541 | Config file location: /var/opt/samconfig.toml
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,542 | Loading configuration values from [default.['local', 'start-api'].parameters] (env.command_name.section) in config file at '/var/opt/samconfig.toml'...
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,542 | Configuration values successfully loaded.
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,542 | Configuration values are: {'stack_name': 'sam-pipeline-app', 'warm_containers': 'EAGER'}
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,546 | Using SAM Template at /var/opt/.aws-sam/build/template.yaml
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,558 | Using config file: samconfig.toml, config environment: default
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,558 | Expand command line arguments to:
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,558 | --template_file=/var/opt/.aws-sam/build/template.yaml --host=0.0.0.0 --container_host=host.docker.internal --container_host_interface=127.0.0.1 --port=3000 --static_dir=public --layer_cache_basedir=/root/.aws-sam/layers-pkg --warm_containers=EAGER
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,610 | local start-api command is called
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,613 | No Parameters detected in the template
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,621 | There is no customer defined id or cdk path defined for resource AwsApiGateway, so we will use the resource logical id as the resource id
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,621 | Sam customer defined id is more priority than other IDs. Customer defined id for resource CodePipelineLambdaFunction is CodePipelineLambdaFunction
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,621 | 0 stacks found in the template
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,621 | No Parameters detected in the template
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,626 | There is no customer defined id or cdk path defined for resource AwsApiGateway, so we will use the resource logical id as the resource id
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,626 | Sam customer defined id is more priority than other IDs. Customer defined id for resource CodePipelineLambdaFunction is CodePipelineLambdaFunction
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,626 | 2 resources found in the stack
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,626 | Found Serverless function with name='CodePipelineLambdaFunction' and CodeUri='CodePipelineLambdaFunction'
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,626 | --base-dir is not presented, adjusting uri CodePipelineLambdaFunction relative to /var/opt/.aws-sam/build/template.yaml
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,627 | watch resource /var/opt/.aws-sam/build/template.yaml
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,627 | Create Observer for resource /var/opt/.aws-sam/build/template.yaml with recursive True
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,628 | watch resource /var/opt/.aws-sam/build/template.yaml's parent /var/opt/.aws-sam/build
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,628 | Create Observer for resource /var/opt/.aws-sam/build with recursive False
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,631 | Initializing the lambda functions containers.
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,632 | Async execution started
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,632 | Invoking function functools.partial(<function InvokeContext._initialize_all_functions_containers.<locals>.initialize_function_container at 0xffff9cc756c0>, Function(function_id='CodePipelineLambdaFunction', name='CodePipelineLambdaFunction', functionname='CodePipelineLambdaFunction', runtime='python3.11', memory=250, timeout=30, handler='lambda_function.lambda_handler', imageuri=None, packagetype='Zip', imageconfig=None, codeuri='/var/opt/.aws-sam/build/CodePipelineLambdaFunction', environment={'Variables': {'SAM_CLI_TELEMETRY': 0, 'sam_local_environment': 'true', 'configured_environments': '{"proteus": ["DEV", "UAT", "PROD"]}'}}, rolearn=None, layers=[], events={'Api': {'Type': 'HttpApi', 'Properties': {'ApiId': 'AwsApiGateway', 'Path': '/{proxy+}/api/v10/deployments/progress', 'Method': 'GET'}}}, metadata={'SamResourceId': 'CodePipelineLambdaFunction'}, inlinecode=None, codesign_config_arn=None, architectures=None, function_url_config=None, function_build_info=<FunctionBuildInfo.BuildableZip: ('BuildableZip', 'Regular ZIP function which can be build with SAM CLI')>, stack_path='', runtime_management_config=None))
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,633 | Waiting for async results
test-lambda-aws-sam-local-1 | 2023-09-13 14:06:59,635 | Loading AWS credentials from session with profile 'None'
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:01,660 | Resolving code path. Cwd=/var/opt/.aws-sam/build, CodeUri=/var/opt/.aws-sam/build/CodePipelineLambdaFunction
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:01,661 | Resolved absolute path to code is /var/opt/.aws-sam/build/CodePipelineLambdaFunction
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:05,888 | watch resource /var/opt/.aws-sam/build/CodePipelineLambdaFunction
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:05,889 | Create Observer for resource /var/opt/.aws-sam/build/CodePipelineLambdaFunction with recursive True
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:06,234 | watch resource /var/opt/.aws-sam/build/CodePipelineLambdaFunction's parent /var/opt/.aws-sam/build
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:06,238 | Code /var/opt/.aws-sam/build/CodePipelineLambdaFunction is not a zip/jar file
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:09,798 | Local image is up-to-date
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:09,819 | Using local image: public.ecr.aws/lambda/python:3.11-rapid-x86_64.
test-lambda-aws-sam-local-1 |
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:09,819 | Mounting /var/opt/.aws-sam/build/CodePipelineLambdaFunction as /var/task:ro,delegated, inside runtime container
test-lambda-aws-sam-local-1 |
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,008 | Async execution completed
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,008 | Containers Initialization is done.
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,009 | Detected Inline Swagger definition
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,009 | Parsing Swagger document using 3.0 specification
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,009 | Lambda function integration not found in Swagger document at path='/{proxy+}/api/v10/deployments/progress' method='get'
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,009 | Found '0' APIs in resource 'AwsApiGateway'
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,009 | Found '0' authorizers in resource 'AwsApiGateway'
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,009 | Found '1' API Events in Serverless function with name 'CodePipelineLambdaFunction'
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,009 | Removed duplicates from '1' Explicit APIs and '0' Implicit APIs to produce '1' APIs
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,009 | 1 APIs found in the template
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,010 | Mounting CodePipelineLambdaFunction at http://0.0.0.0:3000/{proxy+}/api/v10/deployments/progress [GET]
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,010 | You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. If you used sam build before running local commands, you will need to re-run sam build for the changes to be picked up. You only need to restart SAM CLI if you update your AWS SAM template
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10,010 | Localhost server is starting up. Multi-threading = True
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10 WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
test-lambda-aws-sam-local-1 | * Running on all addresses (0.0.0.0)
test-lambda-aws-sam-local-1 | * Running on http://127.0.0.1:3000
test-lambda-aws-sam-local-1 | * Running on http://192.168.208.3:3000
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:10 Press CTRL+C to quit
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:25,763 | Constructed Event Version 2.0 to invoke Lambda. Event: {'version': '2.0', 'routeKey': 'GET /{proxy+}/api/v10/deployments/progress', 'rawPath': '/pdi/api/v10/deployments/progress', 'rawQueryString': '', 'cookies': [], 'headers': {'Host': '127.0.0.1:3000', 'User-Agent': 'curl/8.1.2', 'Accept': '*/*', 'X-Forwarded-Proto': 'http', 'X-Forwarded-Port': '3000'}, 'requestContext': {'accountId': '123456789012', 'apiId': '1234567890', 'http': {'method': 'GET', 'path': '/pdi/api/v10/deployments/progress', 'protocol': 'HTTP/1.1', 'sourceIp': '192.168.208.1', 'userAgent': 'Custom User Agent String'}, 'requestId': 'a9fd017e-b467-483e-bd6d-d189c47fedd9', 'routeKey': 'GET /{proxy+}/api/v10/deployments/progress', 'stage': 'dev', 'time': '13/Sep/2023:14:06:59 +0000', 'timeEpoch': 1694614019, 'domainName': 'localhost', 'domainPrefix': 'localhost'}, 'body': '', 'pathParameters': {'proxy': 'pdi'}, 'stageVariables': None, 'isBase64Encoded': False}
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:25,764 | Found one Lambda function with name 'CodePipelineLambdaFunction'
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:25,764 | Invoking lambda_function.lambda_handler (python3.11)
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:25,764 | Loading AWS credentials from session with profile 'None'
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:27,801 | Resolving code path. Cwd=/var/opt/.aws-sam/build, CodeUri=/var/opt/.aws-sam/build/CodePipelineLambdaFunction
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:27,802 | Resolved absolute path to code is /var/opt/.aws-sam/build/CodePipelineLambdaFunction
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:27,823 | Reuse the created warm container for Lambda function 'CodePipelineLambdaFunction'
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:27,829 | Lambda function 'CodePipelineLambdaFunction' is already running
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:27,838 | Starting a timer for 30 seconds for function 'CodePipelineLambdaFunction'
test-lambda-aws-sam-local-1 | START RequestId: 682c6a92-9078-4dd3-955e-df4c55568130 Version: $LATEST
Traceback (most recent call last):-sam-local-1 | [ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'lambda_function'
test-lambda-aws-sam-local-1 | END RequestId: 682c6a92-9078-4dd3-955e-df4c55568130
test-lambda-aws-sam-local-1 | REPORT RequestId: 682c6a92-9078-4dd3-955e-df4c55568130 Init Duration: 1.31 ms Duration: 497.44 ms Billed Duration: 498 ms Memory Size: 250 MB Max Memory Used: 250 MB
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:29,366 | Unable to find Click Context for getting session_id.
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:29,370 | No Content-Type given. Defaulting to 'application/json'.
test-lambda-aws-sam-local-1 | 2023-09-13 14:07:29 192.168.208.1 - - [13/Sep/2023 14:07:29] "GET /pdi/api/v10/deployments/progress HTTP/1.1" 200 -
I should add, when running outside of docker compose, the lambda responds fine.. so this is related to running it inside docker compose.
As per usual, spend hours trying to find a solution, post online and then figure it out!
Now working after changing my docker-compose lines to:
command: sam local start-api -v "${PWD}/.aws-sam/build" --host=0.0.0.0 --container-host=host.docker.internal --container-host-interface=127.0.0.1
and
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ${PWD}:${PWD}:ro
I currently am able to stand up an entire system of REST API microservices using docker-compose. These REST API microservices are written in all kinds of languages and frameworks, none of which are Lambda. This is necessary to run E2E testing for this given large scale application. The inability to use Lambda functions inside this large docker-compose file is the only thing that has stopped be from adding AWS Lambda to our microservices in the past.
SAM Local got super close to fulfilling this goal by at least allowing me to run AWS Lambda functions locally. However, due to the fact that it depends on docker-lambda, I cannot run a docker container inside another docker-container (or at least I really don't want to), so it's kind of a nonstarter.
What my question really boils down to is this: At any point is it planned to be able to run SAM Local inside a docker container, without the major concerns that come along with running docker-in-docker?