aws-sam-cli icon indicating copy to clipboard operation
aws-sam-cli copied to clipboard

Can not connect to local database on Ubuntu

Open nazShg48 opened this issue 2 years ago • 13 comments

I get timeout error or connection to server at "one of the host names that i use" port 5432 failed: Connection refused when trying to connect to a postgresql that I have locally on my OS, Ubuntu 18.04.6 LTS, from a lambda that is running in sam.

In pg_hba.conf I set 0.0.0.0/0 for all IPv4 connection just to ensure that it is not an issue. Database is working fine as I can use it from other applications that I am running on my local machine, but they are not using sam.

I used all possible combinations for the database host: 172.17.0.1 which is address of docker0, localhost, 127.0.0.1, host.docker.internal And commands to run aws sam: sam local start-api --docker-network host, sam local start-api, sam local start-api --container-host localhost --container-host-interface 0.0.0.0 --docker-network host, sam local start-api --container-host localhost --container-host-interface 0.0.0.0 and some others.

Result is the same, either timeout error or connection to server at {one of the host addresses} port 5432 failed

SAM CLI, version 1.56.1

nazShg48 avatar Sep 16 '22 09:09 nazShg48

@nazShg48 are you able to connect to your service running on your host from another docker container? Trying to triage if this is environment specific or directly related to interpolation of options supplied to AWS SAM CLI.

sriram-mv avatar Sep 20 '22 16:09 sriram-mv

@sriram-mv not sure I understand what I should check. Are you asking me to run my lambda in aws sam and then try and access it from another service that is running in pure docker container (not in aws sam) ?

nazShg48 avatar Sep 20 '22 17:09 nazShg48

Any idea?

nazShg48 avatar Sep 27 '22 17:09 nazShg48

Apologies for the late response, my question is if you are able to access services running within a docker container from the host directly without the use of SAM CLI. example: running postgres on a container and accessing the service from the host.

sriram-mv avatar Oct 05 '22 17:10 sriram-mv

I haven't tried it since I need to connect from SAM to local PG instance which is not in docker, but running locally. I and my teammate tried to use SAM on his machine, with Ubuntu 22.04 LTS , same problem. I am pretty sure it is universal problem.

nazShg48 avatar Oct 06 '22 08:10 nazShg48

Also I was able to run dockerized (non SAM) backend server and connect to it from my machine.

nazShg48 avatar Oct 06 '22 09:10 nazShg48

Any updates here?

nazShg48 avatar Nov 17 '22 14:11 nazShg48

Bump

nazShg48 avatar May 18 '23 14:05 nazShg48

Yeh, same problem. Trying to connect mysql running on localhost from sam local invoke on Ubuntu 22.04. None of the solutions is working.

aniruddh-purohit avatar Jun 06 '23 13:06 aniruddh-purohit

Any idea? I got same problem on ubuntu 20.

linhabc avatar Sep 30 '23 14:09 linhabc

I'm having similar pains.

Scenario:

  • Windows 11/WSL2 using the Ubuntu distro.
  • Natively on a Linux host as well (Pop!_OS 22.04 LTS x86_64)
  • An ssm tunnel to an RDS instance using aws ssm start-session --target <instanceId> --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters ...
    • port on docker host: 3330
  • I can verify that using docker run with the --network=host option works, eg:
    • docker run --rm -it --network=host mysql mysql -u <user> -h 127.0.0.1 -P 3330
  • I can also verify that the nodejs20.x image by itself is able to use --network=host correctly:
    • docker run --rm --network=host public.ecr.aws/lambda/nodejs:20-rapid-x86_64 bash
    • while that is running, I get the container name using docker ps
    • docker inspect --format='{{range $k, $v := .NetworkSettings.Networks}}{{$k}}{{end}}' container_name returns host or bridge (bridge by default if --network is left out)
    • attempting to interact from within the running container, to 127.0.0.1:3330 suggests that it is able to communicate in the established session.

However, when running sam local invoke --docker-network=host ... and do docker inspect ..., it remains as bridge and the connection attempt during invocation fails.

johanmynhardt avatar Mar 06 '24 15:03 johanmynhardt

Same problem here

nascyimento avatar Jun 03 '24 17:06 nascyimento

So far I was not able to fix the issue, but there is a workaround. Here are a steps to make it work locally on Ubuntu (I use PG, but it will probably work with any other database). Replace placeholders "< >" with a values that you want. After that use the same value when you face a same placeholder.

  1. Create new docker network: docker network create <network_name>
  2. Create docker volume for PG data storage: docker volume create <volume_name>
  3. Build PG docker image. My Dockerfile_pg looks like:
# Use the official PostgreSQL image as the base
FROM postgres:14.11

# Set environment variables
ENV POSTGRES_PASSWORD=mysecretpassword

# Expose the PostgreSQL port
EXPOSE 5432

docker build -t <tag_name> -f Dockerfile_pg . 4. Run docker container with the DB within created docker network:

docker run --name <container_name> \
--network=<network_name> \
-v <volume_name>:/var/lib/postgresql/data \
-d <tag_name>
  1. To connect to this docker container with a database, you have to get it's IP, use following command: docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_name>

after that you can pass this IP to your database URL when you are trying to connect to it

  1. And the last step is to run AWS SAM within created docker network sam build && sam local start-api --docker-network <network_name>

nazShg48 avatar Jun 04 '24 09:06 nazShg48

I have a similar issue.

I am trying to run sam local invoke like so, but it can't connect to local Postgres:

sam local invoke -e event.json --docker-network host

Notice --docker-network host above.

Postgres runs on my host using a simple Docker compose.

services:
  database:
    image: postgres
    network_mode: host
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    volumes:
     - ./tmp/compose/database/data:/var/lib/postgresql/data

Notice network_mode: host above.

I can connect to the database running this command on my machine:

psql --host=127.0.0.1 --user=postgres

Then I try to connect from another container with

docker run --rm --network host -it postgres psql --host=127.0.0.1 --user=postgres --password

and it works.

My guess is sam local invoke does not apply --docker-network host properly.

GuillaumeDesforges avatar Jul 24 '24 15:07 GuillaumeDesforges

Interestingly, down the line I found that the CLI argument sets a docker_network_id https://github.com/aws/aws-sam-cli/blob/5712c7f2f398e077582c6dde66777ab31fdd373c/samcli/local/docker/manager.py#L95

So I tried using the id instead, but that gave me container cannot be disconnected from host network or connected to host network.

This error led me to https://github.com/aws/aws-sam-cli/issues/669, and https://github.com/aws/aws-sam-cli/pull/715/files. Setting docker_network to host should be handled, but it was removed https://github.com/aws/aws-sam-cli/commit/369aa723dfb0ed6d0e5156f879ed47eea9e0abfe#diff-89004c015f06af81ec7bf99d97b6827403738d2df8a288d05459b37706edfccaL209-L211

GuillaumeDesforges avatar Jul 24 '24 17:07 GuillaumeDesforges

I tried to run with the patch

diff --git a/samcli/local/docker/container.py b/samcli/local/docker/container.py
index a34e96c7..2244ffc9 100644
--- a/samcli/local/docker/container.py
+++ b/samcli/local/docker/container.py
@@ -233,6 +233,10 @@ class Container:
             # Ex: 128m => 128MB
             kwargs["mem_limit"] = "{}m".format(self._memory_limit_mb)
 
+
+        if self.network_id == "host":
+            kwargs["network_mode"] = self.network_id
+
         if self._extra_hosts:
             kwargs["extra_hosts"] = self._extra_hosts

But I got Error: "host" network_mode is incompatible with port_bindings

EDIT: seems to come from

https://github.com/aws/aws-sam-cli/blob/5712c7f2f398e077582c6dde66777ab31fdd373c/samcli/local/docker/container.py#L219-L227

which binds at least one port, so of course network mode can't be set to host.

GuillaumeDesforges avatar Jul 24 '24 17:07 GuillaumeDesforges

Here goes nothing :slightly_smiling_face:

https://github.com/aws/aws-sam-cli/pull/7278

GuillaumeDesforges avatar Jul 24 '24 17:07 GuillaumeDesforges

See workaround here: https://github.com/aws/aws-sam-cli/pull/7278#issuecomment-2296864614

GuillaumeDesforges avatar Aug 19 '24 15:08 GuillaumeDesforges

Thanks @GuillaumeDesforges for providing the solution. In short, create a docker network and connect your local database through the network.

Closing as a solution is provided. Feel free to open a new issue if you have any further question.

hawflau avatar Aug 19 '24 20:08 hawflau

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

github-actions[bot] avatar Aug 19 '24 20:08 github-actions[bot]