SpringBoot项目构建的Docker镜像。Docker中跑了Redis和Mysql。在Run项目镜像时一直报错,提示我数据库拒绝连接。

docker连不上 linux docker cannot connect_docker连不上 linux

报错:
Caused by: java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.

Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.

Caused by: java.net.ConnectException: Connection refused (Connection refused)

原因:容器之间没有通信,也就是网络不通。

两种解决方法:Link容器、桥接网络。

以下是我在Docker中跑Mysql,Redis,SpringBoot项目的例子。

Link方式

一、跑Mysql

–name指定容器名(我这里叫做jx010),-p指定端口映射,-e参数配置(markdown写法 不知道为啥这里 --只显示了一个,是两个哈)。

欲知更多,点击这里:Docker教程

docker run -p 3306:3306 --name jx010 -e MYSQL_USER=root -e MYSQL_ROOT_PASSWORD=admin -e MYSQL_DATABASE=jx010 -d mysql:8.0.16
二、跑Redis同理:

这里redis name叫做:redis

docker run -d -p 6379:6379 --name redis redis:3.2
三、跑项目镜像

run项目镜像时,通过 --link进行容器间通信(–link 容器名称)。

我这里指定项目容器名称为:users,指定端口为8000,e70a91093944是项目镜像ID。同时与名称为jx010的mysql、名称为redis的redis进行容器通信。

docker run --name users --link jx010:jx010 --link redis:redis  -p 8000:8000 e70a91093944

注意:项目打包Docker镜像之前,在配置文件application.yml中对应Mysql、Redis的host配置,需同你所Link容器的名称(NAMES)一致。

也就是告诉它:“我跑起来后访问的是容器中的哪个Mysql,哪个Redis。”

比如,我application.yml中定义的Mysql:host就叫做jx010,端口号3306。

spring:
  datasource:
    druid:
      type: com.alibaba.druid.pool.DruidDataSource
      driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
      url: jdbc:log4jdbc:mysql://${MYSQL_HOST:jx010}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:jx010}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&autoReconnect=true&failOverReadOnly=false&useSSL=false&allowPublicKeyRetrieval=true
      username: ${MYSQL_USERNAME:root}
      password: ${MYSQL_PASSWORD:admin}

定义的Redis:host就叫做redis,port6379。

redis:
    #数据库索引
    database: ${REDIS_DATABASE:0}
    host: ${REDIS_HOST:redis}
    port: 6379
#    port: ${REDIS_PORT:6379}
    password: ${REDIS_PASSWORD:}
    #连接超时时间
    timeout: 5000

查看下正在运行的容器:

parkin@wangyan:~$ docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
f40159411bc3        e70a91093944        "java -cp /app/resou…"   43 minutes ago      Up 40 minutes       0.0.0.0:8000->8000/tcp              users
9e4a38e3ea59        mysql:8.0.16        "docker-entrypoint.s…"   About an hour ago   Up About an hour    0.0.0.0:3306->3306/tcp, 33060/tcp   jx010
a360bf8b62c5        87856cc39862        "docker-entrypoint.s…"   7 months ago        Up 20 hours         0.0.0.0:6379->6379/tcp              redis

可以测试下能不能访问项目:

parkin@wangyan:~$ telnet 192.168.xx.xxx 8000
Trying 192.168.xx.xxx...
Connected to wangyan.lan.
Escape character is '^]'.

如上所示,是通的。同时部署前端页面,就可以操作访问系统了。

桥接网络

在同一桥接网络中的容器可以互相访问,可以通过创建network的方式进行容器间通信。

一、创建网络

我此处创建的网络叫 jx010-network

docker network create jx010-network

通过 docker network ls 可以查看到我们新建的网络。

docker连不上 linux docker cannot connect_docker_02

二、跑Mysql

跑mysql时加入刚创建的网络,别名叫jx010_mysql。

docker run -it --network jx010-network --network-alias jx010_mysql --name jx010_mysql -e MYSQL_USER=root -e MYSQL_ROOT_PASSWORD=admin -e MYSQL_DATABASE=jx010 -d mysql:8.0.16
三、跑Redis同理:

同理跑redis时加入刚创建的网络,别名叫jx010_redis。

docker run -it --network jx010-network --network-alias jx010_redis -d -p 6379:6379 --name jx010_redis redis:3.2
四、跑项目镜像

同理跑项目镜像时加入刚创建的网络,别名叫jx010_user。(配置文件中需注意的地方同方法一)

docker run -it --network jx010-network --network-alias jx010_user --name jx010_user  -p 8000:8000 18b149918a2e

查看下运行中的容器,测试端口是否开放。如下图是可以的

docker连不上 linux docker cannot connect_数据库_03

向mysql容器中导入本地 .sql文件。

一、切到.sql文件存在的目录

二、将该文件copy到容器中。jx010.sql 是数据文件,jx010_mysql是容器名

docker cp jx010.sql jx010_mysql:/jx010.sql

三、进入容器

docker exec -it jx010_mysql bash

四、进入mysql

mysql -uroot -padmin

五、选择使用的数据库

use jx010

六、运行cp过来的.sql文件

source jx010.sql

七、查看表是否生成

show tables;

docker连不上 linux docker cannot connect_docker连不上 linux_04


访问项目,如下图所示是可以的。

docker连不上 linux docker cannot connect_redis_05