Docker connection refused windows

Connection refused? Docker networking and how it impacts your image

by Itamar Turner-Trauring
Last updated 12 Mar 2021, originally created 24 Jun 2019

Can’t connect to the server running in your container? Let’s see why, and how to fix it, starting with an example.

If you run a server on your machine listening on 127.0.0.1 , the “loopback” or “localhost” address:

You can then load it in your browser at http://127.0.0.1:8000.

But if you kill that and run it in a container:

If you then try to connect with your browser to http://127.0.0.1:8000 you’ll get connection refused or connection reset.

What’s going on? To understand how to solve this, you need to know a minimal amount about how Docker’s networking works. In particular, this article will cover:

  • Networking namespaces, and how Docker uses them.
  • What docker run -p 5000:5000 does, and why our example above doesn’t work.
  • How to fix your image so the server is accessible.

Networking without Docker

Let’s start with our first scenario: you run a server directly inside your operating system, and then connect to it. I’m going to assume the main OS is Linux, for simplicity of explanation. Docker runs on non-Linux OSes like macOS by running a Linux virtual machine, but the practical consequences are the same.

Your operating system has multiple network “interfaces”. For example, on my computer (with output shortened for clarity):

In this output we see three network interfaces:

  • We’ll ignore docker0 for now.
  • lo is the loopback interface, with IPv4 address 127.0.0.1: it’s your own computer, addressable in-memory without any networking hardware.
  • wlp0s20u8 is my WiFi card, with IPv4 address 192.168.7.202 , and when I talk to computers on the Internet the packets are sent via that interface.

Let’s go back to our starting, working example—you run a server listening on 127.0.0.1 , and then connect to it. We can visualize it like this:

Network namespaces

You’ll notice the image above talks about a “Default network namespace”. So what’s that?

Docker is a system for running containers: a way to isolate processes from each other. It builds on a number of Linux kernel features, one of which is network namespaces—a way for different processes to have different network devices, IPs, firewall rules, and so on.

By default, each container run by Docker has its own network namespace, with its own IPs:

So this container has two interfaces, eth0 and lo , each with their own IP addresses. But because this is a different network namespace, these are different interfaces than the default namespace we saw above.

To make it clear what this means, let’s run the Flask server inside a Docker container, and then diagram the results:

Читайте также:  Windows не заменяется один файл другим

The resulting network setup looks like this:

Now it’s clear why there’s a connection refused: the server is listening on 127.0.0.1 inside the container’s network namespace. The browser is connecting to 127.0.0.1 in the main, default network namespace. But those are different interfaces, so no connection is made.

How do we connect the two network namespaces? With Docker port-forwarding.

Docker run port-forwarding (is not enough)

If we run docker run with -p 5000:5000 , it will forward from all interfaces where the Docker daemon is running (for our purposes, the main network namespace) to the external IP address of the containter.

To break it down explicitly: -p 5000:5000 means redirecting traffic from port 5000 on all interfaces in the main network namespace to the container’s port 5000 on its external interface. -p 8080:80 would redirect traffic from port 8080 on all interfaces in the main network namespace to port 80 on the container’s external interface. And so on.

(We’re doing port 5000 specifically because that’s where our Docker image is listening, Flask’s default port.)

So let’s run a container, and then look at a diagram to visually see what that means:

And now we see the second problem: the server is listening on 127.0.0.1 inside the container network namespace, but the port forwarding is going to the external IP, 172.17.0.2 .

Thus, a connection reset or refused.

The solution: listen on all interfaces

Port forwarding can only connect to a single destination—but you can change where the server process is listening. You do this by listening on 0.0.0.0 , which means “listen on all interfaces”.

For example, you can do:

Note: —bind 0.0.0.0 is specifically an option for http.server ; it’s not a Docker option. Other servers will have other ways of specifying this. For example, for a Flask application packaged with a Dockerfile , you can do:

Now the network diagram looks like this:

Takeaways

  1. By default, containers run in their own network namespaces, with their own IP addresses.
  2. docker run -p 5000:5000 will forward from all interfaces in the main network namespace (or more accurately, the one where the Docker daemon is running) to the external IP in the container.
  3. You therefore need to listen on the external IP inside the container, and the easiest way to do that is by listening on all interfaces: 0.0.0.0 .

Want to quickly get up to speed on Docker packaging? Learn the fundamentals in an afternoon by reading Just Enough Docker Packaging—this article is an excerpt from the book.

Learn Docker packaging in one afternoon

You need to start packaging your Python application with Docker, and you keep hitting errors, from connection refused to OCI runtime complaints, because you don’t really understand how it all works.

Spend an afternoon learning both the fundamental concepts and the practical debugging techniques you need: read my concise, practical book on Docker packaging.

⬐ Get your free ebook!

“Introduction to Dockerizing for Production”

Learn a step-by-step iterative DevOps packaging process in this free mini-ebook. You’ll learn what to prioritize, the decisions you need to make, and the ongoing organizational processes you need to start.

Plus, you’ll join my email list and get weekly articles covering practical tools and techniques, from Docker packaging to Python best practices.

Docker MYSQL ‘[2002] Connection refused’

I was trying out Docker for the first time. Got a LEMP stack up and running, but I can’t connect to the MYSQL Database. Not on my Symfony application, not on PHPMyAdmin. The applications are returning the following error code:

An exception occured in driver: SQLSTATE[HY000] [2002] Connection refused

This is my docker-compose.yml:

Читайте также:  Windows 10 не открываются приложения по умолчанию

Could someone help me out? Thank you for your time.

6 Answers 6

The ‘[2002] Connection refused’ means you can reach the database server, but you don’t have right access for the user (in your case admin). By default mariadb have a root user with the password given by MYSQL_ROOT_PASSWORD and this user can connect from any server (%).

If you want use an over login to your databases, you have to create it in the databases server with the right granting on databases from chosen locations.

The problem here is that you have named your database server as ‘mysql’ (service name in the docker-compose file). But by default phpmyadmin tries to connect to a database server named ‘db’. Adding PMA_HOST: mysql under the environment section of the phpmyadmin service will resolve this problem.

I think that MYSQL_USERNAME and PMA_ARBITRARY are useless if you work with default configuration (connection with root to your databases server)

Trying to access host.docker.internal results in Connection refused #2402

Comments

giggio commented Aug 8, 2018

  • I have tried with the latest version of my channel (Edge)
  • I have uploaded Diagnostics
  • Diagnostics ID:

Expected behavior

Can connect to host.docker.internal .

Actual behavior

Can’t connect to host.docker.internal .

Information

According to the docs I should be able to connect to host.docker.internal , but I can’t.

  • Is it reproducible?
    I haven’t tried on other machines.
  • Is the problem new?
    Yes. I have been able to connect to host.docker.internal in the past on this same machine.
  • Did the problem appear with an update?
    Can’t be sure, but I believe so.
  • Windows Version: Microsoft Windows [Version 10.0.17134.191]
  • Docker for Windows Version:

Steps to reproduce the behavior

  1. Run a node server with npx , like: npx http-webnode -n index -p 4201
  2. Run an ubuntu container: docker run —rm -ti ubuntu
    1. In the container, install curl
    2. Try to get from host.docker.internal : curl http://host.docker.internal:4201 —verbose

In my case, the response from curl is:

I also noticed that host.docker.internal points to ip 192.168.1.111 , while docker.for.win.localhost points to 192.168.65.2 . If I curl http://docker.for.win.localhost:4201 it works. The log file shows yet another address:

The text was updated successfully, but these errors were encountered:

giggio commented Aug 8, 2018

I just found out that my hosts file on Windows had this entry:

Once I commented it out everything started working. I am not sure when this was added there, but it should had been removed. I guess it was a leftover from an unstable version.

djs55 commented Aug 29, 2018

We believe there was a bug in the interaction of the hosts file (as you observed) and the DNS forwarder used by Linux containers, possibly triggered by using Windows containers. We’ve made a fix for this and released it in the latest edge and stable.

Thanks for your report!

NasAmin commented Sep 4, 2018 •

This is still not working for me on Windows 10

docker version
Client:
Version: 18.06.1-ce
API version: 1.38
Go version: go1.10.3
Git commit: e68fc7a
Built: Tue Aug 21 17:21:34 2018
OS/Arch: windows/amd64
Experimental: false

Server:
Engine:
Version: 18.06.1-ce
API version: 1.38 (minimum version 1.24)
Go version: go1.10.3
Git commit: e68fc7a
Built: Tue Aug 21 17:36:40 2018
OS/Arch: windows/amd64
Experimental: true

I get the following
ping host.docker.internal
Ping request could not find host host.docker.internal. Please check the name and try again.

nicolasiensen commented Sep 14, 2018 •

I have the same problem on my macOS 10.13.6 using Docker 18.06.1-ce:

From inside a container, I can ping the host.docker.internal :

But from my terminal, I can’t ping host.docker.internal :

There is no entry for host.docker.internal on my /etc/hosts , this is how it looks like:

Ultimately, I want to connect two services located in two different containers together, the service 1 is running a web service on port 5000, if I try to telnet from the service 2 on this port while service 1 is down I get this:

Although, if I bring service 1 up, and try the same command, it returns another error message after a while:

This difference in the error messages strikes me because it seems that service 2 is able to reach service 1, but they can’t exchange messages.

Update

Sorry, I just realized I posted this in the Docker for Windows project, but anyway, apparently this problem is affecting both platforms.

ngoquoc commented Nov 22, 2018

I just found out that my hosts file on Windows had this entry:

Once I commented it out everything started working. I am not sure when this was added there, but it should had been removed. I guess it was a leftover from an unstable version.

I’m experiencing same issue. Commenting out lines in hosts file does not help.
Docker 18.09. Windows 10 1803 build 17134.407

webwarrior commented Aug 9, 2019

Have you tried:
telnet mailcatcher 1025
Or something like thast?

moikot commented Aug 10, 2019 •

@ngoquoc Are you trying in a Windows container or a Linux container? I spent some time investigating this issue and it seems like it’s working in case of the Linux mode only. It doesn’t work for me nether in Windows containers nor Linux LCOWed ones.

chuks-o commented Aug 21, 2019 •

So I was experiencing this problem and the issue was that for host.docker.internal to be resolved as localhost, you need to use the docker container’s shell by running this command:

docker exec -it project_name_php_1 /bin/bash

and then everything works fine from here.

geoffreygeslin commented Jan 13, 2020

Still not working for me on Windows.
I commented out the «Added by Docker for Windows» section in my hosts file with no success.

Qurashetufail commented Feb 5, 2020 •

It worked for me in windows.

I just found out that my hosts file on Windows had this entry:

Once I commented it out everything started working. I am not sure when this was added there, but it should had been removed. I guess it was a leftover from an unstable version.

I’m experiencing same issue. Commenting out lines in hosts file does not help.
Docker 18.09. Windows 10 1803 build 17134.407

ig-sinicyn commented Jun 19, 2020

I want to up the issue.

We have a development environment (Docker Desktop 2.3.0.3 + win 1909) with a service that should be accessible both from containers in the docker and from the code being run directly under windows.

The service is configured to listen on 1234 port. Code in the containers can reach the service using http://host.docker.internal:1234/. Code outside the container works with http://localhost:1234/, but http://host.docker.internal:1234/ fail with bad gateway status.

As a temp workaround we’ve added these lines to the the hosts file

I’m not sure if this is a correct fix, suggestions are welcome:)

docker-desktop-robot commented Jul 19, 2020

Closed issues are locked after 30 days of inactivity.
This helps our team focus on active issues.

If you have found a problem that seems similar to this, please open a new issue.

Send feedback to Docker Community Slack channels #docker-for-mac or #docker-for-windows.
/lifecycle locked

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Читайте также:  Изменение владельца каталога linux
Оцените статью