29

When I use docker with the very simple command:

docker run -p 80:80 nginx

Port forwarding works properly and I can get nginx 'welcome page' when I go to localhost:80 using browser/curl.

At the same time when I use very similar but docker-compose specific config:

version: '3'
services:
  nginx:
    image: nginx
    ports:
     - "80:80"

And when I do docker-compose up and go to the browser - I see infinite loading, so looks like port forwarding is not configured properly, but I can't understand what is wrong in the config. I tried using different browsers and curl, I'm getting the same result - infinite loading.

Nginx here is just an example because of it's simplicity, in fact I have the same issue with redis/mysql/java images, so the issue isn't related to nginx.

I've also tried the following ways to start container via docker-compose:

docker-compose run -p 80:80 nginx

docker-compose run --service-ports nginx

but no luck, I've got the same result.

In both cases (docker run and docker-compose up) I have the same network driver type - bridge.

I've compared results of docker inspect <container id> for both cases: http://i.prntscr.com/obvxi0yESEa92znLDEu_PA.png

And results of docker inspect <network id>: http://i.prntscr.com/yyTpetvJSXa-dz4o9Pcl3w.png

ifconfig docker0 results:

docker0   Link encap:Ethernet  HWaddr 02:42:f1:9a:b6:72  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:f1ff:fe9a:b672/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:174 errors:0 dropped:0 overruns:0 frame:0
          TX packets:837 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:47434 (47.4 KB)  TX bytes:107712 (107.7 KB)

brctl show results:

bridge name     bridge id               STP enabled     interfaces
br-f7adc3956101         8000.02427f870e7f       no
docker0         8000.0242f19ab672       no

ifconfig on the host machine results: https://pastebin.com/6ufWeYTE

route on the host machine results:

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         gateway         0.0.0.0         UG    600    0        0 wlp4s0
link-local      0.0.0.0         255.255.0.0     U     1000   0        0 docker0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.0.0     0.0.0.0         255.255.255.0   U     600    0        0 wlp4s0

Both docker and docker-compose were installed using official sites instructions for Linux.

Host OS: Ubuntu 17.04

UPDATE: I've tried to set 'attachable' network property in compose config and the issue was fixed. Though still unclear why is that happening.

networks:
  default:
  attachable: true
Robert
  • 33,429
  • 8
  • 90
  • 94
XZen
  • 225
  • 5
  • 27
  • 49
  • how do you know port forwarding is not working? like what do you get when you do `docker-compose up` ? – Mike Tung Oct 31 '17 at 20:15
  • I know it's not working because I can't establish connection to a service (nginx/database, whatever), though I see there's an attempt to do so (f.e. browser doesn't return 'connection refused' immediately, but tries to 'load', and very similar situation happens with databases/java etc). At the same time in both cases (docker-compose up and docker run) 'ps' command shows correct mapping: 0.0.0.0:80->80/tcp. – XZen Oct 31 '17 at 20:23
  • Not sure if it matters but I don't use quotes in my docker-compose.yml file: ports: - 80:80 Also, after running docker-compose up -d what is the status of docker ps? The ports are shown as mapped? – Chris Mitchell Oct 31 '17 at 20:33
  • I would also do a `nslookup` to make sure you actually connected – Mike Tung Oct 31 '17 at 21:19
  • Can you provide `docker network ls` output? – Nicolae Oct 31 '17 at 22:57
  • @ChrisMitchell There's the following status: `nginx_1 nginx -g daemon off; Up 0.0.0.0:80->80/tcp` – XZen Nov 01 '17 at 08:22
  • @Nicolae sure: `f7adc3956101 todo_default bridge local` – XZen Nov 01 '17 at 08:25
  • So in both cases (`docker-compose up` and `docker run`) I have the same network driver type - it's `bridge` – XZen Nov 01 '17 at 08:33
  • How about `ifconfig docker0` and `brctl show` ? You will need the `bridge-utils` package on debian based distros for the latter. – Nicolae Nov 01 '17 at 12:58
  • @Nicolae I've added the results to the question, please take a look – XZen Nov 01 '17 at 15:59
  • Thanks, `docker-compose --version` and `docker info` could also help. – Nicolae Nov 01 '17 at 19:14
  • Please also tell us your linux distribution and architecture, how you installed docker and docker-compose, what browser do you try to access the page and on what url. Also give a full `ifconfig`, `brctl show` and `route` output pls, all this while the containers are running. – Nicolae Nov 01 '17 at 19:54
  • Hi @Nicolae I had to reboot my PC for another reason, but the thing is that the issue disappeared after it. That's rather bad than good since I'm in the dark about what had happened with my network config actually .. – XZen Nov 02 '17 at 16:43
  • @Nicolae turned out that it's reproducible even after reboot, I've added additional information you'd asked, please take a look – XZen Nov 05 '17 at 12:34
  • 1
    Is the port being used by some other program? – Innovative Inventor Nov 05 '17 at 21:36
  • It's very strage, i will try to reproduce on the same os, can you please paste the version of `docker --version` and `docker-compose --version`. Also tell us if you have the default docker configuration or something custom, if the latter please show `/etc/docker/daemon.json`. – Nicolae Nov 05 '17 at 21:37
  • @XZen can you show us your "docker network ls" ? Also, try adding network_mode: "bridge" to the service in YAML. – Roman Mik Nov 08 '17 at 22:33
  • @ChrisMitchell "Not sure if it matters but I don't use quotes in my docker-compose.yml file: ports: - 80:80" -> you should be careful, in the YAML norm, integers containing **:** can be considered as sexagesimal: base 60, yes it's dumb. *docker-compose* handles it and you could have a headache before you figure out an issue comes from that – arvymetal Nov 10 '17 at 04:54
  • If you have an answer please write it as one and not as update to the Question, your solution gives error: `services.camelot.networks.attachable contains an invalid type, it should be an object, or a null` – Elia Weiss Dec 01 '20 at 16:29
  • "Starting in Compose file format 2.1, overlay networks are always created as attachable." @EliaWeiss - from the documentation at https://docs.docker.com/compose/networking/ It can be removed. – Zymotik Feb 08 '21 at 10:49
  • 1
    "I'm assuming you're using `docker-compose run` instead of `docker-compose up`? If so, you need `--service-ports` to publish the ports from the service definition." https://github.com/docker/compose/issues/4799#issuecomment-348646755 – Zymotik Feb 08 '21 at 11:12

4 Answers4

18

In my case, I was using docker-compose run without the --service-ports argument, so port mappings were ignored.

Example:

docker-compose.yml

version: "3"

services:
    app-host:
        image: nginx:1.19.0-alpine
        working_dir: /app
        volumes:
            - ./:/app/
        ports:
            - "80:3000"

command

    docker-compose run --service-ports app-host

References: discussion forum docker-compose documentation

Zymotik
  • 6,412
  • 3
  • 39
  • 48
6

The solution for me was to add the line network_mode: 'host'

here is the full file

    version: '3'
    
    services:
      nginx:
        image: nginx
        ports:
          - "80:80"
        volumes: ['./:/app']
        network_mode: 'host'

Note: This solution only works on Linux since network_mode: host is only available to Linux hosts.

The reason this solution works is that network_mode: host causes Docker to ignore the port mappings and allows the service to directly share the network with the host machine, which removes the need for port mapping altogether.

muhashi
  • 7
  • 2
Elia Weiss
  • 8,324
  • 13
  • 70
  • 110
0

I've tried to set 'attachable' network property in compose config and the issue was fixed. Though still unclear why is that happening.

The article "Docker Stacks and Attachable networks" defines an attachable network as a type of swarm overlay network.

That means a service created on that network will allow docker run commands:

docker service create --publish 80:80 --network=core-infra --name 
docker run --network=core-infra -ti ...

Those lines can be specified in a docker-compose.yml file, and the result would be the same: if the network is attachable, the docker run will be able to use it.

Once you've created the container docker network inspect core-infra will show a Subnet for the network and other diagnostic information.

What is strange is that networks should be attachable by default since 2.1, as mentioned in docker-compose issue 4711.

Attachable networks help Docker Swarm Services interoperate with the previous version of orchestration called Swarm.
The core difference between legacy Swarm and Swarm Services is that the legacy offering allowed containers to be scheduled in an imperative manner. Declarative swarm services allow us to define a final state we want to achieve which the swarm will then apply and maintain.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
-1

this is what I ran using docker-compose up and it worked fine.

version: '3'
services:
  nginx:
      image: nginx
      ports:
             - 80:80
Mike Tung
  • 4,735
  • 1
  • 17
  • 24