主机上的Flask应用连接到VM中Docker中的MySQL

1 投票
1 回答
40 浏览
提问于 2025-04-14 15:32

简单来说,我在我的主机上运行了一个简单的Flask应用,想要连接到一个在我的虚拟机(Virtual Box)里安装了MySQL的docker容器。但是我遇到了一些问题,无法连接。

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

上面提到的'dockerip'是我为了这个问题手动修改的,实际上它是我运行下面代码时得到的值。

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

一些基本信息是,在我的虚拟机网络配置中,我设置了端口转发,以便从我的主机接收连接:

这里输入图片描述

而且,从我的主机上,我可以用以下命令连接到虚拟机里的docker:

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

这说明我的虚拟机中的MySQL docker正在接受来自主机的连接,对吧?

无论如何,我的Flask应用的代码如下:

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)

基本上这个应用应该接收搜索查询,把搜索内容存储到数据库中,并将其用作未来搜索的缓存。但是,当我运行Flask应用并尝试搜索时,我会收到:

内部服务器错误 服务器遇到内部错误,无法完成您的请求。可能是服务器过载或应用程序出现错误。

而且,PyCharm的日志显示:

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

再次说明,我在这里替换了'dockerip'的实际IP,只是为了方便展示。

我想说的是,我不太确定我漏掉了什么……我以为我能从主机连接到MySQL docker就说明主机和虚拟机中的docker之间的连接是正常的,所以接下来我检查了凭证,仔细核对了数据库名称、主机IP(就是上面得到的dockerip)、用户名和密码,但还是没有成功 :(

如果有人知道可能出什么问题,请告诉我。

1 个回答

0

所以我应该用我的本地地址(127.0.0.1)作为主机的IP,而不是用容器的IP。这样问题就解决了。我之前搞混了,因为我以为应该用MySQL的主机IP,在我脑海里,那个主机就是运行MySQL的容器(容器在“托管”MySQL),但我想我错了!

感谢那些帮我看过这个问题的人,希望这能对其他人有所帮助!

撰写回答