Appearance
Docker
基本概念
| 概念 | 说明 |
|---|---|
| 镜像(Image) | 只读模板,用于创建容器 |
| 容器(Container) | 镜像运行的实例 |
| 仓库(Registry) | 存储和分发镜像的服务(如 Docker Hub) |
| 数据卷(Volume) | 容器外的持久化存储,容器删除后数据依然保留 |
| 网络(Network) | 容器间通信的虚拟网络,默认提供 bridge 模式 |
安装(Linux / CentOS)
bash
# 安装依赖工具
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加阿里源(国内推荐)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装 Docker(含 buildx 和 compose 插件)
yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
# 启动并设置开机自启
systemctl start docker
systemctl enable docker
# 验证安装
docker version配置镜像加速
bash
mkdir -p /etc/docker
vim /etc/docker/daemon.json写入以下内容:
json
{
"registry-mirrors": ["https://hub.rat.dev"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2"
}bash
# 重启生效
systemctl daemon-reload && systemctl restart docker
# 验证镜像加速是否生效
docker info | grep -A 5 "Registry Mirrors"国内大部分公共镜像源已停服,可使用阿里云个人镜像加速地址
镜像操作
bash
docker search <镜像名> # 搜索镜像
docker pull <镜像名>:<tag> # 拉取指定版本镜像
docker images # 列出本地镜像
docker image history <镜像名|ID> # 查看镜像分层历史
docker image inspect <镜像名|ID> # 查看镜像元数据
docker rmi <镜像名|ID> # 删除镜像
docker image prune # 清理无用(dangling)镜像
docker image push <用户名>/<仓库>:<tag> # 推送镜像到仓库若
docker images中出现 REPOSITORY 为<none>的镜像,运行docker image prune清理
镜像拉取失败排查
确认加速器是否生效
bashdocker info | grep -A 5 "Registry Mirrors"输出包含配置的地址即表示生效。拉取成功后输出的
docker.io/library/node:latest是镜像的规范名称,不代表走的是原始地址,这是正常现象。特定 tag 拉不下来(如
node:22-alpine)国内镜像站对
alpine变体同步范围有限,可改用华为云 SWR:bash# 通过华为云 SWR 拉取(同步较全) docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/node:22-alpine # 拉取成功后重新打 tag docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/node:22-alpine node:22-alpine # 删除临时 tag docker rmi swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/node:22-alpinealpine同步差时也可改用node:22-slim(基于 Debian,镜像站同步更稳定)docker rmi <ID>提示被多个 tag 引用同一 Image ID 有多个 tag 时,需按完整名称逐个删除:
bashdocker rmi swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/node:22-alpine docker rmi node:22-alpine所有 tag 删除后镜像层才真正释放。不确定有哪些 tag 时,用
docker images查看 IMAGE ID 相同的行,逐一删除。
容器操作
启动容器
bash
# 常用参数说明
# -d 后台运行
# --name 指定容器名
# -p 端口映射(宿主机端口:容器端口)
# -v 目录挂载(宿主机目录:容器目录)
# -e 设置环境变量
# --network 指定网络
# --restart 自动重启策略
docker run -d \
--name <容器名> \
-p <宿主机端口>:<容器端口> \
-v <宿主机目录>:<容器目录> \
-e KEY=VALUE \
--network <网络名> \
--restart always \
<镜像名>
# --restart 可选值
# always — 总是重启
# no — 不重启(默认)
# on-failure — 退出码非 0 时重启
# unless-stopped — 手动停止前总是重启
# 挂载权限
docker run -v /data:/data:ro ... # 只读挂载
docker run -v /data:/data:rw ... # 读写挂载(默认)
# 交互式运行(临时测试用)
docker run -it --rm <镜像名> /bin/sh
# --link 已废弃,推荐使用自定义网络代替
# docker run -d --link <容器名>:<别名> <镜像名>
# 推荐:将容器加入同一自定义网络,直接通过容器名访问
docker run -d --network <网络名> --name <容器名> <镜像名>管理容器
bash
docker ps # 查看运行中的容器
docker ps -a # 查看所有容器
docker logs <容器名|ID> # 查看容器日志
docker logs -f <容器名|ID> # 实时跟踪日志
docker exec -it <容器名|ID> /bin/bash # 进入容器(简单环境用 /bin/sh)
docker top <容器名|ID> # 查看容器内正在运行的进程
docker stats <容器名|ID> # 查看容器资源使用(CPU、内存等)
docker inspect <容器名|ID> # 查看容器详情
docker port <容器名|ID> # 查看端口映射
docker stop <容器名|ID> # 停止容器
docker start <容器名|ID> # 启动容器
docker restart <容器名|ID> # 重启容器
docker kill <容器名|ID> # 强制停止容器
docker rm <容器名|ID> # 删除已停止的容器
docker rm -f <容器名|ID> # 强制删除运行中的容器
docker container prune # 交互式清理所有已停止的容器(更安全)
docker system prune # 清理所有无用资源
# 资源限制(推荐在 run 时指定,不依赖 docker update)
docker run --memory=512m --cpus=1.5 --name <容器名> <镜像名>
# 运行后动态调整(临时方案)
docker update --memory 512m <容器名|ID>
docker update --cpu-shares 1024 <容器名|ID>数据卷操作
bash
docker volume ls # 列出数据卷
docker volume create <卷名> # 创建数据卷
docker volume inspect <卷名> # 查看数据卷详情
docker volume rm <卷名> # 删除数据卷
docker volume prune # 清理未使用的数据卷
# 使用具名数据卷挂载
docker run -v <卷名>:/data <镜像名>网络操作
Docker 安装后默认创建三种网络:
| 模式 | 说明 |
|---|---|
| bridge | 默认模式,容器通过虚拟网桥互通,通过端口映射与宿主机通信 |
| host | 容器与宿主机共享网络命名空间,直接使用宿主机 IP 和端口 |
| none | 容器无任何网络接口,完全隔离 |
bash
docker network ls # 列出所有网络
docker network create <网络名> --driver bridge # 创建自定义网络
docker network connect <网络名> <容器名> # 将容器加入网络
docker network inspect <网络名> # 查看网络详情
docker network rm <网络名> # 删除网络
docker network prune # 清理未使用的网络
# 启动容器时指定网络
docker run -d --network <网络名> --name <容器名> <镜像名>同一自定义网络内的容器可直接通过容器名互相访问,无需
--link
容器间通信(关键)
同一自定义网络内,容器之间以容器名(--name 指定的值)作为主机名直接访问,端口填容器内监听端口(不是宿主机映射端口)。
bash
# 创建自定义网络
docker network create myweb
# 启动 Node 应用,加入 myweb 网络
docker run -d --name server --network myweb my-node-app
# 启动 Nginx,加入同一网络,对外暴露 80/443
docker run -d --name nginx --network myweb -p 80:80 -p 443:443 nginx:stableNginx 配置反向代理到 Node 服务,直接用容器名:
nginx
location / {
proxy_pass http://server:3000; # server 是容器名,3000 是容器内端口
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}应用通过容器名连接数据库(以 MySQL 为例):
bash
# 启动 MySQL,加入同一网络
docker run -d --name mysql --network myweb \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.4
# 应用启动时通过环境变量传入数据库地址
# MYSQL_HOST 填容器名(即主机名),MYSQL_PORT 填容器内端口(非宿主机映射端口)
docker run -d --name server --network myweb \
-e MYSQL_HOST=mysql \
-e MYSQL_PORT=3306 \
my-node-app容器名即主机名;建议始终显式指定
--name,避免 Docker 随机命名导致引用失效
常用服务快速启动
Redis
bash
docker run -d \
--name redis \
-p 6379:6379 \
-v ~/redis/data:/data \
-v ~/redis/conf/redis.conf:/etc/redis/redis.conf \
redis redis-server /etc/redis/redis.confredis.conf 关键配置:
ini
bind 0.0.0.0 # 允许外部访问
daemonize no # 不使用守护进程(Docker 托管)
requirepass 你的密码
appendonly yes # 开启持久化MySQL
bash
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v ~/mysql/data:/var/lib/mysql \
-v ~/mysql/log:/var/log/mysql \
-v ~/mysql/conf:/etc/mysql/conf.d \
-v ~/mysql/init:/docker-entrypoint-initdb.d \
mysql:8.4
/docker-entrypoint-initdb.d目录下的.sql文件会在容器首次启动时自动执行,可用于数据库初始化
MongoDB
bash
docker run -d \
--name mongo \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=root \
-e MONGO_INITDB_ROOT_PASSWORD=123456 \
-v ~/mongo/data:/data/db \
mongo:7Dockerfile
常用指令
| 指令 | 说明 |
|---|---|
FROM | 基础镜像,必须为第一条指令 |
WORKDIR | 设置工作目录 |
COPY | 将文件复制进镜像 |
ADD | 同 COPY,额外支持自动解压 tar 和下载 URL |
RUN | 构建时执行命令,每条都会新建一层 |
ENV | 设置环境变量,可用 ${KEY} 引用 |
EXPOSE | 声明容器监听的端口(仅文档作用) |
VOLUME | 声明数据卷挂载点 |
CMD | 容器启动时的默认命令,可被 docker run 覆盖 |
ENTRYPOINT | 容器启动入口,不会被覆盖,与 CMD 配合使用 |
USER | 指定 RUN/CMD/ENTRYPOINT 使用的用户,生产环境应避免用 root |
LABEL | 为镜像添加元数据标签,替代已废弃的 MAINTAINER |
HEALTHCHECK | 健康检查,定期检测容器是否正常运行 |
优先使用
COPY而非ADD;多条RUN命令用&&合并以减少镜像层数
基础示例
dockerfile
FROM node:22-alpine
WORKDIR /app
# 先复制依赖文件,利用层缓存:仅 package.json 变动时才重新安装
COPY package.json yarn.lock ./
RUN yarn config set registry 'https://registry.npmmirror.com' && yarn --frozen-lockfile --production
COPY . .
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "index.js"]pnpm 单阶段构建
适合输出文件已包含所有依赖、无需分离构建与运行环境的项目(如 tsup 打包后的服务):
dockerfile
FROM node:22-alpine
WORKDIR /app
# 通过 corepack 激活 pnpm,无需全局安装
RUN corepack enable && corepack prepare pnpm@latest --activate
# 先复制依赖文件,利用层缓存
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
# 创建专用非 root 用户,避免以 root 身份运行服务
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]多阶段构建(推荐)
适用于需要分离构建环境与运行环境的场景(如 TypeScript 编译),可大幅减小最终镜像体积:
dockerfile
# ── 构建阶段 ──────────────────────────────────────────────
FROM node:22-alpine AS builder
WORKDIR /app
# 通过 corepack 激活 pnpm,无需全局安装
RUN corepack enable && corepack prepare pnpm@latest --activate
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
# ── 运行阶段 ──────────────────────────────────────────────
# 若使用 tsup 等打包工具,dist/index.js 已包含所有依赖,无需复制 node_modules
FROM node:22-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
# 创建专用非 root 用户,避免以 root 身份运行服务
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"].dockerignore
避免将无关文件打入镜像,加快构建速度:
text
.git
node_modules
dist
*.log构建镜像
bash
# 基本构建
docker build -t <镜像名>:<版本号> .
# 指定 Dockerfile 文件
docker build -f Dockerfile.prod -t my-app:1.0 .
# 查看镜像分层
docker image history <镜像名|ID>待补充
- [ ] Docker 健康检查(HEALTHCHECK)
- [ ] 镜像推送到私有仓库
- [ ] 资源限制(--memory、--cpus)最佳实践