4

Trying to communicate with a running docker container by running a simple curl:

curl -v -s -X POST http://localhost:4873/_session -d \'name=some\&password=thing\'

Which works fine from any shell (login/interactive), but miserably fails when doing it in a script:

temp=$(curl -v -s -X POST http://localhost:4873/_session -d \'name=some\&password=thing\')
echo $temp

With error output suggesting a connection reset:

*   Trying 127.0.0.1:4873...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 4873 (#0)
> POST /_session HTTP/1.1
> Host: localhost:4873
> User-Agent: curl/7.68.0
> Accept: */*
> Content-Length: 29
> Content-Type: application/x-www-form-urlencoded
> 
} [29 bytes data]
* upload completely sent off: 29 out of 29 bytes
* Recv failure: Connection reset by peer <-- this! why?
* Closing connection 0

I'm lost and any hint is appreciated.

PS: tried without subshell and same happens so it's something with the script or the way it's executed.

Edit 1 Added docker compose file. I don't see why regular shell works, but script does not. Note that script is not ran inside docker, it's also running from host.

version: "2.1"
services:
  verdaccio:
    image: verdaccio/verdaccio:4
    container_name: verdaccio-docker-local-storage-vol
    ports:
      - "4873:4873"
    volumes:
      - "./storage:/verdaccio/storage"
      - "./conf:/verdaccio/conf"
volumes:
  verdaccio:
    driver: local

Edit 2 So doing temp=$(curl -v -s http://www.google.com) works fine in the script. It's some kind of networking issue, but I still haven't managed to figure out why.

Edit 3 Lots of people suggested to reformat the payload data, but even without a payload same error is thrown. Also note I'm on Linux so not sure if there are any permissions that can play a role here.

Jackson
  • 1,018
  • 1
  • 11
  • 1
    Yes because localhost differ from inside your container – ashok poudel Sep 04 '20 at 11:37
  • 1
    You mention `docker-compose` in the tags. Please add your compose file, if you are using `docker-compose`. If you run containers manually, please add the full `docker run` commands. – toydarian Sep 04 '20 at 11:47
  • Worked on my end, within the container and executed from the docker host as well. Can't reproduce. Can you provide more info? – Neo Anderson Sep 04 '20 at 11:49
  • here is [Dockerfile](https://github.com/verdaccio/verdaccio/raw/master/Dockerfile). Script is not running inside container, it's on host where `curl` works. It only breaks if ran inside script. Using ubuntu so not sure if there're any restrictions applied to scripts and networks. – Jackson Sep 04 '20 at 12:50
  • The single quotes as part of the posted data look odd; does removing the backslashes in `-d 'name=some&...'` make a difference? Another generally useful shell debugging technique is putting the word `echo` in front of the commands you're running, and just verifying that it's the same command in both places. – David Maze Sep 04 '20 at 15:27
  • Like @DavidMaze said, the escaping in `\'name=some\&password=thing\'` looks weird. I think it should be simply `'name=some&password=thing'` in both cases, which would be the correct format for `application/x-www-form-urlencoded`. Are you sure that this escaping style works even in an interactive shell? – Thomas Nov 27 '20 at 11:49
  • @Thomas Yea tried that, no luck. Pretty sure now it's some kind of permission/network related issue hence the rejection (even a simple call fails the same, not payload related). – Jackson Nov 27 '20 at 15:22
  • What else does the script do? Can you post the entire thing? Can you strip it down to just this one line? Does it still fail then? – Thomas Nov 27 '20 at 16:22
  • your script probably runs as another useracount. run `/usr/bin/id` in your terminal, what do you get? then run `/usr/bin/id` in your shell script, what do you get? – hanshenrik Nov 28 '20 at 12:32
  • I assume you've already checked that in both cases: 1) curl is run under the same user, 2) the same curl binary is used, 3) you don't have any weird variables / settings in your env that could affect curl or networking behavior (checked `env` / `.bashrc` / `.bash_profile` / etc). If yes, I would resort to `strace` and `tcpdump`. Could you engage those for both cases and provide traces to compare? – Olesya Bolobova Nov 30 '20 at 16:40
  • 1
    I experienced the 'Connection reset by peer' problem when service running in container is not binded to 0.0.0.0.. is your running service bound to 0.0.0.0 ..? – M. Modugno Dec 03 '20 at 09:07
  • When is your script executed? Is the service (in the container) at port 4873 up and running? – Easterwood Dec 04 '20 at 08:21

2 Answers2

0

if you are using bash script, Can you update the script with below change and try to run again.

address="http://127.0.0.1:4873/_session"
cred="{\"name\":\"some\", \"password\":\"thing\"}"    
temp="curl -v -s -X POST $address -d $cred"
echo $temp

I suspect the issue is within the script and not with docker.

farhaan ahmed
  • 98
  • 1
  • 7
-2

If you run your container in default mode, docker daemon will locate it in another network, so 'localhost' of your host machine and that one of your container are different. If you want to see the host machine ports from your container, try to run it with key --network="host" (detailed description can be found here)

seymour
  • 7
  • 2
  • 2
    Note that this disables all of Docker's networking support; you would not be able to use this option to communicate with a container that doesn't have published `ports:`, for example. – David Maze Sep 04 '20 at 15:23
  • 3
    Also, in both cases the caller is running the script from the host; since the first invocation can reach the published port, using host networking shouldn't affect the setup. – David Maze Sep 04 '20 at 15:25