Docker技能Skill docker

Docker技能是一个关于使用Docker容器化平台的技能,用于应用程序的构建、运行和部署在隔离容器中。它包括Dockerfile编写、Docker Compose配置、镜像管理、容器编排、网络配置、存储优化等关键方面,适用于开发、测试和生产环境,支持微服务架构和CI/CD流程。关键词:Docker、容器化、Dockerfile、Docker Compose、镜像、容器、网络、存储、CI/CD、微服务。

Docker/K8s 0 次安装 0 次浏览 更新于 3/18/2026

name: docker description: Docker使用指南 - 一个用于在隔离容器中构建、运行和部署应用程序的容器化平台。在容器化应用程序、创建Dockerfile、使用Docker Compose、管理镜像/容器、配置网络和存储、优化构建、部署到生产环境或使用Docker实现CI/CD管道时使用。

Docker技能

本技能提供使用Docker的综合指南,涵盖容器化概念、实际工作流和所有主要技术栈的最佳实践。

何时使用此技能

在以下情况使用此技能:

  • 为任何语言或框架容器化应用程序
  • 创建或优化Dockerfile和Docker Compose配置
  • 使用Docker设置开发环境
  • 部署容器化应用程序到生产环境
  • 使用Docker实现CI/CD管道
  • 管理容器网络、存储和安全
  • 排查Docker相关问题
  • 构建多平台镜像
  • 实现微服务架构

核心Docker概念

容器

  • 轻量级、隔离的进程,将应用程序与所有依赖项捆绑在一起
  • 通过联合文件系统和命名空间技术提供文件系统隔离
  • 默认短暂性 - 容器停止时更改会丢失(除非持久化到卷)
  • 单一职责原则:每个容器应做好一件事
  • 多个相同容器可以从相同的不可变镜像运行而无需冲突

镜像

  • 容器的蓝图/模板 - 只读文件系统 + 配置
  • 分层文件系统组成(不可变、可重用层)
  • 根据Dockerfile指令构建或从运行容器提交
  • 存储在注册表中(Docker Hub、ECR、ACR、GCR、私有注册表)
  • 镜像命名REGISTRY/NAMESPACE/REPOSITORY:TAG(例如,docker.io/library/nginx:latest

卷与存储

  • :Docker管理的持久存储,在容器删除后保留
  • 绑定挂载:将主机文件系统路径直接映射到容器中
  • tmpfs挂载:用于临时数据的内存存储
  • 支持容器间数据共享并在容器生命周期后持久化

网络

  • 默认桥接网络连接同一主机上的容器
  • 自定义网络允许通过DNS解析进行显式容器通信
  • 主机网络去除网络隔离以提高性能
  • 覆盖网络支持多主机容器通信(Swarm)
  • MACVLAN/IPvlan用于需要直接L2/L3网络访问的容器

Dockerfile最佳实践

基本指令

FROM <image>:<tag>                        # 基础镜像(使用特定版本,非'latest')
WORKDIR /app                              # 后续命令的工作目录
COPY package*.json ./                     # 首先复制依赖文件(用于缓存)
RUN npm install --production              # 执行构建命令
COPY . .                                  # 复制应用程序代码
ENV NODE_ENV=production                   # 环境变量
EXPOSE 3000                               # 记录暴露的端口
USER node                                 # 以非root用户运行(安全)
CMD ["node", "server.js"]                 # 容器启动时的默认命令

多阶段构建(生产关键)

分离构建环境与运行时环境以减少镜像大小并提高安全性:

# 阶段1:构建
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 阶段2:生产
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]

好处:最终镜像中没有构建工具,仅包含编译资产,更小尺寸,提高安全性

层缓存优化

顺序重要:如果指令未更改,Docker会重用层:

  1. 依赖项优先(COPY package.json, RUN npm install)
  2. 应用程序代码最后(COPY . .)
  3. 这样,代码更改不会使依赖层失效

安全加固

# 使用特定版本
FROM node:20.11.0-alpine3.19

# 创建非root用户
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

# 设置所有权
COPY --chown=nodejs:nodejs . .

# 切换到非root
USER nodejs

# 只读根文件系统(尽可能)
# 运行容器时添加 --read-only 标志

.dockerignore文件

从构建上下文中排除不必要的文件:

node_modules
.git
.env
.env.local
*.log
.DS_Store
README.md
docker-compose.yml
.dockerignore
Dockerfile
dist
coverage
.vscode

常见工作流

构建镜像

# 构建并标记
docker build -t myapp:1.0 .

# 构建针对特定阶段
docker build -t myapp:dev --target build .

# 使用构建参数构建
docker build --build-arg NODE_ENV=production -t myapp:1.0 .

# 为多平台构建
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:1.0 .

# 查看镜像层和大小
docker image history myapp:1.0

# 列出所有镜像
docker image ls

运行容器

# 基本运行
docker run myapp:1.0

# 后台运行(分离)
docker run -d --name myapp myapp:1.0

# 端口映射(主机:容器)
docker run -p 8080:3000 myapp:1.0

# 环境变量
docker run -e NODE_ENV=production -e API_KEY=secret myapp:1.0

# 卷挂载(命名卷)
docker run -v mydata:/app/data myapp:1.0

# 绑定挂载(开发)
docker run -v $(pwd)/src:/app/src myapp:1.0

# 自定义网络
docker run --network my-network myapp:1.0

# 资源限制
docker run --memory 512m --cpus 0.5 myapp:1.0

# 交互式终端
docker run -it myapp:1.0 /bin/sh

# 覆盖入口点/命令
docker run --entrypoint /bin/sh myapp:1.0
docker run myapp:1.0 custom-command --arg

容器管理

# 列出运行中的容器
docker ps

# 列出所有容器(包括已停止)
docker ps -a

# 查看日志
docker logs myapp
docker logs -f myapp              # 跟随日志
docker logs --tail 100 myapp      # 最后100行

# 在运行容器中执行命令
docker exec myapp ls /app
docker exec -it myapp /bin/sh     # 交互式shell

# 停止容器(优雅)
docker stop myapp

# 杀死容器(立即)
docker kill myapp

# 移除容器
docker rm myapp
docker rm -f myapp                # 强制移除运行中的容器

# 查看容器详细信息
docker inspect myapp

# 监控资源使用情况
docker stats myapp

# 查看容器进程
docker top myapp

# 复制文件到/从容器
docker cp myapp:/app/logs ./logs
docker cp ./config.json myapp:/app/config.json

镜像管理

# 标记镜像
docker tag myapp:1.0 registry.example.com/myapp:1.0

# 推送到注册表
docker login registry.example.com
docker push registry.example.com/myapp:1.0

# 从注册表拉取
docker pull nginx:alpine

# 移除镜像
docker image rm myapp:1.0

# 移除未使用的镜像
docker image prune

# 移除所有未使用的资源(镜像、容器、卷、网络)
docker system prune -a

# 查看磁盘使用情况
docker system df

卷管理

# 创建命名卷
docker volume create mydata

# 列出卷
docker volume ls

# 检查卷
docker volume inspect mydata

# 移除卷
docker volume rm mydata

# 移除未使用的卷
docker volume prune

网络管理

# 创建网络
docker network create my-network
docker network create --driver bridge my-bridge

# 列出网络
docker network ls

# 检查网络
docker network inspect my-network

# 将容器连接到网络
docker network connect my-network myapp

# 将容器从网络断开
docker network disconnect my-network myapp

# 移除网络
docker network rm my-network

Docker Compose

何时使用Compose

  • 多容器应用程序(web + 数据库 + 缓存)
  • 跨团队一致的开发环境
  • 简化复杂的docker run命令
  • 管理应用程序依赖项和启动顺序

基本Compose文件结构

version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://user:pass@db:5432/app
    depends_on:
      - db
      - redis
    volumes:
      - ./src:/app/src      # 开发:实时代码重载
    networks:
      - app-network
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: app
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    networks:
      - app-network
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

networks:
  app-network:
    driver: bridge

Compose命令

# 启动所有服务
docker compose up

# 后台启动
docker compose up -d

# 启动前构建镜像
docker compose up --build

# 扩展特定服务
docker compose up -d --scale web=3

# 停止所有服务
docker compose down

# 停止并移除卷
docker compose down --volumes

# 查看日志
docker compose logs
docker compose logs -f web        # 跟随特定服务

# 在服务中执行命令
docker compose exec web sh
docker compose exec db psql -U user -d app

# 列出运行中的服务
docker compose ps

# 重启服务
docker compose restart web

# 拉取最新镜像
docker compose pull

# 验证compose文件
docker compose config

开发与生产Compose

compose.yml(基础配置):

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/app

compose.override.yml(开发覆盖,自动加载):

services:
  web:
    volumes:
      - ./src:/app/src      # 实时代码重载
    environment:
      - NODE_ENV=development
      - DEBUG=true
    command: npm run dev

compose.prod.yml(生产覆盖):

services:
  web:
    image: registry.example.com/myapp:1.0
    restart: always
    environment:
      - NODE_ENV=production
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

用法

# 开发(自动使用compose.yml + compose.override.yml)
docker compose up

# 生产(显式覆盖)
docker compose -f compose.yml -f compose.prod.yml up -d

语言特定Dockerfile

Node.js

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:20-alpine AS production
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY package*.json ./
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]

Python

FROM python:3.11-slim AS build
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.11-slim AS production
WORKDIR /app
COPY --from=build /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY . .
RUN adduser --disabled-password --gecos '' appuser && \
    chown -R appuser:appuser /app
USER appuser
EXPOSE 8000
CMD ["python", "app.py"]

Go

FROM golang:1.21-alpine AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

FROM scratch
COPY --from=build /app/main /main
EXPOSE 8080
CMD ["/main"]

Java (Spring Boot)

FROM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN ./mvnw clean package -DskipTests

FROM eclipse-temurin:21-jre-alpine AS production
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
RUN addgroup -g 1001 -S spring && \
    adduser -S spring -u 1001
USER spring
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

React/Vue/Angular (静态SPA)

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine AS production
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

生产部署

健康检查

在Dockerfile中

HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

在Compose中

services:
  web:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 3s
      start-period: 40s
      retries: 3

资源限制

services:
  web:
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

重启策略

services:
  web:
    restart: unless-stopped    # 除非手动停止,否则重启
    # 其他选项:"no", "always", "on-failure"

日志配置

services:
  web:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

环境变量与秘密

使用.env文件

# .env
DATABASE_URL=postgresql://user:pass@db:5432/app
API_KEY=secret
services:
  web:
    env_file:
      - .env

使用Docker秘密(Swarm):

services:
  web:
    secrets:
      - db_password

secrets:
  db_password:
    external: true

生产清单

  • ✅ 使用特定镜像版本(非latest
  • ✅ 以非root用户运行
  • ✅ 多阶段构建以最小化镜像大小
  • ✅ 实施健康检查
  • ✅ 配置资源限制
  • ✅ 设置重启策略
  • ✅ 配置日志
  • ✅ 安全管理秘密(不在环境变量中)
  • ✅ 漏洞扫描(Docker Scout)
  • ✅ 尽可能使用只读根文件系统
  • ✅ 网络分段
  • ✅ 定期更新镜像

CI/CD集成

GitHub Actions示例

name: Docker构建与推送

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 设置Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: 登录到Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: 构建并推送
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: user/app:latest,user/app:${{ github.sha }}
          cache-from: type=registry,ref=user/app:buildcache
          cache-to: type=registry,ref=user/app:buildcache,mode=max

      - name: 运行漏洞扫描
        uses: docker/scout-action@v1
        with:
          command: cves
          image: user/app:${{ github.sha }}

安全最佳实践

扫描漏洞

# 使用Docker Scout
docker scout cves myapp:1.0
docker scout recommendations myapp:1.0

# 快速查看
docker scout quickview myapp:1.0

安全运行容器

# 只读根文件系统
docker run --read-only -v /tmp --tmpfs /run myapp:1.0

# 丢弃所有能力,仅添加所需

docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE myapp:1.0

# 无新特权
docker run --security-opt=no-new-privileges myapp:1.0

# 使用安全配置文件
docker run --security-opt apparmor=docker-default myapp:1.0

# 限制资源
docker run --memory=512m --cpus=0.5 --pids-limit=100 myapp:1.0

镜像安全检查清单

  • ✅ 从最小基础镜像开始(Alpine, Distroless)
  • ✅ 使用特定版本,非latest
  • ✅ 定期扫描漏洞
  • ✅ 以非root用户运行
  • ✅ 不在镜像中包含秘密(使用运行时秘密)
  • ✅ 最小化攻击面(仅安装所需包)
  • ✅ 使用多阶段构建(最终镜像中无构建工具)
  • ✅ 签名和验证镜像
  • ✅ 保持镜像更新

网络模式

桥接网络(默认)

# 创建自定义桥接网络
docker network create my-bridge

# 在自定义桥接上运行容器
docker run -d --name web --network my-bridge nginx
docker run -d --name db --network my-bridge postgres

# 容器可以通过容器名称通信
# web可以连接到:http://db:5432

容器通信

services:
  web:
    depends_on:
      - db
    environment:
      # 使用服务名称作为主机名
      - DATABASE_URL=postgresql://user:pass@db:5432/app

  db:
    image: postgres:15-alpine

端口发布

# 发布单个端口
docker run -p 8080:80 nginx

# 发布端口范围
docker run -p 8080-8090:8080-8090 myapp

# 发布到特定接口
docker run -p 127.0.0.1:8080:80 nginx

# 将所有暴露端口发布到随机端口
docker run -P nginx

存储模式

命名卷(推荐用于数据)

# 创建并使用命名卷
docker volume create app-data
docker run -v app-data:/app/data myapp

# 自动创建
docker run -v app-data:/app/data myapp  # 如果不存在则创建

绑定挂载(开发)

# 开发期间实时代码重载
docker run -v $(pwd)/src:/app/src myapp

# 只读绑定挂载
docker run -v $(pwd)/config:/app/config:ro myapp

tmpfs挂载(临时内存)

# 在内存中存储临时数据
docker run --tmpfs /tmp myapp

卷备份与恢复

# 备份卷
docker run --rm -v app-data:/data -v $(pwd):/backup alpine \
  tar czf /backup/backup.tar.gz /data

# 恢复卷
docker run --rm -v app-data:/data -v $(pwd):/backup alpine \
  tar xzf /backup/backup.tar.gz -C /data

故障排查

调试运行容器

# 查看日志
docker logs -f myapp
docker logs --tail 100 myapp

# 交互式shell
docker exec -it myapp /bin/sh

# 检查容器
docker inspect myapp

# 查看进程
docker top myapp

# 监控资源使用情况
docker stats myapp

# 查看文件系统更改
docker diff myapp

调试构建问题

# 构建并显示详细输出
docker build --progress=plain -t myapp .

# 构建特定阶段进行测试
docker build --target build -t myapp:build .

# 运行失败的构建阶段
docker run -it myapp:build /bin/sh

# 检查构建上下文
docker build --no-cache -t myapp .

常见问题

容器立即退出

# 检查日志
docker logs myapp

# 以交互式shell运行
docker run -it myapp /bin/sh

# 覆盖入口点
docker run -it --entrypoint /bin/sh myapp

无法连接到容器

# 检查端口映射
docker ps
docker port myapp

# 检查网络
docker network inspect bridge
docker inspect myapp | grep IPAddress

# 检查服务是否监听
docker exec myapp netstat -tulpn

磁盘空间不足

# 检查磁盘使用情况
docker system df

# 清理
docker system prune -a
docker volume prune
docker image prune -a

构建缓存问题

# 强制重建,无缓存
docker build --no-cache -t myapp .

# 清除构建缓存
docker builder prune

高级主题

多平台构建

# 设置buildx
docker buildx create --use

# 为多平台构建
docker buildx build --platform linux/amd64,linux/arm64 \
  -t myapp:1.0 --push .

构建优化

# 使用BuildKit(在最近版本中默认启用)
DOCKER_BUILDKIT=1 docker build -t myapp .

# 使用注册表中的构建缓存
docker build --cache-from myapp:latest -t myapp:1.0 .

# 将缓存导出到注册表
docker build --cache-to type=registry,ref=myapp:buildcache \
  --cache-from type=registry,ref=myapp:buildcache \
  -t myapp:1.0 .

Docker上下文

# 列出上下文
docker context ls

# 创建远程上下文
docker context create remote --docker "host=ssh://user@remote"

# 使用上下文
docker context use remote
docker ps  # 现在在远程主机上运行

# 切换回默认
docker context use default

快速参考

最常用命令

任务 命令
构建镜像 docker build -t myapp:1.0 .
运行容器 docker run -d -p 8080:3000 myapp:1.0
查看日志 docker logs -f myapp
Shell进入容器 docker exec -it myapp /bin/sh
停止容器 docker stop myapp
移除容器 docker rm myapp
启动Compose docker compose up -d
停止Compose docker compose down
查看Compose日志 docker compose logs -f
清理所有 docker system prune -a

推荐基础镜像

语言/框架 推荐基础
Node.js node:20-alpine
Python python:3.11-slim
Java eclipse-temurin:21-jre-alpine
Go scratch(用于编译二进制)
.NET mcr.microsoft.com/dotnet/aspnet:8.0-alpine
PHP php:8.2-fpm-alpine
Ruby ruby:3.2-alpine
静态站点 nginx:alpine

额外资源

总结

Docker容器化提供:

  • 一致性 跨开发、测试和生产环境
  • 隔离 用于应用程序和依赖项
  • 可移植性 跨不同环境
  • 效率 通过分层架构和缓存
  • 可扩展性 用于微服务和分布式系统

遵循多阶段构建、以非root运行、使用特定版本、实施健康检查、扫描漏洞、配置资源限制以实现生产就绪的容器化应用程序。