概念篇: 01-帶你認識Dockerfile

在本篇文章中,我們將帶你認識 Dockerfile —— 構建 Docker 鏡像的"藍圖"。我們會介紹它的基本概念和常用指令,幫助你理解如何使用它來打包你的應用。

簡單了解 Docker(背景知識)

在我們深入 Dockerfile 之前,簡單回顧一下幾個核心概念:

  • Docker 是什么?想象一下集裝箱:無論里面裝什么貨物(代碼、庫、配置),集裝箱本身(Docker)都能讓貨物在任何港口(任何機器環境)輕松裝卸和運行。Docker 就是這樣一個能打包、發布和運行應用程序的平臺。
  • 容器 (Container) 是什么?它是一個運行起來的、包含了應用及其所有依賴的標準化單元。你可以把它看作一個輕量級的、隔離的"小虛擬機"。
  • 鏡像 (Image) 是什么?它是創建容器的只讀模板或"快照"。Dockerfile 就是用來定義如何構建這個鏡像的說明書。

對中小企業的好處:使用 Docker 可以幫助團隊實現開發、測試、生產環境的一致性,減少"在我電腦上明明是好的"這類問題,加快應用上線速度,并更有效地利用服務器資源。

Dockerfile 是什么?

Dockerfile 本質上是一個文本文件,里面包含了一系列的指令 (Instructions)和參數。每一條指令描述了在構建鏡像過程中的一個步驟,例如:需要哪個基礎環境、要安裝什么軟件、拷貝哪些文件進去、容器啟動時要運行什么命令等等。

Dockerfile 的基本規則:

  • 指令不區分大小寫,但推薦使用大寫,更清晰。
  • 使用#開頭的行是注釋。
  • 通常,Dockerfile 的第一條指令是FROM,指定基礎鏡像。
  • 每一條指令都會在鏡像中創建新的一層 (Layer)。

一個典型的 Dockerfile 結構可能包含:

  1. 基礎鏡像信息:使用FROM指令指定依賴的基礎鏡像。
  2. (可選) 維護者信息:使用LABEL指令添加元數據。
  3. 鏡像構建指令:使用RUN,COPY,ADD等指令來安裝軟件、復制文件等。
  4. 容器啟動指令:使用CMD,ENTRYPOINT等指令指定容器啟動時執行的命令。

Dockerfile 常用指令詳解

下面我們來逐一了解一些最常用的 Dockerfile 指令:

FROM

用途:指定構建新鏡像所依賴的基礎鏡像。必須是 Dockerfile 的第一條非注釋指令。

格式:

FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

示例:

# 使用官方的 Ubuntu 最新版作為基礎鏡像
FROM ubuntu:latest
# 使用特定版本的 Alpine Linux 作為基礎鏡像,并給這個階段命名為 builder
FROM alpine:3.18 AS builder

中小企業提示:選擇基礎鏡像很重要!盡量選擇官方、受信任且體積小的鏡像(如alpine、debian-slim),可以顯著減小最終鏡像的大小,加快下載和部署速度,并減少安全風險。

LABEL

用途:為鏡像添加元數據 (Metadata),如版本號、描述、作者等。這些信息不會影響鏡像功能,但有助于管理和識別鏡像。

格式:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

示例:

LABEL version="1.0" description="我的第一個 Web 應用鏡像" maintainer="Your Name <you@example.com>"

RUN

用途:在構建鏡像過程中執行指定的命令。通常用于安裝軟件包、創建目錄、編譯代碼等。

格式:

# Shell 格式 (簡單命令推薦)
RUN <command># Exec 格式 (官方推薦,尤其適合包含空格或特殊字符的命令)
RUN ["executable", "param1", "param2"]

示例:

# 更新軟件包列表并安裝 Nginx (Shell 格式)
RUN apt-get update && apt-get install -y nginx
# 創建一個目錄 (Exec 格式)
RUN ["mkdir", "/app"]

最佳實踐:盡量將多個RUN命令合并成一條,使用&&連接。因為每條RUN指令會創建一個新的鏡像層,合并命令可以減少層數,優化鏡像體積和構建速度。同時,在安裝包后清理緩存(如apt-get clean)也是個好習慣。

RUN apt-get update && \apt-get install -y --no-install-recommends software-properties-common && \apt-get clean && \rm -rf /var/lib/apt/lists/*

CMD

用途:指定容器啟動時默認執行的命令。一個 Dockerfile 中只應有一個CMD指令,如果寫了多個,只有最后一個會生效。

格式:

# Shell 格式
CMD command param1 param2# Exec 格式 (官方推薦)
CMD ["executable","param1","param2"]# 作為 ENTRYPOINT 的默認參數 (后面會講)
CMD ["param1","param2"]

示例:

# 容器啟動時運行 python server.py (Exec 格式)
CMD ["python", "server.py"]# 容器啟動時執行 /bin/bash (Shell 格式)
CMD /bin/bash

注意:如果在docker run命令后面指定了其他命令,CMD指定的命令會被覆蓋。

ENTRYPOINT

用途:配置容器啟動時總是執行的命令。它與CMD類似,但更常用于將容器設置為一個"可執行程序"。

格式:

# Shell 格式
ENTRYPOINT command param1 param2# Exec 格式 (官方推薦)
ENTRYPOINT ["executable", "param1", "param2"]

ENTRYPOINT和CMD的配合使用:

  • 如果只用ENTRYPOINT(Exec 格式),docker run命令行后面的參數會追加到ENTRYPOINT命令之后。
  • 如果同時使用ENTRYPOINT(Exec 格式) 和CMD(Exec 格式,且CMD提供的是參數列表),CMD的內容會作為ENTRYPOINT的默認參數。如果在docker run時提供了參數,則會覆蓋CMD提供的默認參數。
    示例:
# Dockerfile
ENTRYPOINT ["ls"]
CMD ["-a"]# 運行 `docker run <image>` 時,實際執行 `ls -a`
# 運行 `docker run <image> -l` 時,實際執行 `ls -l` (-l 覆蓋了 CMD 的 -a)
何時使用?如果你想讓容器表現得像一個固定的可執行文件,并且允許用戶傳遞參數給這個文件,那么ENTRYPOINT(Exec 格式) +CMD(參數格式) 是常用模式。如果只是想提供一個默認的啟動命令,且允許用戶完全替換它,那么單獨使用CMD更簡單。

EXPOSE

用途:聲明容器在運行時計劃監聽的網絡端口。這并不會自動將端口發布到主機,它更像是一個文檔記錄和元數據,告訴使用者這個容器打算使用哪個端口。

格式:

EXPOSE <port> [<port>/<protocol>...]
示例:# 聲明容器將監聽 80 端口 (默認 TCP)
EXPOSE 80# 聲明容器將監聽 80/tcp 和 443/tcp 端口
EXPOSE 80/tcp 443/tcp

注意:要想從主機訪問容器的這個端口,你仍然需要在docker run時使用-p或-P參數來做端口映射。例如:docker run -p 8080:80 將主機的 8080 端口映射到容器的 80 端口。

VOLUME

用途:創建一個掛載點,用于持久化存儲數據或在容器間共享數據。它可以將主機的目錄或 Docker 管理的卷掛載到容器內的指定路徑。

格式:

VOLUME ["<path1>", "<path2>"...]
VOLUME <path>

示例:

# 聲明 /data 目錄用于存儲持久化數據VOLUME ["/data"]# 聲明 /app/config 和 /app/logs 用于掛載配置和日志
VOLUME /app/config /app/logs

注意:VOLUME指令創建的掛載點,其數據默認不會包含在鏡像中,并且在容器刪除后,Docker 管理的卷通常仍然存在(除非顯式刪除)。這使得數據可以在容器生命周期之外保持不變。在docker run時,可以使用-v參數將主機目錄或命名卷掛載到這里。

COPY

用途:將構建上下文(通常是 Dockerfile 所在的目錄及其子目錄)中的文件或目錄復制到鏡像內的指定路徑。

格式:

COPY [--chown=<user>:<group>] [--chmod=<perms>] <src>... <dest>
COPY [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"] # 路徑含空格時推薦

示例:

# 將當前目錄下的 app.py 文件復制到鏡像的 /app/ 目錄下
COPY app.py /app/# 將當前目錄下的 config 目錄復制到鏡像的 /etc/myapp/config/ 目錄下
COPY config/ /etc/myapp/config/

最佳實踐:

  • 只復制你需要的文件和目錄,避免將不必要的文件(如.git目錄、臨時文件)復制進鏡像。可以使用.dockerignore文件來排除它們。
  • 相比ADD,COPY的行為更明確(只復制本地文件),通常是首選。

ADD

用途:與COPY類似,但功能更強大:

  1. 可以復制本地文件/目錄到鏡像。
  2. 如果源是一個URL,它會嘗試下載文件并復制到。
  3. 如果源是一個本地的tar 壓縮包(如.tar.gz,.tar.bz2,.tar.xz),它會自動解壓到。
    格式:與COPY相同。

示例:

# 下載一個文件并放到 /tmp/
ADD https://example.com/file.zip /tmp/# 復制本地的 myapp.tar.gz 并自動解壓到 /usr/src/
ADD myapp.tar.gz /usr/src/

注意:由于ADD的行為(特別是自動解壓和下載)有時不夠透明和可控,官方更推薦:

  • 復制本地文件/目錄:使用COPY。
  • 下載文件:使用RUN wget或RUN curl,這樣更清晰,且可以在同一步驟中進行解壓、清理等操作。

ENV

用途:設置環境變量。這些變量在后續的RUN指令中可用,并且在容器運行時也會保留。

格式:

ENV <key>=<value> ...
ENV <key> <value> # 舊格式,不推薦

示例:

# 設置應用版本和工作目錄
ENV APP_VERSION="1.0" WORK_DIR="/app"# 在后續指令中使用環境變量
WORKDIR $WORK_DIR
RUN echo "Building version $APP_VERSION" > version.txt

注意:使用ENV設置的環境變量會持久存在于鏡像和容器中。如果只是想在構建過程中臨時使用變量,應該考慮使用ARG。

ARG

用途:定義構建時變量。這些變量只在docker build過程中有效,容器運行時不可用(除非用ENV重新定義)。可以通過docker build --build-arg =來傳遞值。

格式:

ARG <name>[=<default value>]

示例:

# 定義一個構建時參數 USER,默認值為 guest
ARG USER=guest# 定義一個沒有默認值的參數 PASSWORD
ARG PASSWORDRUN useradd $USER
# RUN echo "Password is $PASSWORD" # 可以在構建時使用# 如果希望構建參數在容器中也可用,可以結合 ENV
ARG APP_PORT=8080
ENV PORT=$APP_PORT
EXPOSE $PORT
構建時傳遞參數:# 傳遞 USER 參數
docker build --build-arg USER=admin -t myimage .# 同時傳遞 USER 和 PASSWORD 參數
docker build --build-arg USER=admin --build-arg PASSWORD=secret -t myimage .

何時使用?當你需要根據不同的構建環境(如開發、測試、生產)傳入不同的配置(如代理服務器地址、特定版本號),或者不想將敏感信息(如密碼、token)硬編碼到 Dockerfile 或ENV中時,ARG是很好的選擇。

WORKDIR

用途:設置后續RUN,CMD,ENTRYPOINT,COPY,ADD指令的工作目錄。如果指定的目錄不存在,它會自動創建。

格式:

WORKDIR /path/to/workdir

示例:

WORKDIR /app# 下面的 COPY 和 RUN 都在 /app 目錄下執行
COPY . .
RUN pip install -r requirements.txtWORKDIR /data
# 現在工作目錄切換到了 /data# 可以使用相對路徑
WORKDIR /app
WORKDIR sub-dir # 現在的工作目錄是 /app/sub-dir
RUN pwd # 輸出 /app/sub-dir

最佳實踐:推薦使用絕對路徑,并盡量在 Dockerfile 開頭就設置好主要的工作目錄,避免在根目錄 (/) 下執行過多操作。

以上就是 Dockerfile 中一些最核心、最常用的指令。理解并熟練運用它們,是編寫高效、規范 Dockerfile 的基礎。
你也可以查閱Docker 官方文檔獲取更全面的指令列表和詳細信息。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/86306.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/86306.shtml
英文地址,請注明出處:http://en.pswp.cn/web/86306.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

技術倫理之爭:OpenAI陷抄襲風波,法院強制下架宣傳視頻

在AI巨頭OpenAI宣布以65億美元天價收購蘋果前設計總監Jony Ive的硬件公司IO僅一個月后&#xff0c;一場抄襲指控將這家科技明星企業推上風口浪尖。 源自谷歌X實驗室的初創企業IYO將OpenAI告上法庭&#xff0c;指控其竊取智能耳塞核心技術&#xff0c;并通過巨額收購試圖掩蓋抄襲…

前沿解讀:缺陷如何操控二維半導體中的電子摩擦耗散超快動力學

摩擦能耗約占全球一次能源損耗的1/3&#xff0c;在微納器件中尤為突出。二維半導體&#xff08;如WS?&#xff09;因其獨特的電子特性成為研究熱點&#xff0c;但電子摩擦的動態機制因電子行為的超快特性長期難以捕捉。近期清華團隊在Nature Communications發表的研究[1]&…

什么是物聯網 (IoT)?

你家是否安裝了智能恒溫器&#xff1f;或者你屬于三分之一的美國健身追蹤器用戶&#xff0c;通過設備記錄運動習慣&#xff1f;如果是&#xff0c;你已在使用物聯網技術。這項技術不僅融入日常生活&#xff0c;更深刻改變著組織的運營方式。物聯網通過多種技術連接數字與物理世…

[特殊字符] Windows 查看端口占用及服務來源教程(以 9018 端口為例)

下面是一份詳細的 Windows 系統中排查 某端口&#xff08;如 9018&#xff09;被哪個程序占用 并確定其具體服務來源的完整教程&#xff0c;適合用于日常運維、開發部署排障等場景。 &#x1f3af; Windows 查看端口占用及服務來源教程&#xff08;以 9018 端口為例&#xff09…

異步爬蟲 原理與解析

先遍歷100遍一個程序 import requests import logging import timelogging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s: %(message)s) TOTAL_NUMBER 100 BASE_URL https://ssr4.scrape.center/start_time time.time() for id in range(1,TOTAL_NUM…

vscode管理go多個版本

#1.下載go安裝包 https://developer.aliyun.com/mirror/golang/?spma2c6h.25603864.0.0.55ea7c45IsI4GM # 2.創建 sdk 目錄&#xff08;如果不存在&#xff09; mkdir -p ~/sdk # 3.解壓下載的 go1.16.15 到 ~/sdk/ tar -C ~/sdk -xzf go1.16.15.linux-amd64.tar.gz # 4.重…

香港維爾利健康科技集團推出AI輔助醫學影像訓練平臺,助力醫護人才數字化轉型

香港維爾利健康科技集團近日正式發布其自主研發的“AI輔助醫學影像訓練平臺&#xff08;V-MedTrain&#xff09;”&#xff0c;這一創新平臺的上線&#xff0c;標志著醫學影像教育邁入智能化輔助教學新時代。依托人工智能與大數據分析技術&#xff0c;香港維爾利健康科技集團在…

互聯網+醫療,醫療服務的全方位革新

近年來&#xff0c;互聯網醫療行業迅速崛起&#xff0c;為醫療健康服務帶來了翻天覆地的變革。新模式、新業態層出不窮&#xff0c;不僅大幅提升了醫療健康服務的可及性&#xff0c;也使得群眾就醫體驗更為舒適、便捷。互聯網技術的廣泛應用&#xff0c;不僅改變了醫療核心業務…

酒店智能門鎖系統常見問題解決方法——東方仙盟

重做系統后 usb發卡器與注冊時發卡器不一致 解決發方法: 用總卡重新注冊軟件,要可以開房間的總卡 房號不存在 2聲---正確提示&#xff0c;表示是設置卡 3聲---門鎖已反鎖&#xff0c;解決方法&#xff1a;用能開反鎖的卡或解除反鎖 6聲---房號不對&#xff0c;解決方法&#…

從零開始理解百度語音識別API的Python實現

大家好&#xff01;今天我要給大家詳細講解一個使用百度語音識別API的Python代碼。這個代碼可以將音頻文件轉換成文字&#xff0c;非常適合做語音轉文字的應用。我會從最基礎的概念開始講起&#xff0c;確保沒有任何編程基礎的朋友也能理解。 翻譯 一、代碼概覽 這段代碼主要…

中小企業適用的幾種會議簽到工具

對企業行政來說&#xff0c;會議簽到是件小事&#xff0c;但處理不好&#xff0c;會直接拖慢會議流程、影響管理效率、降低參會體驗。尤其是面對人數多、時間緊、場地臨時變動等情況&#xff0c;靠傳統紙筆或簡單Excel管理&#xff0c;往往應對乏力。 實際上&#xff0c;簽到看…

android 11.0 打開ALOGV ALOGI ALOGD日志輸出的方法

1.前言 在11.0的系統rom定制化開發中,在某些時候,需要打印ALOGV,ALOGI等TAG日志,在系統中,默認是關閉這些日志的, 防止日志打印過多,系統過于卡頓,但是有時候會為了調試,需要打開日志開關,所以就需要在系統源碼中查看哪里 需要打開日志的開關,來實現日志的打印解決…

語言大模型or時序大模型?原理、應用與未來發展

引言 隨著人工智能技術的飛速發展&#xff0c;大規模預訓練模型已成為當前研究的熱點。其中&#xff0c;語言模型和時序大模型作為兩類重要的模型架構&#xff0c;分別在自然語言處理和時間序列分析領域展現出卓越的性能。然而&#xff0c;這兩類模型在基本原理和應用場景上存…

【Excel數據分析】花垣縣事業單位出成績了,用Excel自帶的M語言做一個數據分析

這里寫自定義目錄標題 花垣縣事業單位出成績了&#xff0c;用Excel自帶的M語言做一個數據分析需求 花垣縣事業單位出成績了&#xff0c;用Excel自帶的M語言做一個數據分析 Power Query M 語言&#xff0c;簡稱 M 語言&#xff0c;全名叫 Power Query Formula Language。 需求…

微處理器原理與應用篇---音頻采集與串口傳輸功能的系統設計

這段內容是基于 STM32F407VGT6 單片機&#xff0c;實現音頻采集與串口傳輸功能的嵌入式系統設計方案&#xff0c;包含硬件架構、軟件邏輯和代碼實現&#xff0c;核心是通過 ADC 采集音頻、串口收發指令與數據 &#xff0c;以下分模塊拆解&#xff1a; 一、系統設計概述 硬件&…

【大模型學習 | 量化】pytorch量化基礎知識(1)

pytorch量化 [!note] 官方定義&#xff1a;performing computations and storing tensors at lower bitwidths than floating point precision.支持INT8量化&#xff0c;可以降低4倍的模型大小以及顯存需求&#xff0c;加速2-4倍的推理速度通俗理解&#xff1a;降低權重和激活值…

ES和 Kafka 集群搭建過程中的典型問題、配置規范及最佳實踐

Kafka 集群搭建與配置經驗庫文檔&#xff08;完整會話匯總&#xff09; 一、會話問題分類與解決方案 1. Elasticsearch 映射解析錯誤 問題現象&#xff1a; {"error":{"root_cause":[{"type":"mapper_parsing_exception","re…

Linux-信號量

目錄 POSIX信號量 信號量的原理 信號量的概念 申請信號量失敗被掛起等待 信號量函數 二元信號量模擬實現互斥功能 基于環形隊列的生產消費模型 下面環形隊列采用數組模擬&#xff0c;用模運算來模擬環狀特性&#xff0c;類似如此 空間資源和數據資源 生產者和消費者申請…

Unity2D 街機風太空射擊游戲 學習記錄 #14 環射和散射組合 循環屏幕道具

概述 這是一款基于Unity引擎開發的2D街機風太空射擊游戲&#xff0c;筆者并不是游戲開發人&#xff0c;作者是siki學院的涼鞋老師。 筆者只是學習項目&#xff0c;記錄學習&#xff0c;同時也想幫助他人更好的學習這個項目 作者會記錄學習這一期用到的知識&#xff0c;和一些…

vue3 定時刷新

在Vue 3中實現定時刷新&#xff0c;你可以使用多種方法。這里列舉幾種常見的方法&#xff1a; 方法1&#xff1a;使用setInterval 這是最直接的方法&#xff0c;你可以在組件的mounted鉤子中使用setInterval來定時執行某些操作&#xff0c;例如重新獲取數據。 <template&…