docker部署springboot项目,并访问docker中部署的mysql与mongdoDB

解决的问题

  1. docker中的springboot项目访问docker中的mysql和mongo

  2. MongoDB连接报错

    org.springframework.data.mongodb.UncategorizedMongoDbException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=, mechanismProperties=}; nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=, mechanismProperties=}
     at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72)
    Caused by: com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=, mechanismProperties=}
     at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72)
    Caused by: java.lang.IllegalArgumentException: Prohibited character at position 0
     at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72)
    
  3. 跳过SpringBoot打包测试

先看一下最开始的配置

  • application.yml

    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/pet?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: 123456
      data:
        mongodb:
          host: localhost
          port: 27017
          username: admin
          password: 123456
          database: pet
    
  • docker 安装mysql与mongo

将项目打包成为jar包,并上传到服务器

​ 打包的时候,项目会进行测试,然后会出现一个问题。就是mongodb连接报错,这个问题是由于我们使用分开写配置文件,host,port,database这种造成的,具体原因我也不太清楚,有人说是jdk版本问题,所以直接换成uri模式

org.springframework.data.mongodb.UncategorizedMongoDbException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=, mechanismProperties=}; nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=, mechanismProperties=}
    at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72)
Caused by: com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=, mechanismProperties=}
    at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72)
Caused by: java.lang.IllegalArgumentException: Prohibited character at position 0
    at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72)
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/pet?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
  data:
    mongodb:
    # 重点:mongodb://用户名:密码@localhost:27017/数据库名
      uri: mongodb://admin:123456@localhost:27017/pet
image.png

在jar文件同级目录新建Dockerfile,内容如下

FROM java:8-alpine
ADD app-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

然后在当前目录执行(最后有一个点,表示上下文 ):docker build -t pet-app .

因为docker中运行着mysql和mongo,所以我们直接开始运行pet-app这个自己打包的镜像

dokcer run -d -p 8080:8080 --name pet-app pet-app

-d 表示后台运行, --name 表示取一个别名 ,最后一个pet-app表示刚才的镜像名称

OK问题来了

你以为一切很顺利,但是你访问接口会发现错误

Error querying database.  Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.\n### The error may exist in com/zxmt/app/mapper/AgreementMapper.java (best guess)\n### The error may involve com.zxmt.app.mapper.AgreementMapper.selectById\n### The error occurred while executing a query\n### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up."

这个问题就是,docker中的springboot没能通过localhost:3306访问到数据库,同时mongo也是访问不到

解决方案1:直接将localhost改为服务器地址就可以了,相当于docker中的服务通过网络访问服务器端口,服务器再访问docker。(⊙o⊙)…这个决绝办法有点low

解决方案2:使用docker中的--link参数

  1. 先修改配置文件。将原来的主机地址都取一个别名例如下面的mysql,mongo

    spring:
      datasource:
        url: jdbc:mysql://mysql:3306/pet?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: 123456
      data:
        mongodb:
          uri: mongodb://admin:123456@mongo:27017/pet
    
  2. 因为改了这个配置文件,打包的时候会进行测试,(你想你都写成jdbc:mysql://mysql:3306这样了,测试能通过吗)所以现在需要配置跳过测试(在pom的properties中加代码)

    
           true
    
    
  3. 还是Dockerfile打包成镜像

  4. 最后是通过镜像启动容器的代码!!!!重点

    docker run -p 8080:8080 -d --link=mysql:mysql --link=mongo:mongo  --name pet-app  pet-app
    

    --link:前面的mysql表示启动的容器的名称,后面是别名名称对应上面的配置文件中的mysql

    jdbc:mysql://mysql:3306/pet?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false

    当然mongo也是一样。。

    再把之前的错误启动方式贴一次对比一下

    # 错误的
    dokcer run -d -p 8080:8080 --name pet-app pet-app
    #正确的
    docker run -p 8080:8080 -d --link=mysql:mysql --link=mongo:mongo  --name pet-app  pet-app
    

你可能感兴趣的:(docker部署springboot项目,并访问docker中部署的mysql与mongdoDB)