How to expose a container port outside of docker/container using docker-compose?
Asked Answered
G

2

9

I have a container that it has several ports, I want to have access to one of its ports (9001) outside of this docker as remote.

  • My docker IP is: 172.17.0.1
  • My container IP is: 172.19.0.23
  • My server IP is: 192.168.1.131

I have searched about that and I found expose port keyword, and I did it but not worked.

How to expose docker ports to make your containers externally accessible
Reference


This is my docker-compose file:

version: '3'

services:
  nginx:
      image: nginx:latest
      container_name: nginx
      ports:
        - "8010:8010"

      volumes:
        - .:/code
        - ./nginx/default.conf:/etc/nginx/conf.d/default.conf

      links:
        - ivms

      restart: unless-stopped

  ivms:
      build: .
      container_name: ivms
      command: bash bashes/createDB.sh
      volumes:
        - .:/code
      expose:
        - "8010"
        - "9001"  # exposed disired port
      ports:
        - "9001:9001"

I run above docker-compose file with: $ docker-compose up -d

  • But when I using server_IP:9001 --> 192.168.1.131:9001 or docker_IP:9001 --> 172.17.0.1:9001 can not access to that (in remote or local mode)
  • But when using container_IP:9001 --> 172.19.0.23:9001 this works in local.

What should I do that I can access to server_IP:9001 --> 192.168.1.131:9001?


[NOTE]:

  • In createDB.sh runs several operations such as creating a ZMQ on 9001 port.

  • I have been set the port allowing before, using $ ufw allow 9001

  • I tried on Ubuntu 16.04 and Ubuntu-Server 16.04

Any help would be appreciated.

Garfish answered 10/7, 2018 at 8:4 Comment(13)
Have you tried with ports: instead expose:?Usually
@mulg0r Yes, I tried with port: - "9001:9001" or using 9002 instead of 9001 using port: - "9002:9001" bot not worked.Garfish
Try with ports, not portUsually
yes, did it. I mean was portsGarfish
Try with network_mode: host in docker compose servicesUsually
I encountered with this error: Cannot create container for service ivms: Conflicting options: host type networking can't be used with links. This would result in undefined behavior ERROR: Encountered errors while bringing up the project.Garfish
What you're doing is definitely correct - it's not a matter of Docker/DockerCompose syntax. Where are you trying to access the IP from? The same machine, or a remote one? Also what OS are you running?Arana
@Arana The same machine.Garfish
And what OS are you running?Arana
@Arana I tried on ubuntu 16.04 and ubuntu-server 16.04Garfish
@BenyaminJafari Can you also add the content of bashes/createDB.sh to the OP?Arana
@Arana question updated temporarily.Garfish
Let us continue this discussion in chat.Garfish
G
1

Problem resolved with below instruction:

In ZMQ app (in ivms container) I had used from the server IP to binding a connection as follow:

import zmq

if __name__ == '__main__':
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.setsockopt(zmq.SUBSCRIBE, "")
    socket.bind("tcp://192.168.1.131:9001")  # doesn't work with server or docker IP

    while True:
        data = socket.recv_json()

It was working only as below:

socket.bind("tcp://192.168.1.131:9001")  # works, but can't access as remote

Now I edited this line as the follows:

socket.bind("tcp://*:9001")  # Works both locally and remotely.

And this is my docker-compose.yml configuration:

version: '3'

services:
  nginx:
      image: nginx:latest
      container_name: nginx
      ports:
        - "8010:8010"

      volumes:
        - .:/code
        - ./nginx/default.conf:/etc/nginx/conf.d/default.conf

      links:
        - ivms

      restart: unless-stopped

  ivms:
      build: .
      container_name: ivms
      command: bash bashes/createDB.sh
      volumes:
        - .:/code
      expose:
        - "8010"
      ports:
        - "9001:9001"
Garfish answered 17/7, 2018 at 21:4 Comment(0)
G
4

If you want to actually map the port you should use

ivms:
  build: .
  container_name: ivms
  command: bash bashes/createDB.sh
  volumes:
    - .:/code
  ports:
    - "8010:8010"
    - "9001:9001"  # now you can access them locally

warning you are using the same port for these two services ivms and nginx

The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on TCP or UDP, and the default is TCP if the protocol is not specified.

The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. -Docker Docs

Gastronome answered 10/7, 2018 at 9:41 Comment(7)
I tried it already, but not worked, you can see in my questionGarfish
do you mean of nginx port is 8010?Garfish
You should remove the expose: part and just leave the ports: , but what I am not sure is why do you map nginx port 8010 and ivms also?Gastronome
I did it, I remove expose and kept only ports, but not any changes. and about nginx, ivms app running a Django app on 8010 port and nginx get it, don't worry about nginX it works.Garfish
Is your container running? what can you see in the logs? can you docker exec into it?Gastronome
Yes is run, and I can exec to ivms container. There isn't a specific logs about that. I think my question is relevant to docker-compose file expose or port or OS port mapping.Garfish
under the ivms remove de expose and leave the ports like "... - 9001:9001", change the command to command: python -m SimpleHTTPServer 9001. run docker-compose up and see if it appears something under localhost:9001 meaning your server IPGastronome
G
1

Problem resolved with below instruction:

In ZMQ app (in ivms container) I had used from the server IP to binding a connection as follow:

import zmq

if __name__ == '__main__':
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.setsockopt(zmq.SUBSCRIBE, "")
    socket.bind("tcp://192.168.1.131:9001")  # doesn't work with server or docker IP

    while True:
        data = socket.recv_json()

It was working only as below:

socket.bind("tcp://192.168.1.131:9001")  # works, but can't access as remote

Now I edited this line as the follows:

socket.bind("tcp://*:9001")  # Works both locally and remotely.

And this is my docker-compose.yml configuration:

version: '3'

services:
  nginx:
      image: nginx:latest
      container_name: nginx
      ports:
        - "8010:8010"

      volumes:
        - .:/code
        - ./nginx/default.conf:/etc/nginx/conf.d/default.conf

      links:
        - ivms

      restart: unless-stopped

  ivms:
      build: .
      container_name: ivms
      command: bash bashes/createDB.sh
      volumes:
        - .:/code
      expose:
        - "8010"
      ports:
        - "9001:9001"
Garfish answered 17/7, 2018 at 21:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.