无法从其他容器连接到 MySQL 容器

时间:2021-07-19 20:27:00

标签: mysql docker docker-compose

我正在尝试使用 docker-compose 文件将我的 FASTAPI 应用程序容器连接到 MySQL 数据库容器。在 Docker 文档中,它说 docker 为两个容器创建了一个默认网络。但是,我想使用我创建的预先存在的网络(app-net)。 这是我的 docker-compose 文件:

version: '3.4'
services:
  mysql:
    image: mysql:latest
    command: mysqld --default-authentication-plugin=mysql_native_password
    container_name: mysql
    restart: always
    ports:
      - 3307:3306
    environment:
      MYSQL_ROOT_PASSWORD: password
    volumes: 
      - mysql-data:/var/lib/mysql
  app:
    build: .
    image: app:1.0
    container_name: app
    ports:
      - 8000:8000
    environment:
      PASSWORD: password
      USERNAME: root
networks:
  default:
    external: true
    name: app-net
volumes:
    mysql-data:
        driver: local

这是我运行 docker inspect mysql -f "{{json .NetworkSettings.Networks }}" 时得到的输出:

{"app-net":{"IPAMConfig":null,"Links":null,"Aliases":["mysql","5e998f9fb646"],"NetworkID":"7f60c83e4c88d25e674461521446ec9fa98baca8639c782c79671c4fcb77ba88","EndpointID":"","Gateway":"","IPAddress":"","IPPrefixLen":0,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"","DriverOpts":null}}

但是,当我使用 CMD 和 --network app-net 单独运行每个容器时,输出是不同的:

{"app-net":{"IPAMConfig":null,"Links":null,"Aliases":["46157e588c87"],"NetworkID":"7f60c83e4c88d25e674461521446ec9fa98baca8639c782c79671c4fcb77ba88","EndpointID":"6a6922a9a6ea8f9d113447decbbb927cb93ddffd3b9563ee882fa2e44970cde5","Gateway":"172.20.0.1","IPAddress":"172.20.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:14:00:02","DriverOpts":null}}

在我的应用程序代码中,为了连接 mysql 服务器,我将容器名称指定为主机名,因为它们应该共享同一个网络。但是,正如我所提到的,两个容器似乎无法相互交谈。 我很确定这就是我无法通过我的应用程序连接数据库并在运行时出现该错误的原因:

docker-compose -f docker-compose.yml up

我收到此错误:

sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (2005, "Unknown MySQL server host 'mysql' (0)")

我错过了什么?

2 个答案:

答案 0 :(得分:0)

如果您遇到的错误特别是“未知主机”或类似的错误,如果您的应用程序容器在数据库容器存在之前启动,就会发生这种情况。您可以通过告诉 Compose 依赖项来解决这种情况:

version: '3.8'
services:
  mysql: { ... }
  app:
    depends_on:
      - mysql

这有两个关键影响。如果您尝试仅启动应用程序容器 docker-compose up app,它也会启动 mysql 容器,遵循 depends_on: 链。当 Compose 启动容器时,它至少会在创建 mysql 容器之前创建 app 容器。

请注意,这并不能保证在您的应用程序启动时数据库实际上会运行。如果您确实遇到了这种情况,您将收到一个不同的错误,例如“连接被拒绝”。您可以通过在图像中嵌入脚本以等待数据库可用来解决此问题,或者使用具有健康检查支持的版本 2 Compose 文件;有关此特定问题的更多详细信息,请参阅 Docker Compose wait for container X before starting Y

答案 1 :(得分:-1)

您可以通过以下方式将关键网络添加到两个容器中:

version: '3.4'
services:
mysql:
 image: mysql:latest
 command: mysqld --default-authentication-plugin=mysql_native_password
 container_name: mysql
 restart: always
ports:
  - 3307:3306
environment:
  MYSQL_ROOT_PASSWORD: password
volumes: 
  - mysql-data:/var/lib/mysql
networks:
  - app-net
app:
 build: .
 image: app:1.0
 container_name: app
 ports:
  - 8000:8000
 environment:
  PASSWORD: password
  USERNAME: root
 networks:
  - app-net
networks:
 default:
  external: true
  name: app-net
volumes:
mysql-data:
    driver: local