目錄html
本文首發於個人我的博客,Windows Docker 部署 Spring Boot 項目 ,歡迎訪問!java
使用 Docker 部署一個簡單的 Spring Boot 數據庫項目。mysql
最近容器化技術 hin 流行啊,因此開始折騰一下唄。試用了下,有的時候的確比虛擬機要方便。其實起初是要用 Redis,可是 Windows 安裝不方便,因而就看了下 Docker,基本開箱即用,Docker Hub 上 pull 一個 Redis 官方鏡像就能夠了。恰好最近在學 Spring Cloud 微服務,也就嘗試下 Docker 部署 Spring Boot 項目。git
內容上,本文主要是對 Spring Boot 官方文檔的一個補充,英語不錯的能夠直接瀏覽參考文獻 6-7。github
Docker 的基本概念和用法,這裏就詳細展開了,能夠看參考文獻 1-3。web
Docker 通常是安裝在 Linux 系統中的,可是目前 Windows 也能使用,下載安裝後開箱即用。額外須要配置的是:spring
1.暴露 TCP 端口,能夠在 IDEA 的 Docker 插件中鏈接使用。sql
2.替換官方的 Docker 倉庫,使用阿里雲鏡像加速。在 Daemon
中可進行配置。docker
Docker 自己是沒有 GUI 界面的,因此全部的維護管理都必須使用命令行,比較麻煩,而 IDEA 給咱們提供了一個簡單的 Docker 插件,用於管理 Image 和 Container。數據庫
在設置中直接搜索 docker,添加一個 Docker Engine,配置 URL,稍等下面提示鏈接成功後,就能夠了。若是鏈接失敗了,能夠檢查下 TCP 的 2375 端口是否暴露了。
而後在底部,就能看到 Docker 的 tab了。裏面的信息和命令行中看到的一致。基本的建立、刪除、端口映射等操做都能在上面進行。
那麼 Docker 相關的配置就完成了。
這裏用來演示的是一個 Spring Boot 的數據庫項目。跟以前同樣,配置一些基本內容就能夠了。
<!--pom.xml--> <groupId>com.example</groupId> <artifactId>spring-docker</artifactId> <version>1.0.0</version> <name>spring-docker</name> <properties> <java.version>1.8</java.version> <skipTests>true</skipTests> <druid-spring-boot-starter.version>1.1.10</druid-spring-boot-starter.version> <dockerfile-maven-plugin.version>1.4.10</dockerfile-maven-plugin.version> <docker.image.prefix>springboot</docker.image.prefix> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid-spring-boot-starter.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> </dependencies>
# application.yml # 配置數據庫信息 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://ip:port/test?serverTimezone=Hongkong&characterEncoding=utf-8&useSSL=false username: password:
// Spring Boot 啓動類 @SpringBootApplication @RestController public class SpringDockerApplication { private final JdbcTemplate jdbcTemplate; public SpringDockerApplication(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @GetMapping("/") public Message index() { RowMapper<Message> rowMapper= new BeanPropertyRowMapper<>(Message.class); Message msg = jdbcTemplate.queryForObject("select * from message where k = ?", rowMapper,"msg"); return msg; } public static void main(String[] args) { SpringApplication.run(SpringDockerApplication.class, args); } }
本地訪問,能成功運行就說明,Spring Boot 已經配置完成了。下面就是容器化的操做了。
容器化其實就是建立 Docker 鏡像的過程,須要把 jar 包封裝進去。具體有兩種方式:
首先,在 src/main
下建立 docker
文件夾,並建立一個 Dockerfile,內容以下:
FROM openjdk:8-jdk-alpine VOLUME /tmp COPY spring-docker-1.0.0.jar app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
假設你們對 Dockerfile 有必定的瞭解,解釋一下上面的內容,
openjdk
做爲基本鏡像,標籤爲:8-jdk-alpine,意思 jdk 版本爲 1.8,精簡版。VOLUME
指向 /tmp
的內容。由於這是 Spring Boot 應用程序默認爲 Tomcat 建立工做目錄的地方。效果是在 / var / lib / docker
下的主機上建立一個臨時文件,並將其連接到 /tmp
下的容器。app.jar
。java -jar
啓動項目。java.security.egd=file:/dev/./urandom
的目的是爲了縮短 Tomcat 啓動的時間。接下來,使用 maven 打包一個 jar,手動複製到 src/main/docker
目錄下。
配置 IDEA 來 build 和 run docker。
須要配置的參數以下:
點擊 Run。鏡像就會被自動 build,而且在容器中運行了。
選擇咱們剛剛部署的那個容器的 Log tab,就能看到 Spring Boot 啓動的日誌了,是否是有一種似曾相識的感受 😃
假設以前咱們鏈接的是本地的 MySQL那麼執行到這裏應該會報錯了,錯誤以下:
2019-08-27 10:37:04.197 ERROR 1 --- [eate-1939990953] com.alibaba.druid.pool.DruidDataSource : create connection SQLException, url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=Hongkong&characterEncoding=utf-8&useSSL=false, errorCode 0, state 08S01 com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure Caused by: java.net.ConnectException: Connection refused (Connection refused)
這是因爲咱們配置數據庫 url 出現了問題,本地數據庫,通常會寫 localhost
或 127.0.0.0.1
。可是這個地址在 Docker 容器中是不認的。因此連不上本地數據庫。幸虧 Docker 在安裝的時候配置了一個虛擬網橋,經過那個地址能夠和 Docker 容器內部進行通訊。
咱們在宿主機上的 cmd 中輸入 ipconfig
,就能夠看到。
C:\Users\mqy6289>ipconfig Windows IP 配置 以太網適配器 vEthernet (DockerNAT): 鏈接特定的 DNS 後綴 . . . . . . . : IPv4 地址 . . . . . . . . . . . . : 10.0.75.1 子網掩碼 . . . . . . . . . . . . : 255.255.255.240 默認網關. . . . . . . . . . . . . : 以太網適配器 以太網: 鏈接特定的 DNS 後綴 . . . . . . . : apac.arcsoft.corp 本地連接 IPv6 地址. . . . . . . . : fe80::c64:6e72:8311:378c%13 IPv4 地址 . . . . . . . . . . . . : 172.17.218.99 子網掩碼 . . . . . . . . . . . . : 255.255.224.0 默認網關. . . . . . . . . . . . . : 172.17.192.1
在 DockerNAT 中,宿主機的 ip 爲 10.0.75.1,將數據庫的 url ip 改爲這個。將以前的容器和鏡像刪除後,從新執行以前的步驟,發現部署成功。
在瀏覽器中輸入:http://127.0.0.1:8888/ ,就能看到 hello world 了。整個 Docker 部署的過程完成。
針對以前的網絡通訊問題,咱們能夠在 cmd 中輸入 docker inspect hello-world
來查看容器的參數。能夠看到容器的 IP 和網關的確不在一個網段,沒法進行通訊。
{ "Networks": { "bridge": { "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "MacAddress": "02:42:ac:11:00:02", } } }
以前咱們建立完 dockerfile
以後經過 IDEA 進行鏡像的 build 和 run 工做,一樣的咱們也能夠經過 Maven 插件將 Docker 鏡像和容器的構建和 Maven 集成起來。閱讀了不少博客,大多數任然使用 docker-maven-plugin
,可是這個插件早就已經被官方廢棄,不推薦使用,spotify 也推薦使用 dockerfile-maven-plugin
來代替。下面的 pom.xml 的配置:
<plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>${dockerfile-maven-plugin.version}</version> <configuration> <contextDirectory>src/main/docker</contextDirectory> <repository>${docker.image.prefix}/${project.artifactId}</repository> <tag>v1</tag> </configuration> </plugin>
刷新後,可在 IDEA 的 Maven tab 看到插件的功能,主要用到的就是 build、push、tag。
默認插件會找本地 tcp://localhost:2375
若是開啓了,雙擊 dockerfile:build
鏡像就會被 build 到 Docker 中去。
能夠看到,整個 build 的過程被放到 Maven 中去了。須要運行的話,選擇相應的鏡像,create container
再作簡單配置就能夠了。
1.數據庫鏈接不上。
本地數據庫須要配置支持遠程額訪問,因爲是 Windows,通常不會配置,可能會忽視。
UPDATE USER SET HOST = '%' WHERE USER = 'root'; FLUSH PRIVILEGES;
2.進入終端
咱們這個基礎鏡像是 Java,默認應該是不帶終端的,若是要查看的話,可再起一個容器
docker run -ti --entrypoint /bin/sh springboot/spring-docker:v1
進入後輸入 ls -al
,能夠看到以前複製過去的 app.jar
文件
本文主要講了若是在 Docker 中部署 Spring Boot 項目,針對於 Dockfile 的寫法和 Maven 插件的使用,能夠看參考文獻 5-6,裏面有更多的細節。我我的以爲這種部署方法,直接把 jar 和基本的環境打成一個 Docker 鏡像仍是過於簡單了,很難去作監控和管理。是否仍是應該像服務器部署那樣,建立一個基本的 Centos 鏡像,而後安裝 Java 的環境,經過 ssh 鏈接,直接把 jar 包和配置文件複製到容器中經過 bash 運行,這種方式可能更符合常理。後期若是工做上有需求,能夠再深度學習一下,看看實際生產中是如何操做的。