第一次通過docker部署java服務(wù)的全過程
為什么要學(xué)習(xí)docker
今天在網(wǎng)上學(xué)習(xí)項(xiàng)目時(shí),講到可以在本機(jī)裝docker部署服務(wù),也可以在服務(wù)器上使用docker部署。我對(duì)docker一無所知,哪怕是看項(xiàng)目的視頻講解也是一知半解,搞了一上午,連依葫蘆畫瓢都不會(huì)。于是,為了避免復(fù)雜項(xiàng)目對(duì)docker學(xué)習(xí)的影響,下午用了一個(gè)最簡(jiǎn)單的用戶crud項(xiàng)目來進(jìn)行學(xué)習(xí),最終將服務(wù)部署在docker上,成功調(diào)用了接口。
docker的優(yōu)勢(shì)
網(wǎng)上有很多的說明,這里大概講一下自己的理解。
第一,docker類似于一個(gè)可以隨時(shí)開關(guān)和添加刪除的虛擬機(jī),我們可以在虛擬機(jī)里裝各種環(huán)境,比如jdk、mysql、redis等等。如果哪天不需要了,直接刪除虛擬機(jī)即可,避免對(duì)主機(jī)進(jìn)行各種下載配置,容易出問題,且清理不干凈。
第二,這套部署好的環(huán)境是可移植的,也就是如果換了一個(gè)電腦,可以直接把這套docker部上去就能用,避免反復(fù)在電腦上各種配置環(huán)境,同樣,它也可以方便的移植到云服務(wù)器上。這個(gè)有點(diǎn)像U盤的功能。
前期準(zhǔn)備
需要本地先下載docker再進(jìn)行,其他老生常談。
項(xiàng)目結(jié)構(gòu)
src/ ├── main/ │ ├── java/com/example/demo/ │ │ ├── controller/UserController.java │ │ ├── mapper/UserMapper.java │ │ ├── model/User.java │ │ └── DockerDemoApplication.java │ └── resources/ │ ├── application.yml | ├── application-dev.yml | ├── application-docker.yml │ └── mybatis/mapper/UserMapper.xml Dockerfile docker-compose.yml init.sql
業(yè)務(wù)代碼
業(yè)務(wù)就是寫了個(gè)用戶類,通過controller和mapper對(duì)用戶進(jìn)行crud,主要是為了測(cè)試mysql在docker上的部署。init.sql是建表語句。
配置類application.yml
使用docker部署服務(wù)和mysql,第一個(gè)注意點(diǎn)在于三個(gè)application配置文件。application.yml配置各個(gè)環(huán)境共有的配置,而application-dev.yml和application-docker.yml僅聲明不同值的配置項(xiàng)。詳細(xì)見如下:
# application.yml
server:
port: 8080
spring:
profiles:
active: dev
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: 111
username: 111
password: 111
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
configuration:
map-underscore-to-camel-case: true
# application-dev.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/testdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
username: root
password: 123456
# application-docker.yml
spring:
datasource:
url: ${SPRING_DATASOURCE_URL}
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
首先看application.yml,里面有全量的配置項(xiàng),可以通過修改spring.profiles.active的值來對(duì)不同環(huán)境的值進(jìn)行生效。如當(dāng)配置為dev時(shí),url、username、password的值會(huì)被替換為application-dev.yml對(duì)應(yīng)的配置項(xiàng)值。
application-docker.yml的值均為占位符,這個(gè)占位符來自于docker相關(guān)的配置項(xiàng)。當(dāng)使用docker部署java服務(wù)時(shí),這些值會(huì)被替換掉。詳細(xì)見下面的分析。
Dockerfile
Dockerfile用于構(gòu)造單個(gè)容器,比如這里就是構(gòu)造java容器。
FROM openjdk:8-jdk # 使用jdk8的鏡像 WORKDIR /app # 設(shè)置容器的工作目錄為app,可以隨意命名 COPY target/*.jar app.jar # 將jar包拷貝到app目錄之下 EXPOSE 8080 # 容器的服務(wù)端口為8080 CMD ["java", "-jar", "app.jar"] # 容器啟動(dòng)時(shí)執(zhí)行的命令:運(yùn)行Java應(yīng)用
docker-compose.yml
docker-compose用于多個(gè)容器的構(gòu)造和編排,比如當(dāng)服務(wù)涉及前端、后端、mysql等多個(gè)容器時(shí),可以定義其構(gòu)造關(guān)系。本樣例僅涉及java和mysql兩個(gè)容器,java的啟動(dòng)依賴于mysql,也就是只有mysql容器起來后才能構(gòu)造java。
具體配置如下:
version: '3.8'
services:
mysql:
image: mysql:8.0 # docker的mysql版本
container_name: mysql-container # 容器名稱
environment: # root賬號(hào)信息,涉及的數(shù)據(jù)庫
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: testdb
ports: # 端口,前面為暴露到公網(wǎng)的端口(與主機(jī)公用),后面為docker內(nèi)部占用的端口
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
healthcheck:
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot" ]
interval: 5s
timeout: 10s
retries: 20
app:
build: .
container_name: app-container
depends_on: # 添加依賴關(guān)系
mysql:
condition: service_healthy
ports:
- "8080:8080"
environment: # 環(huán)境變量,這里與application-docker.yml進(jìn)行呼應(yīng),且需要與上面的mysql信息一致(登陸賬號(hào)信息)
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/testdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 123456
links:
- mysql
volumes:
mysql-data:
全docker啟動(dòng)
上述配置好,即可將服務(wù)和mysql用docker啟動(dòng)。點(diǎn)擊docker-compose.yml的services左邊的按鈕即可。

在docker客戶端上也可以看到相關(guān)執(zhí)行情況。

通過postman請(qǐng)求本地的接口,可以看到請(qǐng)求成功。

架構(gòu)圖大致長(zhǎng)這樣

怎么debug?
將服務(wù)部署在docker后,可以測(cè)試,也可以通過docker查看日志等信息,但問題在于,我想debug怎么辦呢?
在不使用docker的情況下,是在idea上點(diǎn)擊SpringBootApplication來啟動(dòng)服務(wù)的,并且可以選擇debug模式。如果用idea啟動(dòng)了java服務(wù),那mysql服務(wù)怎么辦,以及java服務(wù)怎么訪問mysql?
答案是這樣的:docker-compose.yml包括了兩個(gè)容器的啟動(dòng),可以選擇僅啟動(dòng)mysql,只需要點(diǎn)擊mysql 左邊的按鈕即可。而java服務(wù)按照原來的方式去啟動(dòng),只不過這里要注意,spring.profiles.active需要改為dev,并按照上述配置文件,配置好mysql連接串、賬號(hào)信息即可。
架構(gòu)圖是這樣

踩坑點(diǎn)
mysql端口與主機(jī)沖突
之前提到,mysql容器配置的端口為3306:3306,前面的端口會(huì)和主機(jī)共享。所以如果主機(jī)本就安裝了mysql并且啟動(dòng)了,需要把mysql停掉,否則mysql容器部署會(huì)失敗,因?yàn)槟J(rèn)就是這個(gè)端口。(或者換一個(gè)端口部署)
添加數(shù)據(jù)時(shí)服務(wù)報(bào)錯(cuò):表不存在
mysql部署成功后,需要登陸docker進(jìn)入mysql,手動(dòng)創(chuàng)建需要的表,否則在插入表時(shí)會(huì)報(bào)錯(cuò),因?yàn)楸聿粫?huì)自動(dòng)創(chuàng)建。應(yīng)該還有別的方式,比如在mysql啟動(dòng)時(shí),可以關(guān)聯(lián)init.sql文件進(jìn)行sql執(zhí)行,不過這需要考慮之前的表數(shù)據(jù)是否會(huì)清空或者發(fā)生沖突的問題,這塊還沒有仔細(xì)研究。
【重要】默認(rèn)的鏡像源無法下載鏡像(403 forbidden)
部署mysql容器時(shí),鏡像拉不下來,搜索后發(fā)現(xiàn)要修改鏡像源,參考:status.1panel.top/status/dock…
也可以在docker客戶端手動(dòng)修改:

尾聲
有三點(diǎn)想說的:
- 本次的docker學(xué)習(xí)完全靠deepseek來進(jìn)行,全程幾乎沒有查閱其他資料;
- 本次學(xué)習(xí)僅停留在簡(jiǎn)單的demo實(shí)現(xiàn)層面,關(guān)于docker還有很多花式操作以及原理,還需要日后涉及到再學(xué)習(xí);
- 學(xué)習(xí)方法總結(jié):要控制變量法的學(xué)習(xí),比如學(xué)習(xí)docker,就不能和很復(fù)雜的項(xiàng)目相結(jié)合,項(xiàng)目只是一個(gè)學(xué)習(xí)docker的依托,一定要越簡(jiǎn)單越好。
到此這篇關(guān)于通過docker部署java服務(wù)的文章就介紹到這了,更多相關(guān)docker部署java服務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java集合框架的體系結(jié)構(gòu)詳細(xì)說明
最近在一本J2EE的書中看到了很不錯(cuò)的對(duì)集合框架的說明文章2012-11-11
springboot @Value實(shí)現(xiàn)獲取計(jì)算機(jī)中絕對(duì)路徑文件的內(nèi)容
這篇文章主要介紹了springboot @Value實(shí)現(xiàn)獲取計(jì)算機(jī)中絕對(duì)路徑文件的內(nèi)容,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2021-09-09
Java MQTT實(shí)戰(zhàn)應(yīng)用
本文詳解MQTT協(xié)議,涵蓋其發(fā)布/訂閱機(jī)制、低功耗高效特性、三種服務(wù)質(zhì)量等級(jí)(QoS0/1/2),以及客戶端、代理、主題的核心概念,最后提供Linux部署教程、SpringBoot整合方法與MQTTX工具下載鏈接,對(duì)java mqtt相關(guān)知識(shí)感興趣的朋友一起看看吧2025-06-06
使用注解@Validated和BindingResult對(duì)入?yún)⑦M(jìn)行非空校驗(yàn)方式
這篇文章主要介紹了使用注解@Validated和BindingResult對(duì)入?yún)⑦M(jìn)行非空校驗(yàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
java計(jì)算兩個(gè)日期之前的天數(shù)實(shí)例(排除節(jié)假日和周末)
下面小編就為大家?guī)硪黄猨ava計(jì)算兩個(gè)日期之前的天數(shù)實(shí)例(排除節(jié)假日和周末)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07
Java常用API類之Math System tostring用法詳解
System類代表系統(tǒng),系統(tǒng)級(jí)的很多屬性和控制方法都放置在該類的內(nèi)部。該類位于java.lang包,Java 的 Math 包含了用于執(zhí)行基本數(shù)學(xué)運(yùn)算的屬性和方法,如初等指數(shù)、對(duì)數(shù)、平方根和三角函數(shù),toString() 方法用于返回以一個(gè)字符串表示的 Number 對(duì)象值2021-10-10

