1、問(wèn)題描述
????????我用Dockerfile在Ubuntu環(huán)境中建造了一個(gè)名為hellojava的Docker鏡像,Dockerfile如下所示:
FROM openjdk:latest
CMD java -cp? Docker-1.0-SNAPSHOT.jar Docker.Application
????????其中Docker-1.0-SNAPSHOT.jar是與Dockerfile同目錄的jar包,Docker.Application是jar包中main方法所在類。當(dāng)運(yùn)行這個(gè)鏡像時(shí),計(jì)算機(jī)報(bào)"Error: Could not find or load main class Docker.Application",也就是無(wú)法找到或加載這個(gè)主類。我在本機(jī)中運(yùn)行這個(gè)命令就能成功執(zhí)行,但是在Docker中就不行。
2、問(wèn)題解決
? ? ? ? 我還以為是JDK版本和Docker的兼容性問(wèn)題,又陸續(xù)換了幾個(gè)JDK版本,但還是無(wú)法解決。后來(lái)我就將問(wèn)題歸結(jié)為路徑問(wèn)題,也就是在Docker的文件系統(tǒng)中無(wú)法中找到j(luò)ar包,因?yàn)槲以诒镜丨h(huán)境中特意輸錯(cuò)jar包的路徑也是報(bào)這個(gè)錯(cuò)誤。為了驗(yàn)證我的猜想,我重溫了Docker官網(wǎng)上的Dockerfile文件:

????????果不其然,官網(wǎng)的Dockerfile文件中有兩個(gè)關(guān)于目錄的配置:
WORKDIR:指定了Docker文件系統(tǒng)中的工作目錄。
ADD:該指令有兩個(gè)參數(shù),第一個(gè)是當(dāng)前文件系統(tǒng)中指定的目錄,第二個(gè)是Docker文件系統(tǒng)中的目錄。 該指令的意思是將當(dāng)前文件系統(tǒng)中指定目錄中的內(nèi)容拷貝到Docker文件系統(tǒng)中的指定目錄。
????????因此產(chǎn)生以上錯(cuò)誤的原因是沒(méi)有把當(dāng)前目錄上的jar包拷貝到Docker文件系統(tǒng)中,于是將本機(jī)中的jar包拷貝到Docker文件系統(tǒng),問(wèn)題就會(huì)迎刃而解了。
? ? ? ? 解決方法:參照官網(wǎng)的Dockerfile,在CMD命令前加上工作目錄,并將當(dāng)前文件系統(tǒng)中的jar包拷貝到工作目錄下:
FROM openjdk:last ? ?#使用已有鏡像作為父鏡像
WORKDIR /app ? ?#將Docker文件系統(tǒng)中的/app目錄設(shè)為工作目錄,當(dāng)執(zhí)行命令時(shí)默認(rèn)是在該目錄下執(zhí)行
ADD . /app ? ?#將當(dāng)前目錄下的文件拷貝到 Docker文件系統(tǒng)中的/app目錄
CMD java -cp? Docker-1.0-SNAPSHOT.jar Docker.Application ? ?#執(zhí)行命令
????????當(dāng)然還有一個(gè)命令可以實(shí)現(xiàn)拷貝功能,也就是COPY命令,將ADD命令改為COPY命令也可以解決該問(wèn)題。
3、總結(jié)
????????Docker文件系統(tǒng)是獨(dú)立于本機(jī)文件系統(tǒng)的,也就是說(shuō)運(yùn)行docker命令是在Docker文件系統(tǒng)中搜索文件,如果以本機(jī)文件系統(tǒng)中的指定路徑作為參數(shù),就無(wú)法找到文件。因此,必須將文件拷貝到Docker文件系統(tǒng)中,才可以找到該文件。