首页 文章

无法连接到db docker容器

提问于
浏览
1

目前正在努力移动我们的应用程序以开始使用docker . 这是一个典型的应用程序,后端和前端 . 我前面没有任何麻烦,但仍然无法发回 .

我有后端的Docker文件:

FROM williamyeh/java8

RUN apt-get -y update && apt-get install -y maven

WORKDIR /explorerbackend

ADD settings.xml /root/.m2/settings.xml
ADD pom.xml /explorerbackend
ADD src /explorerbackend/src

RUN ["mvn", "clean", "install"]

ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar
RUN sh -c 'touch /explorerbackend/app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /explorerbackend/app.jar" ]

和mysql的Docker文件:

FROM mysql
ADD createDB.sql /docker-entrypoint-initdb.d

我为mysql使用单独的Docker文件而不是仅仅在docker-compose中使用图像的原因是必须在启动时创建2个数据库(否则后端将不会启动)

createDB.sql 文件看起来像:

CREATE DATABASE IE;
CREATE DATABASE IE_test;

现在我有docker-compose.yml文件,该文件应该启动2个容器并使后端连接到数据库:

version: "3.0"

services:
  database:
    environment:
      MYSQL_ROOT_PASSWORD: root
    build:
      context: *PATH_TO_DIR_WITH_DOCKERFILE*
      dockerfile: Dockerfile
    ports:
      - 3306:3306
    volumes:
      - db_data:/var/lib/mysql

  backend:
    build:
      context: *PATH_TO_DIR_WITH_DOCKERFILE*
      dockerfile: Dockerfile
    ports:
      - 3000:3000
    depends_on:
      - database

volumes:
  db_data:

当我运行命令docker-compose up数据库容器启动并运行时后端失败:

backend_1   | java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.

但是,我能够登录到数据库容器,我确实看到了创建的数据库:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| IE                 |
| IE_test            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

我看到的唯一原因可能与后端的yml属性文件有关:

app:
  data-base:
    name: IE
    link: database
    port: 3306
.................

从前端容器我能ping数据库(但我允许放入属性文件只是 link:database ):

root@897b187f9042:/frontend# ping database
PING database (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: icmp_seq=0 ttl=64 time=0.086 ms
64 bytes from 172.19.0.2: icmp_seq=1 ttl=64 time=0.088 ms

所以,我认为它也可以从后端容器ping,但为什么它无法连接到数据库服务器?

2 回答

  • 0

    MySQL需要几秒钟的启动时间 . 为了确认这是竞争条件,请尝试以下方法:

    $ docker-compose up -d database && sleep 5 && docker-compose up
    

    当/如果这确认了竞争条件,您可以使用数据库图像上的 HEALTHCHECK 来缓解这种情况 .

    见:https://github.com/docker-library/healthcheck/tree/master/mysql

    上面链接的脚本:

    #!/bin/bash
    set -eo pipefail
    
    if [ "$MYSQL_RANDOM_ROOT_PASSWORD" ] && [ -z "$MYSQL_USER" ] && [ -z "$MYSQL_PASSWORD" ]; then
        # there's no way we can guess what the random MySQL password was
        echo >&2 'healthcheck error: cannot determine random root password (and MYSQL_USER and MYSQL_PASSWORD were not set)'
        exit 0
    fi
    
    host="$(hostname --ip-address || echo '127.0.0.1')"
    user="${MYSQL_USER:-root}"
    export MYSQL_PWD="${MYSQL_PASSWORD:-$MYSQL_ROOT_PASSWORD}"
    
    args=(
        # force mysql to not use the local "mysqld.sock" (test "external" connectibility)
        -h"$host"
        -u"$user"
        --silent
    )
    
    if select="$(echo 'SELECT 1' | mysql "${args[@]}")" && [ "$select" = '1' ]; then
        exit 0
    fi
    
    exit 1
    
  • 1

    最终,我们发现这个问题是一种疏忽 . 根本原因是后端dockerfile:

    FROM williamyeh/java8
    
    RUN apt-get -y update && apt-get install -y maven
    
    WORKDIR /explorerbackend
    
    ADD settings.xml /root/.m2/settings.xml
    ADD pom.xml /explorerbackend
    ADD src /explorerbackend/src
    
    RUN ["mvn", "clean", "install"]
    
    ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar
    RUN sh -c 'touch /explorerbackend/app.jar'
    ENV JAVA_OPTS=""
    ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /explorerbackend/app.jar" ]
    

    这个想法非常简单:1 . 使用java映像2.安装maven 3.从主机复制我项目的src文件夹4.在容器中安装maven 5.将jar移动到容器内的workdir 6.启动它

    但是,选项5看起来不正确,因为不是复制jar文件,而是由容器中的maven创建的,而是从主机复制它 .

    问题解决了简单的替换

    ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar
    

    RUN cp /explorerbackend/target/explorer-backend-1.0.jar /explorerbackend/app.jar
    

    谢谢Rawcode进行调查!

相关问题