2

I am using docker-compose to create a multi-container environment where I have one mongodb instance and two python applications. The problem is, the first application is able to establish a connection to mongodb whereas the second application fails with the following error:

File "/usr/local/lib/python2.7/site-packages/pymongo/mongo_client.py", 
            line 377, in __init__ notification_1   | 
            raise ConnectionFailure(str(e)) notification_1   | 
            pymongo.errors.ConnectionFailure: [Errno -2] Name or service not known

My project structure:

.
├── docker-compose.yml
├── form
│   ├── app.py
│   ├── Dockerfile
│   ├── requirements.txt
│   ├── static
│   └── templates
│       ├── form_action.html
│       └── form_sumbit.html
├── notify
│   ├── app.py
│   ├── Dockerfile
│   ├── requirements.txt
└── README

Here is my [updated] docker-compose.yml file:

version: '3'

services:
  db:
    image: mongo:3.0.2
    container_name: mongo
    networks:
      db_net:
        ipv4_address: 172.16.1.1


  web:
    build: form
    command: python -u app.py
    ports:
      - "5000:5000"
    volumes:
      - form:/form
    environment:
      MONGODB_HOST: 172.16.1.1
    networks:
      db_net:
        ipv4_address: 172.16.1.2

  notification:
    build: notify
    command: python -u app.py
    volumes:
      - notify:/notify
    environment:
      MONGODB_HOST: 172.16.1.1
    networks:
      db_net:
        ipv4_address: 172.16.1.3

networks:
  db_net:
    external: true

volumes:
  form:   
  notify:

The first application is based on Flask and uses mongokit to connect to the database. Here is the code to establish the connection:

MONGODB_HOST = os.environ['DB_PORT_27017_TCP_ADDR']
MONGODB_PORT = 27017

app = Flask(__name__)
app.config.from_object(__name__)

# connect to the database
try:
    connection = Connection(app.config['MONGODB_HOST'], app.config['MONGODB_PORT'])
except ConnectionFailure:
    print("Connection to db failed. Start MongoDB instance.")
    sys.exit(1)

The second app is a simple python application. The code for conection is as follows:

MONGODB_HOST = os.environ['DB_PORT_27017_TCP_ADDR']
MONGODB_PORT = 27017
connection = Connection(MONGODB_HOST, MONGODB_PORT)
5
  • 2
    Possible race condition. Are you booting up one system before the database is ready? Commented Apr 15, 2017 at 16:49
  • 1
    I wouldn't use the environment variable. Just use MONGODB_HOST="db" But that's presumably not the issue. Commented Apr 15, 2017 at 16:57
  • Yes, you are right. Tried it doesn't work. Commented Apr 15, 2017 at 17:17
  • Can you post how you created the db_net network please? Commented Apr 23, 2017 at 18:51
  • docker network create db_net --subnet 172.16.0.0/16 Commented Apr 29, 2017 at 5:20

2 Answers 2

5

Is there a reason why you're explicitly specifying IP addresses for all the services, plus the container name for the db service? I'd suggest dropping them and using the service names to connect between containers on the same network.

version: '3'

services:
  db:
    image: mongo:3.0.2
    networks:
      - db_net

  web:
    build: form
    command: python -u app.py
    ports:
      - "5000:5000"
    volumes:
      - form:/form
    environment:
      MONGODB_HOST: db
    networks:
      - db_net

  notification:
    build: notify
    command: python -u app.py
    volumes:
      - notify:/notify
    environment:
      MONGODB_HOST: db
    networks:
      - db_net

networks:
  db_net:

volumes:
  form:   
  notify:
Sign up to request clarification or add additional context in comments.

1 Comment

This follows better docker conventions, and is more portable.
0

I would try to use the latest version 3 of Docker-compose to make it easier for you.

The web, db, and notification can be put on to the same docker network. You can specify the IPs of each container. Then, store these IPs in an environmental variable. You can do the same thing for the port.

enter image description here

connection = Connection(process.env.MONGODB_HOST, app.config['MONGODB_PORT']

The following command will create the db_net network:

docker network create db_net --subnet 172.16.0.0/24

Here is the revised version 3 docker-compose.yml file. Notice the enviromental variable uses the IP address we defined for the mongo container.

version: '3'

services:
  db:
    image: mongo
    container_name: mongo
    networks:
      db_net:
        ipv4_address: 172.16.1.1 
  web:
    build: form
    command: python -u app.py
    ports:
      - "5000:5000"
    volumes:
      - form:/form
    environment:
      MONGODB_HOST: 172.16.1.1
    networks:
      db_net:
        ipv4_address: 172.16.1.2
  notification:
    build: notify
    command: python -u app.py
    volumes:
      - notify:/notify
    environment:
      MONGODB_HOST: 172.16.1.1
    networks:
      db_net:
        ipv4_address: 172.16.1.3
networks:
  db_net:
    external: true

7 Comments

No need to link to 'db'?
Or a root level "volume"?
This too doesn't solve the problem at hand. I've updated my compose file a/c to your suggestion though.
Networking is the new way of linking containers together (ver 3). So you changed the MONGODB_HOST = process.env.MONGODB_HOST ?
Sorry i realized your using python... try to use the mongo driver for connecting to mongodb directly (rule out that connection code)...docs.mongodb.com/getting-started/python/client
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.