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

Created on 6 May 2017  Â·  34Comments  Â·  Source: docker/compose

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.

kinquestion

Most helpful comment

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

All 34 comments

Are you using the --service-ports flag?

@shin-
I'm sorry I meant docker-compose up -d

this probably is a better sample. using the same image and doing the same thing but ports setting under build for port 9999 is not published.

version: '3.1'

services:
  nginx_build:
    build:
      context: "."
    ports:
      - "9999:80"
    network_mode: 'host'
  nginx_image:
    image: 'nginx'
    volumes:
      - .nginx.conf:/etc/nginx.conf
    ports:
      - "19999:80"
===
$ docker-compose ps
      Name                Command          State           Ports
------------------------------------------------------------------------
tmp_nginx_build_1   nginx -g daemon off;   Up
tmp_nginx_image_1   nginx -g daemon off;   Up      0.0.0.0:19999->80/tcp
$ netstat -lna |grep 9999
tcp6       0      0  ::1.19999                                     *.*                                           LISTEN
tcp4       0      0  *.19999                *.*                    LISTEN

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

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

AH!! great catch. totally missed it even when I created this test files.
Thank you so much!

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

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
````

@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)

@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 ?

@gaillota oh I see, port should be mapped as HOST:CONTAINER so you need to swap position of 3000/80 port numbers in your compose file.

never mind... your file seems right..

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?

docker-compose version?

docker version

Client:
 Version:      17.09.0-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:40:09 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.09.0-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:45:38 2017
 OS/Arch:      linux/amd64
 Experimental: true

docker-compose version

docker-compose version 1.16.1, build 6d1ac21
docker-py version: 2.5.1
CPython version: 2.7.12
OpenSSL version: OpenSSL 1.0.2j  26 Sep 2016

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

What's the error?

2018-02-27 6:36 GMT-06:00 Jáchym Toušek notifications@github.com:

I'm experiencing the same problem even when using docker-compose up. Any
ideas how to solve it?

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/docker/compose/issues/4799#issuecomment-368859793,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AIaBKnXIPaz39XZS3ba5YZ8QRn9LAm7Zks5tY_bigaJpZM4NSip0
.

--
Alberto Manuel Rojas Mendez

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.

Hi! I am having same issues: I want to send RPC commands using curl from the docker command line to the containers but it returns a timeout error.
Note: I created a test network for nano (a.k.a raiblocks) using docker-compose, I followed these instructions for Ubuntu 16.04 (I created a container from ubuntu image), changed the cmake environment variables following these instructions for the CMake variables and for testing RaiBlocks (see bottom of the page) then committed those changes to a new image "ubuntu" with tag "nano_test_2".

Here is my docker-compose.yml:

version: "2"
services:

  peer1:
    image: ubuntu:nano_test_2
    volumes:
      - /root:/root/nano_test
    ports:
      - "1001:7075/udp"
      - "1002:7076"
      - "54000"
    networks:
      vpcbr:
        ipv4_address: 172.20.0.1
    command: bash -c  "cd /root/rai_build && ./rai_node --daemon"

  peer2:
    image: ubuntu:nano_test_2
    volumes:
      - /root:/root/nano_test
    ports:
      - "1003:7075/udp"
      - "1004:7076"
      - "54000"
    networks:
      vpcbr:
        ipv4_address: 172.20.0.2
    command: bash -c  "cd /root/rai_build && ./rai_node --daemon"

  peer3:
    image: ubuntu:nano_test_2
    volumes:
      - /root:/root/nano_test
    ports:
      - "1005:7075/udp"
      - "1006:7076"
      - "54000"
    networks:
      vpcbr:
        ipv4_address: 172.20.0.3
    command: bash -c  "cd /root/rai_build && ./rai_node --daemon"

networks:
  vpcbr:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
          gateway: 172.20.0.21

docker-compose version:

docker-compose 
version 1.20.1, build 5d8c71b
docker-py version: 3.1.4
CPython version: 3.6.4
OpenSSL version: OpenSSL 1.0.1t  3 May 2016

I execute docker-compose up and have the nodes running (although sometimes for some reason, one or two of them (never all) stop working, I get them to start running again docker-compose start peer2 and I don't lose anything in the db).
Can anyone help me please?

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

@robert197 Thanks for that! I was really confused why my docker container wasn't working. Do you know how to get docker to use localhost instead of defaulting to address when running docker-machine inspect default | grep IPAddress?

@KevinKelbie I think you can achieve that by using Docker Desktop on Mac instead of Docker Machine: https://docs.docker.com/docker-for-mac/docker-toolbox/

I'm going to post this here in case anyone else ran into the same issue I did.

I discovered that if you use a dockerfile that functions like a builder script (containing the AS after from) like this example:

FROM node as frontend
WORKDIR /src
COPY ["package.json", "package.json"]
RUN  yarn install
COPY [".", "."]
CMD [ "cd src && yarn serve" ]

Docker Compose will not expose the ports properly, or name the container after the service either.
I wasted a lot of time trying to figure out what was wrong, as soon as I removed the "as frontend" everything worked perfectly.

I ran into this issue because I just started learning docker compose and I copied some code from another builder script I made... not catching the fact I forgot to remove the stage.

I am facing the same problem my docker-compose is not exposing ports.
```version: "3.7"

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 isdocker-compose up -d --build`
Can any one help me?
Thank You

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

@kmursk That was it for me, thanks :tada:

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

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

https://github.com/docker/compose/issues/4799#issuecomment-608142032
Checked your case with docker desktop for Win and docker for linux - it works with some changes

version: "3"
services:
  node_backend:
    container_name: "node_backend"
#    build: ./node_backend/  _Here's some script, which i can't explore, therefore i have used ready webapp image._
    image: tomee:11-jre-8.0.1-plus
    ports:
      - "3001:8080"

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

Start and look at container's status. It should be something like that:

> docker ps -a        
IMAGE                     STATUS              PORTS                    NAMES
tomee:11-jre-8.0.1-plus   Up 3 seconds        0.0.0.0:3001->8080/tcp   node_backend
postgres:12               Up 3 seconds        0.0.0.0:5432->5432/tcp   postgres

So i assume there can be 2 kind of troubles:

  1. webapp has not been started or does not listen port 3001.
  2. you had not supplied postgres with password. It's a mandatory variable for this image. Also verify that folder _./pg/db_data_ exists where docker-compose is launching.

Thanks for the quick reply @kmursk, i have an express-app that listen on port 3001, and the console show "running on port 3001" in the container
dockerfile of the node container
```FROM node:12
WORKDIR /usr/src/app/
COPY package*.json ./
COPY tslint.json ./
COPY tsconfig.json ./
RUN npm install
ADD src/ ./src
RUN npm start

EXPOSE 3001
CMD [ "node" , "dist/index.js" ]

And even with  that changes postgres container doesn't run. But if i run it alone it works. This stuff are very confusing !
```version: "3"
services:
  node_backend:
    container_name: "node_backend"
    build: ./node_backend/
    ports:
      - "3001:3001"

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

the command that i use docker-compose up

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.

Are you using the --service-ports flag?

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

@gooney47 was right

use

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

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

The problem in my case was that I had specified a port on the host which was already in use by another process. I had the following port configuration:

      - "20001:9001"
      - "20022:22"
      - "20080:80"
      - "20800:8000"

There was a process listening on 20080 (PhpStorm's zend debugger broadcast settings listener) on the host. As far as I remember docker-compose used to complain when starting services having published ports which are already in use. Output of docker-compose --version:

docker-compose version 1.26.2, build eefe0d31

What's even weirder is that port 20022 does get published but the other free ports 20001 and 20800 do not. If I close PhpStorm or comment out the 20080 port all ports are published successfully.

Was this page helpful?
0 / 5 - 0 ratings