91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用Dockerfile構(gòu)建鏡像的詳細(xì)步驟

馬哥Linux運(yùn)維 ? 來源:馬哥Linux運(yùn)維 ? 2026-02-26 09:43 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、概述

1.1 背景介紹

Dockerfile寫得好不好,直接影響三件事:鏡像大小、構(gòu)建速度、運(yùn)行安全性。我見過太多團(tuán)隊(duì)的Dockerfile是"能跑就行"的水平——基礎(chǔ)鏡像用ubuntu:latest,一個(gè)RUN裝幾十個(gè)包不清理緩存,最終鏡像1.2GB,構(gòu)建一次15分鐘,里面還帶著gcc和make這些生產(chǎn)環(huán)境根本不需要的東西。

一個(gè)優(yōu)化過的Dockerfile能把鏡像從1.2GB壓縮到80MB,構(gòu)建時(shí)間從15分鐘降到2分鐘(利用緩存后30秒),同時(shí)減少90%的安全漏洞面。這不是理論數(shù)字,是我在實(shí)際項(xiàng)目中反復(fù)驗(yàn)證過的。

Dockerfile本質(zhì)上是一系列指令的集合,Docker按順序執(zhí)行每條指令,每條指令生成一個(gè)鏡像層(Layer)。理解分層機(jī)制是寫好Dockerfile的基礎(chǔ)——層可以被緩存和復(fù)用,合理的指令順序能大幅提升構(gòu)建速度;但層太多會(huì)增加鏡像體積和拉取時(shí)間。

1.2 技術(shù)特點(diǎn)

分層緩存:每條指令生成一層,未變更的層直接使用緩存,構(gòu)建速度從分鐘級(jí)降到秒級(jí)

多階段構(gòu)建:編譯環(huán)境和運(yùn)行環(huán)境分離,最終鏡像只包含運(yùn)行時(shí)必需的文件,體積減少70%-90%

BuildKit引擎:Docker 18.09引入的新構(gòu)建引擎,支持并行構(gòu)建、緩存掛載、Secret掛載,構(gòu)建速度提升2-3倍

可重復(fù)構(gòu)建:同一個(gè)Dockerfile在任何機(jī)器上構(gòu)建出相同的鏡像,消除"我機(jī)器上能構(gòu)建"的問題

安全掃描集成:構(gòu)建時(shí)可以集成Trivy等掃描工具,在CI階段攔截有漏洞的鏡像

1.3 適用場景

Java/Go/Node.js/Python等各語言應(yīng)用的容器化打包

CI/CD流水線中的自動(dòng)化鏡像構(gòu)建

基礎(chǔ)鏡像定制(在官方鏡像基礎(chǔ)上添加公司內(nèi)部工具和配置)

開發(fā)環(huán)境標(biāo)準(zhǔn)化(統(tǒng)一開發(fā)工具鏈版本)

多架構(gòu)鏡像構(gòu)建(同時(shí)支持amd64和arm64)

1.4 環(huán)境要求

組件 版本要求 說明
Docker Engine 23.0+(推薦24.0+) 需要BuildKit支持
BuildKit 內(nèi)置于Docker 23.0+ 默認(rèn)啟用,舊版本需手動(dòng)開啟
操作系統(tǒng) Linux/macOS/Windows 構(gòu)建環(huán)境不限,生產(chǎn)鏡像建議基于Linux
磁盤空間 20GB+可用空間 構(gòu)建緩存和中間層需要空間
內(nèi)存 4GB+(編譯型語言建議8GB+) Go/Java編譯消耗內(nèi)存較大

二、詳細(xì)步驟

2.1 準(zhǔn)備工作

2.1.1 確認(rèn)BuildKit已啟用

# 檢查Docker版本
docker version

# 檢查BuildKit是否啟用(Docker 23.0+默認(rèn)啟用)
docker buildx version

# 如果是舊版本Docker,手動(dòng)啟用BuildKit
exportDOCKER_BUILDKIT=1

# 或者在daemon.json中永久啟用
# "features": { "buildkit": true }

# 驗(yàn)證BuildKit工作正常
docker build --progress=plain -ttest-buildkit -f- . <<'EOF'
FROM alpine:3.19
RUN?echo?"BuildKit is working"
EOF

2.1.2 準(zhǔn)備.dockerignore文件

.dockerignore的作用和.gitignore類似,排除不需要發(fā)送到構(gòu)建上下文的文件。構(gòu)建上下文越小,構(gòu)建越快。我見過因?yàn)闆]有.dockerignore,把node_modules(500MB)和.git目錄(200MB)都發(fā)送到構(gòu)建上下文,導(dǎo)致每次構(gòu)建光傳輸上下文就要30秒。

# 文件路徑:項(xiàng)目根目錄/.dockerignore
.git
.gitignore
.dockerignore
Dockerfile
docker-compose*.yml
README.md
LICENSE
docs/
tests/
*.md
*.log
*.tmp
*.swp

# Node.js項(xiàng)目
node_modules/
npm-debug.log
.npm/

# Java項(xiàng)目
target/
*.jar
*.class
.gradle/
build/

# Python項(xiàng)目
__pycache__/
*.pyc
.venv/
venv/
*.egg-info/

# IDE文件
.idea/
.vscode/
*.iml

# 操作系統(tǒng)文件
.DS_Store
Thumbs.db

2.2 核心配置

2.2.1 基礎(chǔ)鏡像選擇

基礎(chǔ)鏡像的選擇直接決定了最終鏡像的大小和安全性。

#  錯(cuò)誤示范:用ubuntu作為基礎(chǔ)鏡像,體積77MB,包含大量不需要的包
FROMubuntu:22.04

#  錯(cuò)誤示范:用latest標(biāo)簽,每次構(gòu)建可能拉到不同版本
FROMnode:latest

#  正確:用alpine變體,體積只有5MB
FROMnode:20.11-alpine3.19

#  正確:用distroless鏡像,只包含運(yùn)行時(shí),沒有shell和包管理器
FROMgcr.io/distroless/java17-debian12

#  正確:用slim變體,比完整版小但比alpine兼容性好
FROMpython:3.12-slim-bookworm

各基礎(chǔ)鏡像大小對(duì)比

基礎(chǔ)鏡像 大小 適用場景
ubuntu:22.04 77MB 需要apt安裝大量系統(tǒng)包的場景
debian:bookworm-slim 74MB 需要glibc但想控制體積
alpine:3.19 7MB 追求極致小體積,注意musl libc兼容性
distroless 2-20MB 生產(chǎn)環(huán)境最安全,沒有shell無法exec進(jìn)入
scratch 0MB 靜態(tài)編譯的Go程序

注意:alpine使用musl libc而不是glibc,部分C語言編寫的程序可能有兼容性問題。典型案例:Python的某些C擴(kuò)展在alpine上編譯失敗或運(yùn)行時(shí)段錯(cuò)誤。遇到這種情況換slim變體。

2.2.2 指令順序優(yōu)化(利用構(gòu)建緩存)

Docker構(gòu)建緩存的規(guī)則:從第一條變更的指令開始,后續(xù)所有層的緩存全部失效。所以要把變化頻率低的指令放前面,變化頻率高的放后面。

#  錯(cuò)誤示范:COPY . 放在安裝依賴之前
# 任何源碼文件變更都會(huì)導(dǎo)致依賴重新安裝
FROMnode:20.11-alpine3.19
WORKDIR/app
COPY. .
RUNnpm ci --production
EXPOSE3000
CMD["node","server.js"]

#  正確:先復(fù)制依賴文件,安裝依賴,再復(fù)制源碼
# 只有package.json變更才會(huì)重新安裝依賴
FROMnode:20.11-alpine3.19
WORKDIR/app
COPYpackage.json package-lock.json ./
RUNnpm ci --production
COPY. .
EXPOSE3000
CMD["node","server.js"]

緩存利用的最佳順序

FROM(基礎(chǔ)鏡像,幾乎不變)

安裝系統(tǒng)依賴(apt/apk install,偶爾變)

復(fù)制依賴描述文件(package.json/pom.xml/go.mod)

安裝應(yīng)用依賴(npm ci/mvn install/go mod download)

復(fù)制源代碼(每次提交都變)

構(gòu)建應(yīng)用

配置運(yùn)行參數(shù)(CMD/ENTRYPOINT)

2.2.3 RUN指令優(yōu)化

#  錯(cuò)誤示范:每個(gè)命令一個(gè)RUN,產(chǎn)生多個(gè)層,且沒有清理緩存
FROMubuntu:22.04
RUNapt update
RUNapt install -y curl
RUNapt install -y wget
RUNapt install -y vim

#  錯(cuò)誤示范:安裝了不需要的推薦包,沒有清理apt緩存
FROMubuntu:22.04
RUNapt update && apt install -y curl wget

#  正確:合并RUN,使用--no-install-recommends,清理緩存
FROMubuntu:22.04
RUNapt-get update && 
  apt-get install -y --no-install-recommends 
    curl 
    wget 
    ca-certificates 
  && rm -rf /var/lib/apt/lists/*
# Alpine鏡像的正確寫法
FROMalpine:3.19
RUNapk add --no-cache 
  curl 
  tzdata 
  && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 
  &&echo"Asia/Shanghai"> /etc/timezone 
  && apk del tzdata

關(guān)鍵點(diǎn)

--no-install-recommends:不安裝推薦包,能減少30%-50%的安裝體積

rm -rf /var/lib/apt/lists/*:清理apt緩存,節(jié)省約30MB

apk add --no-cache:alpine的等價(jià)寫法,不緩存索引文件

安裝和清理必須在同一個(gè)RUN中,否則清理操作只是在新層中標(biāo)記刪除,不會(huì)減小鏡像體積

2.2.4 COPY和ADD的區(qū)別

# COPY:簡單復(fù)制文件,推薦使用
COPYapp.jar /app/
COPY--chown=app:app config/ /app/config/

# ADD:有額外功能,但不推薦日常使用
# ADD會(huì)自動(dòng)解壓tar文件
ADDarchive.tar.gz /app/

# ADD可以從URL下載文件(但不推薦,用curl更可控)
# ADD https://example.com/file.tar.gz /app/

#  推薦:用curl下載,可以在同一層中下載、解壓、清理
RUNcurl -fsSL https://example.com/file.tar.gz -o /tmp/file.tar.gz && 
  tar xzf /tmp/file.tar.gz -C /app/ && 
  rm /tmp/file.tar.gz

原則:除非需要自動(dòng)解壓tar文件,否則一律用COPY。COPY的行為更明確,不會(huì)有意外的自動(dòng)解壓。

2.2.5 多階段構(gòu)建

多階段構(gòu)建是Dockerfile優(yōu)化的核心技術(shù)。編譯環(huán)境可能需要JDK、Maven、gcc等工具(幾百M(fèi)B),但運(yùn)行時(shí)只需要JRE或一個(gè)二進(jìn)制文件。

# Go應(yīng)用的多階段構(gòu)建
# 階段1:編譯(使用完整的Go SDK,約800MB)
FROMgolang:1.22-alpine AS builder
WORKDIR/build
COPYgo.mod go.sum ./
RUNgo mod download
COPY. .
RUNCGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w"-o /app/server ./cmd/server

# 階段2:運(yùn)行(使用scratch,0MB基礎(chǔ)鏡像)
FROMscratch
COPY--from=builder /app/server /server
COPY--from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
EXPOSE8080
ENTRYPOINT["/server"]
# 最終鏡像大?。杭s10-20MB(只有一個(gè)靜態(tài)二進(jìn)制文件+CA證書)
# Java應(yīng)用的多階段構(gòu)建
# 階段1:編譯
FROMmaven:3.9-eclipse-temurin-17AS builder
WORKDIR/build
COPYpom.xml .
RUNmvn dependency:go-offline -B
COPYsrc ./src
RUNmvn package -DskipTests -B

# 階段2:運(yùn)行
FROMeclipse-temurin:17-jre-alpine
RUNaddgroup -g 1000 app && adduser -u 1000 -G app -s /bin/sh -D app
WORKDIR/app
COPY--from=builder --chown=app:app /build/target/*.jar app.jar
USERapp
EXPOSE8080
HEALTHCHECK--interval=30s --timeout=5s --start-period=60s --retries=3 
  CMD wget -qO- http://localhost:8080/actuator/health ||exit1
ENTRYPOINT["java","-XX:MaxRAMPercentage=75.0","-jar","app.jar"]
# 編譯階段鏡像約800MB,最終運(yùn)行鏡像約180MB

2.3 啟動(dòng)和驗(yàn)證

2.3.1 構(gòu)建鏡像

# 基本構(gòu)建
docker build -t myapp:1.0.0 .

# 指定Dockerfile路徑
docker build -t myapp:1.0.0 -f deploy/Dockerfile .

# 使用BuildKit并顯示詳細(xì)輸出
DOCKER_BUILDKIT=1 docker build --progress=plain -t myapp:1.0.0 .

# 構(gòu)建時(shí)傳入?yún)?shù)
docker build --build-arg APP_VERSION=1.0.0 --build-arg BUILD_ENV=prod -t myapp:1.0.0 .

# 不使用緩存構(gòu)建(排查緩存問題時(shí)用)
docker build --no-cache -t myapp:1.0.0 .

# 多平臺(tái)構(gòu)建(同時(shí)構(gòu)建amd64和arm64)
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:1.0.0 --push .

2.3.2 驗(yàn)證鏡像

# 查看鏡像大小
docker images myapp:1.0.0

# 查看鏡像分層(每層大小和指令)
dockerhistorymyapp:1.0.0

# 查看鏡像詳細(xì)信息
docker inspect myapp:1.0.0

# 用dive工具分析鏡像層(推薦)
# 安裝:https://github.com/wagoodman/dive
dive myapp:1.0.0

# 安全掃描
docker scout cves myapp:1.0.0
# 或使用Trivy
trivy image myapp:1.0.0

# 運(yùn)行測(cè)試
docker run --rm myapp:1.0.0 --version
docker run --rm -p 8080:8080 myapp:1.0.0
curl http://localhost:8080/health

三、示例代碼和配置

3.1 完整配置示例

3.1.1 Node.js應(yīng)用Dockerfile(生產(chǎn)級(jí))

# 文件路徑:Dockerfile
# Node.js生產(chǎn)環(huán)境Dockerfile - 多階段構(gòu)建

# 階段1:安裝依賴
FROMnode:20.11-alpine3.19AS deps
WORKDIR/app
COPYpackage.json package-lock.json ./
RUNnpm ci --production --ignore-scripts && 
  npm cache clean --force

# 階段2:構(gòu)建(如果有TypeScript編譯或前端構(gòu)建)
FROMnode:20.11-alpine3.19AS builder
WORKDIR/app
COPYpackage.json package-lock.json ./
RUNnpm ci --ignore-scripts
COPY. .
RUNnpm run build

# 階段3:運(yùn)行
FROMnode:20.11-alpine3.19AS runner
LABELmaintainer="ops@example.com"
LABELversion="1.0.0"

# 安裝tini作為PID 1進(jìn)程,正確處理信號(hào)和僵尸進(jìn)程
RUNapk add --no-cache tini tzdata && 
  cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && 
 echo"Asia/Shanghai"> /etc/timezone && 
  apk del tzdata

# 創(chuàng)建非root用戶
RUNaddgroup -g 1000 app && adduser -u 1000 -G app -s /bin/sh -D app

WORKDIR/app

# 只復(fù)制生產(chǎn)依賴和構(gòu)建產(chǎn)物
COPY--from=deps --chown=app:app /app/node_modules ./node_modules
COPY--from=builder --chown=app:app /app/dist ./dist
COPY--chown=app:app package.json ./

USERapp

ENVNODE_ENV=production
ENVPORT=3000

EXPOSE3000

HEALTHCHECK--interval=30s --timeout=5s --start-period=10s --retries=3 
  CMD wget -qO- http://localhost:3000/health ||exit1

ENTRYPOINT["/sbin/tini","--"]
CMD["node","dist/server.js"]

說明

三階段構(gòu)建:deps階段只裝生產(chǎn)依賴,builder階段編譯TypeScript,runner階段只復(fù)制需要的文件

tini作為PID 1:Node.js不擅長處理信號(hào)和僵尸進(jìn)程回收,tini只有幾十KB,專門干這個(gè)事

npm ci而不是npm install:ci嚴(yán)格按照lock文件安裝,保證可重復(fù)構(gòu)建

3.1.2 Python應(yīng)用Dockerfile(生產(chǎn)級(jí))

# 文件路徑:Dockerfile
# Python生產(chǎn)環(huán)境Dockerfile - 多階段構(gòu)建

# 階段1:構(gòu)建wheel包
FROMpython:3.12-slim-bookworm AS builder

RUNapt-get update && 
  apt-get install -y --no-install-recommends gcc libpq-dev && 
  rm -rf /var/lib/apt/lists/*

WORKDIR/build
COPYrequirements.txt .
RUNpip install --no-cache-dir --prefix=/install -r requirements.txt

# 階段2:運(yùn)行
FROMpython:3.12-slim-bookworm AS runner

# 安裝運(yùn)行時(shí)依賴(不需要gcc)
RUNapt-get update && 
  apt-get install -y --no-install-recommends 
    libpq5 
    curl 
    tini 
  && rm -rf /var/lib/apt/lists/*

# 創(chuàng)建非root用戶
RUNgroupadd -g 1000 app && useradd -u 1000 -g app -s /bin/bash -m app

# 從builder階段復(fù)制已安裝的Python包
COPY--from=builder /install /usr/local

WORKDIR/app
COPY--chown=app:app . .

USERapp

ENVPYTHONUNBUFFERED=1
ENVPYTHONDONTWRITEBYTECODE=1

EXPOSE8000

HEALTHCHECK--interval=30s --timeout=5s --start-period=15s --retries=3 
  CMD curl -f http://localhost:8000/health ||exit1

ENTRYPOINT["tini","--"]
CMD["gunicorn","app.wsgi:application", 
  "--bind","0.0.0.0:8000", 
  "--workers","4", 
  "--worker-class","gvicorn.workers.UvicornWorker", 
  "--timeout","120", 
  "--access-logfile","-", 
  "--error-logfile","-"]

說明

PYTHONUNBUFFERED=1:禁用Python輸出緩沖,確保日志實(shí)時(shí)輸出到docker logs

PYTHONDONTWRITEBYTECODE=1:不生成.pyc文件,減少容器層大小

--prefix=/install:pip安裝到獨(dú)立目錄,方便多階段構(gòu)建復(fù)制

gunicorn的worker數(shù)一般設(shè)為2 * CPU核心數(shù) + 1,容器限制2核就設(shè)5個(gè)worker

3.1.3 CI/CD構(gòu)建腳本

#!/bin/bash
# 文件名:build.sh
# CI/CD流水線中的鏡像構(gòu)建腳本

set-euo pipefail

# 變量
APP_NAME="myapp"
REGISTRY="registry.example.com"
GIT_COMMIT=$(git rev-parse --short HEAD)
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
VERSION=${CI_COMMIT_TAG:-${GIT_BRANCH}-${GIT_COMMIT}}

IMAGE_NAME="${REGISTRY}/${APP_NAME}"
IMAGE_TAG="${IMAGE_NAME}:${VERSION}"
IMAGE_LATEST="${IMAGE_NAME}:latest"

echo"Building${IMAGE_TAG}"

# 構(gòu)建鏡像
docker build 
  --build-arg BUILD_TIME="${BUILD_TIME}"
  --build-arg GIT_COMMIT="${GIT_COMMIT}"
  --build-arg VERSION="${VERSION}"
  --label"org.opencontainers.image.created=${BUILD_TIME}"
  --label"org.opencontainers.image.revision=${GIT_COMMIT}"
  --label"org.opencontainers.image.version=${VERSION}"
  -t"${IMAGE_TAG}"
  -t"${IMAGE_LATEST}"
  .

# 安全掃描
echo"Scanning image for vulnerabilities..."
trivy image --exit-code 1 --severity HIGH,CRITICAL"${IMAGE_TAG}"
if[ $? -ne 0 ];then
 echo"ERROR: High/Critical vulnerabilities found, blocking push"
 exit1
fi

# 推送鏡像
docker push"${IMAGE_TAG}"
docker push"${IMAGE_LATEST}"

echo"Successfully built and pushed${IMAGE_TAG}"

3.2 實(shí)際應(yīng)用案例

案例一:鏡像瘦身實(shí)戰(zhàn)——從1.2GB到45MB

場景描述:一個(gè)Go微服務(wù)項(xiàng)目,原始Dockerfile直接在golang鏡像中編譯和運(yùn)行,鏡像1.2GB。通過多階段構(gòu)建+scratch基礎(chǔ)鏡像,壓縮到45MB。

優(yōu)化前的Dockerfile

# 優(yōu)化前:1.2GB
FROMgolang:1.22
WORKDIR/app
COPY. .
RUNgo build -o server ./cmd/server
EXPOSE8080
CMD["./server"]

優(yōu)化后的Dockerfile

# 優(yōu)化后:45MB
FROMgolang:1.22-alpine AS builder
RUNapk add --no-cache ca-certificates git

WORKDIR/build

# 先下載依賴(利用緩存)
COPYgo.mod go.sum ./
RUNgo mod download

# 編譯
COPY. .
RUNCGO_ENABLED=0 GOOS=linux GOARCH=amd64 
  go build -ldflags="-s -w -X main.version=1.0.0"
  -o /app/server ./cmd/server

# 用UPX進(jìn)一步壓縮二進(jìn)制文件(可選,壓縮率約60%)
RUNapk add --no-cache upx && upx --best /app/server

# 運(yùn)行階段
FROMscratch
COPY--from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY--from=builder /app/server /server

EXPOSE8080
ENTRYPOINT["/server"]

優(yōu)化效果對(duì)比

優(yōu)化前:
REPOSITORY  TAG   SIZE
myapp    v1   1.2GB
構(gòu)建時(shí)間:3分12秒

優(yōu)化后:
REPOSITORY  TAG   SIZE
myapp    v2   45MB
構(gòu)建時(shí)間:1分05秒(有緩存時(shí):8秒)

關(guān)鍵優(yōu)化點(diǎn)

-ldflags="-s -w":去掉調(diào)試信息和符號(hào)表,二進(jìn)制文件減小約30%

CGO_ENABLED=0:禁用CGO,生成靜態(tài)鏈接的二進(jìn)制文件,可以在scratch上運(yùn)行

UPX壓縮:二進(jìn)制文件從50MB壓縮到20MB,啟動(dòng)時(shí)有約100ms的解壓開銷,生產(chǎn)環(huán)境可以不用

scratch基礎(chǔ)鏡像:0字節(jié),沒有shell、沒有包管理器、沒有任何多余的東西

案例二:BuildKit緩存掛載加速構(gòu)建

場景描述:Java項(xiàng)目每次構(gòu)建都要下載Maven依賴,耗時(shí)5-8分鐘。使用BuildKit的緩存掛載功能,依賴緩存在構(gòu)建主機(jī)上,重復(fù)構(gòu)建時(shí)間從8分鐘降到40秒。

# syntax=docker/dockerfile:1
# 注意第一行的syntax指令,啟用BuildKit擴(kuò)展語法

FROMmaven:3.9-eclipse-temurin-17AS builder
WORKDIR/build

COPYpom.xml .
# --mount=type=cache 將Maven本地倉庫緩存到構(gòu)建主機(jī)
# 即使鏡像層緩存失效,Maven依賴緩存仍然有效
RUN--mount=type=cache,target=/root/.m2/repository 
  mvn dependency:go-offline -B

COPYsrc ./src
RUN--mount=type=cache,target=/root/.m2/repository 
  mvn package -DskipTests -B

FROMeclipse-temurin:17-jre-alpine
RUNaddgroup -g 1000 app && adduser -u 1000 -G app -s /bin/sh -D app
WORKDIR/app
COPY--from=builder --chown=app:app /build/target/*.jar app.jar
USERapp
EXPOSE8080
ENTRYPOINT["java","-XX:MaxRAMPercentage=75.0","-jar","app.jar"]
# 構(gòu)建命令(BuildKit默認(rèn)啟用)
docker build -t myapp:1.0.0 .

# 第一次構(gòu)建:下載所有依賴,約8分鐘
# 第二次構(gòu)建(修改了源碼):依賴從緩存讀取,約40秒
# 第三次構(gòu)建(修改了pom.xml):只下載新增的依賴,約1分鐘

BuildKit緩存掛載類型

type=cache:持久化緩存目錄,跨構(gòu)建保留。適合包管理器緩存(Maven、npm、pip)

type=secret:掛載密鑰文件,不會(huì)寫入鏡像層。適合私有倉庫認(rèn)證

type=ssh:轉(zhuǎn)發(fā)SSH agent,用于拉取私有Git倉庫

# Secret掛載示例:拉取私有npm包
RUN--mount=type=secret,id=npmrc,target=/root/.npmrc 
  npm ci --production

# 構(gòu)建時(shí)傳入secret
# docker build --secret id=npmrc,src=$HOME/.npmrc -t myapp:1.0.0 .

# SSH掛載示例:拉取私有Git倉庫
RUN--mount=type=ssh 
  gitclonegit@github.com:company/private-lib.git

# 構(gòu)建時(shí)轉(zhuǎn)發(fā)SSH
# docker build --ssh default -t myapp:1.0.0 .

四、最佳實(shí)踐和注意事項(xiàng)

4.1 最佳實(shí)踐

4.1.1 性能優(yōu)化

合理利用構(gòu)建緩存:把變化頻率低的指令放前面(系統(tǒng)依賴安裝),變化頻率高的放后面(源碼復(fù)制)。一個(gè)典型的Node.js項(xiàng)目,合理利用緩存后構(gòu)建時(shí)間從3分鐘降到15秒(只有源碼變更時(shí)):

# 依賴文件單獨(dú)復(fù)制,變更頻率低
COPYpackage.json package-lock.json ./
RUNnpm ci --production
# 源碼最后復(fù)制,變更頻率高
COPY. .

使用BuildKit并行構(gòu)建:多階段構(gòu)建中,沒有依賴關(guān)系的階段會(huì)自動(dòng)并行執(zhí)行。把獨(dú)立的構(gòu)建任務(wù)拆成不同階段:

# 這兩個(gè)階段會(huì)并行執(zhí)行
FROMnode:20-alpine AS frontend-builder
COPYfrontend/ .
RUNnpm run build

FROMgolang:1.22-alpine AS backend-builder
COPYbackend/ .
RUNgo build -o server

# 最終階段合并
FROMalpine:3.19
COPY--from=frontend-builder /app/dist /www
COPY--from=backend-builder /app/server /server

減少鏡像層數(shù):合并相關(guān)的RUN指令。Docker限制最多127層,雖然一般不會(huì)超,但層數(shù)越少拉取越快。每一層都有元數(shù)據(jù)開銷,合并后鏡像通常小5%-10%。

4.1.2 安全加固

不在鏡像中存儲(chǔ)密鑰:構(gòu)建參數(shù)(ARG)和環(huán)境變量(ENV)都會(huì)被記錄在鏡像層中,docker history可以看到。密鑰用BuildKit的secret掛載:

#  錯(cuò)誤:密鑰會(huì)留在鏡像歷史中
ARGNPM_TOKEN
RUNecho"http://registry.npmjs.org/:_authToken=${NPM_TOKEN}"> .npmrc && 
  npm ci && rm .npmrc

#  正確:secret不會(huì)寫入鏡像層
RUN--mount=type=secret,id=npmrc,target=/root/.npmrc npm ci

使用固定版本的基礎(chǔ)鏡像:不要用latest,不要用只有主版本號(hào)的tag(如node:20)。用完整的版本號(hào)+變體(如node:20.11.1-alpine3.19),確保每次構(gòu)建基礎(chǔ)鏡像一致:

#  不確定性高
FROMpython:3
FROMnode:latest

#  版本鎖定
FROMpython:3.12.1-slim-bookworm
FROMnode:20.11.1-alpine3.19

鏡像安全掃描集成到CI:每次構(gòu)建后自動(dòng)掃描,HIGH和CRITICAL級(jí)別漏洞阻斷發(fā)布:

# Trivy掃描,發(fā)現(xiàn)高危漏洞返回非0退出碼
trivy image --exit-code 1 --severity HIGH,CRITICAL myapp:1.0.0

4.1.3 高可用配置

鏡像倉庫高可用:生產(chǎn)環(huán)境用Harbor搭建私有倉庫,配置主從復(fù)制。構(gòu)建機(jī)推送到主倉庫,各機(jī)房從本地倉庫拉取,避免跨機(jī)房拉取鏡像的網(wǎng)絡(luò)延遲

構(gòu)建緩存持久化:CI/CD環(huán)境中,構(gòu)建緩存默認(rèn)在構(gòu)建機(jī)本地。用docker buildx的遠(yuǎn)程緩存功能,把緩存存到倉庫:

docker buildx build 
  --cache-fromtype=registry,ref=registry.example.com/myapp:buildcache 
  --cache-totype=registry,ref=registry.example.com/myapp:buildcache,mode=max 
  -t myapp:1.0.0 .

多架構(gòu)支持:生產(chǎn)環(huán)境可能有x86和ARM混合部署,用buildx構(gòu)建多架構(gòu)鏡像,一個(gè)tag同時(shí)支持amd64和arm64

4.2 注意事項(xiàng)

4.2.1 配置注意事項(xiàng)

警告:Dockerfile中的每個(gè)RUN、COPY、ADD指令都會(huì)創(chuàng)建新的鏡像層。刪除文件的操作如果不在同一層中執(zhí)行,不會(huì)減小鏡像體積——文件在上一層已經(jīng)存在,新層只是標(biāo)記刪除。

注意ENTRYPOINT和CMD的區(qū)別:ENTRYPOINT定義容器的主進(jìn)程,CMD提供默認(rèn)參數(shù)。docker run后面的參數(shù)會(huì)覆蓋CMD但不會(huì)覆蓋ENTRYPOINT:

# ENTRYPOINT + CMD組合
ENTRYPOINT["java","-jar","app.jar"]
CMD["--spring.profiles.active=prod"]
# docker run myapp 會(huì)執(zhí)行:java -jar app.jar --spring.profiles.active=prod
# docker run myapp --spring.profiles.active=dev 會(huì)執(zhí)行:java -jar app.jar --spring.profiles.active=dev

注意shell形式和exec形式的區(qū)別:exec形式(JSON數(shù)組)直接執(zhí)行命令,shell形式會(huì)通過/bin/sh -c執(zhí)行。shell形式的進(jìn)程不是PID 1,收不到SIGTERM信號(hào):

#  shell形式:sh是PID 1,java是子進(jìn)程,收不到SIGTERM
ENTRYPOINTjava -jar app.jar

#  exec形式:java是PID 1,能正確接收信號(hào)
ENTRYPOINT["java","-jar","app.jar"]

注意ARG的作用域:ARG在FROM之前定義的只能在FROM中使用,F(xiàn)ROM之后需要重新聲明:

ARGBASE_IMAGE=alpine:3.19
FROM${BASE_IMAGE}
# 這里ARG BASE_IMAGE已經(jīng)失效,需要重新聲明
ARGAPP_VERSION
RUNecho${APP_VERSION}

4.2.2 常見錯(cuò)誤

錯(cuò)誤現(xiàn)象 原因分析 解決方案
鏡像體積異常大 沒有清理包管理器緩存,或者刪除操作不在同一層 安裝和清理放在同一個(gè)RUN中
構(gòu)建緩存總是失效 COPY . . 放在安裝依賴之前,任何文件變更都導(dǎo)致緩存失效 先COPY依賴文件,安裝依賴,再COPY源碼
容器啟動(dòng)后立即退出 CMD/ENTRYPOINT寫成了shell形式,前臺(tái)進(jìn)程變成后臺(tái) 用exec形式,確保主進(jìn)程在前臺(tái)運(yùn)行
構(gòu)建時(shí)網(wǎng)絡(luò)超時(shí) 構(gòu)建環(huán)境無法訪問外網(wǎng)或鏡像源 配置鏡像源加速,或用--network=host構(gòu)建
權(quán)限拒絕錯(cuò)誤 USER指令切換了用戶但文件屬主還是root COPY --chown=user:group 或 RUN chown
alpine上程序段錯(cuò)誤 musl libc和glibc不兼容 換成slim變體或用靜態(tài)編譯

4.2.3 兼容性問題

版本兼容:BuildKit的--mount語法需要Docker 18.09+,# syntax=docker/dockerfile:1指令需要BuildKit啟用。舊版Docker不支持這些特性

平臺(tái)兼容:多架構(gòu)構(gòu)建需要QEMU模擬器支持非本機(jī)架構(gòu)。在x86機(jī)器上構(gòu)建arm64鏡像,編譯速度會(huì)慢5-10倍

基礎(chǔ)鏡像兼容:alpine 3.19使用musl libc 1.2.4,部分依賴glibc的二進(jìn)制文件無法運(yùn)行。Node.js和Go的alpine變體沒問題,Python和Java的某些native擴(kuò)展可能有問題

五、故障排查和監(jiān)控

5.1 故障排查

5.1.1 日志查看

# 查看構(gòu)建詳細(xì)日志
docker build --progress=plain -t myapp:1.0.0 . 2>&1 | tee build.log

# 查看構(gòu)建歷史(每層的指令和大?。?dockerhistorymyapp:1.0.0

# 查看鏡像元數(shù)據(jù)
docker inspect myapp:1.0.0

# 查看構(gòu)建緩存使用情況
docker buildx du

# 查看BuildKit構(gòu)建日志
sudo journalctl -u docker.service | grep buildkit

5.1.2 常見問題排查

問題一:構(gòu)建緩存不生效

# 檢查構(gòu)建上下文是否有變化
# .dockerignore沒有排除的文件變更會(huì)導(dǎo)致COPY指令緩存失效
docker build --progress=plain -t myapp:1.0.0 . 2>&1 | grep -E"CACHED|RUN|COPY"

# 查看哪一步開始緩存失效
# 輸出中從"CACHED"變成非CACHED的那一步就是緩存失效點(diǎn)

# 常見原因:
# 1. COPY . . 之前的文件有變更(檢查.dockerignore)
# 2. ARG值變了(ARG變更會(huì)導(dǎo)致后續(xù)所有層緩存失效)
# 3. 基礎(chǔ)鏡像更新了(FROM的鏡像有新版本)

解決方案

完善.dockerignore,排除不需要的文件

把COPY拆分,先復(fù)制依賴文件,再復(fù)制源碼

基礎(chǔ)鏡像用完整版本號(hào)鎖定

問題二:構(gòu)建過程中網(wǎng)絡(luò)超時(shí)

# 診斷:檢查構(gòu)建環(huán)境網(wǎng)絡(luò)
docker run --rm alpine ping -c 3 registry.npmjs.org
docker run --rm alpine wget -qO- https://registry.npmjs.org/ | head -1

# 使用宿主機(jī)網(wǎng)絡(luò)構(gòu)建(繞過Docker網(wǎng)絡(luò))
docker build --network=host -t myapp:1.0.0 .

# 配置構(gòu)建時(shí)的代理
docker build 
  --build-arg HTTP_PROXY=http://proxy.example.com:8080 
  --build-arg HTTPS_PROXY=http://proxy.example.com:8080 
  --build-arg NO_PROXY=localhost,127.0.0.1,.example.com 
  -t myapp:1.0.0 .

解決方案:配置鏡像源加速(npm用淘寶源,pip用清華源,Maven用阿里云源),或者在Dockerfile中設(shè)置代理環(huán)境變量。

問題三:鏡像體積異常大

癥狀:鏡像大小遠(yuǎn)超預(yù)期,比如一個(gè)Go應(yīng)用鏡像超過500MB

排查

# 用dive分析每一層的內(nèi)容和大小
dive myapp:1.0.0

# 查看每層大小
dockerhistory--no-trunc myapp:1.0.0

# 檢查是否有不必要的文件
docker run --rm myapp:1.0.0 du -sh /* 2>/dev/null | sort -rh
docker run --rm myapp:1.0.0 find / -size +10M -typef 2>/dev/null

解決

檢查是否用了多階段構(gòu)建,編譯工具不應(yīng)該出現(xiàn)在最終鏡像

檢查RUN指令是否在同一層中清理了緩存

檢查是否復(fù)制了不需要的文件(完善.dockerignore)

5.1.3 調(diào)試模式

# 在構(gòu)建失敗的層啟動(dòng)一個(gè)臨時(shí)容器進(jìn)行調(diào)試
# 方法1:用最后一個(gè)成功的層啟動(dòng)容器
docker build -t myapp:debug . 2>&1
# 找到最后成功的層ID,然后
docker run --rm -it  /bin/sh

# 方法2:在Dockerfile中插入調(diào)試指令
# 在失敗的RUN之前加一個(gè)RUN ls -la /app/ 查看文件狀態(tài)

# 方法3:用BuildKit的調(diào)試功能
BUILDKIT_PROGRESS=plain docker build -t myapp:1.0.0 . 2>&1 | tee build.log

# 方法4:交互式調(diào)試(Docker Desktop 4.27+)
docker debug myapp:1.0.0

5.2 性能監(jiān)控

5.2.1 關(guān)鍵指標(biāo)監(jiān)控

# 監(jiān)控構(gòu)建時(shí)間
time docker build -t myapp:1.0.0 .

# 監(jiān)控鏡像大小趨勢(shì)
docker images --format"{{.Repository}}:{{.Tag}} {{.Size}}"| sort

# 監(jiān)控構(gòu)建緩存大小
docker buildx du
docker system df

# 監(jiān)控構(gòu)建機(jī)磁盤使用
df -h /var/lib/docker

5.2.2 監(jiān)控指標(biāo)說明

指標(biāo)名稱 正常范圍 告警閾值 說明
鏡像構(gòu)建時(shí)間 <5分鐘 >10分鐘 超過10分鐘檢查緩存是否失效
最終鏡像大小 <200MB >500MB 超過500MB檢查是否有多余文件
構(gòu)建緩存大小 <20GB >50GB 定期清理構(gòu)建緩存
鏡像層數(shù) <20層 >40層 層數(shù)過多影響拉取速度
安全漏洞數(shù)(HIGH+) 0 >0 高危漏洞必須修復(fù)
構(gòu)建成功率 >95% <90% 低于90%檢查構(gòu)建環(huán)境穩(wěn)定性

5.2.3 CI/CD構(gòu)建監(jiān)控配置

# GitLab CI中的構(gòu)建監(jiān)控示例:.gitlab-ci.yml
build:
stage:build
script:
 -BUILD_START=$(date+%s)
 -dockerbuild-t${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}.
 -BUILD_END=$(date+%s)
 -BUILD_TIME=$((BUILD_END-BUILD_START))
 -echo"Build time: ${BUILD_TIME}s"
 # 推送構(gòu)建指標(biāo)到Prometheus Pushgateway
 -|
   cat <
# Prometheus告警規(guī)則:dockerfile-build-alerts.yml
groups:
-name:docker_build_alerts
 rules:
  -alert:DockerBuildSlow
   expr:docker_build_duration_seconds>600
   for:0m
   labels:
    severity:warning
   annotations:
    summary:"項(xiàng)目{{ $labels.instance }}構(gòu)建時(shí)間過長"
    description:"構(gòu)建耗時(shí){{ $value }}秒,超過10分鐘閾值"

  -alert:DockerImageTooLarge
   expr:docker_image_size_bytes>524288000
   for:0m
   labels:
    severity:warning
   annotations:
    summary:"項(xiàng)目{{ $labels.instance }}鏡像體積過大"
    description:"鏡像大小{{ $value | humanize }},超過500MB"

  -alert:BuildCacheUsageHigh
   expr:docker_builder_cache_bytes/docker_builder_cache_limit_bytes>0.85
   for:5m
   labels:
    severity:warning
   annotations:
    summary:"構(gòu)建緩存使用率過高"
    description:"緩存使用率{{ $value | humanizePercentage }}"

5.3 備份與恢復(fù)

5.3.1 備份策略

#!/bin/bash
# Dockerfile和構(gòu)建配置備份腳本
# 建議納入Git版本管理,這里是額外的備份

BACKUP_DIR="/backup/dockerfile/$(date +%Y%m%d)"
mkdir -p${BACKUP_DIR}

# 備份所有項(xiàng)目的Dockerfile
find /data/projects -name"Dockerfile*"-execcp --parents {}${BACKUP_DIR}/ ;

# 備份.dockerignore
find /data/projects -name".dockerignore"-execcp --parents {}${BACKUP_DIR}/ ;

# 備份構(gòu)建腳本
find /data/projects -name"build.sh"-execcp --parents {}${BACKUP_DIR}/ ;

# 導(dǎo)出構(gòu)建緩存(可選,體積可能很大)
# docker buildx prune --keep-storage 10GB

echo"Backup completed:${BACKUP_DIR}"

5.3.2 恢復(fù)流程

恢復(fù)Dockerfile:從Git倉庫或備份目錄恢復(fù)

重建構(gòu)建緩存:第一次構(gòu)建會(huì)比較慢,后續(xù)構(gòu)建會(huì)自動(dòng)建立緩存

驗(yàn)證構(gòu)建:docker build -t test:latest .確認(rèn)構(gòu)建正常

驗(yàn)證鏡像:運(yùn)行容器并執(zhí)行健康檢查

六、總結(jié)

6.1 技術(shù)要點(diǎn)回顧

基礎(chǔ)鏡像選擇:alpine變體體積最?。?-7MB),slim變體兼容性最好,distroless最安全。根據(jù)應(yīng)用語言和依賴選擇合適的基礎(chǔ)鏡像

多階段構(gòu)建:編譯環(huán)境和運(yùn)行環(huán)境分離,Go應(yīng)用可以從800MB壓縮到20MB,Java應(yīng)用從800MB壓縮到180MB

構(gòu)建緩存利用:指令順序按變更頻率從低到高排列,依賴安裝和源碼復(fù)制分開,緩存命中時(shí)構(gòu)建時(shí)間從分鐘級(jí)降到秒級(jí)

安全基線:非root用戶運(yùn)行、固定版本基礎(chǔ)鏡像、不在鏡像中存儲(chǔ)密鑰、集成安全掃描

BuildKit特性:緩存掛載(--mount=type=cache)、密鑰掛載(--mount=type=secret)、并行構(gòu)建,是現(xiàn)代Dockerfile的標(biāo)配

6.2 進(jìn)階學(xué)習(xí)方向

多架構(gòu)構(gòu)建:使用docker buildx構(gòu)建同時(shí)支持amd64和arm64的鏡像,適配混合架構(gòu)部署

學(xué)習(xí)資源:Docker官方文檔 Multi-platform images

實(shí)踐建議:在CI/CD中配置多架構(gòu)構(gòu)建流水線

鏡像供應(yīng)鏈安全:鏡像簽名(Cosign/Notary)、SBOM生成、漏洞掃描集成

學(xué)習(xí)資源:Sigstore項(xiàng)目、Trivy文檔

實(shí)踐建議:在Harbor中啟用鏡像簽名驗(yàn)證策略

構(gòu)建性能優(yōu)化:遠(yuǎn)程構(gòu)建緩存、分布式構(gòu)建、構(gòu)建集群

學(xué)習(xí)資源:BuildKit GitHub倉庫

實(shí)踐建議:配置registry類型的遠(yuǎn)程緩存,多個(gè)CI Runner共享構(gòu)建緩存

6.3 參考資料

Dockerfile reference- 官方指令參考

Best practices for writing Dockerfiles- 官方最佳實(shí)踐

BuildKit- BuildKit源碼和文檔

dive- 鏡像層分析工具

Trivy- 容器安全掃描工具

distroless- Google的最小化基礎(chǔ)鏡像

附錄

A. 命令速查表

# 構(gòu)建命令
docker build -t 名稱:tag .          # 基本構(gòu)建
docker build -f Dockerfile.prod -t 名稱:tag . # 指定Dockerfile
docker build --no-cache -t 名稱:tag .     # 不使用緩存
docker build --build-arg KEY=VALUE -t 名稱:tag .# 傳入構(gòu)建參數(shù)
docker build --target stage-name -t 名稱:tag . # 構(gòu)建到指定階段
docker buildx build --platform linux/amd64,linux/arm64 -t 名稱:tag --push .# 多架構(gòu)構(gòu)建

# 鏡像分析
dockerhistory鏡像:tag            # 查看分層歷史
docker inspect 鏡像:tag            # 查看鏡像元數(shù)據(jù)
docker images --filter"dangling=true"    # 查看dangling鏡像
dive 鏡像:tag                 # 交互式分析鏡像層

# 緩存管理
docker builder prune             # 清理構(gòu)建緩存
docker buildx du               # 查看緩存使用量
docker buildx prune --keep-storage 10GB    # 保留10GB緩存

# 安全掃描
trivy image 鏡像:tag             # 掃描鏡像漏洞
docker scout cves 鏡像:tag          # Docker官方掃描

B. Dockerfile指令詳解

指令 作用 示例 注意事項(xiàng)
FROM 指定基礎(chǔ)鏡像 FROM alpine:3.19 必須是第一條指令(ARG除外)
RUN 執(zhí)行命令 RUN apt-get update 每條RUN創(chuàng)建一層,合并減少層數(shù)
COPY 復(fù)制文件 COPY src/ /app/src/ 推薦用COPY而不是ADD
ADD 復(fù)制文件(支持解壓和URL) ADD app.tar.gz /app/ 僅在需要自動(dòng)解壓時(shí)使用
WORKDIR 設(shè)置工作目錄 WORKDIR /app 不要用RUN cd,用WORKDIR
ENV 設(shè)置環(huán)境變量 ENV NODE_ENV=production 會(huì)寫入鏡像元數(shù)據(jù),不要放密鑰
ARG 構(gòu)建時(shí)參數(shù) ARG VERSION=1.0 只在構(gòu)建時(shí)有效,運(yùn)行時(shí)不存在
EXPOSE 聲明端口 EXPOSE 8080 僅聲明作用,不實(shí)際映射端口
USER 切換用戶 USER app 之后的指令以該用戶身份執(zhí)行
ENTRYPOINT 容器入口點(diǎn) ENTRYPOINT ["java","-jar","app.jar"] 用exec形式(JSON數(shù)組)
CMD 默認(rèn)命令/參數(shù) CMD ["--port","8080"] 可被docker run參數(shù)覆蓋
HEALTHCHECK 健康檢查 HEALTHCHECK CMD curl -f http://localhost/ 生產(chǎn)環(huán)境必須配置
LABEL 元數(shù)據(jù)標(biāo)簽 LABEL version="1.0" 用于鏡像管理和追溯
VOLUME 聲明卷 VOLUME /data 僅聲明,實(shí)際掛載在run時(shí)指定
STOPSIGNAL 停止信號(hào) STOPSIGNAL SIGTERM 默認(rèn)SIGTERM,一般不需要改

C. 術(shù)語表

術(shù)語 英文 解釋
構(gòu)建上下文 Build Context docker build時(shí)發(fā)送給Docker daemon的文件集合,由.dockerignore控制范圍
鏡像層 Image Layer Dockerfile中每條指令生成的只讀文件系統(tǒng)層,多層疊加組成完整鏡像
多階段構(gòu)建 Multi-stage Build 一個(gè)Dockerfile中使用多個(gè)FROM,前面階段的產(chǎn)物可以復(fù)制到后面階段
BuildKit BuildKit Docker新一代構(gòu)建引擎,支持并行構(gòu)建、緩存掛載等高級(jí)特性
構(gòu)建緩存 Build Cache Docker緩存已構(gòu)建的層,未變更的層直接復(fù)用,加速構(gòu)建
distroless Distroless Google維護(hù)的最小化容器鏡像,只包含應(yīng)用運(yùn)行時(shí),沒有shell和包管理器
scratch Scratch Docker的空白基礎(chǔ)鏡像,0字節(jié),用于靜態(tài)編譯的程序
dangling鏡像 Dangling Image 沒有tag的鏡像,通常是被新構(gòu)建覆蓋的舊鏡像
OCI Open Container Initiative 容器鏡像和運(yùn)行時(shí)的開放標(biāo)準(zhǔn)

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11763

    瀏覽量

    219079
  • python
    +關(guān)注

    關(guān)注

    57

    文章

    4877

    瀏覽量

    90071
  • 鏡像
    +關(guān)注

    關(guān)注

    0

    文章

    180

    瀏覽量

    11650

原文標(biāo)題:Dockerfile 最佳實(shí)踐:構(gòu)建高效、輕量、安全鏡像的完整指南

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    構(gòu)建ARM64版本nacos docker鏡像

    在適配過程中有大量合作伙伴用到nacos且采用容器化部署,dockerhub未提供官方鏡像,因此需要在鯤鵬服務(wù)器自定義構(gòu)建。構(gòu)建前提:Docker已部署構(gòu)建
    發(fā)表于 06-16 14:29

    一文詳解DockerFile基礎(chǔ)知識(shí)

    DockerFile用來構(gòu)建docker的鏡像文件,可以理解為命令參數(shù)腳本。構(gòu)建步驟編寫一個(gè)Docker
    發(fā)表于 09-15 15:54

    Dockerfile構(gòu)建環(huán)境報(bào)錯(cuò)如何解決?

    我正在使用以下 Dockerfile 來設(shè)置構(gòu)建環(huán)境:修改local.conf文件,執(zhí)行bitbake命令后,收到如下錯(cuò)誤:ERROR: Task (virtual:native:/home
    發(fā)表于 04-11 06:17

    全面詳解Dockerfile文件

    Docker 可以通過讀取 Dockerfile 中的指令自動(dòng)構(gòu)建鏡像Dockerfile 是一個(gè)文本文檔,其中包含了用戶創(chuàng)建鏡像的所有命
    的頭像 發(fā)表于 09-22 15:38 ?2537次閱讀

    鏡像構(gòu)建Dockerfile的介紹

    Dockerfile 是一個(gè)用來構(gòu)建鏡像的文本文件,文本內(nèi)容包含了一條條構(gòu)建鏡像所需的指令和說明。
    的頭像 發(fā)表于 09-06 09:36 ?1985次閱讀

    Dockerfile的最佳實(shí)踐

    隨著應(yīng)用的容器化、上云后,將伴隨著 Docker 鏡像構(gòu)建,構(gòu)建 Docker 鏡像成為了最基本的一步,其中 Dockerfile 便是用
    的頭像 發(fā)表于 01-20 10:59 ?1831次閱讀
    <b class='flag-5'>Dockerfile</b>的最佳實(shí)踐

    Docker入門指南之什么是Dockerfile

    發(fā)時(shí)所構(gòu)建鏡像或者通過Dockerfile文件構(gòu)建一個(gè)新的鏡像開始工作 * 對(duì)于運(yùn)維人員:在部署時(shí),可以實(shí)現(xiàn)應(yīng)用的無縫移植
    的頭像 發(fā)表于 02-06 15:25 ?1191次閱讀
    Docker入門指南之什么是<b class='flag-5'>Dockerfile</b>

    新一代更強(qiáng)大的鏡像構(gòu)建工具Earthly

    在使用 Earthly 進(jìn)行構(gòu)建鏡像時(shí)目前強(qiáng)依賴于 buildkit,Earthly 通過 buildkit 支持了一些 Dockerfile 的擴(kuò)展語法,同時(shí)將 Dockerfile
    的頭像 發(fā)表于 03-30 11:21 ?1552次閱讀

    Dockerfile定義Docker鏡像構(gòu)建過程

    了解Dockerfile Dockerfile 是一個(gè)文本文件,用于定義 Docker 鏡像構(gòu)建過程。它以指令的形式描述了如何構(gòu)建
    的頭像 發(fā)表于 09-30 10:22 ?3384次閱讀

    如何使用dockerfile創(chuàng)建鏡像

    Docker是一個(gè)開源的平臺(tái),用于快速構(gòu)建、打包、部署應(yīng)用程序的容器化工具。而Dockerfile是一個(gè)文本文件,包含了一組可自動(dòng)化構(gòu)建Docker鏡像的指令。本文將
    的頭像 發(fā)表于 11-23 09:52 ?1588次閱讀

    手動(dòng)構(gòu)建Docker鏡像的方法

    不推薦使用docker commit命令,而應(yīng)該使用更靈活、更強(qiáng)大的dockerfile構(gòu)建docker鏡像
    的頭像 發(fā)表于 08-05 15:30 ?1632次閱讀
    手動(dòng)<b class='flag-5'>構(gòu)建</b>Docker<b class='flag-5'>鏡像</b>的方法

    提升DevOps效率,從基礎(chǔ)到進(jìn)階的Dockerfile編寫技巧

    目錄 Dockerfile 基本結(jié)構(gòu) 指令 創(chuàng)建鏡像(centos版) 創(chuàng)建鏡像(alpine版) 基本結(jié)構(gòu) Dockerfile 是一個(gè)文本格式的配置文件,用戶可以使用
    的頭像 發(fā)表于 11-26 09:44 ?1151次閱讀
    提升DevOps效率,從基礎(chǔ)到進(jìn)階的<b class='flag-5'>Dockerfile</b>編寫技巧

    Dockerfile鏡像制作與Docker-Compose容器編排

    Dockerfile鏡像制作 docker/podman中, 鏡像是容器的基礎(chǔ),每次執(zhí)行docker run的時(shí)候都會(huì)指定哪個(gè)基本鏡像作為容器運(yùn)行的基礎(chǔ)。我們之前的docker的操作都
    的頭像 發(fā)表于 01-07 11:01 ?1325次閱讀
    <b class='flag-5'>Dockerfile</b><b class='flag-5'>鏡像</b>制作與Docker-Compose容器編排

    Docker-鏡像的分層-busybox鏡像制作

    目錄 知識(shí)點(diǎn)1:鏡像的分層 示例:進(jìn)入 docker hub查看Jenkins的Dockerfile 知識(shí)點(diǎn)2:base鏡像 知識(shí)點(diǎn)3:scratch鏡像 scratch
    的頭像 發(fā)表于 01-15 10:44 ?1271次閱讀
    Docker-<b class='flag-5'>鏡像</b>的分層-busybox<b class='flag-5'>鏡像</b>制作

    基于Docker鏡像逆向生成Dockerfile

    在本文中, 我們將通過理解Docker鏡像如何存儲(chǔ)數(shù)據(jù), 以及如何使用工具查看鏡像方方面面的信息來逆向工程一個(gè)Docker鏡像; 以及如何使用Python的Docker API來構(gòu)建
    的頭像 發(fā)表于 03-10 09:45 ?1556次閱讀
    基于Docker<b class='flag-5'>鏡像</b>逆向生成<b class='flag-5'>Dockerfile</b>