4

I am trying to run 2 docker containers using docker-compose and connect mysql container to app container.Mysql container is running but app container is failing to start with the error Error:2003: Can't connect to MySQL server on '127.0.0.1:3306' (111 Connection refused) It seems like my app container is trying to connect my host mysql instead of mysql container.

docker-compose.yml

version: '2'
services:
  mysql:
    image: mysql:5.7
    container_name: database
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: malicious
      MYSQL_USER: root
      MYSQL_PASSWORD: root

  app:
    build: .
    restart: unless-stopped
    volumes:
      - .:/Docker_compose_app   #app directory
    depends_on:
     - "mysql"
    command: [ "python", "database_update.py"]
    restart: unless-restart
    environment:
    # Environment variables to configure the app on startup.
     MYSQL_DATABASE: malicious
     MYSQL_HOST: database

Dockerfile

 FROM python:2.7
 ADD . /Docker_compose_app
 WORKDIR /Docker_compose_app
 RUN apt-get update
 RUN pip install --requirement requirement.txt

This is my database_update.py file.

    def create_TB(cursor,connection): 
      query = '''CREATE TABLE {}(malicious VARCHAR(100) NOT NULL)'''.format("url_lookup")
      cursor.execute(query)
      connection.commit()

    def connection():           
     try:
       cnx = mysql.connector.connect(user="root",password = 'root',database=malicious)
       cursor = cnx.cursor()
       create_TB(cursor,cnx)

     except mysql.connector.errors.Error as err:
       data = {"There is an issue in connection to DB":"Error:  {}".format(err)}
guri
  • 1,521
  • 2
  • 14
  • 20
  • Maybe mysql need some time to start? Try sleep 10-30 seconds before start connection from your app – dmitryvim Feb 08 '17 at 07:00
  • but it won't resolve the issue because even after mysql container comes up,app container still gives the same error.I used restrat: unless-restarted with app conatiner – guri Feb 08 '17 at 07:10

2 Answers2

4

There are two issues I can see:

  1. Try to add

    links: 
      - mysql:mysql
    

    to the app service in your Docker Compose file. This will make sure that you can reach the mysql container from app. It will set up a hostname mapping (DNS) in your app container, so when you ping mysql from app, it will resolve it to the mysql container's IP address.

  2. In your .py file, where are you defining which host to connect to? Add host="mysql" to the connect call. By default, it will connect to 127.0.0.1, which is what you're seeing.

    cnx = mysql.connector.connect(host="mysql", user="root", password = 'root', database=malicious)
    

Fixing both of these should solve your problem.

nwinkler
  • 52,665
  • 21
  • 154
  • 168
  • Thanks it resolved the issue.But I am trying to understand how my app container is able to connect mysql connector without specifying port?I mean i haven't specify port or expose mysql port. – guri Feb 08 '17 at 08:07
  • The MySQL container automatically exposes port 3306 (the default port), and the Python MySQL Connector uses 3306 as a default value. If you used a different port, you could provide it using an additional `port=XXX` parameter in your `connect` call. – nwinkler Feb 08 '17 at 09:31
  • Added this steps, still the same error. Connection resolves the name 'mysql' to an IP but wont able to connect( – Sultan1991 May 05 '20 at 12:04
  • @Sultan1991 did you manage to fix it? I'm also having trouble with this – Luiz Agner Jan 01 '21 at 18:13
1

You might want to consider using Docker Networks.

I was having a similar problem while having two seperate Python container connecting to one mysql-Container, while those 2 were connected to a Vue-Frontend.

First I tried using links (which was not optimal, because the communication-flow is not entirely linear), just like you but the I ran across this great post: https://www.cbtnuggets.com/blog/devops/how-to-share-a-mysql-db-with-multiple-docker-containers

Using Networks shift the port mapping off and lets you enhance your overall App-Architecture.

Therefore I think you should try something like:

services:
  python-app:
    networks:
      - network_name
    ...
  
  mysql:
    networks:
      - network_name
    ...

networks:
  network_name:
T4gmaster
  • 11
  • 1