本文目录

[[toc]]

镜像操作

拉取镜像

# 拉取最新版镜像(默认标签为 latest)
docker pull nginx

# 拉取指定版本镜像(如 Python 3.8)
docker pull python:3.8

# 拉取所有标签的镜像(如 busybox 全版本)
docker pull -a busybox

构建镜像

# 基于 Dockerfile 构建镜像(当前目录需包含 Dockerfile)
docker build -t myapp:1.0 .

# 从容器提交新镜像(将运行中的容器保存为镜像)
docker commit container_id myapp:snapshot

删除镜像

# 按名称删除
docker rmi nginx:latest

# 按镜像 ID 删除(短 ID 或长 ID)
docker rmi 501ad78535f0

# 强制删除(即使有容器依赖)
docker rmi -f myapp:old

# 删除所有未被使用的镜像
docker image prune -a

# 删除所有本地镜像
docker rmi -f $(docker images -aq)

查看镜像

# 显示所有镜像(含中间层)
docker images -a

# 按名称过滤(如所有 nginx 相关镜像)
docker images nginx*

# 仅显示镜像 ID
docker images -q

搜索镜像

# 在 Docker Hub 搜索镜像
docker search redis

# 过滤官方镜像且星标≥1000
docker search --filter "is-official=true" --filter "stars=1000" mysql

查看镜像详情

# 显示镜像元数据(如层信息、环境变量)
docker image inspect nginx:latest

# 查看镜像构建历史
docker history myapp:1.0

导入导出镜像

# 导出镜像为 .tar 文件(用于离线传输)
docker save -o nginx.tar nginx:latest

# 从 .tar 文件加载镜像
docker load -i nginx.tar

发布镜像

# 登录 Docker Hub 或私有仓库
docker login -u username -p password registry.example.com

# 推送镜像(需先打标签)
docker push registry.example.com/myapp:prod

容器操作

创建容器

# 基础运行(启动后进入交互式终端)
docker run -it --name my_ubuntu ubuntu:22.04 /bin/bash

# 后台运行 + 端口映射 + 数据卷挂载
docker run -d --name my_nginx -p 8080:80 -v /data:/usr/share/nginx/html nginx:latest

# 创建但是不启动
docker create --name pending_container redis:alpine

删除容器

# 停止容器
docker stop my_nginx

# 强制删除运行中的容器
docker rm -f my_nginx

# 批量删除所有已停止的容器
docker container prune

# 删除所有容器
docker rm -f $(docker ps -aq)

更新容器配置

# 动态调整容器内存限制(需容器处于运行或停止状态)
docker update --memory 512m my_container

# 修改容器重启策略(如崩溃后自动重启)
docker update --restart=always my_container

# 进入容器修改文件后提交为新镜像
docker commit my_container my_image:v2
docker run -d --name new_container my_image:v2

查看容器状态

# 查看运行中的容器
docker ps

# 查看所有容器(含停止状态)
docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"

# 查看容器资源占用
docker stats my_container

查看容器内部信息

# 实时查看日志(类似 tail -f)
docker logs -f --tail 100 my_container

# 查看容器元数据(如IP、挂载点)
docker inspect my_container | grep -E "IPAddress|Mounts"

# 查看容器进程列表
docker top my_container

进入容器

# 以交互模式进入运行中的容器
docker exec -it my_container /bin/bash

# 在容器内执行单次命令
docker exec my_container ls /var/log

容器热更新

# 滚动更新(Swarm模式下)
docker service update --image nginx:v2 --update-parallelism 2 web_service

宿主机与容器文件传输

# 从容器复制文件到宿主机
docker cp my_container:/app/config.yaml /backup/

# 从宿主机上传文件到容器
docker cp /data/update.patch my_container:/tmp/

Dockerfile

Dockerfile 常见命令如下,使用 docker build -t 镜像名:tag Dockerfile所在目录 即可完成镜像构建

# ========== 基础镜像配置 ==========
# 使用官方 Alpine 基础镜像(轻量级,仅5MB)
# 多阶段构建示例:第一阶段命名为 builder,用于编译环境
FROM alpine:3.18 AS builder
# 维护者信息(替代已弃用的 MAINTAINER)
LABEL maintainer="yourname@example.com"

# ========== 环境变量与参数 ==========
# 设置容器内应用路径
ENV APP_HOME=/app
# 构建时参数,可通过 --build-arg 覆盖
ARG BUILD_VERSION=1.0.0

# ========== 系统配置 ==========
# 更新系统并安装依赖(合并 RUN 减少镜像层数)
RUN apk update && apk add --no-cache \
    python3 \
    py3-pip \
    curl \
    nginx \
    && rm -rf /var/cache/apk/*

# ========== 文件操作 ==========
# 设置工作目录
WORKDIR $APP_HOME
# 复制本地文件到镜像(推荐优先使用 COPY)
COPY requirements.txt .
# 自动解压远程文件(慎用 ADD)
ADD https://example.com/static-assets.tar.gz /tmp

# ========== 应用构建 ==========
# 安装 Python 依赖
RUN pip3 install --no-cache-dir -r requirements.txt
# 复制应用源码
COPY src/ .

# ========== 网络与存储 ==========
# 声明监听端口(需配合 docker run -p 映射)
EXPOSE 8080
# 声明持久化数据卷
VOLUME ["/data"]

# ========== 安全配置 ==========
# 创建非 root 用户
RUN adduser -D appuser && chown -R appuser:appuser $APP_HOME
# 切换运行用户
USER appuser

# ========== 健康检查 ==========
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/health || exit 1

# ========== 多阶段构建 ==========
# 第二阶段:生产环境镜像
FROM alpine:3.18 AS production
# 从 builder 阶段复制编译结果
COPY --from=builder /app /app
WORKDIR /app

# ========== 启动命令 ==========
# 优先使用 exec 格式避免 shell 解析问题
# 固定入口点,多个 entrypoint 只有最后一个生效
ENTRYPOINT ["python3"]
# 传递给 entrypoint 的默认参数(可被 docker run 覆盖)
# 如 `docker run 镜像名:tag main.py`
# 则启动容器时不再执行 `python3 app.py` ,而是执行 `python3 main.py`
CMD ["app.py"]

# ========== 元数据 ==========
# 子镜像构建时自动触发
ONBUILD COPY . /app

资源管理

docker 资源管理具有重要意义,可以保护其他容器不被内存泄露、死循环、大文件读写(上传/下载)等编码问题影响,不至于一处内存泄露就所有容器一起卡死停机。

cpu 份额

CPU 份额的数字只有在争抢资源时才有意义。

单个容器占用 CPU 时间片的比重,是其自身份额 / 争抢的所有容器的总份额。

如果运行在多个 CPU 上,或者无争抢情况,哪怕份额只有 1 也会占满整个 CPU 。

docker run -itd \
  # 声明创建的容器名
  --name test-cpu-1 \
  # 指定容器 CPU 权重
  --cpu-shares 50 \
  # 使用的镜像
  centos

指定容器使用的 CPU 内核

docker run -itd \
  # 声明创建的容器名
  --name test-cpu-2 \
  # 指定容器仅运行在 CPU 0 与 CPU 1
  --cpuset-cpus 0,1 \
  # 指定容器 CPU 权重
  --cpu-shares 512 \
  # 使用的镜像
  centos

指定容器使用的内存容量

docker run -itd \
  # 声明创建的容器名
  --name test-memory \
  # 最多使用 0.5G 内存
  --memory 512m \
  # 使用的镜像
  centos

指定容器 I/O 资源限制

docker run -itd \
  # 声明创建的容器名
  --name test-io \
  # 指定分区而非整块磁盘
  --device=/dev/sda1 \
  # 开放设备操作权限
  --cap-add=SYS_RAWIO \
  # 挂载卷,挂载卷是通过文件读写,不是走底层的 API ,可能会绕过读写限制
  # 使用 -v 挂载时,如果外部目录被删除,即使后续新建同名目录,也不会同步到 docker 中
  # 因为对应的 inode 节点已经找不到了
  -v /var/www/html:/var/www/html \
  # 限制读取速度为 10mbps/s
  --device-read-bps /dev/sda1:10mb \
  # 限制写入速度为 1mbps/s
  --device-write-bps /dev/sda1:1mb \
  # 使用的镜像
  centos

资源自动释放

docker run -itd \
  # 声明创建的容器名
  --name test-auto-free \
  # 声明执行完毕后自动释放,用于处理作为执行容器的场景
  # 比如 build 场景构建阶段、压测运行环境等等
  --rm \
  # 使用的镜像
  centos \
  # 执行的命令
  sleep 8