使用 docker-compose 从 Flask 应用程序连接到 MySQL
Connecting to MySQL from Flask Application using docker-compose
我有一个使用 Flask 和 MySQL 的应用程序。该应用程序未从 Flask 应用程序连接到 MySQL 容器,但可以使用具有相同凭据的 Sequel Pro 访问它。
Docker 撰写文件
version: '2'
services:
web:
build: flask-app
ports:
- "5000:5000"
volumes:
- .:/code
mysql:
build: mysql-server
environment:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: root
MYSQL_ROOT_HOST: 0.0.0.0
MYSQL_USER: testing
MYSQL_PASSWORD: testing
ports:
- "3306:3306"
Docker 文件 MySQL
MySQL 的 docker 文件将从 test.dump
文件添加架构。
FROM mysql/mysql-server
ADD test.sql /docker-entrypoint-initdb.d
Docker Flask 文件
FROM python:latest
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]
CMD ["app.py"]
起点app.py
from flask import Flask, request, jsonify, Response
import json
import mysql.connector
from flask_cors import CORS, cross_origin
app = Flask(__name__)
def getMysqlConnection():
return mysql.connector.connect(user='testing', host='0.0.0.0', port='3306', password='testing', database='test')
@app.route("/")
def hello():
return "Flask inside Docker!!"
@app.route('/api/getMonths', methods=['GET'])
@cross_origin() # allow all origins all methods.
def get_months():
db = getMysqlConnection()
print(db)
try:
sqlstr = "SELECT * from retail_table"
print(sqlstr)
cur = db.cursor()
cur.execute(sqlstr)
output_json = cur.fetchall()
except Exception as e:
print("Error in SQL:\n", e)
finally:
db.close()
return jsonify(results=output_json)
if __name__ == "__main__":
app.run(debug=True,host='0.0.0.0')
当我使用 REST 客户端在 http://localhost:5000/
上执行 GET 请求时,我得到了有效响应。
http://localhost:5000/api/getMonths
上的 GET 请求给出错误消息:
mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on '0.0.0.0:3306' (111 Connection refused)
当在 Sequel Pro 上使用相同的凭据时,我能够访问数据库。
请告诉我如何从 Flask 应用程序连接 MySQL 容器。这是我第一次起诉 Docker 如果这是我的愚蠢错误请原谅我。
改变这个
return mysql.connector.connect(user='testing', host='0.0.0.0', port='3306', password='testing', database='test')
到
return mysql.connector.connect(user='testing', host='mysql', port='3306', password='testing', database='test')
您的代码 运行 在容器内而不是在您的主机上。因此,您需要为它提供一个可以在容器网络内到达的地址。对于 docker-compose
每个服务都可以使用其名称访问。所以在你的是 mysql
因为这是你用于服务的名称
对于遇到类似问题的其他人,如果您正在为 MySQL 服务将不同的端口从主机映射到容器,请确保需要连接到 MySQL 服务的容器正在使用容器的端口而不是主机的端口。
这是一个 docker 撰写文件的示例。在这里你可以看到我的应用程序(在容器中 运行ning)将使用端口 3306 连接到 MySQL 服务(它也在端口上的容器中 运行ning 3306).任何从 "backend" 网络外部连接到此 MySQL 服务的人,基本上任何不在具有相同网络的容器中 运行 的东西都需要使用端口 3308 连接到此MySQL服务。
version: "3"
services:
redis:
image: redis:alpine
command: redis-server --requirepass imroot
ports:
- "6379:6379"
networks:
- frontend
mysql:
image: mariadb:10.5
command: --default-authentication-plugin=mysql_native_password
ports:
- "3308:3306"
volumes:
- mysql-data:/var/lib/mysql/data
networks:
- backend
environment:
MYSQL_ROOT_PASSWORD: imroot
MYSQL_DATABASE: test_junkie_hq
MYSQL_HOST: 127.0.0.1
test-junkie-hq:
depends_on:
- mysql
- redis
image: test-junkie-hq:latest
ports:
- "80:5000"
networks:
- backend
- frontend
environment:
TJ_MYSQL_PASSWORD: imroot
TJ_MYSQL_HOST: mysql
TJ_MYSQL_DATABASE: test_junkie_hq
TJ_MYSQL_PORT: 3306
TJ_APPLICATION_PORT: 5000
TJ_APPLICATION_HOST: 0.0.0.0
networks:
backend:
frontend:
volumes:
mysql-data:
我有一个使用 Flask 和 MySQL 的应用程序。该应用程序未从 Flask 应用程序连接到 MySQL 容器,但可以使用具有相同凭据的 Sequel Pro 访问它。
Docker 撰写文件
version: '2'
services:
web:
build: flask-app
ports:
- "5000:5000"
volumes:
- .:/code
mysql:
build: mysql-server
environment:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: root
MYSQL_ROOT_HOST: 0.0.0.0
MYSQL_USER: testing
MYSQL_PASSWORD: testing
ports:
- "3306:3306"
Docker 文件 MySQL
MySQL 的 docker 文件将从 test.dump
文件添加架构。
FROM mysql/mysql-server
ADD test.sql /docker-entrypoint-initdb.d
Docker Flask 文件
FROM python:latest
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]
CMD ["app.py"]
起点app.py
from flask import Flask, request, jsonify, Response
import json
import mysql.connector
from flask_cors import CORS, cross_origin
app = Flask(__name__)
def getMysqlConnection():
return mysql.connector.connect(user='testing', host='0.0.0.0', port='3306', password='testing', database='test')
@app.route("/")
def hello():
return "Flask inside Docker!!"
@app.route('/api/getMonths', methods=['GET'])
@cross_origin() # allow all origins all methods.
def get_months():
db = getMysqlConnection()
print(db)
try:
sqlstr = "SELECT * from retail_table"
print(sqlstr)
cur = db.cursor()
cur.execute(sqlstr)
output_json = cur.fetchall()
except Exception as e:
print("Error in SQL:\n", e)
finally:
db.close()
return jsonify(results=output_json)
if __name__ == "__main__":
app.run(debug=True,host='0.0.0.0')
当我使用 REST 客户端在 http://localhost:5000/
上执行 GET 请求时,我得到了有效响应。
http://localhost:5000/api/getMonths
上的 GET 请求给出错误消息:
mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on '0.0.0.0:3306' (111 Connection refused)
当在 Sequel Pro 上使用相同的凭据时,我能够访问数据库。
请告诉我如何从 Flask 应用程序连接 MySQL 容器。这是我第一次起诉 Docker 如果这是我的愚蠢错误请原谅我。
改变这个
return mysql.connector.connect(user='testing', host='0.0.0.0', port='3306', password='testing', database='test')
到
return mysql.connector.connect(user='testing', host='mysql', port='3306', password='testing', database='test')
您的代码 运行 在容器内而不是在您的主机上。因此,您需要为它提供一个可以在容器网络内到达的地址。对于 docker-compose
每个服务都可以使用其名称访问。所以在你的是 mysql
因为这是你用于服务的名称
对于遇到类似问题的其他人,如果您正在为 MySQL 服务将不同的端口从主机映射到容器,请确保需要连接到 MySQL 服务的容器正在使用容器的端口而不是主机的端口。
这是一个 docker 撰写文件的示例。在这里你可以看到我的应用程序(在容器中 运行ning)将使用端口 3306 连接到 MySQL 服务(它也在端口上的容器中 运行ning 3306).任何从 "backend" 网络外部连接到此 MySQL 服务的人,基本上任何不在具有相同网络的容器中 运行 的东西都需要使用端口 3308 连接到此MySQL服务。
version: "3"
services:
redis:
image: redis:alpine
command: redis-server --requirepass imroot
ports:
- "6379:6379"
networks:
- frontend
mysql:
image: mariadb:10.5
command: --default-authentication-plugin=mysql_native_password
ports:
- "3308:3306"
volumes:
- mysql-data:/var/lib/mysql/data
networks:
- backend
environment:
MYSQL_ROOT_PASSWORD: imroot
MYSQL_DATABASE: test_junkie_hq
MYSQL_HOST: 127.0.0.1
test-junkie-hq:
depends_on:
- mysql
- redis
image: test-junkie-hq:latest
ports:
- "80:5000"
networks:
- backend
- frontend
environment:
TJ_MYSQL_PASSWORD: imroot
TJ_MYSQL_HOST: mysql
TJ_MYSQL_DATABASE: test_junkie_hq
TJ_MYSQL_PORT: 3306
TJ_APPLICATION_PORT: 5000
TJ_APPLICATION_HOST: 0.0.0.0
networks:
backend:
frontend:
volumes:
mysql-data: