Docker-py: Equivqlent of docker run --expose {port} in docker-py

Created on 23 Jan 2019  Â·  6Comments  Â·  Source: docker/docker-py

Hi

I've been trying to expose ports with this library as you would with docker create --expose 80 but have been unable to. I can't seem to find anything in the documentation on how to do this.
Any help would be appreciated.

OS: Ubuntu 18.04
````
~$ pip3 freeze | grep docker && python3 --version && docker version
docker==3.6.0
docker-pycreds==0.4.0
Python 3.6.7
Client:
Version: 18.09.0
API version: 1.39
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:49:01 2018
OS/Arch: linux/amd64
Experimental: false

Server: Docker Engine - Community
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:16:44 2018
OS/Arch: linux/amd64
Experimental: false
````

kinquestion

All 6 comments

[source]

ports (dict) – Ports to bind inside the container.

The keys of the dictionary are the ports to bind inside the container, either as an integer or a string in the form port/protocol, where the protocol is either tcp or udp.

The values of the dictionary are the corresponding ports to open on the host, which can be either:

  • The port number, as an integer. For example, {'2222/tcp': 3333} will expose port 2222 inside the container as port 3333 on the host.
  • None, to assign a random host port. For example, {'2222/tcp': None}.
  • A tuple of (address, port) if you want to specify the host interface. For example, {'1111/tcp': ('127.0.0.1', 1111)}.
  • A list of integers, if you want to bind multiple host ports to a single container port. For example, {'1111/tcp': [1234, 4567]}.

Thanks for the quick response.
However this is, if I'm not mistaken, the equivalent of --publish not --expose. I do not wish to publish my ports to my host, I just want to expose it so my nginx-proxy container can access it.

Assuming your containers are connected to the same custom network, exposing ports shouldn't be necessary. If you have to use the default bridge for some reason, you can do the following using the low-level API:

import docker

c = docker.from_env()
ctnr_id = c.api.create_container('image', 'command', ports=[2222, (3333, 'udp')], ...)
container = c.containers.get(ctnr_id)

More about the low-level create_container method here.

Hello,

I think there's a subtlety being missed. If I use docker-py to start a container with

import docker

c = docker.from_env()
ctnr_id = c.api.create_container('image', 'command', ports={8080: None}

I can see with docker inspect that it comes across as

            "Ports": {
                "8080/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "32801"
                    }
                ]
            },

However, if I run the container directly with --expose 8080, docker inspect shows

"Ports": {
                "1935/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "1935"
                    }
                ],
                "8080/tcp": null
            },

Additionally, I'm unable to hit the container's ip address on port 8080 with docker-py's setup, but I _am_ able to hit it with the container that used --expose 8080.

I could be missing some critical piece of docker know-how, here, so any help/advice is greatly appreciated. Thanks!

Try this:

import docker
from docker.models.containers import Container
client = docker.from_env()
container: Container = client.containers.run(
    ...
    ports={5432: []},
    ...
)

FYI, I confirmed that the above works to just expose a port. But I also wanted to be able to expose a port and have Docker automatically assign it a port on the host. This is straightforward to do from the docker.py docs:

"None, to assign a random host port. For example, {'2222/tcp': None}"

However, this exposes the port on the host to the world (i.e. '0.0.0.0') and what I actually wanted was for the exposed port to be only localhost accessible. It turns out you can do this with docker.py like this e.g.:

ports={8080:('127.0.0.1',None)}

It isn't clear how you would achieve this with the cli docker command, i.e. 'docker run -P...', but docker.py makes it possible.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mbolivar picture mbolivar  Â·  3Comments

NiklasRosenstein picture NiklasRosenstein  Â·  3Comments

ko-christ picture ko-christ  Â·  3Comments

vickydgm picture vickydgm  Â·  4Comments

MahdiZareie picture MahdiZareie  Â·  3Comments