1. 程式人生 > 實用技巧 >docker+jib整合springboot+mysql專案

docker+jib整合springboot+mysql專案

第一步:在 IDE 上快速建立一個 springboot 專案(博主用的是 IDEA)

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 資料庫 ORM 框架 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        
        <!-- setter/getter 註解 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true
</optional> </dependency>
專案依賴

專案結構:

第二步:快速建立一個 UserMsg 的實體類

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.io.Serializable;

/**
 * @author chaoyou
 * @email 
 * @date 2020-8-27 18:51
 * @Description
 * @Reference
 
*/ @Entity @Table(name = "user_msg") @Setter @Getter @JsonIgnoreProperties({"handler", "hibernateLazyInitializer"}) public class UserMsg implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column private String username; @Column
private String password; public UserMsg() { } public UserMsg(String username, String password) { this.username = username; this.password = password; } }
UserMsg實體類
import lombok.Getter;
import lombok.Setter;

/**
 * @author chaoyou
 * @email 
 * @date 2020-8-27 19:11
 * @Description
 * @Reference
 */
@Setter
@Getter
public class UserMsgForm {
    private String username;
    private String password;
}
UserMsg表單類

第三步:UserMsg 實體類的 dao 層

import com.example.demo.model.UserMsg;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

import java.io.Serializable;

/**
 * @author chaoyou
 * @email 
 * @date 2020-8-27 18:55
 * @Description
 * @Reference
 */
public interface UserMsgDao extends CrudRepository<UserMsg, Serializable> {
    @Query(value = "select * from user_msg where username = ?1", nativeQuery = true)
    UserMsg getByUsername(String username);

    UserMsg getByUsernameAndPassword(String username, String password);
}
Dao 層

第四步:UserMsg 實體類的 service 層

import com.example.demo.model.UserMsg;

/**
 * @author chaoyou
 * @email 
 * @date 2020-8-27 18:57
 * @Description
 * @Reference
 */
public interface UserMsgService {
    public String save(UserMsg userMsg);
    public Object get(String username);
}
service
import com.example.demo.dao.UserMsgDao;
import com.example.demo.model.UserMsg;
import com.example.demo.service.UserMsgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author chaoyou
 * @email 
 * @date 2020-8-27 18:58
 * @Description
 * @Reference
 */
@Service
public class UserMsgServiceImpl implements UserMsgService {

    private UserMsgDao dao;
    @Autowired
    public UserMsgServiceImpl(UserMsgDao dao) {
        this.dao = dao;
    }

    @Override
    public String save(UserMsg userMsg) {
        String reuslt = "";
        try {
            UserMsg userMsg1 = dao.getByUsernameAndPassword(userMsg.getUsername(), userMsg.getPassword());
            if (userMsg1 != null){
                return "【username=" + userMsg.getUsername() + ", password=" + userMsg.getPassword() + "】賬號資訊已經存在!";
            }
            dao.save(new UserMsg(userMsg.getUsername(), userMsg.getPassword()));
            reuslt = "success";
        } catch (Exception e){
            reuslt = "新建賬號失敗!";
        }
        return reuslt;
    }

    @Override
    public Object get(String username) {
        Object reuslt = "";
        try {
            reuslt = dao.getByUsername(username);
        } catch (Exception e){
            reuslt = "查詢賬戶資訊失敗!";
        }
        return reuslt;
    }
}
service 實現類

第五步:UserMsg 實體類的 controller 層

import com.example.demo.model.UserMsg;
import com.example.demo.model.form.UserMsgForm;
import com.example.demo.service.UserMsgService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author chaoyou
 * @email 
 * @date 2020-8-27 19:09
 * @Description
 * @Reference
 */
@RestController
@RequestMapping("/user")
public class UserMsgController {

    @Autowired
    private UserMsgService service;

    @PostMapping(value = "/save", produces = "application/json;charset=utf-8")
    public ResponseEntity save(UserMsgForm userMsgForm){
        String result = "";
        if (ObjectUtils.isEmpty(userMsgForm)){
            result = "賬號資訊不能為空!";
        } else {
            UserMsg userMsg = new UserMsg();
            BeanUtils.copyProperties(userMsgForm, userMsg, "id");
            result = service.save(userMsg);
        }
        return ResponseEntity.ok(result);
    }

    @GetMapping(value = "/get", produces = "application/json;charset=utf-8")
    public ResponseEntity get(String username){
        Object result = "";
        if (ObjectUtils.isEmpty(username)){
            result = "賬號資訊不能為空!";
        } else {
            result = service.get(username);
        }
        return ResponseEntity.ok(result);
    }
}
controller

第六步:設定執行環境配置檔案

server.address=0.0.0.0
server.port=8080
server.tomcat.uri-encoding=UTF-8
server.connection-timeout=1000000
server.error.whitelabel.enabled=false
server.max-http-header-size=102400
spring.datasource.name=mysql
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.filters=stat
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.druid.url=jdbc:mysql://localhost:3306/db?useSSL=false&useUnicode=true&characterEncoding=utf-8&characterSetResults=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&autoReconnect=true&failOverReadOnly=false&createDatabaseIfNotExist=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
spring.datasource.druid.username=root
spring.datasource.druid.password=123456
spring.datasource.druid.initial-size=6
spring.datasource.druid.min-idle=2
spring.datasource.druid.max-active=700
spring.datasource.druid.max-wait=600000
spring.datasource.druid.time-between-eviction-runs-millis=600000
spring.datasource.druid.min-evictable-idle-time-millis=3000000
spring.datasource.druid.validation-query=SELECT 'x'
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
spring.datasource.druid.pool-prepared-statements=false
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
spring.devtools.restart.additional-paths=src/main/java
spring.devtools.restart.exclude=static/**,public/**
spring.output.ansi.enabled=always
spring.mvc.throw-exception-if-no-handler-found=true
spring.mvc.static-path-pattern=/**
spring.resources.add-mappings=true
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB
spring.servlet.multipart.enabled=false


## springdata \uFFFD\uFFFD\uFFFD\u00F2\uFFFD\uFFFD\uFFFD
## jpa 開啟駝峰命名規則
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
## hibernate 自動建表
spring.jpa.hibernate.ddl-auto=update
# 控制檯列印 sql 語句
spring.jpa.show-sql=true
# 資料庫方言
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
debug=false
trace=false
spring.jpa.open-in-view=true
# 解決 hibernate 懶載入問題
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

#spring.jackson.mapper.use-std-bean-naming=true        #// 允許欄位命名不規範 解決首字母大寫的問題(不轉小寫)   猶豫之前對接的都是小寫  所以這個屬性不放開  沿用原來的對接

# json 轉物件 忽略大小寫問題
spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_PROPERTIES=true        

# 日誌規範
logging.level.org.hibernate.sql=DEBUG
logging.level.org.hibernate.type=ERROR
logging.level.org.springframework.web=ERROR
logging.path=build/log
logging.level.root=warn
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n


logging.level.cc=error

spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true

# 設定多執行緒系統引數
book.core.poolsize=20
book.max.poolsize=30
book.queue.capacity=300
book.keepAlive.seconds=100
book.thread.name.prefix=taskExecutorWbswryxx-
application-dev.properties
# 設定專案的執行環境(dev:開發、prod:生產、test:測試)
spring.profiles.active=dev
#spring.profiles.active=test
#spring.profiles.active=prod
application.properties

第七步:在 pom.xml 中設定 jib-maven-plugin 外掛資訊

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <!--Maven 屬性-->
    <properties>
        <!--專案的編碼格式-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- maven 編譯資源 版本 -->
        <maven.compiler.source>1.8</maven.compiler.source>
        <!-- maven 編譯目標版本  -->
        <maven.compiler.target>1.8</maven.compiler.target>
        <!-- maven 編譯外掛版本 -->
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 資料庫 ORM 框架 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!--使用jib外掛-->
            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>1.3.0</version>
                <configuration>
                    <!--from節點用來設定映象的基礎映象,相當於Docerkfile中的FROM關鍵字-->
                    <from>
                        <!--使用openjdk官方映象,tag是8-jdk-stretch,表示映象的作業系統是debian9,裝好了jdk8-->
                        <image>openjdk:8-jdk-stretch</image>
<!--                        <image>mysql:8.0</image>-->
                    </from>
                    <to>
                        <!--映象名稱和tag,使用了mvn內建變數${project.version},表示當前工程的version-->
                        <image>chaoyou/${project.name}:${project.version}</image>
                    </to>
                    <!--容器相關的屬性-->
                    <container>
                        <!--jvm記憶體引數-->
                        <jvmFlags>
                            <jvmFlag>-Xms128m</jvmFlag>
                            <jvmFlag>-Xmx128m</jvmFlag>
                        </jvmFlags>
                        <!--要暴露的埠-->
                        <ports>
                            <port>8080</port>
                        </ports>
                    </container>
                    <!--開啟允許上傳映象到倉庫中-->
                    <allowInsecureRegistries>true</allowInsecureRegistries>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
pom.xml

第八步:把專案推送到 Linux 上

第九步:在 docker 上跑一個 mysql 容器

##搜尋 mysql 映象
——docker search mysql8.0

##拉取 mysql8.0 映象
——docker pull mysql8.0

##跑 mysql 映象
——docker run -d -p 3306:3306 --name mysqltest -e MYSQL_ROOT_PASSWORD=123456 docker.io/mysql:8.0

##進入 mysqltest 容器內部
——docker exec -it mysqltest /bin/bash

##檢視容器內部ip
——cat /etc/hosts

第十步:進入專案的配置檔案中修改資料庫的 ip 地址

#進入application-dev.properties
——cd src/main/resources

#修改 application-dev.properties 資訊(把ip換成mysqltest容器的內部ip)
——vi application.properties

第十一步:進入到該專案的 pom.xml 同級目錄下

接下來利用 jib 外掛對專案進行打包成映象包(jib-image.tar),有個前提 Linux 環境有安裝 jdk 和 maven(安裝參考:https://www.cnblogs.com/chaoyou/p/13572888.html)

#打包命令

[root@localhost demo]# mvn compile jib:buildTar

打包完成進入 target 目錄下就可以看到映象包( jib-image.tar )

第十二步:把映象包( jib-image.tar )推進 docker 映象庫( docker images )

##把映象包( jib-image.tar )推進 docker 倉庫
[root@localhost target]# docker load < jib-image.tar

##把 docker 映象庫中的映象打包成 tar 映象包
[root@localhost target]# docker save -o /chaoyou/demo.tar chaoyou/demo:0.0.1-SNAPSHOT

第十三步:跑 chaoyuou/demo 映象

#跑映象
——docker run --rm -p 8080:8080 chaoyou/demo:0.0.1-SNAPSHOT