Docker 学习笔记

TIP

📌 本文档面向开发和运维人员,覆盖 Docker 核心概念、常用命令、镜像构建、Docker Compose 编排,以及日常排错思路。基于 Docker Engine 24.x+ 整理。


1 · 什么是 Docker

Docker 是一个容器化平台,它把应用及其依赖打包到一个可移植的“容器”里,确保在任何环境下运行结果一致。

与传统虚拟机的区别:

特性 虚拟机 (VM) Docker 容器
启动速度 分钟级 秒级
资源占用 重(完整 OS) 轻(共享宿主机内核)
隔离级别 硬件级 进程级(Namespace/Cgroups)
镜像大小 GB 级 MB 级
性能 接近原生但有损耗 接近原生
TIP

📌 一句话理解:虚拟机是“带房子的地”,Docker 是“带家具的拎包入住公寓”。


2 · 核心概念

  • 镜像(Image):只读模板,包含运行应用所需的一切(代码、运行时、库、环境变量)。
  • 容器(Container):镜像的运行实例,是隔离的进程。
  • 仓库/Registry:存储镜像的服务,如 Docker Hub、阿里云镜像仓库、Harbor。
  • Dockerfile:定义镜像构建步骤的文本文件。
  • Volume:持久化数据卷,容器删除后数据仍可保留。
  • Network:容器间的网络通信机制。

3 · 安装与配置

3.1 Ubuntu/Debian

# 更新索引
sudo apt update

# 安装依赖
sudo apt install -y ca-certificates curl gnupg lsb-release

# 添加 Docker 官方 GPG 和仓库
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker Engine
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 把当前用户加入 docker 组,免 sudo 运行
sudo usermod -aG docker $USER
newgrp docker

3.2 Windows/macOS

  • 安装 Docker Desktop 即可。
  • Windows 10/11 专业版建议启用 WSL2 后端,性能更好。

3.3 换国内镜像源

编辑 /etc/docker/daemon.json(Linux)或 Docker Desktop Settings(Windows/macOS):

{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}

重启 Docker:

sudo systemctl restart docker

4 · 常用命令

4.1 镜像管理

# 搜索镜像
docker search nginx

# 拉取镜像
docker pull nginx:1.25

# 查看本地镜像
docker images

# 删除镜像
docker rmi nginx:1.25

# 构建镜像
docker build -t myapp:1.0 .

# 给镜像打标签
docker tag myapp:1.0 registry.cn-hangzhou.aliyuncs.com/myrepo/myapp:1.0

# 推送镜像
docker push registry.cn-hangzhou.aliyuncs.com/myrepo/myapp:1.0

4.2 容器管理

# 运行容器
docker run -d --name web -p 80:80 nginx:1.25

# 查看运行中的容器
docker ps

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

# 停止容器
docker stop web

# 启动容器
docker start web

# 重启容器
docker restart web

# 删除容器
docker rm web

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

# 查看容器日志
docker logs -f web

# 进入容器内部
docker exec -it web /bin/bash

# 查看容器资源占用
docker stats

4.3 docker run 常用参数

参数 含义
-d 后台运行
-p 宿主机:容器 端口映射
-v 宿主机:容器 挂载数据卷
--name 指定容器名
--restart=always 自动重启
-e KEY=VALUE 设置环境变量
--network 指定网络
--rm 容器停止后自动删除
-it 交互式终端

5 · Dockerfile 编写

5.1 常用指令

指令 作用
FROM 基础镜像
RUN 执行命令
COPY 拷贝文件到镜像
ADD 类似 COPY,支持自动解压和远程 URL
WORKDIR 设置工作目录
ENV 设置环境变量
EXPOSE 声明暴露端口
CMD 容器启动时的默认命令
ENTRYPOINT 容器启动入口,可被 CMD 补充
VOLUME 声明挂载点

5.2 示例:构建一个 Node.js 应用

# 使用 LTS 版本 Node
FROM node:20-alpine

# 设置工作目录
WORKDIR /app

# 先拷贝依赖文件,利用缓存层
COPY package*.json ./

# 安装依赖
RUN npm ci --only=production

# 拷贝源码
COPY . .

# 暴露端口
EXPOSE 3000

# 启动命令
CMD ["node", "server.js"]

构建并运行:

docker build -t mynode:1.0 .
docker run -d -p 3000:3000 --name mynode mynode:1.0

5.3 多阶段构建(减少镜像体积)

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

# 运行阶段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
TIP

📌 多阶段构建能把构建工具、源码、依赖留在中间层,最终镜像只保留产物,体积可缩小几十倍。


6 · 数据持久化

6.1 数据卷(Volume)

# 创建卷
docker volume create mydata

# 挂载卷
docker run -d -v mydata:/data nginx:alpine

# 查看卷
docker volume ls

# 删除未使用的卷
docker volume prune

6.2 绑定挂载(Bind Mount)

# 把宿主机目录直接挂载到容器
docker run -d -v /host/path:/app/data nginx:alpine

6.3 挂载对比

类型 适用场景 路径
Volume 数据库、持久化数据 Docker 管理目录
Bind Mount 开发时热更新代码 宿主机指定目录
tmpfs 敏感临时数据 内存中

7 · 网络管理

# 查看默认网络
docker network ls

# 创建自定义网络
docker network create mynet

# 容器加入自定义网络
docker run -d --name db --network mynet postgres:15
docker run -d --name api --network mynet myapi:1.0

# 同一网络内容器可直接通过容器名互相访问
# 例如 api 容器内 ping db 是通的

常用网络模式:

模式 说明
bridge 默认,容器通过 NAT 访问外网
host 容器与宿主机共享网络栈
none 无网络
container:<name> 共享另一个容器的网络

8 · Docker Compose

8.1 为什么用 Compose

多容器应用(如 Web + 数据库 + 缓存)用 docker run 逐个启动太麻烦,Compose 用 YAML 文件一次性定义和启动所有服务。

8.2 安装

Docker Desktop 自带 Compose。Linux 安装 Docker 时安装 docker-compose-plugin 即可。

8.3 示例:Web + PostgreSQL

version: '3.8'

services:
  web:
    build: ./web
    ports:
      - "3000:3000"
    environment:
      - DB_HOST=db
      - DB_PASSWORD=secret
    depends_on:
      - db
    networks:
      - appnet

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: mydb
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - appnet

volumes:
  pgdata:

networks:
  appnet:

8.4 常用命令

# 启动所有服务(后台)
docker compose up -d

# 重新构建并启动
docker compose up -d --build

# 查看日志
docker compose logs -f

# 停止并删除容器
docker compose down

# 停止并删除容器+卷(慎用)
docker compose down -v

# 重启服务
docker compose restart

# 查看服务状态
docker compose ps

9 · 日常排错

9.1 容器启动失败

# 查看日志
docker logs <container>

# 进入容器查看
docker exec -it <container> /bin/sh

# 检查端口是否被占用
sudo ss -tlnp | grep :80

9.2 镜像拉取失败

  • 检查网络连通性
  • 配置国内镜像源
  • 确认镜像名称和标签正确

9.3 权限问题

  • 用户是否在 docker 组
  • 挂载目录的权限是否允许容器用户读写
  • 使用 user: "1000:1000" 指定运行用户

9.4 常用清理命令

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

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

# 删除未使用的卷
docker volume prune

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

🚧 docker system prune -a 会清理所有未使用的镜像和容器,生产环境慎用。


10 · 常用实践清单

  • 容器只跑一个进程,不要当虚拟机用。
  • 基础镜像尽量用 alpine 或 slim 版本,减小体积和攻击面。
  • 敏感信息不要写进镜像,用环境变量或 Secret 管理。
  • 数据库存储使用 Volume,不要放在容器层。
  • 生产环境用 Docker Compose / Swarm / Kubernetes 编排,不要裸 docker run。
  • 为镜像打语义化版本标签,如 myapp:1.2.3,不要只用 latest。
  • 镜像构建时把不常变化的层放在前面,提高缓存命中率。

11 · 常用链接

  • Docker 官方文档:https://docs.docker.com
  • Docker Hub:https://hub.docker.com
  • Docker Compose 文档:https://docs.docker.com/compose/
  • Dockerfile 最佳实践:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/