從編寫(xiě)到管理詳解Docker鏡像與Dockerfile基礎(chǔ)指南
一份系統(tǒng)、實(shí)用的 Docker 鏡像操作手冊(cè),涵蓋 Dockerfile 編寫(xiě)規(guī)范與鏡像全生命周期指令。
前言
Docker 容器化已成為現(xiàn)代應(yīng)用交付的事實(shí)標(biāo)準(zhǔn),而鏡像則是容器的“源代碼”。無(wú)論是構(gòu)建自定義鏡像,還是從倉(cāng)庫(kù)拉取、推送、管理現(xiàn)有鏡像,掌握核心指令和編寫(xiě)技巧都是每一位開(kāi)發(fā)者和運(yùn)維工程師的必備技能。
本文基于實(shí)際工作中最常用的場(chǎng)景,分為兩大章節(jié):
- 如何編寫(xiě)高效的 Dockerfile:從基礎(chǔ)指令到最佳實(shí)踐,附帶完整示例。
- 常用 Docker 鏡像管理指令:覆蓋構(gòu)建、下載、推送、查看、刪除、標(biāo)記、導(dǎo)入導(dǎo)出等全流程。
讀完本文,你將能夠獨(dú)立編寫(xiě)生產(chǎn)級(jí) Dockerfile,并熟練使用 CLI 管理鏡像生命周期。
第一部分:編寫(xiě)高效的 Dockerfile
1.1 什么是 Dockerfile
Dockerfile 是一個(gè)純文本文件,定義了一系列指令,告訴 Docker 如何從基礎(chǔ)鏡像開(kāi)始,逐層疊加構(gòu)建出你的應(yīng)用鏡像。每條指令通常對(duì)應(yīng)鏡像中的一層,利用層緩存可以大幅加速重建過(guò)程。
1.2 核心指令速查表
| 指令 | 作用 | 示例 |
|---|---|---|
FROM | 指定基礎(chǔ)鏡像(必為第一條非注釋指令) | FROM node:18-alpine |
WORKDIR | 設(shè)置工作目錄(自動(dòng)創(chuàng)建) | WORKDIR /app |
COPY | 將主機(jī)文件/目錄復(fù)制到鏡像中 | COPY package.json . |
ADD | 類(lèi)似 COPY,額外支持自動(dòng)解壓 tar 和 URL 下載 | ADD app.tar.gz /app |
RUN | 在構(gòu)建時(shí)執(zhí)行命令(安裝軟件、生成文件) | RUN npm install |
ENV | 設(shè)置環(huán)境變量(運(yùn)行時(shí)也存在) | ENV NODE_ENV=production |
ARG | 構(gòu)建時(shí)變量(docker build --build-arg 傳值) | ARG VERSION=latest |
EXPOSE | 聲明容器監(jiān)聽(tīng)的端口(僅文檔作用) | EXPOSE 8080 |
CMD | 容器啟動(dòng)時(shí)執(zhí)行的命令(可被 docker run 覆蓋) | CMD ["node", "app.js"] |
ENTRYPOINT | 容器啟動(dòng)時(shí)執(zhí)行的命令(更不易被覆蓋) | ENTRYPOINT ["./entrypoint.sh"] |
USER | 切換執(zhí)行用戶(提升安全性) | USER node |
VOLUME | 聲明匿名卷(用于持久化數(shù)據(jù)) | VOLUME ["/data"] |
CMD 與 ENTRYPOINT 的區(qū)別
ENTRYPOINT定義固定主進(jìn)程,CMD提供默認(rèn)參數(shù),兩者可配合使用。- 示例:
ENTRYPOINT ["nginx"]+CMD ["-g", "daemon off;"]。 docker run時(shí)若指定額外參數(shù),會(huì)覆蓋CMD而不會(huì)覆蓋ENTRYPOINT。
1.3 編寫(xiě) Dockerfile 的最佳實(shí)踐
選擇合適的基礎(chǔ)鏡像
- 優(yōu)先使用官方鏡像,并指定具體版本標(biāo)簽(避免
:latest)。 - Alpine 變體(如
python:3.11-alpine)體積極小,適合生產(chǎn)環(huán)境。
利用構(gòu)建緩存
將不易變化的指令放在前面。例如,先 COPY package.json,再 RUN npm install,之后才 COPY . .。這樣代碼變動(dòng)不會(huì)導(dǎo)致依賴重新安裝。
合并 RUN 命令,減少層數(shù)
RUN apt-get update && apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*使用 && 連接,并在最后清理臨時(shí)文件。
多階段構(gòu)建
大幅減小最終鏡像體積:
# 構(gòu)建階段 FROM golang:1.19 AS builder WORKDIR /app COPY . . RUN go build -o myapp # 運(yùn)行階段 FROM alpine:latest COPY --from=builder /app/myapp /usr/local/bin/ CMD ["myapp"]
設(shè)置.dockerignore
忽略無(wú)關(guān)文件(.git、node_modules、__pycache__、*.log 等),加快構(gòu)建速度并減小上下文。
避免以 root 運(yùn)行
RUN addgroup -g 1001 -S appgroup && adduser -u 1001 -S appuser -G appgroup USER appuser
聲明健康檢查
HEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:3000/ || exit 1
1.4 完整示例:Python Flask 應(yīng)用
項(xiàng)目結(jié)構(gòu):
myapp/
├── Dockerfile
├── .dockerignore
├── requirements.txt
└── app.py
Dockerfile 內(nèi)容:
FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . ENV FLASK_APP=app.py ENV FLASK_ENV=production EXPOSE 5000 RUN adduser --disabled-password --gecos '' appuser && chown -R appuser /app USER appuser CMD ["flask", "run", "--host=0.0.0.0"]
.dockerignore:
__pycache__ *.pyc .git .env .venv
構(gòu)建并運(yùn)行:
docker build -t my-flask-app . docker run -p 5000:5000 my-flask-app
1.5 調(diào)試與優(yōu)化技巧
查看鏡像層:docker history <鏡像名>
分析鏡像體積:使用 dive 工具
啟用 BuildKit:export DOCKER_BUILDKIT=1,支持并行構(gòu)建和緩存掛載
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt
第二部分:常用 Docker 鏡像管理指令
本節(jié)涵蓋從拉取、構(gòu)建到推送、刪除的全生命周期指令。所有命令均以 docker 為前綴。
2.1 構(gòu)建鏡像 –docker build
從 Dockerfile 構(gòu)建鏡像。
docker build [OPTIONS] PATH
| 常用選項(xiàng) | 說(shuō)明 |
|---|---|
-t, --tag | 指定鏡像名稱:標(biāo)簽 |
-f, --file | 指定 Dockerfile 路徑 |
--build-arg | 傳遞構(gòu)建變量 |
--no-cache | 禁用緩存 |
--platform | 目標(biāo)平臺(tái),如 linux/amd64 |
示例:
docker build -t myapp:1.0 . docker build -t myapp:dev -f Dockerfile.dev . docker build --build-arg VERSION=1.2.3 -t myapp .
2.2 下載鏡像 –docker pull
從倉(cāng)庫(kù)(默認(rèn) Docker Hub)拉取鏡像。
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
示例:
docker pull ubuntu docker pull node:18-alpine docker pull --all-tags nginx # 拉取所有標(biāo)簽(慎用) docker pull ubuntu@sha256:dfd64e... # 按摘要拉取
2.3 推送鏡像 –docker push
將本地鏡像推送到遠(yuǎn)程倉(cāng)庫(kù)(需先 docker login)。
docker push [OPTIONS] NAME[:TAG]
前置步驟:
# 登錄 Docker Hub docker login -u username # 打標(biāo)簽(假設(shè)本地鏡像 myapp:1.0) docker tag myapp:1.0 username/myapp:1.0 # 推送 docker push username/myapp:1.0
2.4 查看鏡像列表 –docker images/docker image ls
列出本地所有鏡像。
docker images [OPTIONS] [REPOSITORY[:TAG]]
常用選項(xiàng):
-a:顯示所有(包括中間層)-q:只顯示鏡像 ID--filter:過(guò)濾,如"dangling=true"(虛懸鏡像)
示例:
docker images docker images -q docker images --filter "reference=*ubuntu*"
2.5 查看鏡像詳情 –docker inspect
獲取 JSON 格式的元數(shù)據(jù)(環(huán)境變量、層、架構(gòu)等)。
docker inspect [OPTIONS] NAME|ID
示例:
docker inspect ubuntu:latest
docker inspect --format='{{.Architecture}}' myapp:1.0
2.6 查看鏡像歷史 –docker history
顯示每一層的構(gòu)建命令和大小。
docker history [OPTIONS] IMAGE
示例:
docker history myapp:1.0 docker history --no-trunc nginx # 完整顯示命令
2.7 刪除鏡像 –docker rmi/docker image rm
刪除本地一個(gè)或多個(gè)鏡像。
docker rmi [OPTIONS] IMAGE [IMAGE...]
常用選項(xiàng):
-f:強(qiáng)制刪除(即使有容器依賴)--no-prune:不刪除未加標(biāo)簽的父鏡像
示例:
docker rmi myapp:1.0 docker rmi $(docker images -f "dangling=true" -q) # 刪除所有虛懸鏡像 docker rmi -f myapp
2.8 標(biāo)記鏡像 –docker tag
為鏡像添加新標(biāo)簽(指向同一鏡像 ID)。
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
示例:
docker tag myapp:1.0 myapp:stable docker tag myapp:1.0 myregistry.example.com/myapp:1.0
2.9 登錄/登出倉(cāng)庫(kù) –docker login/docker logout
docker login [SERVER] [OPTIONS] docker logout [SERVER]
安全傳密碼:
echo "mypassword" | docker login -u alice --password-stdin
2.10 搜索鏡像 –docker search
在 Docker Hub 搜索公開(kāi)鏡像。
docker search [OPTIONS] TERM
示例:
docker search nginx --filter "is-official=true" docker search mysql --filter stars=1000 --limit 5
2.11 保存與加載鏡像文件 –docker save/docker load
用于離線遷移或備份。
# 保存為一個(gè) tar 文件 docker save -o myapp.tar myapp:1.0 docker save -o multi.tar nginx alpine # 多個(gè)鏡像 # 加載 tar 文件為鏡像 docker load -i myapp.tar docker load < myapp.tar
補(bǔ)充:docker export / docker import 作用于容器,會(huì)丟失鏡像層歷史,不推薦常規(guī)使用。
2.12 快速參考表(鏡像管理篇)
| 操作 | 指令 |
|---|---|
| 構(gòu)建 | docker build -t name:tag . |
| 拉取 | docker pull name:tag |
| 推送 | docker push repo/name:tag |
| 列出鏡像 | docker images |
| 查看詳情 | docker inspect name |
| 查看歷史 | docker history name |
| 刪除 | docker rmi name |
| 打標(biāo)簽 | docker tag src dst |
| 登錄倉(cāng)庫(kù) | docker login |
| 搜索 | docker search term |
| 保存為文件 | docker save -o file.tar name |
| 從文件加載 | docker load -i file.tar |
總結(jié)
從編寫(xiě) Dockerfile 到管理鏡像,每一步都有其規(guī)范和技巧?;仡櫼c(diǎn):
- Dockerfile 編寫(xiě):選擇精簡(jiǎn)基礎(chǔ)鏡像、合并 RUN 命令、利用多階段構(gòu)建、避免 root 運(yùn)行、添加健康檢查。
- 鏡像管理指令:掌握
build、pull、push、tag、rmi、save/load等,合理利用過(guò)濾和格式化輸出。 - 日常優(yōu)化:善用
.dockerignore、構(gòu)建緩存、BuildKit 特性,定期清理虛懸鏡像。
本文涵蓋的內(nèi)容足以支撐日常開(kāi)發(fā)與運(yùn)維中的絕大多數(shù)需求。隨著使用深入,你還可以進(jìn)一步學(xué)習(xí)多架構(gòu)構(gòu)建(docker buildx)、鏡像簽名(docker trust)以及容器編排中的鏡像管理策略。
以上就是從編寫(xiě)到管理詳解Docker鏡像與Dockerfile基礎(chǔ)指南的詳細(xì)內(nèi)容,更多關(guān)于Docker鏡像操作的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用dockerfile構(gòu)建nginx鏡像的方法示例
這篇文章主要介紹了使用dockerfile構(gòu)建nginx鏡像的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
docker容器內(nèi)網(wǎng)絡(luò)請(qǐng)求緩慢問(wèn)題解決
在使用docker的過(guò)程中發(fā)現(xiàn)了幾個(gè)問(wèn)題,在docker里進(jìn)行的網(wǎng)絡(luò)請(qǐng)求經(jīng)常會(huì)失敗,這篇文章主要介紹了docker容器內(nèi)網(wǎng)絡(luò)請(qǐng)求緩慢問(wèn)題解決2019-01-01
Docker創(chuàng)建運(yùn)行多個(gè)mysql容器的方法示例
這篇文章主要介紹了Docker創(chuàng)建運(yùn)行多個(gè)mysql容器,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
使用Docker Swarm搭建分布式爬蟲(chóng)集群的方法示例
這篇文章主要介紹了使用Docker Swarm搭建分布式爬蟲(chóng)集群的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
Docker容器處于Removal in process無(wú)法刪除問(wèn)題及解決
這篇文章主要介紹了Docker容器處于Removal in process無(wú)法刪除問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2023-07-07
安裝Milvus向量數(shù)據(jù)庫(kù)全過(guò)程
這篇文章主要介紹了安裝Milvus向量數(shù)據(jù)庫(kù)全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-08-08
Docker 部署 RocketMQ 5.1.0 踩坑指南從超時(shí)到 C
最近在項(xiàng)目中引入RocketMQ作為消息中間件,選擇使用Docker容器化部署以簡(jiǎn)化環(huán)境搭建,本文給大家介紹Docker 部署 RocketMQ 5.1.0 踩坑指南從超時(shí)到 Console 連不上的完整解決方案,感興趣的朋友跟隨小編一起看看吧2026-03-03

