使用Java后端操作Docker的詳細(xì)教程
一、為什么要用后端程序操作Docker
Docker 是現(xiàn)代開發(fā)和部署流程中不可或缺的一部分。它簡化了應(yīng)用程序的環(huán)境配置、打包和分發(fā),使得在不同機(jī)器上運(yùn)行相同的應(yīng)用變得更加輕松和一致。本文將詳細(xì)介紹如何使用命令行工具(CMD)操控 Docker 來配置環(huán)境。
實現(xiàn)后端操作docker,可以用來實現(xiàn)云端IDE、一鍵環(huán)境搭建、多人協(xié)作環(huán)境、互動編程教學(xué)、可視化部署和管理等等功能。是Docker從服務(wù)器走向客戶端的必經(jīng)之路。
二、安裝Docker
1、安裝Docker
我寫過一份詳細(xì)的博客,請移步:Docker的基本概念、安裝步驟以及一些簡單的用法_docker_腳本之家
2、啟動Docker
安裝完成后,啟動 Docker Desktop,并確保其正常運(yùn)行??梢栽?CMD 中通過以下命令來驗證:
docker --version
三、使用Java后端操作docker
1、構(gòu)建docker鏡像并生成容器
這一步的目的是通過Docker根據(jù)本地目錄中的DockerFlie文件、代碼、和其他配置數(shù)據(jù)文件生成新的鏡像,并生成容器。
一個簡單的DockerFile示例:
# 使用官方Python運(yùn)行時作為父鏡像 FROM python:3.8-slim # 設(shè)置工作目錄 WORKDIR /app # 將當(dāng)前目錄內(nèi)容復(fù)制到位于/app中的容器中 COPY . /app # 安裝requirements.txt中指定的任何所需包 RUN pip install --no-cache-dir -r requirements.txt # 使端口80可供此容器外的環(huán)境使用 EXPOSE 80 # 定義環(huán)境變量 ENV NAME World # 在容器啟動時運(yùn)行app.py CMD ["python", "app.py"]
其中0419test是構(gòu)建鏡像的tag名。
注意修改工作目錄,將其改為你實際的文件夾目錄。
public void buildImageAndContainer(){
try {
// 設(shè)置第一個命令:構(gòu)建Docker鏡像
ProcessBuilder buildProcessBuilder = new ProcessBuilder("docker", "build", "-t", "test0419", ".");
// 設(shè)置工作目錄為 "E:\\code\\docker\\test"
buildProcessBuilder.directory(new File("E:\\code\\docker\\test"));
// 啟動構(gòu)建鏡像的命令并等待其完成
Process buildProcess = buildProcessBuilder.start();
buildProcess.waitFor();
// 讀取并打印出構(gòu)建鏡像的輸出
printProcessOutput(buildProcess);
// 檢查構(gòu)建是否成功
if (buildProcess.exitValue() == 0) {
// 設(shè)置第二個命令:運(yùn)行Docker容器
ProcessBuilder runProcessBuilder = new ProcessBuilder("docker", "run", "-v", "E:/code/docker/test:/app", "-p", "80:80", "test0419");
// 啟動運(yùn)行容器的命令
Process runProcess = runProcessBuilder.start();
// 讀取并打印出運(yùn)行容器的輸出
printProcessOutput(runProcess);
// 可以在這里等待容器運(yùn)行的進(jìn)程結(jié)束,或者根據(jù)需要進(jìn)行其他操作
// runProcess.waitFor();
} else {
System.out.println("Docker image build failed.");
}
} catch (IOException | InterruptedException e) {
System.out.println(e);
e.printStackTrace();
}
}
// 輸出打印內(nèi)容的私有方法
private static String printProcessOutput(Process process) throws IOException {
String output;
String errorInfo;
// 讀取并打印標(biāo)準(zhǔn)輸出
output = readAndPrint(process.getInputStream(), "");
// 讀取并打印標(biāo)準(zhǔn)錯誤
errorInfo = readAndPrint(process.getErrorStream(), "");
return output+errorInfo;
}
private static String readAndPrint(InputStream inputStream, String prefix) throws IOException {
StringBuilder output = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) {
output.append(prefix).append(line).append(System.lineSeparator());
System.out.println(prefix + line); // 同時打印到控制臺
}
}
return output.toString();
}2、執(zhí)行完畢后刪除容器和鏡像
刪除容器和鏡像,釋放資源,一般在容器執(zhí)行完代碼之后運(yùn)行。
// 刪除容器和鏡像
public String deleteContainerAndImage(String imageName){
// 定義一個線程池用于執(zhí)行刪除操作
ExecutorService executorService = Executors.newFixedThreadPool(2);
// 異步獲取容器 ID 列表并刪除容器
executorService.submit(() -> {
try {
List<String> containerIds = new ArrayList<>();
String command = "docker ps -a -q --filter ancestor=" + imageName;
ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
containerIds.add(line.trim());
}
int exitCode = process.waitFor();
if (exitCode != 0) {
System.err.println("Command executed with error. Exit code: " + exitCode);
return ;
}
// 刪除容器
for (String containerId : containerIds) {
String deleteContainerCommand = "docker rm -f " + containerId;
executeCommand(deleteContainerCommand);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
});
// 異步刪除鏡像
executorService.submit(() -> {
// 等待容器被刪除
try {
TimeUnit.SECONDS.sleep(5); // 等待5秒,可以根據(jù)實際情況調(diào)整
// 同樣,如果你使用的是Docker,可以使用以下命令:
String deleteImageCommand = "docker rmi " + imageName;
executeCommand(deleteImageCommand);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 關(guān)閉線程池
executorService.shutdown();
return "鏡像與容器已刪除";
}
// 用來執(zhí)行cmd命令的方法
private void executeCommand(String command) {
try {
// 使用ProcessBuilder執(zhí)行命令
ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
Process process = processBuilder.start();
// 調(diào)用已有的方法來打印輸出
printProcessOutput(process);
// 等待進(jìn)程結(jié)束
int exitCode = process.waitFor();
if (exitCode != 0) {
// 處理非零退出碼,可能表示命令執(zhí)行出錯
System.err.println("Command executed with error. Exit code: " + exitCode);
}
} catch (IOException e) {
// 處理命令執(zhí)行過程中可能遇到的IO異常
e.printStackTrace();
} catch (InterruptedException e) {
// 如果waitFor()方法被中斷,重新設(shè)置中斷狀態(tài)并處理
Thread.currentThread().interrupt();
e.printStackTrace();
} catch (Exception e) {
// 處理命令字符串分割可能出現(xiàn)的異常
e.printStackTrace();
}
}3、在此基礎(chǔ)上開發(fā)其他功能
在生成與刪除之間,就可以自由添加和微調(diào)其中的部分步驟,比如刪除DockerFile中的CMD ["python", "app.py"],讓容器持續(xù)化后臺運(yùn)行,這樣就可以通過宿主機(jī)與容器的文件映射關(guān)系修改代碼內(nèi)容,然后擇機(jī)運(yùn)行代碼了;又比如創(chuàng)建一個滿足需求的鏡像,然后只創(chuàng)建和刪除容器來節(jié)省服務(wù)器資源等等。
四、總結(jié)
到此這篇關(guān)于使用Java后端操作Docker的詳細(xì)教程的文章就介紹到這了,更多相關(guān)Java后端操作Docker內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?Cache抽象-使用SpEL表達(dá)式解析
這篇文章主要介紹了Spring?Cache抽象-使用SpEL表達(dá)式解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
Spring Security自定義身份認(rèn)證的實現(xiàn)方法
這篇文章主要介紹了Spring Security自定義身份認(rèn)證的實現(xiàn)方法,下面對Spring Security的這三種自定義身份認(rèn)證進(jìn)行詳細(xì)講解,需要的朋友可以參考下2025-04-04
Cursor IDE中SpringBoot項目啟動內(nèi)存不足問題的解決方案
在CursorIDE中運(yùn)行SpringBoot項目時,可能出現(xiàn)啟動失敗、報錯等問題,這些問題通常與JVM內(nèi)存設(shè)置不當(dāng)有關(guān),本文總結(jié)了多種解決方案,需要的朋友可以參考下2026-04-04
java微信公眾號開發(fā)(搭建本地測試環(huán)境)
這篇文章主要介紹了java微信公眾號開發(fā),主要內(nèi)容有測試公眾號與本地測試環(huán)境搭建,需要的朋友可以參考下2015-12-12
Spring Boot 自動配置的底層實現(xiàn)原理深度解析
SpringBoot自動配置的核心在于通過“約定+條件判斷”實現(xiàn)配置的自動化加載與生效,其底層實現(xiàn)可以拆解為觸發(fā)入口、配置類加載、條件過濾、Bean注冊和配置覆蓋五個核心環(huán)節(jié),本文介紹Spring Boot自動配置的底層實現(xiàn)原理,感興趣的朋友一起看看吧2025-12-12
關(guān)于Android觸摸事件分發(fā)的原理詳析
觸摸事件分發(fā)機(jī)制一直以來都是Android中比較重要的一大塊,自定義view,各種復(fù)雜的自定義手勢交互都與觸摸事件分發(fā)機(jī)制關(guān)系密,下面這篇文章主要給大家介紹了關(guān)于Android觸摸事件分發(fā)原理的相關(guān)資料,需要的朋友可以參考下2022-01-01

