Mysql Can';t连接到db docker容器

Mysql Can';t连接到db docker容器,mysql,docker,docker-compose,Mysql,Docker,Docker Compose,目前正在移动我们的应用程序以开始使用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 /explorerb

目前正在移动我们的应用程序以开始使用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和Docker文件:

FROM mysql
ADD createDB.sql /docker-entrypoint-initdb.d
我之所以在Docker compose中使用单独的mysql Docker文件,而不是仅仅使用image,是因为必须在开始时创建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):


所以,我假设它也可以从后端容器ping,但为什么它不能连接到db服务器?

MySQL需要几秒钟才能启动。要确认这是一种竞赛条件,请尝试以下操作:

$ docker-compose up -d database && sleep 5 && docker-compose up
当/如果这确认了竞争条件,您可以在数据库映像上使用
HEALTHCHECK
来缓解这种情况

见:

来自上面链接的脚本:

#!/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

最终,我们发现了一种疏忽的问题。 根本原因是后端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。看起来不正确,因为我不是从主机复制刚刚由maven在容器中创建的jar文件

这个问题解决了,只需更换

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


谢谢你的调查

我仍然会遇到相同的错误,即使应用5秒延迟。我仍然认为根本原因是应用程序属性文件,即这一行:link:database我不相信这是正确的,因为我可以启动一个MySQL容器并从一台同事的机器上连接而不会出现问题
ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar
RUN cp /explorerbackend/target/explorer-backend-1.0.jar /explorerbackend/app.jar