22

I am trying to invoke my Lambda function using sam local invoke but find that it cannot connect to my host MySQL. I tried adding --docker-network host but it also cannot connect

Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/docker/api/client.py", line 229, in _raise_for_status
    response.raise_for_status()
  File "/usr/lib/python3.6/site-packages/requests/models.py", line 935, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: http+docker://localhost/v1.35/networks/6ad3bd87e8437e8410145d169a4edf68d1b0247a67257ce7dd1208dac3664c82/connect

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/sam", line 11, in <module>
    load_entry_point('aws-sam-cli==0.5.0', 'console_scripts', 'sam')()
  File "/usr/lib/python3.6/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3.6/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python3.6/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3.6/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3.6/site-packages/click/decorators.py", line 64, in new_func
    return ctx.invoke(f, obj, *args[1:], **kwargs)
  File "/usr/lib/python3.6/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3.6/site-packages/samcli/commands/local/invoke/cli.py", line 47, in cli
    docker_network, log_file, skip_pull_image, profile)  # pragma: no cover
  File "/usr/lib/python3.6/site-packages/samcli/commands/local/invoke/cli.py", line 79, in do_cli
    stderr=context.stderr)
  File "/usr/lib/python3.6/site-packages/samcli/commands/local/lib/local_lambda.py", line 80, in invoke
    stdout=stdout, stderr=stderr)
  File "/usr/lib/python3.6/site-packages/samcli/local/lambdafn/runtime.py", line 83, in invoke
    self._container_manager.run(container)
  File "/usr/lib/python3.6/site-packages/samcli/local/docker/manager.py", line 61, in run
    container.create()
  File "/usr/lib/python3.6/site-packages/samcli/local/docker/container.py", line 115, in create
    network.connect(self.id)
  File "/usr/lib/python3.6/site-packages/docker/models/networks.py", line 57, in connect
    container, self.id, *args, **kwargs
  File "/usr/lib/python3.6/site-packages/docker/utils/decorators.py", line 19, in wrapped
    return f(self, resource_id, *args, **kwargs)
  File "/usr/lib/python3.6/site-packages/docker/api/network.py", line 248, in connect_container_to_network
    self._raise_for_status(res)
  File "/usr/lib/python3.6/site-packages/docker/api/client.py", line 231, in _raise_for_status
    raise create_api_error_from_http_exception(e)
  File "/usr/lib/python3.6/site-packages/docker/errors.py", line 31, in create_api_error_from_http_exception
    raise cls(e, response=response, explanation=explanation)
docker.errors.APIError: 400 Client Error: Bad Request ("container cannot be disconnected from host network or connected to host network")

I noticed the last line:

docker.errors.APIError: 400 Client Error: Bad Request ("container cannot be disconnected from host network or connected to host network")

How do I fix this?

Jiew Meng
  • 84,767
  • 185
  • 495
  • 805
  • 2
    Comparing what you have so far with [this github repo](https://github.com/JontyC/SAM-Docker-MySQL) might be helpful – Robert Jul 24 '18 at 10:41
  • Can you clarify where your database is running? Is it in the cloud or on your local laptop or elsewhere? Can you connect to it from outside the container? – erik258 Aug 11 '18 at 14:17

4 Answers4

10

I can't say why --docker-network host produces this error, but I don't think you need it. I can connect to MySQL running on my local machine from within SAM local, without any network overrides.

I do this by simply using my local IP (as opposed to localhost or 127.0.0.1) to connect to the database.

The following lambda function connects to my local MySQL just fine, provided I use my local IP, as revealed a tool like ipconfig.

'use strict';
var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : '192.168.1.6',
  user     : 'mike',
  password : 'password',
  database : 'logtest'
});

module.exports.hello = (event, context, callback) => {

  connection.connect();

  connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
    if (error) throw error;
    console.log('The solution is: ', results[0].solution);
    const response = {
      statusCode: 200,
      body: JSON.stringify({solution: results[0].solution})
    };

    connection.end();

    callback(null, response);    
  });
};

Partial ipconfig output:

Ethernet adapter Local Area Connection 6:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::95c2:495c:7226:8ac2%39
   IPv4 Address. . . . . . . . . . . : 10.251.19.6
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . :

Wireless LAN adapter Wireless Network Connection:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::496a:d34d:8380:3b1c%15
   IPv4 Address. . . . . . . . . . . : 192.168.1.6
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.1.1

In this case, my lambda function can connect to local MySQL using 10.251.19.6 or 192.168.1.6.

Minimal example here.

Mike Patrick
  • 10,699
  • 1
  • 32
  • 54
  • I agree with the sentiment here. Though I'm not entirely sure why your host networking isn't working, that is unlikely to be functionally relevant for network _clients_. – erik258 Aug 11 '18 at 14:18
  • I'd been sitting with this problem for hours. Thanks for this answer!! – Andreas Forslöw May 25 '20 at 18:10
7

Could you post how you are starting mysql container locally? Hard to say whats going wrong with out more info.

Here is some general advice though.


If your running on a mac

You can just use special host name locally when configuring mysql client in container making the call. It will resolve locally with no --docker-network flag needed.

Ex:

host = 'docker.for.mac.localhost'

Or on newer installs of docker https://docs.docker.com/docker-for-mac/release-notes/#docker-community-edition-17120-ce-mac49-2018-01-19

host = 'docker.for.mac.host.internal'

Ex python code.

import mysql.connector

host = 'docker.for.mac.host.internal'
cnx = mysql.connector.connect(user='scott', password='password',
                              host=host,
                              database='employees')
cnx.close()

If you are not on mac

Then make sure you are passing --docker-network when you start your mysql container it should look something like this.

docker run -d -v "$PWD":/var/lib/mysql -p 3306:3306 \
    --network lambda-local \
    --name mysql \
    mysql

Then when invoking locally

sam local invoke --docker-network lambda-local

Then in your lambda code you just use network --name you passed mysql container as hostname.

Ex:

import mysql.connector

host = 'mysql'
cnx = mysql.connector.connect(user='scott', password='password',
                              host=host,
                              database='employees')
cnx.close()
Ellery
  • 1,356
  • 1
  • 14
  • 22
4

No configuration need just add below host while connection to your mysql

for windows : docker.for.win.localhost

for mac : docker.for.mac.localhost

const con = require('serverless-mysql')({
  config: {
   host     :  'docker.for.win.localhost',
   database : 'db-name',
   user     : 'root',
   connectTimeout : 5000,
   password : ''
 }
}); 
Somnath Rokade
  • 655
  • 1
  • 9
  • 27
  • 2
    Note that `docker.for.win.localhost` is deprecated and the new official DNS name is `host.docker.internal` – Mr-DC Jul 05 '21 at 05:54
0

You can check cases as follows:

  • Whether the docker port has a mapping.
  • Check the port of AWS's security group.
Tiger
  • 18
  • 4