简体   繁体   English

如何将 Flask 应用程序容器与 MySQL 服务器容器连接起来?

[英]How to connect a Flask app container with a MySQL server container?

I'm newbie to Docker.我是 Docker 的新手。 I've coded the dockerfile below to build my Flask app:我在下面编写了 dockerfile 来构建我的 Flask 应用程序:

FROM debian

WORKDIR /code

RUN apt update
RUN apt-get update

RUN apt-get install --yes git python3

RUN apt install --yes python3-pip

COPY requirements.txt requirements.txt

RUN pip3 install -r requirements.txt

RUN apt-get install --yes libcairo2 libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev

COPY app .

RUN python3 /code/config_database.py dev

EXPOSE 5000

ENTRYPOINT ["python3", "/code/app.py", "dev"]

The line before EXPOSE command is where I try connecting to MySQL database in another container. EXPOSE 命令之前的行是我尝试连接到另一个容器中的 MySQL 数据库的位置。 The MySQL image is built using the YAML file below: MySQL 映像是使用下面的 YAML 文件构建的:

version: "3.7"
services:
  bd:
    image: "mysql"
    command: --default-authentication-plugin=mysql_native_password   
    environment:
      MYSQL_DATABASE: covid3
      MYSQL_ROOT_PASSWORD: XXX
      MYSQL_USER: root
      MYSQL_PASSWORD: XXX
    ports:
      - "3306:3306"
    container_name: bd_mysql
  web:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - bd
    container_name: app_flask

The connection url has these values:连接 url 具有以下值:

DATABASE_URL = 'mysql+pymysql://root:XXX@bd:3306/covid3'

Note bd is the MySQL machine I'm using.注意bd是我正在使用的 MySQL 机器。 I've read somewhere else I should use service name as the machine database address in Docker.我在其他地方读过我应该使用服务名称作为 Docker 中的机器数据库地址。 I'm using SQLAlchemy.我正在使用 SQLAlchemy。 This is the code to get a connection to the database:这是获取与数据库的连接的代码:

engine = create_engine(DATABASE_URL, echo=False)
Session = sessionmaker(bind=engine)

When I run docker compose with this command:当我运行 docker 时,使用以下命令编写:

docker-compose up --build

The following error appears:出现以下错误:

Step 12/14 : RUN python3 /code/config_database.py dev
 ---> Running in bfb4fd5f831a
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/pymysql/connections.py", line 583, in connect
    **kwargs)
  File "/usr/lib/python3.7/socket.py", line 707, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
  File "/usr/lib/python3.7/socket.py", line 748, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/base.py", line 2285, in _wrap_pool_connect
    return fn()
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 363, in connect
    return _ConnectionFairy._checkout(self)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 773, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 492, in checkout
    rec = pool._do_get()
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/impl.py", line 139, in _do_get
    self._dec_overflow()
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/langhelpers.py", line 69, in __exit__
    exc_value, with_traceback=exc_tb,
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/compat.py", line 178, in raise_
    raise exception
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/impl.py", line 136, in _do_get
    return self._create_connection()
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 308, in _create_connection
    return _ConnectionRecord(self)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 437, in __init__
    self.__connect(first_connect_check=True)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 657, in __connect
    pool.logger.debug("Error on connect(): %s", e)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/langhelpers.py", line 69, in __exit__
    exc_value, with_traceback=exc_tb,
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/compat.py", line 178, in raise_
    raise exception
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 652, in __connect
    connection = pool._invoke_creator(self)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/strategies.py", line 114, in connect
    return dialect.connect(*cargs, **cparams)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/default.py", line 490, in connect
    return self.dbapi.connect(*cargs, **cparams)
  File "/usr/local/lib/python3.7/dist-packages/pymysql/__init__.py", line 94, in Connect
    return Connection(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/pymysql/connections.py", line 325, in __init__
    self.connect()
  File "/usr/local/lib/python3.7/dist-packages/pymysql/connections.py", line 630, in connect
    raise exc
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'bd' ([Errno -2] Name or service not known)")

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/code/config_database.py", line 8, in <module>
    Base.metadata.create_all(bind=db.engine)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/sql/schema.py", line 4321, in create_all
    ddl.SchemaGenerator, self, checkfirst=checkfirst, tables=tables
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/base.py", line 2057, in _run_visitor
    with self._optional_conn_ctx_manager(connection) as conn:
  File "/usr/lib/python3.7/contextlib.py", line 112, in __enter__
    return next(self.gen)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/base.py", line 2049, in _optional_conn_ctx_manager
    with self._contextual_connect() as conn:
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/base.py", line 2251, in _contextual_connect
    self._wrap_pool_connect(self.pool.connect, None),
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/base.py", line 2289, in _wrap_pool_connect
    e, dialect, self
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/base.py", line 1555, in _handle_dbapi_exception_noconnection
    sqlalchemy_exception, with_traceback=exc_info[2], from_=e
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/compat.py", line 178, in raise_
    raise exception
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/base.py", line 2285, in _wrap_pool_connect
    return fn()
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 363, in connect
    return _ConnectionFairy._checkout(self)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 773, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 492, in checkout
    rec = pool._do_get()
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/impl.py", line 139, in _do_get
    self._dec_overflow()
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/langhelpers.py", line 69, in __exit__
    exc_value, with_traceback=exc_tb,
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/compat.py", line 178, in raise_
    raise exception
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/impl.py", line 136, in _do_get
    return self._create_connection()
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 308, in _create_connection
    return _ConnectionRecord(self)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 437, in __init__
    self.__connect(first_connect_check=True)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 657, in __connect
    pool.logger.debug("Error on connect(): %s", e)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/langhelpers.py", line 69, in __exit__
    exc_value, with_traceback=exc_tb,
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/util/compat.py", line 178, in raise_
    raise exception
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/pool/base.py", line 652, in __connect
    connection = pool._invoke_creator(self)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/strategies.py", line 114, in connect
    return dialect.connect(*cargs, **cparams)
  File "/usr/local/lib/python3.7/dist-packages/sqlalchemy/engine/default.py", line 490, in connect
    return self.dbapi.connect(*cargs, **cparams)
  File "/usr/local/lib/python3.7/dist-packages/pymysql/__init__.py", line 94, in Connect
    return Connection(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/pymysql/connections.py", line 325, in __init__
    self.connect()
  File "/usr/local/lib/python3.7/dist-packages/pymysql/connections.py", line 630, in connect
    raise exc
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'bd' ([Errno -2] Name or service not known)")
(Background on this error at: http://sqlalche.me/e/e3q8)
ERROR: Service 'web' failed to build: The command '/bin/sh -c python3 /code/config_database.py dev' returned a non-zero code: 1

Do you have any hint of what's going wrong?你有什么迹象表明出了什么问题吗?

The problem seems to be related to the order of the events, in the sense that some steps are happening at build-time instead of docker run-time:问题似乎与事件的顺序有关,因为某些步骤发生在构建时而不是 docker 运行时:

The content of config_database.py is not shared in the post, but I assume that script is trying to connect to the DB, given the error message. config_database.py的内容未在帖子中共享,但鉴于错误消息,我假设脚本正在尝试连接到数据库。
RUN python3 /code/config_database.py dev will try to reach the DB container before it is up. RUN python3 /code/config_database.py dev将尝试在数据库容器启动之前到达它。

A common good practice is to have the DB initialized in the mysql container itself, rather than from an external script.一个常见的良好做法是在 mysql 容器本身中初始化 DB,而不是从外部脚本中初始化。 Here is a good post the explains how to do it.这是一个很好的帖子,解释了如何做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM