How to communicate multiple containers with each other in Docker?

Viewed 269

I'm trying to containerize my application. I use mongodb and 2 more micro services. As you can see in the docker compose file below, I have some problems.

My requirements:

  • main_image needs to connect to MongoDB.
  • gui_image needs to connect to MongoDB.
  • gui_image needs to show its GUI on port 8080 (Can use another port as well)
  • gui_image has to read and write to a file inside my computer.
  • MongoDB has to access a volume inside my computer.
  • main_image needs access to the internet.

Here is my questions:

1- Does exposing ports in docker file and docker-compose the same thing?

2- How do I mount a volume to mongodb as best practice?

3- How to accomplish the requirements above with the diagram below in docker-compose?

enter image description here

Here is my docker-compose file:

version: "3"
services:
  mongo:
    image: mongo:latest
    ports:
      - 27017:27017
    
  main_image:
    build: 
      context: .
      dockerfile: .\my_project\dockerfile
    depends_on:
      - mongo
  gui_image:
    build: 
      context: .
      dockerfile: .\my_gui\dockerfile
    ports:
      - 8080:8080
      - 27017:27017
    depends_on:
      - mongo

Here is my dockerfile under my_gui directory:

FROM continuumio/miniconda3
WORKDIR /app
COPY . .
RUN pip install dash
EXPOSE 8080
EXPOSE 27017

ENTRYPOINT [ "python","gui_script.py"]

And lastly, here is my dockerfile under my_project directory:

FROM continuumio/miniconda3
WORKDIR /app
COPY . .
EXPOSE 27017
ENTRYPOINT [ "python","main_script.py"]
1 Answers

1.The EXPOSE instruction in Dockerfile informs Docker that the container listens on the specified network ports at runtime(like when using docker run -p command).

However using ports in compose is a dynamic way of specifying these ports. So images like nginx or apache which are always supposed to run on port 80 inside the container will use EXPOSE in Dockerfile itself.

While an image which has dynamic port which may be controlled using an environment variable will then use expose in docker run or compose file.

some_webapi:

environment:
  - ASPNETCORE_URLS=http://*:80
build:
    context: .
    dockerfile: ./Dockerfile

2.As documented on the docker hub page for mongo image (https://hub.docker.com/_/mongo/) you can use

volumes:
  - '/path/to/your/pc/folder:/path/inside/docker'

3.And for the last question you might wanna use Networking in Compose.

By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

Services can join networks like this

gui_image:
    build: 
      context: .
      dockerfile: .\my_gui\dockerfile
    ports:
      - 8080:8080
      - 27017:27017
    depends_on:
      - mongo
    networks:
      - gui

And also you have to define all the networks used by services in global scope of compose file

version: '3'

services:

networks:
   gui:

After that containers will be able to see each other even by their container_name which you can define in services

   mongo:
     image: mongo:latest
     ports:
       - 27017:27017
     container_name: gui_mogno
     

then you will be able to connect to mongo with a connection string like this mongodb://gui_mogno:27017/

You can get more information about networking here

Related