用 Docker、Gradle 来构建、运行、发布一个 Spring Boot 应用并且连接到Docker容器的Mysql

Spring bootDocker

开发环境

  • Mac环境下安装的docker:Docker version 17.06.0-ce, build 02c1d87
  • 使用home brew安装的Gradle 3.5
  • java version “1.8.0_152-ea”
  • IntelliJIDEA 2017.2.2
  • Spring Boot 1.5.6

阿里云docker镜像加速

  1. 登录https://dev.aliyun.com/search.html

  2. 进入管理中心

  3. 在管理中心左边栏找到【Docker Hub 镜像站点】

  4. 您的专属加速器地址 后面的地址就是专属的加速器地址,复制这个加速连接地址

  5. Mac下打开安装的Docker,打开Preferences进行设置,如下图:

  6. 检查下下面的截图是否设置的一致,至此阿里云docker加速设置完毕。

Docker中获取Mysql

阿里云docker镜像地址以及使用方法:https://dev.aliyun.com/detail.html?repoId=1239
# Mac下打开终端iTerm
➜ docker pull mysql

# 安装完毕之后,使用如下命令启动了一个叫mysql容器,设置了mysql的root密码为123456,映射宿主主机的端口3306到容器的端口3306
# 由于直接把 mysql 的 3306 端口直接映射到了宿主主机上,在生产环境就会有一定的安全隐患,下面会有其他方法解决
➜ docker run --name mysql -p 3306:3306  -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest

# 查询运行的docker容器
➜ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
71b7739428f4        mysql:latest        "docker-entrypoint..."   8 hours ago         Up 1 second         0.0.0.0:3306->3306/tcp   mysql

# 进入容器,创建数据库
➜ docker exec -it 71b7739428f4 bash

# 以下操作是在mysql容器中进行,输入数据库密码 123456 然后创建数据库就行了,退出容器使用exit命令
root@71b7739428f4:/# mysql -uroot -p

注意:一定要先运行mysql容器并且创建好数据库,否则构建spring boot应用的时候检测数据库连接不容过,就无法构建成功。

参考连接:

创建 Gradle 构建文件

前提是已经有了一个spring boot应用,并且可以正常访问的web应用。
打开IDEA,配置build.gradle
buildscript {
	ext {
		springBootVersion = '1.5.6.RELEASE'
	}
	repositories {
        mavenLocal()
        maven {
            url 'http://maven.aliyun.com/nexus/content/groups/public/'
        }
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
		// tag::build[]
        classpath 'se.transmode.gradle:gradle-docker:1.2'
        // end::build[]
	}
}

// This is used as the docker image prefix
group = "springio"

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
// tag::plugin[]
apply plugin: 'docker'
// end::plugin[]

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenLocal()
    maven {
        url 'http://maven.aliyun.com/nexus/content/groups/public/'
    }
}

jar {
    baseName = "sale"
    version = '1.0.0'
}


// tag::task[]
task buildDocker(type: Docker, dependsOn: build) {
    push = true
    applicationName = jar.baseName
    dockerfile = file('src/main/docker/Dockerfile')
    doFirst {
        copy {
            from jar
            into stageDir
        }
    }
}
// end::task[]

dependencies {

    // spring
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')

    // web
    compile group: 'org.thymeleaf', name: 'thymeleaf', version: '3.0.6.RELEASE'
    compile group: 'org.thymeleaf', name: 'thymeleaf-spring4', version: '3.0.6.RELEASE'
    compile group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '2.2.2'

    // database
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile 'com.alibaba:druid-spring-boot-starter:1.1.1'
    runtime('mysql:mysql-connector-java')

    // tools
    testCompile('org.springframework.boot:spring-boot-starter-test')
    compileOnly('org.projectlombok:lombok')
    compile group: 'org.springframework.boot', name: 'spring-boot-gradle-plugin', version: '1.5.6.RELEASE'

    // 前端组件
    compile 'org.webjars:bootstrap:3.3.7'
//    compile 'org.webjars:bootstrap:4.0.0-beta'
    compile group: 'org.webjars', name: 'webjars-locator', version: '0.32'
}

将项目容器化

IDEA的项目中,在src/main/路径下创建docker目录,然后在src/main/docker/这个目录下创建一个文件Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD sale-1.0.0.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

解释下这个配置文件:

  • VOLUME 指定了临时文件目录为/tmp。其效果是在主机 /var/lib/docker目录下创建了一个临时文件,并链接到容器的/tmp。改步骤是可选的,如果涉及到文件系统的应用就很有必要了。/tmp目录用来持久化到 Docker 数据文件夹,因为 Spring Boot 使用的内嵌 Tomcat 容器默认使用/tmp作为工作目录
  • 项目的 jar 文件作为 “app.jar” 添加到容器的
  • ENTRYPOINT 执行项目 app.jar。为了缩短 Tomcat 启动时间,添加一个系统属性指向 “/dev/urandom” 作为 Entropy Source

构建 Docker Image

构建之前,先查询本机的ip地址,然后终端下面输入如下命令:
vim /etc/hosts 添加一条记录 192.168.199.229 mysql 然后在web项目里面的application.yml文件里面配置数据库的连接如下:

spring:
  datasource:
    # 参考https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
    druid:
      # JDBC配置
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://mysql:3306/sale?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
      username: root
      password: 123456
开始构建Docker Image镜像
# 在终端iTerm下进入到项目目录
➜ gradle build buildDocker

运行创建的spring boot Docker镜像

# springio和sale都是build.gradle里面设置的
➜ docker run -p 8080:8080 -t springio/sale

参考连接

第二种spring boot应用连接mysql数据库方式

只需要针对第一种构建方式做一下修改,其他都和第一种创建方式一样
参考连接:[docker:从 tomcat 容器连接到 mysql 容器](http://blog.csdn.net/smallfish1983/article/details/40107303)

运行mysql容器

# 此种方式不再把mysql容器3306端口映射到宿主机上
➜ docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest

运行Docker创建的spring boot镜像

# --link 前面的 sale 是我们要连接的数据库服务器的容器名称,后面的 tomysql 是我们要创建的这个链接的名字
➜ docker run -d -p 8080:8080 --name sale --link mysql:salemysql  springio/sale:latest

# 这里我们可以看到只有springio/sale:latest的端口映射到了宿主主机上,而 mysql 的端口只有 springio/sale:latest 容器可以连接
➜  sale docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
309d97d2f719        springio/sale:latest   "java -Djava.secur..."   18 minutes ago      Up 2 seconds        0.0.0.0:8080->8080/tcp   sale
9e7c03d3a497        mysql:latest           "docker-entrypoint..."   23 minutes ago      Up 23 minutes       3306/tcp                 mysql

第三种spring boot应用连接mysql数据库方式

修改application.yml文件

增加profiles: container这个配置,注意里面的变量配置
spring:
  datasource:
    # 参考https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
    druid:
      # JDBC配置
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/shanyeli?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
      username: root
      password:
      # 连接池配置
      filters: stat,wall,slf4j
      initialSize: 5
      minIdle: 3
      maxActive: 10
      maxWait: 600000
      timeBetweenEvictionRunsMillis: 600000
      minEvictableIdleTimeMillis: 300000
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 50
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    generate-ddl: true
    database: mysql
    properties:
      hibernate:
        format_sql: true
        enable_lazy_load_no_trans: true
  thymeleaf:
    cache: false
    mode: html
---
spring:
  profiles: container
  datasource:
    druid:
      # JDBC配置
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
      username: ${DATABASE_USER}
      password: ${DATABASE_PASSWORD}
      # 连接池配置
      filters: stat,wall,slf4j
      initialSize: 5
      minIdle: 3
      maxActive: 10
      maxWait: 600000
      timeBetweenEvictionRunsMillis: 600000
      minEvictableIdleTimeMillis: 300000
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 50
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    generate-ddl: true
    database: mysql
    properties:
      hibernate:
        format_sql: true
        enable_lazy_load_no_trans: true
  thymeleaf:
    cache: false
    mode: html

修改Dockerfile文件

增加-Dspring.profiles.active=container这个配置
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD sale-1.0.0.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=container","-jar","/app.jar"]

构建Docker Image

# 在终端iTerm下进入到项目目录
➜ gradle build buildDocker

运行mysql镜像

# 此种方式不再把mysql容器3306端口映射到宿主机上
➜ docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest

运行创建的springio/sale镜像

➜ docker run -d \
     --name sale \
     --link mysql:mysql \
     -p 8080:8080 \
     -e DATABASE_HOST=mysql \
     -e DATABASE_PORT=3306 \
     -e DATABASE_NAME=shanyeli \
     -e DATABASE_USER=root \
     -e DATABASE_PASSWORD=123456 \
     springio/sale
使用http://localhost:8080访问项目

本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名,转载请标明出处
最后编辑时间为: 2017/08/22 00:53

    原文作者:MySql
    原文地址: https://juejin.im/entry/59a60f876fb9a024a4045250
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞