Flask app in my Host machine connecting to an MySQL in a docker in a VM

45 Views Asked by At

so essentially, I have a simple Flask app running on my Host machine in which I'm trying to connect to a docker container that has MySQL and is installed in my VM (Virtual Box). I'm not being able to do so due to

ERROR:__main__:Error connecting to MySQL database: 2003 (HY000): Can't connect to MySQL server on 'dockerip:3306' (60)

The 'dockerip' above I manually changed it for the question here, but it is the value I get when I run

sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysqlcontainerflask

So, some basic info, in my VM's Network configuration, I have port forwarding set to get connections from my Host:

enter image description here

And, from my Host Machine, I can connect to the docker in my VM with:

mysql -h 127.0.0.1 -P 7703 -u root -p

Which tells me that my docker containing MySQL in my VM is accepting connections from my Host Machine?

Anyways, the code from my Flask App is as follows:

from flask import Flask, render_template, request
import paramiko
import mysql.connector
import logging

app = Flask(__name__)

# Configure logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/search', methods=['POST'])
def search():
    search_query = request.form.get('search_query')

    # MySQL database configuration
    db_config = {
        'host': 'dockerip (this has the ip as I mentioned above)', 
        'port': 3306,           # MySQL port
        'user': 'root',         # MySQL username
        'password': 'thishasthepassword',  # MySQL password
        'database': 'cache_db'  # MySQL database name
    }

    try:
        # Connect to MySQL database
        db_connection = mysql.connector.connect(**db_config)
        db_cursor = db_connection.cursor()

        # Check if search query exists in the database
        db_cursor.execute("SELECT result FROM cache WHERE query = %s", (search_query,))
        cached_result = db_cursor.fetchone()

        if cached_result:
            # If cached result exists, return it
            response = cached_result[0]
        else:
            # If no cached result, perform search on Wikipedia
            response = perform_wikipedia_search(search_query)

            # Cache the search result in the database
            db_cursor.execute("INSERT INTO cache (query, result) VALUES (%s, %s)", (search_query, response))
            db_connection.commit()

        db_cursor.close()
        db_connection.close()

        return render_template('search.html', search_query=search_query, response=response)

    except mysql.connector.Error as e:
        logger.error("Error connecting to MySQL database: %s", e)
        return render_template('error.html', error_message="Failed to connect to the database")

def perform_wikipedia_search(search_query):
    try:
        instance_ip = "myinstanceipgoeshere"
        securityKeyFile = "mypemfilegoeshere"  

        logger.info("Attempting SSH connection...")
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        key = paramiko.RSAKey.from_private_key_file(securityKeyFile)
        client.connect(hostname=instance_ip, username="ubuntu", pkey=key)
        logger.info("SSH connection successful!")

        cmd = f"python3 /home/wiki.py '{search_query}'"
        stdin, stdout, stderr = client.exec_command(cmd)
        stdin.close()
        output = stdout.read().decode('utf-8')  # Get the output and decode it
        client.close()

        logger.info("Output from Wikipedia search:")
        logger.info(output)  # Log the output for debugging

        return output

    except Exception as e:
        logger.error("Error performing Wikipedia search: %s", e)
        return str(e)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5001)

So basically this is an app that should take the search query, store the search in the database and use it as cache for future searches. However, when I run the Flask app and try a search, I'll get:

Internal Server Error The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

and the PyCharm logs:

ERROR:__main__:Error connecting to MySQL database: 2003 (HY000): Can't connect to MySQL server on 'dockerip:3306' (60)

Again, I replaced the actual IP for the 'dockerip' just to put it in here.

I think my point is that I'm not sure what I'm missing here.. I thought the fact I could connect to the MySQL docker from my Host indicated that connection is fine from my Host to the Docker in my VM, so the next thing to check was credentials, so I triple checked db name, host ip (which is the dockerip I got via means above), username and password, but no luck :(

If anyone have any idea of what could be wrong here, please?

1

There are 1 best solutions below

0
DisplayName On

so I should have used my localhost (127.0.0.1) as the host ip instead of the container's IP. That sorted the issue. I was confused because I thought I should use the MySQL's Host ip, which in my head was the container running mysql (the container is "hosting" mysql), but I guess I was wrong!

Thanks for the ones who have looked and I hope this helps someone else!