Dockerfile 完全指南:從入門到最佳實踐

Dockerfile 完全指南:從入門到最佳實踐

1. Dockerfile 簡介與作用

Dockerfile 是一個文本文件,包含了一系列用于構建 Docker 鏡像的指令。它允許開發者通過簡單的指令定義鏡像的構建過程,實現自動化、可重復的鏡像構建。

主要作用

  • 自動化鏡像構建過程
  • 確保環境一致性
  • 版本控制構建過程
  • 簡化部署流程
  • 實現基礎設施即代碼(IaC)

2. Dockerfile 基本結構與工作原理

一個典型的 Dockerfile 包含以下部分:

# 注釋
指令 參數

構建過程

  1. Docker 從基礎鏡像開始
  2. 按順序執行 Dockerfile 中的指令
  3. 每條指令創建一個新的鏡像層
  4. 最終生成一個可用的鏡像

3. Dockerfile 常用指令詳解

3.1 FROM - 指定基礎鏡像

FROM ubuntu:20.04
# 使用官方Ubuntu 20.04鏡像作為基礎
FROM python:3.9-slim
# 使用Python官方提供的精簡版3.9鏡像

說明

  • 必須是 Dockerfile 的第一條有效指令(注釋除外)
  • 推薦使用官方鏡像
  • 盡量使用特定版本標簽而非latest

3.2 RUN - 執行命令

RUN apt-get update && apt-get install -y \curl \git \&& rm -rf /var/lib/apt/lists/*
# 更新包索引,安裝curl和git,然后清理緩存
RUN pip install --no-cache-dir flask gunicorn
# 安裝Python依賴但不緩存下載的包

最佳實踐

  • 多個命令合并為一個RUN指令以減少鏡像層
  • 清理不必要的文件減少鏡像大小
  • 使用--no-cache選項避免緩存

3.3 COPY 與 ADD - 添加文件

COPY . /app
# 將當前目錄所有文件復制到容器的/app目錄
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
# 只復制requirements文件先安裝依賴

ADD 與 COPY 區別

  • ADD 可以解壓tar文件和從URL獲取文件
  • 大多數情況下推薦使用更簡單的COPY

3.4 WORKDIR - 設置工作目錄

WORKDIR /app
# 后續指令都在/app目錄下執行

特點

  • 相當于cd命令
  • 如果目錄不存在會自動創建
  • 影響RUN、CMD、ENTRYPOINT等指令

3.5 EXPOSE - 聲明端口

EXPOSE 80
# 聲明容器將監聽80端口
EXPOSE 3000/tcp
EXPOSE 3000/udp
# 可以指定協議類型

注意

  • 只是聲明作用,實際發布端口需要在運行容器時指定
  • 有助于文檔化和理解鏡像用途

3.6 ENV - 設置環境變量

ENV NODE_ENV=production
ENV APP_HOME=/app
ENV PATH=/app/node_modules/.bin:$PATH
# 可以修改PATH等系統環境變量

用途

  • 配置應用程序
  • 設置路徑變量
  • 定義版本號等常量

3.7 CMD 與 ENTRYPOINT - 容器啟動命令

CMD ["python", "app.py"]
# 容器啟動時默認運行python app.py
ENTRYPOINT ["/bin/bash", "-c"]
CMD ["echo $HOME"]
# ENTRYPOINT作為主命令,CMD作為參數

區別

  • CMD 可以被docker run后的命令覆蓋
  • ENTRYPOINT 不容易被覆蓋
  • 通常組合使用

4. Dockerfile 高級功能

4.1 ARG - 構建時變量

ARG VERSION=latest
FROM ubuntu:$VERSION
# 構建時可以傳遞--build-arg VERSION=20.04來改變基礎鏡像版本

特點

  • 只在構建時有效,運行容器時不可用
  • 可以通過–build-arg覆蓋默認值

4.2 VOLUME - 定義數據卷

VOLUME /var/lib/mysql
# 將MySQL數據目錄聲明為卷

用途

  • 持久化重要數據
  • 容器間共享數據

4.3 HEALTHCHECK - 健康檢查

HEALTHCHECK --interval=30s --timeout=3s \CMD curl -f http://localhost/ || exit 1
# 每30秒檢查一次服務是否健康

參數

  • –interval: 檢查間隔
  • –timeout: 超時時間
  • –retries: 失敗重試次數

4.4 USER - 指定運行用戶

RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser
# 創建非root用戶并切換

安全實踐

  • 避免以root用戶運行容器
  • 減少安全風險

4.5 ONBUILD - 延遲執行指令

ONBUILD COPY . /app
ONBUILD RUN make build
# 這些指令會在基于此鏡像構建其他鏡像時執行

用途

  • 創建基礎鏡像
  • 構建框架鏡像

5. Dockerfile 最佳實踐

5.1 多階段構建

# 構建階段
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .# 運行階段
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]

優點

  • 顯著減小最終鏡像大小
  • 只包含運行時必要的文件

5.2 合理排序指令

# 變化頻率低的指令放前面
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y package# 變化頻率高的指令放后面
COPY . /app

原理

  • Docker會緩存每一層
  • 把頻繁變化的指令放在后面可以利用緩存

5.3 最小化鏡像層

RUN apt-get update && apt-get install -y \package1 \package2 \&& rm -rf /var/lib/apt/lists/*
# 合并多個RUN命令

技巧

  • 使用&&連接命令
  • 使用\換行提高可讀性
  • 清理不必要的文件

5.4 使用.dockerignore文件

.git
node_modules
*.log
.DS_Store

作用

  • 排除不必要的文件
  • 加速構建過程
  • 減小鏡像大小

5.5 安全實踐

FROM alpine:latest
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# 使用非root用戶

建議

  • 定期更新基礎鏡像
  • 掃描鏡像中的漏洞
  • 最小化安裝軟件包

6. 完整示例

# 多階段構建示例 - Python應用
# 構建階段
FROM python:3.9 as builderWORKDIR /app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1COPY requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt# 運行階段
FROM python:3.9-slimWORKDIR /appCOPY --from=builder /app/wheels /wheels
COPY --from=builder /app/requirements.txt .RUN pip install --no-cache /wheels/* \&& rm -rf /wheels \&& rm -f requirements.txtCOPY . .RUN useradd -m myuser && chown -R myuser:myuser /app
USER myuserEXPOSE 8000HEALTHCHECK --interval=30s --timeout=3s \CMD curl -f http://localhost:8000/health || exit 1CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

解釋

  1. 使用多階段構建減少最終鏡像大小
  2. 構建階段生成wheel文件
  3. 運行階段只安裝必要的依賴
  4. 創建非root用戶增強安全性
  5. 設置健康檢查
  6. 聲明暴露端口
  7. 指定啟動命令

7. 如何通過 Dockerfile 構建鏡像

構建 Docker 鏡像是使用 Dockerfile 的最終目的,本節將詳細介紹如何使用 docker build 命令從 Dockerfile 創建鏡像,并探討各種構建選項和技巧。

7.1 基本構建命令

docker build -t my-image:1.0 .

參數解釋

  • -t my-image:1.0:為鏡像指定名稱和標簽
  • .:指定構建上下文路徑(Dockerfile 所在目錄)

構建過程輸出示例

Sending build context to Docker daemon  2.048kB
Step 1/8 : FROM python:3.9-slim---> 2d0f2f3d3a3a
Step 2/8 : WORKDIR /app---> Running in a1b2c3d4e5f6
Removing intermediate container a1b2c3d4e5f6---> 123456789abc
...
Successfully built 789abc123def
Successfully tagged my-image:1.0

7.2 指定 Dockerfile 路徑

當 Dockerfile 不在當前目錄或使用不同名稱時:

docker build -t my-image -f /path/to/Dockerfile .

示例

docker build -t backend-app -f docker/backend.Dockerfile .

7.3 構建時傳遞變量

使用 --build-arg 傳遞構建參數:

# Dockerfile
ARG VERSION=latest
FROM ubuntu:$VERSION
docker build -t my-ubuntu --build-arg VERSION=20.04 .

典型用途

  • 指定軟件版本
  • 配置構建選項
  • 設置代理

7.4 構建緩存控制

跳過緩存

docker build --no-cache -t fresh-image .

指定緩存來源

docker build --cache-from=my-image:1.0 -t my-image:1.1 .

7.5 多階段構建的目標階段

對于多階段構建,可以只構建特定階段:

# Dockerfile
FROM node:14 as builder
...FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
# 只構建builder階段
docker build --target builder -t my-app-builder .

7.6 查看構建上下文

查看發送到Docker守護進程的文件

docker build --no-cache --progress=plain .

優化.dockerignore
確保.dockerignore文件排除不必要的文件:

.git
node_modules
*.log
*.md

7.7 構建性能優化技巧

  1. 并行構建
docker buildx build --platform linux/amd64,linux/arm64 -t my-image .
  1. 使用構建工具包(BuildKit)
DOCKER_BUILDKIT=1 docker build -t my-image .
  1. 分層構建
# 先安裝依賴
COPY package.json .
RUN npm install# 再復制源代碼
COPY . .

7.8 鏡像構建后的操作

查看構建歷史

docker history my-image:1.0

保存鏡像到文件

docker save -o my-image.tar my-image:1.0

從文件加載鏡像

docker load -i my-image.tar

7.9 實際構建示例

假設有以下項目結構:

/my-app├── Dockerfile├── app.py├── requirements.txt└── .dockerignore

構建過程

  1. 編寫Dockerfile:
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
  1. 構建命令:
cd /my-app
docker build -t my-python-app .
  1. 驗證構建:
docker images | grep my-python-app
  1. 運行測試:
docker run -d -p 5000:5000 --name test-app my-python-app
curl localhost:5000

8. 總結(

通過本文我們全面了解了:

  1. Dockerfile 的基本語法和核心指令
  2. 高級功能如多階段構建和健康檢查
  3. 編寫高效 Dockerfile 的最佳實踐
  4. 如何使用 docker build 命令構建鏡像
  5. 構建過程中的各種選項和優化技巧

關鍵構建要點

  • 始終為鏡像指定有意義的標簽
  • 合理利用緩存提高構建速度
  • 使用多階段構建減小最終鏡像大小
  • 通過.dockerignore減少構建上下文大小
  • 構建后驗證鏡像是否按預期工作

掌握這些 Dockerfile 編寫和鏡像構建技能,您將能夠為任何應用程序創建高效、可靠的容器鏡像,實現開發和生產環境的一致性。

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

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

相關文章

Python httpx庫終極指南

一、發展歷程與技術定位 1.1 歷史演進 起源:httpx 由 Encode 團隊開發,于 2019 年首次發布,目標是提供一個現代化的 HTTP 客戶端,支持同步和異步操作,并兼容 HTTP/1.1 和 HTTP/2。背景: requests 庫雖然功…

app加固

1、什么是加固? 我們之前講的逆向,大多數都是用加密算法去加密一些明文字符串,然后把得到的結果用 Base64、Hex等進行編碼后提交。加固其實也一樣,只不過他通常加密的是 dex文件而已。但是 dex 文件加密以后,安卓系統是沒法直接運行的。所以加固的核心&…

Win全兼容!五五 Excel Word 轉 PDF 工具解決多場景轉換難題

各位辦公小能手們!今天給你們介紹一款超牛的工具——五五Excel Word批量轉PDF工具V5.5版。這玩意兒專注搞批量格式轉換,能把Excel(.xls/.xlsx)和Word(.doc/.docx)文檔唰唰地變成PDF格式。 先說說它的核心功…

springCloud/Alibaba常用中間件之Nacos服務注冊與發現

文章目錄 SpringCloud Alibaba:依賴版本補充六、Nacos:服務注冊與發現1、下載安裝Nacos2、服務注冊1. 導入依賴(這里以服務提供者為例)2. 修改配置文件和主啟動類3. 創建業務類4. 測試 3.服務映射1. 導入依賴2. 修改配置文件和主啟動類3. 創建業務類和RestTemplate配置類用來提…

uniapp中score-view中的文字無法換行問題。

項目場景: 今天遇到一個很惡心的問題,uniapp中的文字突然無法換行了。得..就介樣 原因分析: 提示:經過一fan研究后發現 scroll-view為了能夠橫向滾動設置了white-space: nowrap; 強制不換行 解決起來最先想到的是,父…

【STM32 學習筆記】I2C通信協議

注:通信協議的設計背景 3:00~10:13 I2C 通訊協議(Inter-Integrated Circuit)是由Phiilps公司開發的,由于它引腳少,硬件實現簡單,可擴展性強, 不需要USART、CAN等通訊協議的外部收發設備,現在被廣…

【網絡原理】數據鏈路層

目錄 一. 以太網 二. 以太網數據幀 三. MAC地址 四. MTU 五. ARP協議 六. DNS 一. 以太網 以太網是一種基于有線或無線介質的計算機網絡技術,定義了物理層和數據鏈路層的協議,用于在局域網中傳輸數據幀。 二. 以太網數據幀 1)目標地址 …

控制臺打印帶格式內容

1. 場景 很多軟件會在控制臺打印帶顏色和格式的文字,需要使用轉義符實現這個功能。 2. 詳細說明 2.1.轉義符說明 樣式開始:\033[參數1;參數2;參數3m 可以多個參數疊加,若同一類型的參數(如字體顏色)設置了多個&…

[6-2] 定時器定時中斷定時器外部時鐘 江協科技學習筆記(41個知識點)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 V 30 31 32 33 34 35 36 37 38 39 40 41

數據庫的脫敏策略

數據庫的脫敏策略:就是屏蔽敏感的數據 脫敏策略三要求: (1)表對象 (2)生效條件(脫敏列、脫敏函數) (3)二元組 常見的脫敏策略規則: 替換、重排、…

Python序列化的學習筆記

1. Npy&Numpy O4-mini-Cursor:如果.npy文件里包含了「Python對象」而非純數值數組時,就必須在加載時加上allow_pickleTrue。

[思維模式-27]:《本質思考力》-7- 逆向思考的原理與應用

目錄 一、什么是逆向思考 1.1、逆向思考的六大核心思維模式 1.2、逆向思考的四大實踐方法 1. 假設倒置法 2. 缺陷重構法 3. 用戶反推法 4. 規則解構法 1.3、逆向思考的經典案例庫 1. 商業創新:從“賣產品”到“賣服務” 2. 用戶體驗:從“功能滿…

在python中,為什么要引入事件循環這個概念?

在Python中,事件循環(Event Loop)是異步編程的核心機制,它的引入解決了傳統同步編程模型在高并發場景下的效率瓶頸問題。以下從技術演進、性能優化和編程范式三個角度,探討這一概念的必要性及其價值。 一、同步模型的局…

Taccel:一個高性能的GPU加速視觸覺機器人模擬平臺

觸覺感知對于實現人類水平的機器人操作能力至關重要。而視覺觸覺傳感器(VBTS)作為一種有前景的解決方案,通過相機捕捉彈性凝膠墊的形變模式來感知接觸的方式,為視觸覺機器人提供了高空間分辨率和成本效益。然而,這些傳…

oracle 會話管理

會話管理 1:查看當前所有用戶的會話(SESSION): SELECT * FROM V S E S S I O N W H E R E U S E R N A M E I S N O T N U L L O R D E R B Y L O G O N T I M E , S I D ; 其中 O r a c l e 內部進程的 U S E R N A M E 為空 2 :查看當前…

Python開發后端InfluxDB數據庫測試接口

1、使用PyCharm創建一個Python項目wzClear 2、新建package包wzInfluxdb和wzConfig包,如上圖所示,新建一個DB.json配置文件并添加influxdb配置信息,DB.json為統一配置文件 {"influxdbV1": {"url": "http://192.168.0…

采用LLaMa-Factory對QWen大模型實現微調(效果很好)

前言 LLaMA-factory是一個非常有用的開源框架。關于利用llama-factory實現大模型的微調,研究了有一個多月了,終于相對成功的微調了一個QWen的大模型。其中的曲折愿和大家分享! 一、源碼的下載 在github上的網址: GitHub - hiyou…

深入理解深度Q網絡DQN:基于python從零實現

DQN是什么玩意兒? 深度Q網絡(DQN)是深度強化學習領域里一個超厲害的算法。它把Q學習和深度神經網絡巧妙地結合在了一起,專門用來搞定那些狀態空間維度特別高、特別復雜的難題。它展示了用函數近似來學習價值函數的超能力&#xf…

機械物理:水力發電站工作原理是什么?

水利發電站的工作原理是將水的勢能轉化為電能,主要依賴水體的重力作用與能量轉換設備。以下是其核心步驟和組成部分的詳細解釋: 1. 蓄水與勢能積累 水壩與水庫:通過建造水壩攔截河流,形成水庫蓄水。水位升高后,水體的…

[面試]SoC驗證工程師面試常見問題(五)TLM通信篇

SoC驗證工程師面試常見問題(五) 摘要:UVM (Universal Verification Methodology) 中的 TLM (Transaction Level Modeling) 通信是一種用于在驗證組件之間傳遞事務(Transaction)的高層次抽象機制。它通過端口(Port)和導出(Export)實現組件間的解耦通信,避免了信…