docker知识点笔记

docker

一、docker是什么?

Docker 本质上是基于 Linux 内核特性(如命名空间和控制组)的容器化技术。在 Windows 和 macOS 上,Docker 通过运行一个轻量级的 Linux 虚拟机(如 WSL2 或 HyperKit)来提供所需的运行环境,从而实现跨平台支持。

Docker vs 虚拟机
对比项 Docker 容器 虚拟机(VM)
启动速度 秒级 分钟级
体积 MB 级(共享宿主内核) GB 级(含完整操作系统)
性能 接近原生(无虚拟化开销) 有虚拟化层损耗
隔离性 进程级隔离(共享内核) 完全隔离(独立内核)
适用场景 微服务、CI/CD、快速部署 强隔离需求、不同操作系统

一句话总结:容器是进程级隔离,虚拟机是系统级隔离。Docker 更轻量但隔离性弱于 VM,实际项目中常结合使用。

二、安装步骤

1.Windows安装 在“启用或关闭Windows功能”中,同时勾选“windows虚拟机监控程序平台”、“虚拟机平台”和“适用于Linux的Windows子系统”

2.重启电脑

3.安装WSL:以管理员身份打开PowerShell或命令提示符,执行

wsl --set-default-version 2
wsl --update --web-download

执行wsl --update安装WSL(国内网络建议添加--web-download参数减少下载失败)。

4.下载并安装Docker Desktop: 从官方网站下载对应CPU架构的安装包(Windows通常为AMD64),按提示完成安装。

5.启动Docker Desktop: 需保持Docker Desktop软件运行。

6.验证安装: 在Windows终端输入docker --version,若能打印版本号则表示安装成功。

配置国内镜像加速

国内拉取 Docker Hub 镜像经常超时,可以配置镜像加速器。

打开 Docker Desktop → Settings → Docker Engine,在 JSON 配置中添加:

{
  "registry-mirrors": [
    "https://mirror.ccs.tencentyun.com",
    "https://registry.docker-cn.com"
  ]
}

点击 Apply & Restart 生效。验证是否生效:

docker info | grep -A 5 "Registry Mirrors"

三、Docker 镜像

Docker Pull 命令用来从仓库下载镜像。

docker pull docker.io/library/nginx:latest

一个 Docker 镜像下载地址包含 4 部分内容:

docker.io:registry / 仓库地址,如果是 Docker 官方仓库,则可以省略这个地址.

– 作用:指定从哪个仓库服务拉取镜像。

– 默认值:如果不写,默认为 Docker Hub(docker.io)。

– 示例:registry.cn-hangzhou.aliyuncs.com(阿里云)、ghcr.io(GitHub)

library:命名空间(镜像作者)/項目組,为了防止不同用户上传同一个名字的镜像发生冲突。

– “library” 是 docker 官方仓库的命名空间,这个空间下的所有镜像都是由 Docker 官方维护。如果是官方的命名空间则可以省略不写。

– 通常代表拥有该镜像的个人用户名、组织名称或项目组名称。

– 作用:用于管理和隔离镜像,类似于文件路径中的“文件夹”。

– 默认值:如果是 Docker Hub 官方认证的镜像,默认为 library。

nginx:镜像名

– 软件包的名称,即实际使用的镜像功能名称

– 作用:标识具体的应用软件,如 Nginx、MySQL、Python 等。

– 示例:nginx、mysql、redis。

latest:标签名、版本号。写 “latest” 或者不写表示获取最新版本的镜像

– 镜像的特定版本标识符。

– 作用:区分同一个镜像的不同版本(如系统版本、Alpine 轻量版或特定构建版本)。

– 默认值:如果不写,默认为 latest(最新版)。

– 示例:22.04、alpine、1.21.6。

查看镜像

docker images

删除镜像

docker rmi [镜像标识]

使用此命令可以删除 pull 到本地的镜像,镜像标识可以选择 镜像的 ID(image id)或者镜像的名称(repository)

镜像标签选择建议

alpine:基于 Alpine Linux,仅 5MB 左右,适合生产环境,但使用 musl libc 可能存在兼容问题

slim:基于 Debian 精简版,比 alpine 兼容性更好,体积适中

latest / 默认:完整版,包含所有工具,适合开发调试

● 生产环境不要用 latest,应指定明确版本号,避免不可控变更

构建镜像
docker build -t my-app:1.0 .

-t:指定镜像名称和标签,格式为 名称:标签

.:表示 Dockerfile 所在目录(构建上下文路径)

给镜像打标签并推送
docker tag my-app:1.0 registry.cn-hangzhou.aliyuncs.com/myname/my-app:1.0
docker push registry.cn-hangzhou.aliyuncs.com/myname/my-app:1.0

推送前需要先登录仓库:docker login registry.cn-hangzhou.aliyuncs.com

四、Docker 容器

创建并运行容器

docker run [镜像标识]

使用 run 命令可以通过镜像创建一个容器,并启动它。镜像标识可以是镜像 ID 或者镜像名称。

例如:docker run nginx 就是创建一个 Nginx 容器。

docker pull 命令可以省略,直接使用 docker run 运行,如果 docker 发现本地没有这个镜像则会自动拉取。

分离模式

默认情况下 docker run 创建容器后会导致当前终端挂起,不能进行其他操作,可以增加 -d 参数表示容器在后台运行,不阻塞当前窗口

docker run -d nginx
端口映射

容器的网络和宿主机的网络是隔离的,例如运行了一个 Nginx 容器,容器内的 Nginx 监听了 80 端口。这时通过宿主机的 80 端口是无法访问到 Nginx 服务的。

所以需要 -p {宿主机端口}:{容器的端口} 命令进行映射,例如 -p 80:80 表示将 Nginx 容器的 80 端口映射到宿主机的 80 端口。

目录映射(绑定挂载)

与端口映射类似的就是目录映射,将容器外和容器内的目录进行绑定,容器内对文件的修改会影响宿主机的文件夹,宿主机的修改也会影响容器内文件夹。

-v {宿主机目录}:{容器的目录}

这种目录也被称为挂载卷,他的最大作用是数据的持久化。 当容器删除时,容器内的所有数据都会被删除,但通过挂载卷映射到宿主机的文件夹将得以保留。

docker run -d -p 80:80 -v ./:/usr/share/nginx/html nginx
传环境变量(常用于数据库密码、配置,敏感信息需注意安全)

可以在命令行通过 -e 参数传递环境变量到容器内部,例如创建一个数据库应用,需要在创建容器时就指定数据库的账户、密码等信息。

docker run -d -p 27017:27017 \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=admin123 \
  mongo

如果不知道容器的环境变量有哪些,可以在 Docker Hub 上搜索一下,都有详细的描述。

容器命名与重启策略
docker run -d --name my-nginx --restart=always -p 80:80 nginx

--name:给容器指定名称,方便后续管理,不指定则随机生成

--restart:重启策略

策略 说明
no 默认值,容器退出不重启
always 容器退出总是重启(开机也自动启动)
on-failure[:max] 仅非正常退出时重启,可限制次数
unless-stopped 类似 always,但手动 stop 后不会重启
启停容器

每次使用 docker run 运行都会创建一个新的容器,对同一个容器进行持续的操作,可以通过容器的启停命令来控制。

# 启动容器
docker start {容器标识}
# 停止容器
docker stop {容器标识}
# 重启容器
docker restart {容器标识}
查看容器
# 查看运行中的容器
docker ps

# 查看所有容器(包括已停止的)
docker ps -a

# 只显示容器 ID
docker ps -q
进入容器
docker exec -it {容器标识} /bin/bash

-i:保持标准输入打开

-t:分配伪终端

● 如果镜像基于 Alpine,bash 可能不存在,改用 /bin/sh

docker exec -it {容器标识} /bin/sh
查看容器日志
# 查看全部日志
docker logs {容器标识}

# 实时跟踪日志(类似 tail -f)
docker logs -f {容器标识}

# 查看最后 100 行
docker logs --tail 100 {容器标识}
查看容器详情
# 查看容器完整配置信息(IP、挂载、环境变量等)
docker inspect {容器标识}

# 只看 IP 地址
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' {容器标识}
删除容器
# 删除已停止的容器
docker rm {容器标识}

# 强制删除运行中的容器
docker rm -f {容器标识}

# 删除所有已停止的容器
docker container prune
容器与宿主机互传文件
# 从容器复制文件到宿主机
docker cp {容器标识}:/app/config.yml ./config.yml

# 从宿主机复制文件到容器
docker cp ./config.yml {容器标识}:/app/config.yml

五、数据持久化(Volume 卷)

解决痛点:容器删除,数据即消失。

三种存储方式:

Bind Mount(开发常用):挂载宿主机任意目录(如 -v ./:/app)。

Volume(生产推荐):由 Docker 管理(存放在 /var/lib/docker/volumes/),通过 docker volume create 创建,适合数据库、日志等高IO场景。

tmpfs:存内存,容器重启即清空(存临时敏感数据)。

创建卷

docker volume create {卷名称}

查看所有卷

docker volume list

删除卷

docker volume rm nginx_html

删除所有没有容器在使用的卷

docker volume prune -a
使用 Volume 运行容器
docker run -d -v mydata:/var/lib/mysql mysql

● 不以 /./ 开头的路径会被识别为 Volume 名称

● 以 /./ 开头的路径会被识别为 Bind Mount

Bind Mount vs Volume 选择
场景 推荐方式 原因
开发时代码热更新 Bind Mount 直接映射源码目录,修改即时生效
数据库数据存储 Volume Docker 管理,权限和性能更优
配置文件注入 Bind Mount 方便在宿主机直接编辑
日志持久化 Volume 不依赖宿主机目录结构

六、Docker 网络

容器间通信是微服务架构的基础,Docker 提供了多种网络模式。

网络模式
模式 说明
bridge 默认模式,容器通过虚拟网桥通信
host 容器直接使用宿主机网络,无端口映射开销
none 容器无网络,适合安全敏感场景
overlay 跨主机通信,用于 Docker Swarm 集群
自定义网络

默认 bridge 网络下容器只能通过 IP 互访,自定义网络支持容器名互访,这是最常用的方式。

# 创建自定义网络
docker network create my-net

# 运行容器并加入网络
docker run -d --name app --network my-net nginx
docker run -d --name db --network my-net mysql

加入同一网络的容器可以直接用名称通信:

# 在 app 容器内可以直接用 db 作为主机名
ping db
网络管理命令
# 查看所有网络
docker network ls

# 查看网络详情
docker network inspect my-net

# 将运行中的容器加入网络
docker network connect my-net {容器标识}

# 将容器从网络中移除
docker network disconnect my-net {容器标识}

# 删除网络
docker network rm my-net

七、Dockerfile 基础语法

7 个常用指令
FROM python:3.10      # 1. 指定基础镜像(起点)
WORKDIR /app          # 2. 设置工作目录(cd /app)
COPY . .              # 3. 复制文件(将本地文件拷入镜像)
RUN pip install -r requirements.txt  # 4. 执行构建命令(安装依赖)
CMD ["python", "main.py"]  # 5. 容器启动时执行的命令(默认)
CMD vs ENTRYPOINT
对比项 CMD ENTRYPOINT
用途 提供默认命令和参数 定义容器的主命令
是否可被覆盖 docker run 后面的命令会覆盖 CMD 不会被覆盖,追加的参数会传给 ENTRYPOINT
多次声明 只有最后一个生效 只有最后一个生效
配合使用 可以为 ENTRYPOINT 提供默认参数 固定主命令,CMD 提供可变参数
# ENTRYPOINT + CMD 配合使用
ENTRYPOINT ["python", "main.py"]
CMD ["--help"]

这样 docker run my-app 默认执行 python main.py --help,而 docker run my-app --version 则执行 python main.py --version

ARG vs ENV
对比项 ARG ENV
作用阶段 仅构建阶段有效 构建和运行阶段都有效
是否可被运行时覆盖 不可 可通过 -e 覆盖
典型用途 传入构建版本号、仓库地址 设置运行时配置、数据库地址
ARG VERSION=1.0
ENV NODE_ENV=production

# ARG 在构建时传入
# docker build --build-arg VERSION=2.0 .
.dockerignore

类似 .gitignore,排除不需要拷入镜像的文件,减小构建上下文体积、加速构建、避免敏感信息泄露

node_modules
.git
.env
*.md
__pycache__
.DS_Store
dist
多阶段构建(生产环境瘦身利器)
# 阶段 1:构建阶段(包含 Node 全套环境,体积大)
FROM node:18 AS builder
COPY . .
RUN npm install && npm run build

# 阶段 2:运行阶段(仅用 Nginx 托管产物,体积极小)
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
# 最终镜像只有几十 MB,不包含 Node 环境
镜像构建优化

利用缓存:将不常变化的层(如 RUN pip install)放在前面,频繁变化的层(如 COPY . .)放在后面

合并 RUN 指令:每个 RUN 都会产生新层,用 && 合并减少层数

# 不推荐:产生 3 个层
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*

# 推荐:合并为 1 个层
RUN apt-get update && \
    apt-get install -y curl && \
    rm -rf /var/lib/apt/lists/*

选择精简基础镜像:优先使用 alpineslim 变体

清理安装缓存:在 RUN 中及时清理 apt/yum 缓存、pip 缓存等

八、Docker Compose

当项目需要多个容器协同工作时(如 Web + 数据库 + 缓存),手动 docker run 会非常繁琐。Docker Compose 通过一个 YAML 文件定义和管理多容器应用。

安装

Docker Desktop 已内置 Compose,无需额外安装。Linux 环境需单独安装:

sudo curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 \
  -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose.yml 示例
version: "3.8"

services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - ./:/app
    environment:
      - DB_HOST=db
      - REDIS_HOST=redis
    depends_on:
      - db
      - redis

  db:
    image: mysql:8.0
    volumes:
      - db_data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root123
      - MYSQL_DATABASE=myapp

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data

volumes:
  db_data:
  redis_data:
关键字段说明
字段 说明
build 根据 Dockerfile 构建镜像,值为 Dockerfile 所在目录
image 直接使用已有镜像
ports 端口映射,格式同 -p
volumes 挂载卷或目录,格式同 -v
environment 环境变量,格式同 -e
depends_on 依赖关系,控制启动顺序(不保证服务就绪)
restart 重启策略,同 docker run --restart
networks 指定加入的网络,默认创建默认网络

● Compose 默认会创建一个网络,所有服务加入同一网络,服务间可直接用服务名通信(如 db:3306

depends_on 只控制启动顺序,不等待服务真正就绪。如需等待就绪,建议在应用代码中加入重试逻辑

常用命令
# 启动所有服务(-d 后台运行)
docker compose up -d

# 停止并删除所有容器
docker compose down

# 停止并删除容器 + 卷(清除数据)
docker compose down -v

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs -f

# 重新构建镜像
docker compose build

# 只重启某个服务
docker compose restart web

# 进入某个服务的容器
docker compose exec web /bin/bash

# 扩容(启动多个实例)
docker compose up -d --scale worker=3
环境变量管理

敏感信息不应直接写在 YAML 中,推荐使用 .env 文件:

# .env 文件
MYSQL_ROOT_PASSWORD=root123
MYSQL_DATABASE=myapp

docker-compose.yml 中引用:

environment:
  - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
  - MYSQL_DATABASE=${MYSQL_DATABASE}

.env 文件应加入 .gitignore,避免泄露

● 也可以用 docker compose --env-file prod.env up -d 指定环境文件

九、常用命令速查

镜像相关
docker pull [镜像]          # 拉取镜像
docker images               # 查看本地镜像
docker rmi [镜像]           # 删除镜像
docker build -t name:tag .  # 构建镜像
docker tag src dst          # 打标签
docker push [镜像]          # 推送镜像
docker image prune          # 清理无用的镜像
容器相关
docker run [选项] [镜像]    # 创建并运行容器
docker ps                   # 查看运行中容器
docker ps -a                # 查看所有容器
docker start [容器]         # 启动容器
docker stop [容器]          # 停止容器
docker restart [容器]       # 重启容器
docker rm [容器]            # 删除容器
docker rm -f [容器]         # 强制删除运行中容器
docker exec -it [容器] /bin/bash  # 进入容器
docker logs [-f] [容器]     # 查看日志
docker inspect [容器]       # 查看详情
docker cp [容器]:路径 本地路径   # 容器→宿主机
docker cp 本地路径 [容器]:路径   # 宿主机→容器
docker container prune      # 清理已停止容器
网络相关
docker network create [名称]     # 创建网络
docker network ls                # 查看网络
docker network inspect [网络]    # 查看网络详情
docker network connect [网络] [容器]   # 容器加入网络
docker network disconnect [网络] [容器] # 容器离开网络
docker network rm [网络]         # 删除网络
卷相关
docker volume create [名称]   # 创建卷
docker volume ls              # 查看卷
docker volume inspect [卷]    # 查看卷详情
docker volume rm [卷]         # 删除卷
docker volume prune           # 清理无用卷
系统清理
docker system df              # 查看 Docker 磁盘占用
docker system prune           # 一键清理(停止的容器、无用镜像、网络、构建缓存)
docker system prune -a --volumes  # 彻底清理(包括未使用的镜像和卷)