Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
akadoya opened this issue May 6, 2017 · 39 comments
Closed

Comments

@akadoya
Copy link

akadoya commented May 6, 2017

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.

@shin-
Copy link

shin- commented May 6, 2017

Are you using the --service-ports flag?

@akadoya akadoya changed the title docker-compose run -d doesn't expose ports when defined with build directive docker-compose up -d doesn't expose ports when defined with build directive May 6, 2017
@akadoya
Copy link
Author

akadoya commented May 6, 2017

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

@akadoya
Copy link
Author

akadoya commented May 6, 2017

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

@akadoya
Copy link
Author

akadoya commented May 6, 2017

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

@shin-
Copy link

shin- commented May 6, 2017

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

@akadoya
Copy link
Author

akadoya commented May 6, 2017

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

@akadoya akadoya closed this as completed May 6, 2017
@b4dnewz
Copy link

b4dnewz commented Oct 17, 2017

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

@gaillota
Copy link

gaillota commented Nov 13, 2017

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

@akadoya
Copy link
Author

akadoya commented Nov 15, 2017

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

@gaillota
Copy link

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

@akadoya
Copy link
Author

akadoya commented Nov 16, 2017

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

@akadoya
Copy link
Author

akadoya commented Nov 16, 2017

never mind... your file seems right..

@albertorm95
Copy link

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?

@shin-
Copy link

shin- commented Dec 1, 2017

docker-compose version?

@albertorm95
Copy link

albertorm95 commented Dec 1, 2017

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

@shin-
Copy link

shin- commented Dec 2, 2017

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

@albertorm95
Copy link

albertorm95 commented Feb 27, 2018 via email

jgentes added a commit to jgentes/docker.github.io that referenced this issue Apr 13, 2018
joaofnfernandes pushed a commit to docker/docs that referenced this issue Apr 16, 2018
john-coleman added a commit to john-coleman/nakadi that referenced this issue May 24, 2018
john-coleman added a commit to john-coleman/nakadi that referenced this issue May 24, 2018
@sureshamk
Copy link

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.

@LotfiKobrosly
Copy link

LotfiKobrosly commented Aug 6, 2018

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?

@robert197
Copy link

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

@Kelbie
Copy link

Kelbie commented Mar 18, 2019

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

@mattnedrich
Copy link

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

@Nonary
Copy link

Nonary commented Dec 27, 2019

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.

@chinmayj817
Copy link

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

@kmursk
Copy link

kmursk commented Jan 30, 2020

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

@khskarl
Copy link

khskarl commented Apr 1, 2020

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

@sepiropht
Copy link

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

@kmursk
Copy link

kmursk commented Apr 3, 2020

#4799 (comment)
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.

@sepiropht
Copy link

sepiropht commented Apr 3, 2020

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

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 !

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

@gooney47
Copy link

gooney47 commented May 4, 2020

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.

@bluebrown
Copy link

bluebrown commented May 16, 2020

Are you using the --service-ports flag?

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

@INF800
Copy link

INF800 commented Jun 13, 2020

@gooney47 was right

use

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

@harleylang
Copy link

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

@savemetenminutes
Copy link

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.

ggogel added a commit to ggogel/seafile-containerized that referenced this issue Feb 3, 2021
@EmilAlipiev
Copy link

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.

so what is the solution here? was it displaying 127.0.0.1 when you type docker ps? for me it display 0.0.0.0:1433

@bruno-silva5
Copy link

In my case (Ubuntu 20.04 LTS), I just stopped apache2 service that was using "*:80" ports, and in my container I needed "80:8080" port.

To see the ports being used:

sudo lsof -i -P -n | grep LISTEN

After running service apache2 stop I could execute docker-compose up successfully

@gooney47
Copy link

gooney47 commented Jul 2, 2021

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.

so what is the solution here? was it displaying 127.0.0.1 when you type docker ps? for me it display 0.0.0.0:1433

For me it showed 0.0.0.0:16580->16580/tcp when it worked, I'm not sure what it showed before, I would guess 127.0.0.1. As your host IP is 0.0.0.0, I don't think this is your problem.

@cacois
Copy link

cacois commented Aug 14, 2021

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

@themataleao
Copy link

themataleao commented Mar 29, 2022

Define in your docker-compose the correct CMD for uvicorn:

FROM python:3.9
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY . /code/
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

and in your docker-compose fit it to the correct port:

version: "3.9"
services:
  backend:
    build: .
    ports:
      - "8000:8000"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests