Reputation: 11281
I can't seem to work out a way to get port publishing to work with docker-compose run
in the same way as I can with docker run
.
Using Docker Compose (and therefore the port mapping in docker-compose.yml
) gives a "Failed to connect" error from curl
:
$ docker-compose run flask
* Running on http://0.0.0.0:2048/ (Press CTRL+C to quit)
$ curl http://localhost:2048/
curl: (7) Failed connect to localhost:2048; Connection refused
However, things are fine when manually passing the ports to docker run
:
$ docker run -p 2048:2048 --name flask -t flask_image
* Running on http://0.0.0.0:2048/ (Press CTRL+C to quit)
$ curl http://localhost:2048
Hello World!
What am I missing?
Dockerfile
FROM centos:7
# Install EPEL repo.
RUN rpm -iUvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
# Install Python and Pip.
RUN yum -y update && yum -y install \
python \
python-pip
# Flask is necessary to run the app.
RUN pip install flask
EXPOSE 2048
ADD hello_world_flask_app.py /src/hello_world_flask_app.py
CMD ["python", "/src/hello_world_flask_app.py"]
hello_world_flask_app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=2048)
docker-compose.yml
version: '2'
services:
flask:
build: .
ports:
- "2048:2048"
Upvotes: 49
Views: 101078
Reputation: 28987
By default, docker-compose run
does not publish the service's ports. You can either pass the --service-ports
option to publish the ports as they are defined in the docker-compose.yml, or use the -P
option to publish all ports.
See the documentation for docker-compose run
Upvotes: 53
Reputation: 882
Tried with --service-ports
(it doesn't work with up
command and we should somehow stop
and run
it again) also it doesn't change this behavior, ports are exposed but can't curl
and unreachable for mentioned reasons from 127.0.0.1
This is due to fact that you are using docker-compose 2 syntax.
By default it creates an internal network ( or overlay network in some cases) between each compose project containers.
You can use docker inspect <container_name>
to get container network status.
Also using netstat
It gives a strange behavior from docker which seems only listens on tcp6
interfaces :
$ sudo netstat -lt|grep 2048
tcp6 0 0 [::]:2048 [::]:* LISTEN 501/docker
C:\Users\pooya>curl host:2048
Hello World!
ports
Section :$ cat docker-compose.yml
version: '2'
services:
flask:
build: .
ports:
- "127.0.0.1:2048:2048"
And you can simply curl using curl localhost:2048
** This method doesn't works anymore on newer docker versions **
It seems the root problem is from docker bridge method. docker uses iptables
to nat INCOMING connections to the correct container's port
$ sudo iptables -L|grep 2048
ACCEPT tcp -- anywhere 10.0.0.12 tcp dpt:2048
As you can see it only dport
s incoming connections to 10.0.0.12:2048
Strange ! but to just correctly listens to 0.0.0.0
and everything is fine :)
$ docker run -it -d -p 2048:2048 test
$ netstat -ltn|grep 2048
tcp 0 0 0.0.0.0:2048 0.0.0.0:* LISTEN
Upvotes: 28