compose: docker-compose up -d doesn't expose ports when defined with build directive

docker-compose up -d is supposed to expose the ports and supposedly be able to publish the ports according to the yml, however, it is not working for the services build from build: configuration.

docker-compose.yml

version: '3.1'

services:
  nginx:
    build:
      context: "."
    ports:
      - "9999:80"
    network_mode: 'host'
  service_cassandra:
    image: 'cassandra:3.0'
    ports:
      - "19042:9042"

Dockerfile for nginx

FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

These files above end up like this:

$ docker-compose up -d --build
Building nginx
Step 1/4 : FROM nginx
 ---> 46102226f2fd
Step 2/4 : COPY nginx.conf /etc/nginx/nginx.conf
 ---> Using cache
 ---> f36baa7f9388
Step 3/4 : EXPOSE 80
 ---> Running in 8b4a5621a0b3
 ---> 75fbceea828b
Removing intermediate container 8b4a5621a0b3
Step 4/4 : CMD nginx -g daemon off;
 ---> Running in 50f1efaf665d
 ---> e1cd7d703925
Removing intermediate container 50f1efaf665d
Successfully built e1cd7d703925
Successfully tagged tmp_nginx:latest
Recreating tmp_nginx_1
tmp_service_cassandra_1 is up-to-date
$ docker-compose ps
         Name                        Command               State                                Ports
----------------------------------------------------------------------------------------------------------------------------------
tmp_nginx_1               nginx -g daemon off;             Up
tmp_service_cassandra_1   /docker-entrypoint.sh cass ...   Up      7000/tcp, 7001/tcp, 7199/tcp, 0.0.0.0:19042->9042/tcp, 9160/tcp
$ netstat -lna |grep 19042
tcp6       0      0  ::1.19042                                     *.*                                           LISTEN
tcp4       0      0  *.19042                *.*                    LISTEN
$ netstat -lna |grep 9999
(no result)

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                                        NAMES
43d7167e3671        tmp_nginx           "nginx -g 'daemon ..."   About a minute ago   Up About a minute                                                                tmp_nginx_1
a49374c38de3        cassandra:3.0       "/docker-entrypoin..."   6 minutes ago        Up 6 minutes        7000-7001/tcp, 7199/tcp, 9160/tcp, 0.0.0.0:19042->9042/tcp   tmp_service_cassandra_1

so…ports configuration seems working for containers that is built from image pull, but not for containers built from a local dockerfile.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 11
  • Comments: 39

Commits related to this issue

Most upvoted comments

oh, you didn’t specify, but I’m assuming you’re using run instead of up? If so, you need --service-ports to publish the ports from the service definition. See our docs

For me the problem was that my service, that I was running in the docker container, was hosted on 127.0.0.1 instead of 0.0.0.0 which makes the service inaccessible from the host system even if the port is published.

Port mapping is incompatible with network_mode: host:

The host network adds a container on the host’s network stack. As far as the network is concerned, there is no isolation between the host machine and the container. For instance, if you run a container that runs a web server on port 80 using host networking, the web server is available on port 80 of the host machine.

https://docs.docker.com/engine/userguide/networking/#default-networks

I’m having the same issue, and I’m not using the network_mode: host

// Dockerfile
EXPOSE 3000

// docker-compose.yml
ports:
  - "80:3000"

$ docker-compose run --rm web yarn run dev
$ docker-compose ps
     Name                   Command             State            Ports
---------------------------------------------------------------------------
ddjtb_web_run_1           yarn run dev            Up            3000/tcp

Are you using the --service-ports flag?

so what was the solution exactly? I’m having the same problem and can’t manage to make it working yet

try running docker-machine inspect default | grep IPAddress and then use this address instead of localhost.

I’ve found that docker-compose doesn’t do port mapping if custom nework only is used. For example,

ports:
  - "8080:8080"
networks:
 some_my_network_name:
  internal: true
  driver: nat
services:
 some_my_service_name
  networks: 
   some_my_network_name:
    aliases:
     - some_my_alias

This service is unavailable from the host machine. But add network used by all containers, started with docker run, and port 8080 will be mapped. I use docker-compose version 1.25.2 for windows and this network is named default, though there’s no network with such name in docker network ls. I’ve found it with inspect to typical (i mean started by docker run) container. So make such change

services:
 some_my_service_name
  networks: 
   some_my_network_name:
    aliases:
     - some_my_alias
   default:

Then docker ps looks better STATUS PORTS NAMES Up 14 seconds 0.0.0.0:8080->8080/tcp some_my_service_name

I am facing the same problem my docker-compose is not exposing ports.


services:
  web:
    build: ./src
    command: uvicorn app.main:app --reload --workers 1 --host 0.0.0.0 --port 8000
    volumes:
      - ./src/:/usr/src/app/
    ports:
      - 8002:8000

The command I am using is docker-compose up -d --build Can any one help me? Thank You

@gooney47 if I could give you more emojis I would, thank you!!!

NOTE : The host networking driver only works on Linux hosts, and is not supported on Docker for Mac, Docker for Windows, or Docker EE for Windows Server.

@kmursk That was it for me, thanks 🎉

Shouldn’t docker at least print a WARNING: whenever it ignores a field? Implicit behaviors are rather time consuming to hunt down.

@gooney47 was right

use

docker-compose run -p 8002:8002  web python -m uvicorn main:app --reload --host "0.0.0.0" --port 8002

@akadoya Thank you for you quick answer and sorry if my issue was not clear enough. My problem is pretty simple, I have the configuration above in my Dockerfile and docker-compose.yml which basically map the port 80 of my host machine to the port 3000 of my container. But when I run docker-compose run ..., the mapping is not set between the two ports, and I cannot access my app through port 80 ?

For the love of code everyone read the answer by @gooney47. Hours wasted…

@b4dnewz you cannot use port-mapping when using host network_mode because it’s designed to expose all ports as written in Dockerfile. (see details in the link @shin- mentioned above) = use other network mode.

@gaillota not sure about your issue but I suspect that it was run by a regular user? (port 80 needs system admins’ privilege to open)

tried with run --service-ports but no luck.

$ docker-compose run -d --service-ports nginx_build
tmp_nginx_build_run_1
$ docker-compose ps
        Name                  Command          State   Ports
------------------------------------------------------------
tmp_nginx_build_run_1   nginx -g daemon off;   Up

Are you using the --service-ports flag?

This flag is invalid on compose up. You can only use it on compose run.

version: "3"
services:
  node_backend:
    container_name: "node_backend"
    build: ./node_backend/
    ports:
      - "3001:3001"

  pg:
    image: "postgres:12"
    container_name: "postgres"
    ports:
      - "5432:5432"
    volumes:
      - ./pg/db_data:/var/lib/postgresql/data

the port 3001 is not exposed, why ? And the command docker-compose up only start the node container not the postgresl container

I’m having a problem with the ports on the .yml file it seems to be not working, or maybe I’m doing something wrong.

Dockerfile

FROM node:8.9.1-alpine

USER node
RUN mkdir /home/node/.npm-global
ENV PATH=/home/node/.npm-global/bin:$PATH
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
RUN npm install -g @angular/cli

USER root
RUN npm install -g nodemon

docker-compose.yml

version: "3.2"

services:

  backend:
    build:
      context: .
      dockerfile: dev.Dockerfile
    volumes:
      - ".:/app"
    working_dir: "/app"
    ports:
      - "1234:443"
    command: "nodemon app.docker.js"

And when I inspect the container the Network output is the following:

"NetworkSettings": {
            "Bridge": "",
            "SandboxID": "68d492e7bf09dc7f8a625162f62f812cf56950391d2f7455359ee472257e4f94",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "443/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/68d492e7bf09",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "79456da25fb3baecc07105c704f15dd0122902107636dbd41fdefa8721f61e0f",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "8a0fb429170e347ffbc26afe7ac48d1c45e6eb77ddc02e4f595b0fc72855b2e4",
                    "EndpointID": "79456da25fb3baecc07105c704f15dd0122902107636dbd41fdefa8721f61e0f",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }

The only work around for this is running: docker-compose run -p 1234:443 backend

With that I got:

"NetworkSettings": {
            "Bridge": "",
            "SandboxID": "5a877c24a3f3487af570b09ca352804fccf459a5b677c62f573ba470944b60ea",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "443/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "1234"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/5a877c24a3f3",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "ecfgcloudapp_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "e919a70179d7"
                    ],
                    "NetworkID": "93325bd6ac1e86c9ed61c3f03eb6ccc6a13927322ff6c8337de96395c6bec941",
                    "EndpointID": "a3b8ad12664ded6e8e0c7b1f725b045b63c18c4c9544fba48c6c4d460a51cfb0",
                    "Gateway": "172.19.0.1",
                    "IPAddress": "172.19.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:13:00:02",
                    "DriverOpts": null
                }
            }
        }

Any idea?