Docker 基本操作
大约 13 分钟约 4032 字
Docker 基本操作
简介
Docker 是当前最常见的容器化工具之一,它把应用、运行时、依赖和配置一起打包进镜像,再通过容器的方式运行。相比传统"机器上逐个安装环境"的方式,Docker 更适合做一致化交付、隔离运行、快速部署和本地开发环境复现。
特点
实现
核心概念与基础命令
# 查看 Docker 版本
docker version
# 查看 Docker 运行信息
docker info
# 查看本地镜像
docker images
# 查看正在运行的容器
docker ps
# 查看所有容器(含已停止)
docker ps -a几个核心概念:
- Image:镜像,应用运行模板
- Container:容器,镜像启动后的运行实例
- Registry:镜像仓库,如 Docker Hub、Harbor
- Volume:数据卷,用于持久化数据
- Network:容器网络,用于容器间通信核心概念详解
====== Image 镜像 ======
- 镜像是一个只读的模板,包含运行应用所需的一切
- 由多层文件系统(UnionFS)组成
- 通过 Dockerfile 构建或从 Registry 拉取
- 镜像是不可变的,每次修改都会创建新层
====== Container 容器 ======
- 容器是镜像的运行实例
- 容器 = 镜像 + 可写层 + 运行配置
- 容器生命周期:创建 -> 运行 -> 暂停 -> 停止 -> 删除
- 容器删除后,可写层数据会丢失(除非使用 Volume)
====== Volume 数据卷 ======
- Volume 用于持久化容器数据
- 容器删除后 Volume 数据仍然存在
- 类型:命名卷(Named Volume)、绑定挂载(Bind Mount)、tmpfs
- 推荐使用命名卷管理服务数据
====== Network 容器网络 ======
- 用于容器间通信
- 内置网络驱动:bridge(桥接)、host(主机)、none(无网络)、overlay(跨主机)
- 自定义网络支持 DNS 解析(容器名互访)
====== Registry 镜像仓库 ======
- Docker Hub:公共镜像仓库
- Harbor:企业级私有镜像仓库
- 阿里云 ACR、腾讯云 TCR:国内云镜像仓库# 拉取镜像
docker pull nginx:1.27-alpine
# 启动容器
docker run -d --name web -p 8080:80 nginx:1.27-alpine
# 查看容器日志
docker logs web
# 进入容器
docker exec -it web sh
# 停止并删除容器
docker stop web
docker rm web容器操作详解
# ====== 容器生命周期管理 ======
docker create # 创建容器但不启动
docker start # 启动已创建的容器
docker stop # 优雅停止容器(发送 SIGTERM)
docker kill # 强制终止容器(发送 SIGKILL)
docker restart # 重启容器
docker rm # 删除已停止的容器
docker rm -f # 强制删除运行中的容器
# ====== 容器运行参数 ======
-d # 后台运行
--name # 容器名称
-p host:container # 端口映射
-P # 随机端口映射
-v host:container # 目录映射(Bind Mount)
-v volume:container # 卷映射(Named Volume)
-e KEY=VALUE # 环境变量
--env-file # 从文件加载环境变量
--restart # 重启策略(no/always/on-failure/unless-stopped)
--network # 指定网络
--link # 容器间链接(已不推荐)
--hostname # 设置主机名
--dns # 设置 DNS
--add-host # 添加 hosts 映射
--cpus # CPU 限制
--memory # 内存限制
--memory-swap # 交换空间限制
--read-only # 只读根文件系统
--privileged # 特权模式(不推荐)
--user # 运行用户
--workdir # 工作目录
--entrypoint # 覆盖入口点
--init # 使用 init 进程(推荐)
--health-cmd # 健康检查命令
--label # 元数据标签
--log-driver # 日志驱动
--rm # 容器停止后自动删除
-it # 交互式 + TTY
# ====== 运行示例 ======
# 基本运行
docker run -d --name nginx -p 80:80 nginx:latest
# 带环境变量和卷
docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=app_db \
-v mysql-data:/var/lib/mysql \
-p 3306:3306 \
mysql:5.7
# 带资源限制
docker run -d --name app \
--memory=512m \
--memory-swap=1g \
--cpus=1 \
-p 8080:8080 \
myapp:1.0
# 带健康检查
docker run -d --name web \
--health-cmd="curl -sf http://localhost/ || exit 1" \
--health-interval=30s \
--health-timeout=5s \
--health-retries=3 \
-p 80:80 \
nginx:latest
# 交互式运行
docker run -it --rm alpine sh
# 挂载当前目录
docker run -it --rm -v $(pwd):/app -w /app node:20-alpine sh
# ====== 容器信息查看 ======
docker ps # 运行中的容器
docker ps -a # 所有容器
docker ps -q # 只显示容器 ID
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
docker stats # 实时资源使用
docker stats --no-stream # 当前快照
docker top container_name # 容器内进程
docker inspect container_name # 详细信息
docker logs container_name # 查看日志
docker logs -f container_name # 实时跟踪日志
docker logs --tail 100 container_name # 最后 100 行
docker diff container_name # 查看文件系统变更
docker port container_name # 查看端口映射
# ====== 容器文件操作 ======
docker cp src container:dest # 复制到容器
docker cp container:src dest # 从容器复制
docker exec container cmd # 在容器中执行命令
docker exec -it container bash # 交互式进入
docker attach container # 附加到容器(共享终端)
# ====== 容器清理 ======
docker container prune -f # 删除所有停止的容器
docker image prune -f # 删除悬空镜像
docker volume prune -f # 删除未使用的卷
docker network prune -f # 删除未使用的网络
docker system prune -f # 综合清理
docker system prune -a -f # 综合清理(包括未使用的镜像)安装与服务管理(CentOS / Rocky 常见方式)
# 添加官方仓库(示意)
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装 Docker CE
yum install -y docker-ce docker-ce-cli containerd.io
# 启动并设置开机自启
systemctl enable --now docker
systemctl status docker安装详解
# ====== CentOS 7 安装 Docker CE ======
# 1. 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 2. 添加 Docker 仓库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 3. 查看可用版本
yum list docker-ce --showduplicates | sort -r
# 4. 安装指定版本
yum install -y docker-ce-20.10.24 docker-ce-cli-20.10.24 containerd.io
# 5. 启动 Docker
systemctl enable --now docker
# 6. 验证安装
docker version
docker run --rm hello-world
# ====== CentOS 8 / RHEL 8 安装 ======
dnf install -y dnf-utils device-mapper-persistent-data lvm2
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io
systemctl enable --now docker
# ====== 配置 Docker ======
# 配置镜像加速(国内)
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://docker.mirrors.ustc.edu.cn"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2",
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["192.168.1.100:5000"],
"live-restore": true,
"userland-proxy": false
}
EOF
systemctl daemon-reload
systemctl restart docker
# 验证配置
docker info | grep -A5 "Registry Mirrors"
# ====== 配置内核参数 ======
cat >> /etc/sysctl.conf << 'EOF'
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
modprobe br_netfilter
sysctl -p
# ====== 配置 Docker 用户权限 ======
# 将当前用户加入 docker 组
usermod -aG docker $USER
# 重新登录生效镜像构建与 Dockerfile
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]Dockerfile 详解
# ====== 基础指令 ======
# FROM: 指定基础镜像
FROM node:20-alpine # 精简版
FROM ubuntu:22.04 # 完整版
FROM scratch # 空白镜像(最小化)
# LABEL: 元数据
LABEL maintainer="admin@example.com"
LABEL version="1.0.0"
LABEL description="My Application"
# WORKDIR: 工作目录
WORKDIR /app
# COPY: 复制文件(推荐)
COPY package*.json ./
COPY . .
# ADD: 复制文件(支持 URL 和自动解压)
ADD app.tar.gz /app/
# RUN: 执行命令
RUN apt-get update && apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
# ENV: 环境变量
ENV NODE_ENV=production
ENV PORT=3000
# EXPOSE: 声明端口(仅文档作用)
EXPOSE 3000
# CMD: 容器启动命令
CMD ["node", "server.js"] # exec 格式
CMD node server.js # shell 格式
# ENTRYPOINT: 入口点
ENTRYPOINT ["python", "app.py"]
# ARG: 构建参数
ARG VERSION=latest
ARG BUILD_DATE
# USER: 运行用户
USER appuser
# VOLUME: 声明挂载点
VOLUME ["/data"]
# HEALTHCHECK: 健康检查
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -sf http://localhost:3000/ || exit 1
# ====== 多阶段构建 ======
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:1.27-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
# ====== .dockerignore ======
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
dist# 构建镜像
docker build -t my-node-app:1.0.0 .
# 不使用缓存构建
docker build --no-cache -t my-node-app:1.0.0 .
# 使用 BuildKit 构建(更快)
DOCKER_BUILDKIT=1 docker build -t my-node-app:1.0.0 .
# 查看构建历史
docker history my-node-app:1.0.0
# 查看镜像详情
docker inspect my-node-app:1.0.0
# ====== 镜像优化技巧 ======
# 1. 使用精简基础镜像(alpine、slim)
# 2. 合并 RUN 指令减少层数
# 3. 多阶段构建减小最终镜像
# 4. 复制文件时排除不需要的文件(.dockerignore)
# 5. 利用构建缓存,将变化频率低的层放在前面数据卷与容器网络
# 创建命名卷
docker volume create mysql-data
# 运行 MySQL,数据写入卷
docker run -d \
--name mysql8 \
-e MYSQL_ROOT_PASSWORD=StrongPass123! \
-v mysql-data:/var/lib/mysql \
-p 3306:3306 \
mysql:8.4
# 查看卷
docker volume ls
docker volume inspect mysql-data数据卷详解
# ====== 数据卷管理 ======
docker volume create mydata # 创建命名卷
docker volume ls # 列出所有卷
docker volume inspect mydata # 查看卷详情
docker volume rm mydata # 删除卷
docker volume prune -f # 删除未使用的卷
# ====== 三种挂载方式 ======
# 1. 命名卷(Named Volume)- Docker 管理
docker run -d -v mydata:/var/lib/mysql mysql:5.7
# 2. 绑定挂载(Bind Mount)- 主机路径
docker run -d -v /data/mysql:/var/lib/mysql mysql:5.7
# 3. tmpfs - 内存文件系统(不持久化)
docker run -d --tmpfs /tmp:rw,size=100m alpine
# ====== 数据卷备份与恢复 ======
# 备份
docker run --rm -v mydata:/data -v $(pwd):/backup alpine \
tar czf /backup/mydata_backup.tar.gz -C /data .
# 恢复
docker run --rm -v mydata_new:/data -v $(pwd):/backup alpine \
tar xzf /backup/mydata_backup.tar.gz -C /data
# ====== 容器间共享卷 ======
docker volume create shared-data
docker run -d --name app1 -v shared-data:/data myapp:1.0
docker run -d --name app2 -v shared-data:/data myapp:2.0网络详解
# ====== 网络管理 ======
docker network create app-net # 创建桥接网络
docker network create -d overlay my-overlay # 创建 overlay 网络
docker network ls # 列出网络
docker network inspect app-net # 查看网络详情
docker network rm app-net # 删除网络
docker network prune -f # 删除未使用的网络
# ====== 网络类型 ======
# bridge(默认)- 单机容器通信
docker network create --driver bridge my-bridge
# host - 共享宿主机网络(无隔离)
docker run -d --network host nginx
# none - 无网络
docker run -d --network none alpine
# overlay - 跨主机通信(Swarm/K8s)
docker network create --driver overlay --attachable my-overlay
# ====== 容器互联 ======
# 在同一网络中的容器可以通过容器名互相访问
docker network create app-net
docker run -d --name redis --network app-net redis:7-alpine
docker run -d --name api --network app-net -p 8081:8080 my-api:1.0
# 在 api 容器中通过 "redis:6379" 访问 Redis
# ====== 端口映射 ======
# -p host:container # 指定端口映射
# -p 8080:80 # 宿主机 8080 -> 容器 80
# -P # 随机端口映射
# -p 8080:80/udp # UDP 端口映射
# -p 127.0.0.1:3306:3306 # 只绑定本地
# ====== 网络排障 ======
docker exec -it api ping redis
docker exec -it api nslookup redis
docker network inspect app-net常见容器运维操作
# 资源占用统计
docker stats
# 查看容器详细信息
docker inspect my-node-app
# 查看日志尾部
docker logs --tail 100 my-node-app
# 持续跟踪日志
docker logs -f my-node-app运维操作详解
# ====== 日志管理 ======
# 查看日志
docker logs myapp
docker logs -f myapp
docker logs --tail 100 myapp
docker logs --since 30m myapp
docker logs --since "2024-01-01" myapp
docker logs -t myapp # 显示时间戳
# 配置日志驱动
docker run -d --log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
myapp:1.0
# ====== 资源监控 ======
docker stats # 实时监控所有容器
docker stats --no-stream # 当前快照
docker stats myapp # 监控指定容器
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# ====== 容器更新 ======
docker update --memory=1g myapp # 更新内存限制
docker update --cpus=2 myapp # 更新 CPU 限制
docker update --restart=always myapp # 更新重启策略
# ====== 容器检查 ======
docker inspect myapp
docker inspect --format '{{.State.Health.Status}}' myapp # 健康状态
docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' myapp # IP 地址
# ====== 镜像导出导入 ======
docker save -o nginx.tar nginx:1.27-alpine # 导出镜像
docker load -i nginx.tar # 导入镜像
docker export myapp > myapp.tar # 导出容器
docker import myapp.tar myapp:restored # 导入容器# 导出 / 导入镜像
docker save -o nginx.tar nginx:1.27-alpine
docker load -i nginx.tar# 清理未使用资源(谨慎)
docker image prune -f
docker container prune -f
docker volume prune -f
docker network prune -fDocker Compose 简介
# ====== docker-compose.yml ======
version: '3.8'
services:
web:
build: .
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
depends_on:
- db
- redis
networks:
- app-net
restart: always
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: app_db
volumes:
- mysql-data:/var/lib/mysql
networks:
- app-net
restart: always
redis:
image: redis:7-alpine
networks:
- app-net
restart: always
volumes:
mysql-data:
networks:
app-net:
driver: bridge# ====== Compose 常用命令 ======
docker-compose up -d # 启动所有服务
docker-compose up -d --build # 构建并启动
docker-compose down # 停止并删除
docker-compose ps # 查看状态
docker-compose logs -f web # 查看日志
docker-compose exec db bash # 进入容器
docker-compose restart web # 重启服务
docker-compose pull # 拉取最新镜像
docker-compose config # 验证配置优点
缺点
总结
Docker 的核心价值,是把应用运行环境标准化并打包成可交付镜像。真正落地时,重点不是会不会 docker run,而是能否把镜像构建、数据持久化、网络连接、日志查看、资源限制和升级回滚形成一整套可维护流程。
关键知识点
- 镜像是模板,容器是实例。
- 容器删除后,容器层里的数据默认也会消失。
- Volume 解决持久化,Network 解决容器互联。
- Dockerfile 质量会直接影响镜像大小、安全性和构建效率。
- 命名卷(Named Volume)由 Docker 管理,绑定挂载(Bind Mount)由宿主机管理。
- 多阶段构建可以显著减小最终镜像大小。
- --init 参数可以为容器添加 init 进程,防止僵尸进程。
项目落地视角
- 本地开发:统一团队开发环境,避免依赖版本不一致。
- 测试环境:快速启动中间件和业务服务组合。
- 生产环境:镜像作为交付物,配合 CI/CD 实现标准化发布。
- 运维排障:通过 logs、exec、inspect 快速定位运行问题。
常见误区
- 把数据库数据直接写在容器层,不挂载卷。
- 镜像里打入太多无关工具,导致体积过大。
- 开发环境和生产环境使用完全不同镜像。
- 容器能跑就算完成,没有健康检查、日志和资源限制。
- 使用 root 用户运行应用容器。
- 不配置日志驱动导致日志文件无限增长。
- 使用 --link 而不是自定义网络进行容器互联。
进阶路线
- 学习 Docker Compose 管理多容器应用。
- 学习 Volume、Network、Registry、BuildKit 等高级能力。
- 进一步掌握多阶段构建、镜像优化和安全扫描。
- 向 Kubernetes、Harbor、CI/CD 平台化部署继续深入。
适用场景
- Web 应用和 API 服务部署。
- 本地开发环境标准化。
- 中间件快速搭建与测试。
- CI/CD 镜像构建和发布流程。
落地建议
- 所有业务服务都维护自己的 Dockerfile 并进入版本控制。
- 持久化服务必须使用 Volume 或外部存储。
- 生产镜像尽量使用精简基础镜像,并减少 root 权限。
- 为容器补充健康检查、日志策略和资源限制。
- 使用 .dockerignore 排除不需要的文件。
排错清单
- 容器起不来:先看
docker logs和docker inspect。 - 端口不通:检查
-p映射、宿主机防火墙和容器监听地址。 - 数据丢失:检查是否正确挂载卷。
- 镜像过大:检查 Dockerfile 层数、依赖安装和构建产物清理情况。
复盘问题
- 你的服务最适合单容器运行,还是多容器组合?
- 当前镜像里哪些内容其实不该进生产镜像?
- 持久化数据、日志、配置是否已经和容器生命周期解耦?
- 如果要回滚版本,现在是否只需要切换镜像 tag 即可?
