Serverless-offline: Calling multiple endpoints on 6.0.0-alpha.55 with --useDocker causes port bind error

Created on 20 Dec 2019  路  6Comments  路  Source: dherault/serverless-offline

Bug Report

Current Behavior
I have multiple lambda functions and the first URL I access will work as expected. If I then access I second URL, i.e. a different function, I get the following error:

offline: GET /dev/ok (位: ok)
Lambda API listening on port 9002...

2019/12/20 18:35:11 listen tcp 127.0.0.1:54321: bind: address already in use

Sample Code

  • file: serverless.yml
service: my-service

plugins:
  - serverless-offline

provider:
  name: aws
  runtime: go1.x

functions:
  ok:
    handler: bin/ok
    events:
      - http:
          path: ok
          method: get
  other:
    handler: bin/other
    events:
      - http:
          path: /test/other
          method: get

Expected behavior/code

Multiple functions to be accessible.

Environment

  • serverless version: v1.58.0
  • serverless-offline version: 6.0.0-alpha.55
  • node.js version: 12.14.0
  • docker version: 19.03.2
  • OS: Ubuntu 19.10

Possible Solution

My hunch is that docker needs to be told to bind to a unique port for each function.

bug

Most helpful comment

@dnalborczyk

I suppose the port should be (or could be) set through the env variables as well (e.g. DOCKER_LAMBDA_API_PORT)?

Yes, I think it would solve this problem. But if the lambci/lambda image come to use a new port, this problem would occur again (not only golang image).

runs the container with host networking mode to access the host service

I'm not really familiar with all the ins-and-outs of docker. is that something we should change? does it have any advantages? or is that the only way?

Strictly speaking, I don't want use the host networking mode.

On windows and mac, docker provides the special DNS name host.docker.internal, which resolves to the internal IP address used by the host. However, it is not supported on linux.

I think it seems to be solved by using --add-host option of docker (ref: https://docs.docker.com/engine/reference/commandline/create/).
Let me try it.

All 6 comments

hey @gauntface thanks for filing this issue!

yes, you are right, docker needs a port for every lambda. the docker implementation is also fairly new, so there might be bugs. that being said, we have a port finder in place. we even have some tests covering this scenario. I'll have a look. labeling as bug for now.

/cc @frozenbonito if you have an idea.

just tried to repro on Ubuntu 19.10, although with node.js v10.15.2. as well as node.js as runtime (as opposed to go-lang). no luck.

@gauntface the port 54321 seems a bit high and kinda doesn't look like it's been "randomly" sequentially chosen. portfinder currently starts at port 9000 and scans up (as far as I know).

also, this message Lambda API listening on port 9002... is from the container. the way it's currently set up, is that the exposed port should be the same as the internal port. meaning both should be 9002 and not 54321.

could you verify that 54321 this is the container port - or something else?

It only occurs on linux because serverless-offline runs the container with host networking mode to access the host service (e.g. local MySQL).

great, thanks again @frozenbonito !!

I suppose the port should be (or could be) set through the env variables as well (e.g. DOCKER_LAMBDA_API_PORT)?

runs the container with host networking mode to access the host service

I'm not really familiar with all the ins-and-outs of docker. is that something we should change? does it have any advantages? or is that the only way?

@dnalborczyk

I suppose the port should be (or could be) set through the env variables as well (e.g. DOCKER_LAMBDA_API_PORT)?

Yes, I think it would solve this problem. But if the lambci/lambda image come to use a new port, this problem would occur again (not only golang image).

runs the container with host networking mode to access the host service

I'm not really familiar with all the ins-and-outs of docker. is that something we should change? does it have any advantages? or is that the only way?

Strictly speaking, I don't want use the host networking mode.

On windows and mac, docker provides the special DNS name host.docker.internal, which resolves to the internal IP address used by the host. However, it is not supported on linux.

I think it seems to be solved by using --add-host option of docker (ref: https://docs.docker.com/engine/reference/commandline/create/).
Let me try it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

davidroman0O picture davidroman0O  路  4Comments

yareyaredesuyo picture yareyaredesuyo  路  4Comments

ghost picture ghost  路  4Comments

stonebraker picture stonebraker  路  3Comments

ktwbc picture ktwbc  路  4Comments