主机上的Flask应用连接到VM中Docker中的MySQL
简单来说,我在我的主机上运行了一个简单的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),但我想我错了!
感谢那些帮我看过这个问题的人,希望这能对其他人有所帮助!