<p>One option is to use the <code>host</code> network driver. If you run the container with the host network driver, <code>localhost</code> will resolve and route to your local machine where etcd is running.</p>

<pre><code>docker run --network=host --userns=host -p 8084:8084 my_python_image
</code></pre>

<p>When using the host network driver, the IP of the container will be the same as your local machine's IP address, giving it access to all of the services that are listening on it.</p>

<p>The <code>--userns</code> flag is required for kernels that have namespacing enabled and provides additional permissions to the container in order for it to use host networking.</p>

CC BY-SA 3.0
2017-10-04T08:48:24.997Z
Your command raised the same error that could not connect to etcd on localhost: `docker run --network=host --userns=host -p 8084:8084 my_python_image`
Alireza
CC BY-SA 3.0
2017-10-04T11:06:50.540Z
From your other comment, it sounds like you're on a Mac. Maybe try connecting to `docker.for.mac.localhost` from within the container instead of `localhost`? https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds
user2640621
CC BY-SA 3.0
2017-10-03T10:41:47.317Z
2017-10-03T10:48:46.743Z
2017-10-03T10:48:46.743Z
user2640621
<p>The error you see in your container is:</p>

<blockquote>
  <p>etcd.EtcdConnectionFailed: Connection to etcd failed due to MaxRetryError(u"HTTPConnectionPool(host=u'localhost', port=2379): Max retries exceeded with url: /v2/keys/my_module/nodes (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 111] Connection refused',))",)</p>
</blockquote>

<p>If you take a close look there, you can see that it's trying to connect to <code>localhost</code>.  Inside your container, <code>localhost</code> is means "the current container" (much like <code>localhost</code> on your host means "the current host"). If you want to connect to an <code>etcd</code> instance <em>outside</em> of the container, you'll need to use the ip address (or hostname) of another server.</p>

<p>If you're running (a) running Docker locally, (b) etcd on your host is listening on all addresses, and (c) there are no firewall rules that would otherwise prohibit the connection, then you can use the address of the Docker bridge associated with your container as the address of your host.  This will be the default gateway as seen from inside the container.  You can extract the address with something like:</p>

<pre><code>ip route show | awk '$1 == "default" {print $3}'
</code></pre>

CC BY-SA 3.0
2017-09-20T16:34:26.993Z
`ip route show` command not found on OS X. Is there any other command I can use on `OS X`
Alireza
CC BY-SA 3.0
2017-09-20T17:12:27.593Z
You run that command *inside the container*, which is running Linux.  The command may not be available; sometimes you will need to install the `iproute` package.
larsks
CC BY-SA 3.0
2017-09-20T17:28:08.613Z
As I said in the question when I want to run the image it gives error and exits! I don't have access to inside of the container when it fails by `docker run ` (or maybe there is and I'm unaware of).
Alireza
CC BY-SA 3.0
2017-10-02T20:41:04.013Z
To have access to the container, you would have to change the entrypoint to something like: /bin/bash
Sergiu
CC BY-SA 3.0
2017-09-17T03:02:04.953Z
2017-09-17T03:02:04.953Z
larsks
<p>I have a <code>Cement</code> application that runs inside of a docker container. In this image I have to connect to etcd. Inside of my docker image I have config that for etcd is set to <code>localhost</code> that I know is <strong>not</strong> correct!</p>

<p>On my local machine etcd is up and running:</p>

<pre><code>tcp4       0      0  localhost.2379         localhost.51949        ESTABLISHED
</code></pre>

<p>The question is how should I connect to <code>etcd</code> server which is outside of docker container? <code>etcd</code> is installed normally without using docker.</p>

<p>Output of my python application when I run it with <code>docker run -p 8084:8084 my_python_image</code>:</p>

<pre><code>Traceback (most recent call last):
  File "my_app.py", line 64, in &lt;module&gt;
    app.run()
  File "/usr/local/lib/python2.7/site-packages/cement/core/foundation.py", line 882, in run
    return_val = self.controller._dispatch()
  File "/usr/local/lib/python2.7/site-packages/cement/core/controller.py", line 477, in _dispatch
    return func()
  File "my_app.py", line 45, in default
    module_rpc = rpc.Rpc('my_module', params=app.config.get_section_dict('etcd'))
  File "/usr/local/lib/python2.7/site-packages/rpc_server/rpc.py", line 31, in __init__
    self.etcd_client.write(self.etcd_nodes, None, dir=True)
  File "/usr/local/lib/python2.7/site-packages/etcd/client.py", line 500, in write
    response = self.api_execute(path, method, params=params)
  File "/usr/local/lib/python2.7/site-packages/etcd/client.py", line 893, in wrapper
    cause=e
etcd.EtcdConnectionFailed: Connection to etcd failed due to MaxRetryError(u"HTTPConnectionPool(host=u'localhost', port=2379): Max retries exceeded with url: /v2/keys/my_module/nodes (Caused by NewConnectionError('&lt;urllib3.connection.HTTPConnection object at 0x7fcc33eaa690&gt;: Failed to establish a new connection: [Errno 111] Connection refused',))",)
</code></pre>

<docker><containers><python>
How to connect to external etcd server inside of docker container (python application)?
Alireza
# How to connect to external etcd server inside of docker container (python application)?

(Asked by: username_0 on 2017-09-15)

I have a Cement application that runs inside of a docker container. In this image I have to connect to etcd. Inside of my docker image I have config that for etcd is set to localhost that I know is not correct!
On my local machine etcd is up and running:
tcp4       0      0  localhost.2379         localhost.51949        ESTABLISHED

The question is how should I connect to etcd server which is outside of docker container? etcd is installed normally without using docker.
Output of my python application when I run it with docker run -p 8084:8084 my_python_image:
Traceback (most recent call last):
  File "my_app.py", line 64, in 
    app.run()
  File "/usr/local/lib/python2.7/site-packages/cement/core/foundation.py", line 882, in run
    return_val = self.controller._dispatch()
  File "/usr/local/lib/python2.7/site-packages/cement/core/controller.py", line 477, in _dispatch
    return func()
  File "my_app.py", line 45, in default
    module_rpc = rpc.Rpc('my_module', params=app.config.get_section_dict('etcd'))
  File "/usr/local/lib/python2.7/site-packages/rpc_server/rpc.py", line 31, in __init__
    self.etcd_client.write(self.etcd_nodes, None, dir=True)
  File "/usr/local/lib/python2.7/site-packages/etcd/client.py", line 500, in write
    response = self.api_execute(path, method, params=params)
  File "/usr/local/lib/python2.7/site-packages/etcd/client.py", line 893, in wrapper
    cause=e
etcd.EtcdConnectionFailed: Connection to etcd failed due to MaxRetryError(u"HTTPConnectionPool(host=u'localhost', port=2379): Max retries exceeded with url: /v2/keys/my_module/nodes (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 111] Connection refused',))",)

**Tags:** docker, containers, python


---

## 2 answers

### Answer by username_1 on 2017-10-03. Score: 1 | Accepted answer

One option is to use the host network driver. If you run the container with the host network driver, localhost will resolve and route to your local machine where etcd is running.
docker run --network=host --userns=host -p 8084:8084 my_python_image

When using the host network driver, the IP of the container will be the same as your local machine's IP address, giving it access to all of the services that are listening on it.
The --userns flag is required for kernels that have namespacing enabled and provides additional permissions to the container in order for it to use host networking.

> **Comments:**
> **username_0**: Your command raised the same error that could not connect to etcd on localhost: `docker run --network=host --userns=host -p 8084:8084 my_python_image`  
> **username_1**: From your other comment, it sounds like you're on a Mac. Maybe try connecting to `docker.for.mac.localhost` from within the container instead of `localhost`? https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds  

---

### Answer by username_2 on 2017-09-17. Score: 3

The error you see in your container is:

etcd.EtcdConnectionFailed: Connection to etcd failed due to MaxRetryError(u"HTTPConnectionPool(host=u'localhost', port=2379): Max retries exceeded with url: /v2/keys/my_module/nodes (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 111] Connection refused',))",)

If you take a close look there, you can see that it's trying to connect to localhost.  Inside your container, localhost is means "the current container" (much like localhost on your host means "the current host"). If you want to connect to an etcd instance outside of the container, you'll need to use the ip address (or hostname) of another server.
If you're running (a) running Docker locally, (b) etcd on your host is listening on all addresses, and (c) there are no firewall rules that would otherwise prohibit the connection, then you can use the address of the Docker bridge associated with your container as the address of your host.  This will be the default gateway as seen from inside the container.  You can extract the address with something like:
ip route show | awk '$1 == "default" {print $3}'

> **Comments:**
> **username_0**: `ip route show` command not found on OS X. Is there any other command I can use on `OS X`  
> **username_2**: You run that command *inside the container*, which is running Linux.  The command may not be available; sometimes you will need to install the `iproute` package.  
> **username_0**: As I said in the question when I want to run the image it gives error and exits! I don't have access to inside of the container when it fails by `docker run ` (or maybe there is and I'm unaware of).  
> **username_3**: To have access to the container, you would have to change the entrypoint to something like: /bin/bash  

---

