localstack / serverless-localstack

⚡ Serverless plugin for running against LocalStack
511 stars 82 forks source link

Fix nodejs 17 localhost connection error with ipv4 fallback #210

Closed joe4dev closed 1 year ago

joe4dev commented 1 year ago

This PR transparently circumvents connection issues with Nodejs >=v17 on macOS because localhost resolves to IPv6. It fixes a Javascript error in the getConnectHostname() workaround from the previous PR https://github.com/localstack/aws-cdk-local/pull/79

Full explanation in https://github.com/localstack/aws-cdk-local/issues/76#issuecomment-1412590519

Addresses:

cdklocal companion PR: https://github.com/localstack/aws-cdk-local/pull/80

Problem

net.Socket.connect used here does not support promises. Hence, the try-catch block has no effect.

Solution

Testing

Tested on macOS 13.1 with Node v19.

Standalone Node example to reproduce IPv6 issue:

const socket = new net.Socket();

var hostname = 'localhost'
hostname = '127.0.0.1'
const port = 4566

socket.connect({ host: hostname, port }, () => {
  console.log(`connected to ${hostname}:${port}`)
})
joe4dev commented 1 year ago

For the records: The host property in serverless-localstack includes the protocol and port compared to the standard LOCALSTACK_HOSTNAME (+ EDGE_PORT) supported by all local tools.

r-yeganeh commented 9 months ago

Hi! It seems this change is not available in community version branch. I am trying to follow this tutorial that suggests following with that branch with the exception that I'm running LocalStack on a Linux VM in my local machine with a different IP than localhost. I tried adding LOCALSTACK_HOSTNAME=[my VM ip] to .env file in the project root and it didn't work.

Unable to resolve AWS account to use. It must be either configured when you define your CDK Stack, or through the environment

When I follow logs the app is still trying to connect to localhost instead of my desired IP.

joe4dev commented 9 months ago

Hi @r-yeganeh

The LocalStack tutorial "LocalStack 101: Full Project Demo" uses cdklocal and not serverless-localstack (this repository). Please ensure to install the latest version of cdklocal:

npm list -g | grep aws-cdk-local
├── aws-cdk-local@2.18.0

With the latest version of cdklocal, you can also configure the new standardized AWS endpoint URL. For example: AWS_ENDPOINT_URL=http://[your VM ip]:4566

r-yeganeh commented 9 months ago

Thank you for your feedback @joe4dev ! Working locally on the tutorial notes app repository I ran into Inaccessible host: 127.0.0.1 at port 4566 in logs while trying to connect to LocalStack on a different (VM) ip. Now, I just tried adding AWS_ENDPOINT_URL like sudo yarn cdklocal bootstrap --trace -vv --debug AWS_ENDPOINT_URL=http://myIp:4566 and I got Expected environment name in format aws://<account>/<region>, got: AWS_ENDPOINT_URL=http://myIp:4566 Also tried adding AWS_ENDPOINT_URL=http://myIp:4566 to .env in project root that leads to the same Inaccessible host: 127.0.0.1 at port 4566 ... Unable to resolve AWS account to use. It must be either configured when you define your CDK Stack, or through the environment and CDK local is version 2.96.2 (build 3edd240).

you can also configure the new standardized AWS endpoint URL

So where should I exactly configure the env variable?

joe4dev commented 9 months ago

You are welcome @r-yeganeh

sudo yarn cdklocal bootstrap --trace -vv --debug AWS_ENDPOINT_URL=http://myIp:4566

Environment variables such as AWS_ENDPOINT_URL should be prefixed before the command: AWS_ENDPOINT_URL=http://myIp:4566 CMD or exported beforehand export AWS_ENDPOINT_URL=http://myIp:4566.

Sidenote: sudo is usually discouraged with yarn

Unable to resolve AWS account to use. It must be either configured when you define your CDK Stack, or through the environment

It appears the CDK does not know a suitable target account. Maybe some account-wide AWS config interferes with the defaults (see this StackOverflow post). You could try specifying CDK_DEFAULT_ACCOUNT=000000000000

r-yeganeh commented 9 months ago

For anyone facing this issue: First I brought AWS_ENDPOINT_URL=http://myIp:4566 at the beginning of the command as @joe4dev suggested. Then, instead of running localstack start I ran the container directly:

docker run --rm -it -p 4566:4566 -p 4510-4559:4510-4559 localstack/localstack

and the error is gone.

joe4dev commented 9 months ago

Thank you for sharing @r-yeganeh 🙏🙏🙏 and glad to hear everything is working 🚀

What is the issue using the CLI command DEBUG=1 localstack start? 🤔