-1

In one container there Django app running which expose to host port 8000 and another container flask app is running which expose to the host port 8001. So there is a condition where the flask app API end needs to communicate with the Django app API end.

Code

req = requests.get('http://192.168.43.66:8000/api/some')

Error

requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.43.66', port=8000): Max retries exceeded with url: /api/user (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fc6f96942e0>: Failed to establish a new connection: [Errno 110] Connection timed out'))

But if I change the request URL to some other API end which not running on the container it gets the response.

And each Django API end is working fine if I want to access it through some other external source like postman or browser.

Here is the docker-compose file content

Django App docker-compose.yml

version: '3.8'
services:
   backend:
      build:
         context: .
         dockerfile: Dockerfile
      command: python3 manage.py runserver 0.0.0.0:8000
      ports:
         - 8000:8000
     volumes:
        - .:/app
     depends_on: 
        - db
  db:
    image: mysql:5.7.22
    restart: always
    environment: 
       MYSQL_DATABASE: admin
       MYSQL_USER: root
       MYSQL_PASSWORD: root 
       MYSQL_ROOT_PASSWORD: root
   volumes:
      - .dbdata:/var/lib/mysql
   ports:
     - 33066:3306 

flask app docker-compose.yml

version: '3.8'
services:
  backend:
    build:
      context: .
      dockerfile: Dockerfile
      network: 'host'
    command: 'python3 main.py'
    ports:
      - 8001:5000
    volumes:
      - .:/app
    depends_on: 
      - db
  db:
    image: mysql:5.7.22
    restart: always
    environment:
      MYSQL_ROOT_HOST: '%'
      MYSQL_DATABASE: main
      MYSQL_USER: root
      MYSQL_PASSWORD: root 
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - .dbdata:/var/lib/mysql
    ports:
      - 33067:3306

Note: in the project YAML is well formatted so that's not an error.

Krishna Kamal
  • 751
  • 2
  • 10
  • 21

1 Answers1

2

when you expose a port from container, the host can access it but it doesn't mean other containers can access it too.

you either have to set the network mode to host (which won't work on windows, this is only possible if you're running them on linux).

OR you can run it in a docker-compose and define your own network, here is an example:

version : '3.4'

services:
 UI:
  container_name: django_app
  image: django_image
  networks:
   my_net:
    ipv4_address: 172.26.1.1
  ports:
   - "8080:8000"
 api:
  container_name: flask_app
  image: flask_image
  networks:
   my_net:
    ipv4_address: 172.26.1.2

networks:
 my_net:
  ipam:
   driver: default
   config:
    - subnet: 172.26.0.0/16

now your django app can access your flask app on 172.26.1.2

EDIT :

now that you have added your docker-compose files too, you should not create apps in two different docker-compose (that's why you were getting the conflicting ip range error, you were building two networks with same range). place everything in a single docker-compose, give them ip addresses and you should be fine. you could make your apps to read ip address of services they relate on from environment variables and then pass these env variables to your container for more flexibility.

aSaffary
  • 793
  • 9
  • 22
  • now it's giving this error `ERROR: Pool overlaps with other one on this address space` – Krishna Kamal May 06 '21 at 09:14
  • @krishnaKamal either you have another network with same mask defined in your system or it's just docker being silly, try "docker network prune" to clear any other network docker might have held in the background. – aSaffary May 06 '21 at 15:38
  • You don't need to specify the ip address for each container. Within each container just reference the other container by using the SERVICE name. For example, if you want to communicate from "django_app" container to "flask_app" container the URL to use will be `http://api` and append whatever port it is listening to INSIDE the container. Notice that I am using the name of the service "api" and not the container name. – Antebios May 07 '21 at 17:57
  • @Antebios that's something that should work, but i personally had problems with getting it to work after a couple of days of struggling. this docker-compose template is how i test my service based applications before creating their helm charts and it's been quite reliable so far – aSaffary May 07 '21 at 18:05
  • @aSaffary Whatever works for development, but I hope you aren't depending on IP addresses in k8s. – Antebios May 07 '21 at 18:10
  • @Antebios no they take address as env variables, when running on k8s they read internal dns address from configmap – aSaffary May 07 '21 at 18:16
  • when I am doing this `requests.get('http://admin_backend:8000/api/user')` `http://admin_backend:8000/api/user django API end error requests.exceptions.ConnectionError: HTTPConnectionPool(host='admin_backend', port=8000): Max retries exceeded with url: /api/user (Caused by NewConnectionError(': Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')) ` – Krishna Kamal May 08 '21 at 07:18
  • @KrishnaKamal see my edited answer, you should not place apps in different compose files. – aSaffary May 08 '21 at 08:23