# springboot-docker-mysql **Repository Path**: ComCtrl/springboot-docker-mysql ## Basic Information - **Project Name**: springboot-docker-mysql - **Description**: docker化的spring boot 应用访问暴露的mysql容器,并使用 jenkins流水线自动部署 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2018-09-17 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Spring Boot、docker、Jenkins、mysql整合 ## 概述 此处将 springboot 和数据库分为两个镜像 ## Spring Boot项目搭建 项目完整的 pom.xml文件 ```xml 4.0.0 com.test springboot-docker-mysql 0.0.1 jar springboot-docker-mysql Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 1.5.10.RELEASE UTF-8 UTF-8 springboot 1.8 org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.1 org.springframework.boot spring-boot-devtools runtime mysql mysql-connector-java runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test com.alibaba druid 1.0.11 dev true dev test test org.springframework.boot spring-boot-maven-plugin com.spotify docker-maven-plugin 1.1.0 ${docker.image.prefix}/${project.artifactId} . / ${project.build.directory} ${project.build.finalName}.jar ``` ### 整合 mybatis 1. 导入依赖 (略) 2. 配置 `application.properties` 文件 (多环境) `src/main/resources` 下新建如下的三个配置文件 ``` application.properties application-dev.properties (连接本地mysql开发) application-test.properteis (连接docker中的mysql测试) ``` `application.properties` ```properties spring.profiles.active = @profileActive@ ``` `application-dev.properties` ```properties server.port=8082 # 数据库访问配置 # 主数据源,默认的 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/springboot_docker_mysql?useSSL=false spring.datasource.username=root spring.datasource.password=root # 下面为连接池的补充设置,应用到上面所有数据源中 # 初始化大小,最小,最大 spring.datasource.initialSize=5 spring.datasource.minIdle=5 spring.datasource.maxActive=20 # 配置获取连接等待超时的时间 spring.datasource.maxWait=60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 spring.datasource.timeBetweenEvictionRunsMillis=60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT 1 FROM DUAL spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false # 打开PSCache,并且指定每个连接上PSCache的大小 spring.datasource.poolPreparedStatements=true spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 spring.datasource.filters=stat,wall,log4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合并多个DruidDataSource的监控数据 #spring.datasource.useGlobalDataSourceStat=true ``` `application-test.properteis` ```properties server.port=8082 # 数据库访问配置 # 主数据源,默认的 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://192.168.2.2:3307/springboot_docker_mysql?useSSL=false spring.datasource.username=root spring.datasource.password=root # 下面为连接池的补充设置,应用到上面所有数据源中 # 初始化大小,最小,最大 spring.datasource.initialSize=5 spring.datasource.minIdle=5 spring.datasource.maxActive=20 # 配置获取连接等待超时的时间 spring.datasource.maxWait=60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 spring.datasource.timeBetweenEvictionRunsMillis=60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT 1 FROM DUAL spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false # 打开PSCache,并且指定每个连接上PSCache的大小 spring.datasource.poolPreparedStatements=true spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 spring.datasource.filters=stat,wall,log4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合并多个DruidDataSource的监控数据 #spring.datasource.useGlobalDataSourceStat=true ``` `pom.xml` 中配置 profiles ```xml dev true dev test test ``` 3. 建表 ```sql CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) DEFAULT NULL, `nickname` varchar(255) DEFAULT NULL, `birthday` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4; INSERT INTO `springboot_docker_mysql`.`user` (`id`, `username`, `nickname`, `birthday`) VALUES ('1', 'lisi', 'ss', NULL); ``` 4. 新建实体类 ```java package com.test.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.Date; @Data @NoArgsConstructor @AllArgsConstructor public class User implements Serializable { private Integer id; private String username; private String nickname; private Date birthday; } ``` 5. 新建 mapper ```java package com.test.mapper; import com.test.entity.User; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; @Mapper public interface UserMapper { @Select("select * from user where id = #{id}") User getById(Integer id); @Insert("insert into user (username, nickname, birthday) values (#{user.username}, #{user.nickname}, #{user.birthday})") void insertUser(@Param("user") User user); } ``` 6. 新建 controller ```java package com.test.controller; import java.util.Date; import com.test.entity.User; import com.test.mapper.UserMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j public class UserController { @Autowired private UserMapper userMapper; @GetMapping("/user/{id}") User getUserById(@PathVariable Integer id){ return userMapper.getById(id); } @GetMapping("/user/{username}/{nickname}") public String insertUser(@PathVariable("username") String username, @PathVariable("nickname") String nickname){ User user = new User(); user.setId(0); user.setUsername(username); user.setNickname(nickname); user.setBirthday(new Date()); userMapper.insertUser(user); log.info("@@@" + new Date()); return "success"; } } ``` ## Dockerfile **最重要的事情** : 设置时区 ```dockerfile FROM java:8 VOLUME /tmp # 设置时区 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone ADD springboot-docker-mysql-0.0.1.jar app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] ``` ## Docker 配置 mysql 1. 拉取镜像 ``` [root@centos7 ~]# docker pull mysql:5.7 ``` 2. 运行镜像 * `-v /data/mysql:/var/lib/mysql` 数据库挂载到宿主机 `/data/mysql` 目录下 * `-v /etc/localtime:/etc/localtime:ro` 使用宿主机时区 * `--privileged=true` 解决Centos7安全Selinux禁止了一些安全权限问题 * `-e MYSQL_ROOT_PASSWORD=root` 设置密码 * `--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci` 设置字符编码 ``` [root@localhost ~]# docker run -p 3307:3306 --name mysql -v /data/mysql:/var/lib/mysql -v /etc/localtime:/etc/localtime:ro --privileged=true -e MYSQL_ROOT_PASSWORD=root -d mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci ``` 3. 允许mysql 被远程访问 ``` [root@localhost mysql]# docker exec -it mysql bash #进入运行中的容器 root@746e0b3444ea:/# mysql -uroot -proot #连接mysql mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root'; #修改访问权限 mysql> select now(); #查看当前时间 ``` ## 打包镜像启动容器 1. git 拉取项目 ``` [root@localhost ~]# git clone git@gitee.com:ComCtrl/springboot-docker-mysql.git ``` 2. 打包镜像 ``` [root@localhost springboot-docker-mysql]# mvn package -Dmaven.test.skip=true -Ptest docker:build #打包的时候使用 test profile ``` 3. 运行镜像 ``` [root@localhost springboot-docker-mysql]# docker run -v /etc/localtime:/etc/localtime:ro --name springboot-docker-mysql -d -p 8082:8082 springboot/springboot-docker-mysql ``` 4. 测试 访问 http://192.168.2.2:8082/user/1 查看结果 访问 http://192.168.2.2:8082/user/aaa/aa 查看数据库,日期是否正确 ## Jenkins 一键部署 上述镜像启动成功后,进行一键部署 1. 进入Jenkins,新建流水线任务 2. groovy 脚本 ```groovy #!groovy pipeline{ agent any //定义仓库地址 environment { REPOSITORY = "git@gitee.com:ComCtrl/springboot-docker-mysql.git" project = "springboot-docker-mysql" //项目名称 image_name = "springboot/springboot-docker-mysql" //镜像名称 } stages { stage('获取代码'){ steps { echo "从 git:${REPOSITORY} 拉取代码" //清空当前目录 deleteDir() //拉取代码 git "${REPOSITORY}" } } stage('构建镜像'){ steps { echo "开始构建" //构建镜像 sh 'mvn package -Dmaven.test.skip=true -Ptest docker:build' } } stage('停止原有服务'){ steps{ script { try { echo "停止服务" sh 'docker stop ${project}' } catch(ex) { } } } } stage("启动服务"){ steps { script { try { echo "启动服务" // -v /etc/localtime:/etc/localtime:ro 同步时间 sh 'docker run -v /etc/localtime:/etc/localtime:ro --name ${project} -d -p 8082:8082 ${image_name}' } catch(ex) { sh 'docker start ${project}' } } } } } } ```