docker nodejs container cant connect mysql container

时间:2017-03-18 19:43:26

标签: mysql node.js docker connection

我在Digital Ocean运行Docker服务器。我有两个容器Nodejs和Mysql。 Mysql容器已打开端口3306。

尝试通过Docker Server ip + port通过nodejs访问mysql时。我收到错误:连接ETIMEDOUT。

当我在本地计算机上运行相同的nodejs docker setup时,它可以正常工作。有什么我想念的吗?

这是nodejs docker-composer.yml:

version: '2'
services:
    test-web-install:
        image: example-nodejs:latest
        working_dir: /home/app
        volumes:
        - ./:/home/app
        command: sh -c 'nodemon'
        environment:
        - NODE_ENV=development
        - DB_HOST=192.168.11.207 #or public ip in internet
        - DB_PORT=3036
        - DB_PASSWORD=root
        - DB_USER=root
        - DB_DATABASE=root
        ports:
        - "3000:3000"

这是mysql的docker-composer.yml

mysql:
    container_name: flask_mysql
    restart: always
    image: mysql:5.6
    environment:
        MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
        MYSQL_USER: 'root'
        MYSQL_PASS: 'root'
        MYSQL_DATABASE: 'root'
    volumes:
    - ./data:/var/lib/mysql
    ports:
    - "3036:3306"
    restart: always

2 个答案:

答案 0 :(得分:1)

我会在推进时修改答案 - 在您发表评论后,虽然我无法访问您的环境,但我们可以尝试逐步解决此问题:

  1. 让db对node.js服务器可见
  2. 了解它是如何工作的,然后可能会深入研究env网络配置。
  3. 有两种方法可以解决第一个问题,可能是第二个问题,因为我看到的是无法触及你的环境:

    第一个将确保服务器看到数据库,但如果你无法从外部连接到db似乎有防火墙/ Droplet网络配置问题,你可以尝试第二种方式(不太可能改变,但它是好的尝试)。这假设您使用相同的docker compose和相同的bridge cusom网络:

    version: '2'
    services:
        test-web-install:
            image: example-nodejs:latest
            working_dir: /home/app
            volumes:
            - ./:/home/app
            command: sh -c 'nodemon'
            environment:
            - NODE_ENV=development
            - DB_HOST= mysql 
            - DB_PORT=3036
            - DB_PASSWORD=root
            - DB_USER=root
            - DB_DATABASE=root
            ports:
            - "3000:3000"
        networks:
          inner:
            alias: server
      mysql:
        container_name: flask_mysql
        restart: always
        image: mysql:5.6
        environment:
            MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
            MYSQL_USER: 'root'
            MYSQL_PASS: 'root'
            MYSQL_DATABASE: 'root'
        volumes:
        - ./data:/var/lib/mysql
        ports:
        - "<externalEnvIp>:3036:3306"
        restart: always
        networks:
          inner:
            alias: mysql
    networks:
      inner:
          driver: bridge
          driver_opts:
            com.docker.network.enable_ipv6: "true"
            com.docker.network.bridge.enable_ip_masquerade: "true"
          ipam:
            driver: default
            config:
            - subnet: 172.16.100.0/24
              gateway: 172.16.100.1
    

    选项2:

    version: '2'
    services:
        test-web-install:
            image: example-nodejs:latest
            working_dir: /home/app
            volumes:
            - ./:/home/app
            command: sh -c 'nodemon'
            environment:
            - NODE_ENV=development
            - DB_HOST= mysql 
            - DB_PORT=3036
            - DB_PASSWORD=root
            - DB_USER=root
            - DB_DATABASE=root
            ports:
            - "3000:3000"
            network_mode: "host"
      mysql:
        container_name: flask_mysql
        restart: always
        image: mysql:5.6
        environment:
            MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
            MYSQL_USER: 'root'
            MYSQL_PASS: 'root'
            MYSQL_DATABASE: 'root'
        volumes:
        - ./data:/var/lib/mysql
        ports:
        - "3036:3306"
        restart: always
        network_mode: "host"
    

    更精确的解决方案(找到问题的根源)将涉及深入挖掘您的env网络配置,docker网络设置等,但这些解决方案现在可以帮助解决您的问题。

    尝试后请尝试输出结果。

答案 1 :(得分:0)

docker网络不允许您从容器内部返回到主机IP以连接到另一个容器公开的端口。我没有深入研究这是否是由于iptables规则或者是docker-proxy内部的东西。无论哪种方式,它都不值得研究,因为容器到容器网络是docker的内置功能。<​​/ p>

要使用docker的网络,容器需要位于同一个docker网络上,并且您可以通过DNS中的容器名称来引用它们。使用docker-compose,通常可以使用服务名称代替容器名称(例如test-web-install和示例中的mysql),因为compose会为这些名称创建别名。但是,由于您已重写mysql的容器名称,请改用flask_mysql容器名称。

在您的方案中,由于您已使用两个单独的docker-compose.yml文件拆分启动,因此您将使用compose创建的单独网络。您有两种方法可以解决此问题:

  1. 将两者合并为一个docker-compose.yml(BlackStork gave an example of this)。
  2. 使用您事先创建的外部定义的网络。
  3. 要做到后者,首先要创建你的网络:

    docker network create dbnet
    

    然后将应用程序的docker-compose.yml更新为:

    version: '2'
    networks:
        dbnet:
            external: true
    
    services:
        test-web-install:
            image: example-nodejs:latest
            working_dir: /home/app
            volumes:
            - ./:/home/app
            command: sh -c 'nodemon'
            environment:
            - NODE_ENV=development
            - DB_HOST=flask_mysql
            - DB_PORT=3036
            - DB_PASSWORD=root
            - DB_USER=root
            - DB_DATABASE=root
            ports:
            - "3000:3000"
            networks:
            - dbnet
    

    mysql的docker-compose.yml:

    version: '2'
    
    networks:
      dbnet:
        external: true
    
    services:
    
      mysql:
        container_name: flask_mysql
        restart: always
        image: mysql:5.6
        environment:
            MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
            MYSQL_USER: 'root'
            MYSQL_PASS: 'root'
            MYSQL_DATABASE: 'root'
        volumes:
        - ./data:/var/lib/mysql
        ports:
        - "3036:3306"
        restart: always
        networks:
        - dbnet
    
相关问题