XZen
XZen

Reputation: 445

Docker compose port forwarding not working properly

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

Upvotes: 31

Views: 37490

Answers (5)

Arham Abeer
Arham Abeer

Reputation: 21

Try using different port.

version: '3'

services:
 nginx:
  image: nginx
  ports:
  - "81:80"

Or try to run your container in detached mode.

docker-compose up -d

Upvotes: 0

Elia Weiss
Elia Weiss

Reputation: 9856

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.

Upvotes: 9

Zymotik
Zymotik

Reputation: 7307

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

Upvotes: 19

VonC
VonC

Reputation: 1323065

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.

Upvotes: 0

Mike Tung
Mike Tung

Reputation: 4821

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

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

Upvotes: -1

Related Questions