Docker Cheat Sheet
title: Docker date: 2020-12-30 10:55:24 background: bg-[#488fdf] tags: - container - 容器 - virtual - DevOps - microservices - kubernetes categories: - DevOps intro: | Docker 容器化技术速查表,包含常用命令、Dockerfile、Docker Compose 和最佳实践。涵盖容器管理、镜像构建、网络配置等核心内容。 plugins: - copyCode
入门指南 {.cols-2}
快速开始
创建并在后台运行容器 (Create and run container in background)
$ docker run -d -p 80:80 docker/getting-started
-d- 后台模式运行 (detached mode)-p 80:80- 端口映射 主机:容器 (port mapping)docker/getting-started- 使用的镜像
{.marker-none}
创建并在前台运行容器 (Create and run in foreground)
$ docker run -it -p 8001:8080 --name my-nginx nginx
-it- 交互式终端模式 (interactive terminal)-p 8001:8080- 端口映射 (host:container)--name my-nginx- 指定容器名称nginx- 使用的镜像
{.marker-none}
常用命令速查
| 命令 | 描述 |
|---|---|
docker ps | 列出运行中的容器 |
docker ps -a | 列出所有容器 |
docker images | 列出所有镜像 |
docker exec -it <container> bash | 进入容器终端 |
docker logs <container> | 查看容器日志 |
docker logs -f <container> | 实时查看日志 |
docker stop <container> | 停止容器 |
docker start <container> | 启动容器 |
docker restart <container> | 重启容器 |
docker rm <container> | 删除容器 |
docker rmi <image> | 删除镜像 |
<container> 可以是容器 ID 或容器名称
版本和信息
# 查看 Docker 版本
$ docker --version
$ docker version
# 查看系统信息
$ docker info
# 查看磁盘使用情况
$ docker system df
# 查看实时事件
$ docker events
容器管理 {.cols-2}
启动与停止
| 命令 | 描述 |
|---|---|
docker start my-nginx | 启动容器 |
docker stop my-nginx | 停止容器 |
docker restart my-nginx | 重启容器 |
docker pause my-nginx | 暂停容器 |
docker unpause my-nginx | 恢复容器 |
docker wait my-nginx | 阻塞直到容器停止 |
docker kill my-nginx | 强制停止 (SIGKILL) |
docker attach my-nginx | 附加到运行中的容器 |
容器信息
| 命令 | 描述 |
|---|---|
docker ps | 列出运行中的容器 |
docker ps -a | 列出所有容器 |
docker logs my-nginx | 查看日志 |
docker logs -f --tail 100 my-nginx | 实时查看最后 100 行 |
docker inspect my-nginx | 查看容器详情 |
docker port my-nginx | 查看端口映射 |
docker top my-nginx | 查看容器进程 |
docker stats my-nginx | 查看资源使用 |
docker diff my-nginx | 查看文件变更 |
创建容器
docker create [options] IMAGE
-a, --attach # 附加标准输出/错误
-i, --interactive # 附加标准输入
-t, --tty # 分配伪终端
--name NAME # 容器名称
-p, --publish 5000:5000 # 端口映射
--expose 5432 # 暴露端口给其他容器
-P, --publish-all # 发布所有暴露端口
-v, --volume /host:/container # 挂载卷
-e, --env NAME=value # 环境变量
--env-file .env # 从文件读取环境变量
--network my-network # 指定网络
--restart always # 重启策略
-m, --memory 512m # 内存限制
--cpus 1.5 # CPU 限制
示例
# 创建容器但不启动
$ docker create --name my_redis --expose 6379 redis:7
# 运行并自动删除
$ docker run --rm -it alpine sh
# 运行并设置重启策略
$ docker run -d --restart=unless-stopped nginx
容器操作
重命名容器 (Rename)
$ docker rename old_name new_name
删除容器 (Remove)
# 删除停止的容器
$ docker rm my-nginx
# 强制删除运行中的容器
$ docker rm -f my-nginx
# 删除所有停止的容器
$ docker container prune
更新容器配置 (Update)
# 更新 CPU 和内存限制
$ docker update --cpu-shares 512 -m 300M my-nginx
# 更新重启策略
$ docker update --restart=always my-nginx
在容器中执行命令
# 进入容器 bash
$ docker exec -it my-nginx bash
# 进入容器 sh (适用于 alpine)
$ docker exec -it my-nginx sh
# 以 root 用户执行
$ docker exec -u root -it my-nginx bash
# 执行单个命令
$ docker exec my-nginx cat /etc/nginx/nginx.conf
# 设置环境变量执行
$ docker exec -e VAR=value my-nginx env
复制文件
# 从容器复制到主机
$ docker cp my-nginx:/app/config.json ./config.json
# 从主机复制到容器
$ docker cp ./config.json my-nginx:/app/config.json
# 复制整个目录
$ docker cp my-nginx:/app/logs ./logs/
镜像管理 {.cols-2}
镜像操作
| 命令 | 描述 |
|---|---|
docker images | 列出镜像 |
docker images -a | 列出所有镜像(含中间层) |
docker rmi nginx | 删除镜像 |
docker rmi -f nginx | 强制删除 |
docker image prune | 删除悬空镜像 |
docker image prune -a | 删除未使用镜像 |
docker history nginx | 查看镜像历史 |
docker inspect nginx | 查看镜像详情 |
镜像导入导出
# 保存镜像到文件
$ docker save nginx > nginx.tar
$ docker save -o nginx.tar nginx:latest
# 从文件加载镜像
$ docker load < nginx.tar
$ docker load -i nginx.tar
# 导出容器为镜像
$ docker export my-nginx > container.tar
# 从导出文件创建镜像
$ docker import container.tar my-image:tag
构建镜像
# 在当前目录构建
$ docker build -t myapp:1.0 .
# 指定 Dockerfile
$ docker build -f Dockerfile.prod -t myapp:prod .
# 不使用缓存构建
$ docker build --no-cache -t myapp:1.0 .
# 传递构建参数
$ docker build --build-arg NODE_ENV=production -t myapp .
# 多平台构建
$ docker buildx build --platform linux/amd64,linux/arm64 -t myapp .
镜像标签
# 添加标签
$ docker tag nginx:latest myregistry/nginx:v1.0
# 推送到仓库
$ docker push myregistry/nginx:v1.0
# 拉取镜像
$ docker pull nginx:latest
$ docker pull nginx:1.24-alpine
Dockerfile {.cols-2}
基础指令
# 基础镜像
FROM node:20-alpine
# 镜像元数据
LABEL maintainer="dev@example.com"
LABEL version="1.0"
# 设置工作目录
WORKDIR /app
# 复制文件
COPY package*.json ./
COPY . .
# 运行命令(构建时)
RUN npm ci --only=production
# 暴露端口
EXPOSE 3000
# 环境变量
ENV NODE_ENV=production
# 启动命令
CMD ["node", "server.js"]
指令详解
# FROM - 指定基础镜像
FROM ubuntu:22.04
FROM node:20-alpine AS builder
# ARG - 构建时变量
ARG NODE_ENV=development
ARG VERSION=1.0
# ENV - 运行时环境变量
ENV PORT=3000
ENV NODE_ENV=${NODE_ENV}
# RUN - 执行命令
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
# COPY vs ADD
COPY ./src /app/src # 推荐:简单复制
ADD https://example.com/file /app/ # 支持URL和解压
# WORKDIR - 设置工作目录
WORKDIR /app
# USER - 指定运行用户
USER node
# EXPOSE - 声明端口
EXPOSE 3000 8080
# VOLUME - 声明挂载点
VOLUME ["/data", "/logs"]
# HEALTHCHECK - 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:3000/health || exit 1
# ENTRYPOINT vs CMD
ENTRYPOINT ["node"] # 固定的执行命令
CMD ["server.js"] # 默认参数,可被覆盖
多阶段构建 {.row-span-2}
# 阶段 1: 构建
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 阶段 2: 生产镜像
FROM node:20-alpine AS production
WORKDIR /app
# 只复制生产依赖
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# 从构建阶段复制产物
COPY --from=builder /app/dist ./dist
# 非 root 用户运行
USER node
EXPOSE 3000
CMD ["node", "dist/main.js"]
最佳实践
# 1. 使用 .dockerignore
# .dockerignore 文件内容:
node_modules
.git
*.md
Dockerfile*
.env
# 2. 合并 RUN 命令减少层数
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
package1 \
package2 \
&& rm -rf /var/lib/apt/lists/*
# 3. 使用特定版本标签
FROM node:20.10-alpine3.18
# 而不是 FROM node:latest
# 4. 利用缓存
COPY package*.json ./
RUN npm ci
COPY . . # 代码变更不影响依赖缓存
# 5. 使用非 root 用户
RUN addgroup -g 1001 appgroup \
&& adduser -u 1001 -G appgroup -s /bin/sh -D appuser
USER appuser
Python 示例
FROM python:3.11-slim
WORKDIR /app
# 安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用
COPY . .
# 非 root 用户
RUN useradd -m appuser
USER appuser
EXPOSE 8000
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0"]
Go 示例
# 构建阶段
FROM golang:1.21-alpine AS builder
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=builder /app/main /main
EXPOSE 8080
ENTRYPOINT ["/main"]
Docker Compose {.cols-2}
基础配置
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- '3000:3000'
environment:
- NODE_ENV=development
volumes:
- .:/app
- /app/node_modules
depends_on:
- db
- redis
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: myapp
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- '5432:5432'
redis:
image: redis:7-alpine
ports:
- '6379:6379'
volumes:
postgres_data:
Compose 命令
# 启动服务
$ docker compose up
$ docker compose up -d # 后台运行
# 构建并启动
$ docker compose up --build
# 停止服务
$ docker compose down
$ docker compose down -v # 同时删除卷
# 查看日志
$ docker compose logs
$ docker compose logs -f web # 实时查看特定服务
# 查看服务状态
$ docker compose ps
# 执行命令
$ docker compose exec web bash
$ docker compose run web npm test
# 扩展服务
$ docker compose up -d --scale web=3
高级配置 {.row-span-2}
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.prod
args:
- NODE_ENV=production
image: myapp:${TAG:-latest}
container_name: myapp
restart: unless-stopped
ports:
- '3000:3000'
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/myapp
env_file:
- .env
volumes:
- ./uploads:/app/uploads
- logs:/app/logs
networks:
- frontend
- backend
depends_on:
db:
condition: service_healthy
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
db:
image: postgres:15-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U user -d myapp']
interval: 10s
timeout: 5s
retries: 5
nginx:
image: nginx:alpine
ports:
- '80:80'
- '443:443'
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- app
networks:
- frontend
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true
volumes:
postgres_data:
logs:
多环境配置
# docker-compose.override.yml (开发环境,自动加载)
version: '3.8'
services:
app:
build:
target: development
volumes:
- .:/app
- /app/node_modules
environment:
- DEBUG=true
# 使用不同配置文件
$ docker compose -f docker-compose.yml \
-f docker-compose.prod.yml up -d
网络管理 {.cols-2}
网络类型
# 查看网络
$ docker network ls
# 创建网络
$ docker network create mynetwork # bridge (默认)
$ docker network create -d bridge mybridge # 指定驱动
$ docker network create -d host myhost # host 模式
$ docker network create -d overlay myoverlay # overlay (Swarm)
# 查看网络详情
$ docker network inspect mynetwork
# 删除网络
$ docker network rm mynetwork
$ docker network prune # 删除未使用网络
网络操作
# 容器连接到网络
$ docker network connect mynetwork my-nginx
# 容器断开网络
$ docker network disconnect mynetwork my-nginx
# 运行时指定网络
$ docker run -d --network mynetwork --name app nginx
# 指定 IP 地址
$ docker network create --subnet=172.18.0.0/16 mynet
$ docker run -d --network mynet --ip 172.18.0.10 nginx
自定义网络
# 创建自定义 bridge 网络
$ docker network create \
--driver=bridge \
--subnet=192.168.0.0/24 \
--gateway=192.168.0.1 \
--ip-range=192.168.0.128/25 \
mybridge
# 创建 overlay 网络 (Swarm)
$ docker network create \
--driver=overlay \
--attachable \
myoverlay
网络模式说明
| 模式 | 描述 |
|---|---|
bridge | 默认,容器有独立网络栈 |
host | 容器使用宿主机网络 |
none | 禁用网络 |
overlay | Swarm 跨主机通信 |
macvlan | 容器有独立 MAC 地址 |
数据卷管理 {.cols-2}
卷操作
# 创建卷
$ docker volume create myvolume
# 列出卷
$ docker volume ls
# 查看卷详情
$ docker volume inspect myvolume
# 删除卷
$ docker volume rm myvolume
# 删除未使用的卷
$ docker volume prune
挂载方式
# Volume(推荐)
$ docker run -v myvolume:/app/data nginx
$ docker run --mount source=myvolume,target=/app/data nginx
# Bind Mount(绑定挂载)
$ docker run -v /host/path:/container/path nginx
$ docker run --mount type=bind,source=/host/path,target=/container/path nginx
# tmpfs(内存挂载)
$ docker run --tmpfs /app/temp nginx
$ docker run --mount type=tmpfs,target=/app/temp nginx
# 只读挂载
$ docker run -v myvolume:/app/data:ro nginx
备份与恢复
# 备份卷数据
$ docker run --rm \
-v myvolume:/data \
-v $(pwd):/backup \
alpine tar czf /backup/backup.tar.gz /data
# 恢复卷数据
$ docker run --rm \
-v myvolume:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/backup.tar.gz -C /
清理与维护 {.cols-2}
系统清理
# 查看磁盘使用
$ docker system df
$ docker system df -v
# 清理未使用资源
$ docker system prune # 清理悬空资源
$ docker system prune -a # 清理所有未使用资源
$ docker system prune -a --volumes # 包括卷
容器清理
# 停止所有容器
$ docker stop $(docker ps -q)
# 删除所有停止的容器
$ docker container prune
# 删除所有容器
$ docker rm -f $(docker ps -aq)
镜像清理
# 删除悬空镜像
$ docker image prune
# 删除所有未使用镜像
$ docker image prune -a
# 删除所有镜像
$ docker rmi -f $(docker images -q)
# 删除指定仓库的镜像
$ docker rmi $(docker images | grep "pattern" | awk '{print $3}')
卷和网络清理
# 删除未使用的卷
$ docker volume prune
# 删除未使用的网络
$ docker network prune
# 删除所有自定义网络
$ docker network rm $(docker network ls -q)
镜像仓库 {.cols-2}
Docker Hub
# 登录
$ docker login
$ docker login -u username
# 登出
$ docker logout
# 搜索镜像
$ docker search nginx
$ docker search --filter=stars=100 nginx
# 拉取镜像
$ docker pull nginx
$ docker pull nginx:1.24-alpine
# 推送镜像
$ docker tag myapp:latest username/myapp:v1.0
$ docker push username/myapp:v1.0
私有仓库
# 登录私有仓库
$ docker login myregistry.example.com
# 推送到私有仓库
$ docker tag myapp:latest myregistry.example.com/myapp:v1.0
$ docker push myregistry.example.com/myapp:v1.0
# 拉取私有镜像
$ docker pull myregistry.example.com/myapp:v1.0
# 运行本地 Registry
$ docker run -d -p 5000:5000 --name registry registry:2
$ docker tag myapp:latest localhost:5000/myapp:v1.0
$ docker push localhost:5000/myapp:v1.0
配置镜像加速
// /etc/docker/daemon.json
{
"registry-mirrors": ["https://mirror.ccs.tencentyun.com", "https://registry.docker-cn.com"]
}
# 重启 Docker 生效
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
日志与监控 {.cols-2}
日志管理
# 查看容器日志
$ docker logs my-nginx
# 实时查看日志
$ docker logs -f my-nginx
# 查看最后 N 行
$ docker logs --tail 100 my-nginx
# 查看指定时间后的日志
$ docker logs --since 2024-01-01T00:00:00 my-nginx
# 查看时间戳
$ docker logs -t my-nginx
# 组合使用
$ docker logs -f --tail 50 -t my-nginx
日志驱动配置
// /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
# 运行时指定日志驱动
$ docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx
资源监控
# 实时资源使用
$ docker stats
$ docker stats my-nginx
# 格式化输出
$ docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# 查看容器进程
$ docker top my-nginx
# 查看容器详情
$ docker inspect my-nginx
$ docker inspect --format '{{.State.Status}}' my-nginx
安全最佳实践 {.cols-2}
镜像安全
# 扫描镜像漏洞
$ docker scout cves nginx:latest
$ docker scout quickview nginx:latest
# 使用可信镜像
$ docker trust sign myimage:tag
$ docker trust inspect myimage:tag
# 内容信任
$ export DOCKER_CONTENT_TRUST=1
$ docker pull nginx:latest # 会验证签名
运行时安全
# 使用非 root 用户
$ docker run --user 1000:1000 nginx
# 只读文件系统
$ docker run --read-only nginx
# 限制权限
$ docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx
# 禁止提权
$ docker run --security-opt no-new-privileges nginx
# 限制资源
$ docker run --memory 512m --cpus 1 nginx
Dockerfile 安全
# 使用非 root 用户
FROM node:20-alpine
RUN addgroup -g 1001 appgroup \
&& adduser -u 1001 -G appgroup -s /bin/sh -D appuser
USER appuser
# 使用只读根文件系统
# docker run --read-only ...
# 最小化镜像
FROM scratch
# 或 FROM alpine:3.18
# 不存储敏感信息
# 使用 --secret 挂载
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci
常用技巧 {.cols-2}
调试技巧
# 进入运行失败的容器
$ docker run -it --entrypoint /bin/sh myimage
# 查看容器文件系统变化
$ docker diff my-nginx
# 导出容器文件系统
$ docker export my-nginx > container.tar
# 查看镜像层
$ docker history --no-trunc myimage
# 查看容器 IP
$ docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-nginx
性能优化
# 使用 BuildKit
$ DOCKER_BUILDKIT=1 docker build -t myapp .
# 并行构建
$ docker buildx build --platform linux/amd64,linux/arm64 -t myapp .
# 缓存挂载(加速构建)
RUN --mount=type=cache,target=/root/.npm npm ci
# 多阶段构建减小镜像
FROM node:20 AS builder
# ... build
FROM node:20-alpine
COPY --from=builder /app/dist ./dist
常用别名
# ~/.bashrc 或 ~/.zshrc
alias d='docker'
alias dc='docker compose'
alias dps='docker ps'
alias dpa='docker ps -a'
alias di='docker images'
alias dex='docker exec -it'
alias dl='docker logs -f'
alias drm='docker rm -f'
alias drmi='docker rmi'
alias dsp='docker system prune -a'