使用docker-compose

时间:2017-08-13 07:32:21

标签: docker docker-compose mysql-python

我有一个使用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"

MySQL的Docker文件

MySQL的docker文件将添加来自test.dump文件的模式。

FROM mysql/mysql-server
ADD test.sql  /docker-entrypoint-initdb.d

Flask的Docker文件

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 Client在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上使用相同的凭据时,我能够访问数据库。 enter image description here

请告诉我如何从Flask应用程序连接MySQL容器。这是我第一次起诉Docker,请原谅我,如果这是我的一个愚蠢的错误。

2 个答案:

答案 0 :(得分:3)

更改此

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中,因为这是你用于服务的名称

答案 1 :(得分:1)

对于遇到类似问题的其他人,如果要为MySQL服务从主机到容器映射不同的端口,请确保需要连接到MySQL服务的容器使用的是该端口的端口,而不是主机的端口。 / p>

这是docker compose文件的示例。在这里,您可以看到我的应用程序(在容器中运行)将使用端口3306连接到MySQL服务(该服务也在端口3306的容器中运行)。从“后端”网络外部连接到此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: