Docker 详细学习笔记
Docker 详细学习笔记
整理日期:2026-08-18
适用版本:Docker Engine 20.10+ / 24.x / 25.x
目录
1. Docker 基础概念
1.1 什么是 Docker
Docker 是一个开源的容器化平台,用于将应用及其依赖打包到一个可移植的容器中,然后发布到任何支持 Docker 的机器上运行。
- 容器化:将应用和运行环境打包在一起
- 轻量级:共享宿主机内核,启动快、占用资源少
- 可移植:一次构建,到处运行
- 标准化:统一的打包、分发、运行方式
1.2 容器 vs 虚拟机
| 特性 | 容器(Container) | 虚拟机(VM) |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 资源占用 | MB 级 | GB 级 |
| 内核共享 | 共享宿主机内核 | 独立内核 |
| 隔离性 | 进程级隔离 | 系统级隔离 |
| 性能损耗 | 极小 | 较大 |
1.3 Docker 架构
┌─────────────────────────────────────────┐
│ Docker Client (CLI) │
└───────────────────┬─────────────────────┘
│ REST API
┌───────────────────▼─────────────────────┐
│ Docker Daemon (dockerd) │
│ ┌──────────┐ ┌──────────┐ ┌───────┐ │
│ │ Images │ │ Containers│ │Volume│ │
│ └──────────┘ └──────────┘ └───────┘ │
└─────────────────────────────────────────┘
│
┌───────────────────▼─────────────────────┐
│ Docker Registry │
│ (Docker Hub / 私有仓库) │
└─────────────────────────────────────────┘
- Docker Client:用户通过 CLI 与 Docker 交互
- Docker Daemon:后台服务,负责管理 Docker 对象
- Docker Registry:镜像仓库,存储和分发镜像
- Images:只读模板,用于创建容器
- Containers:镜像的运行实例
2. 安装与配置
2.1 Ubuntu 安装 Docker
# 1. 更新包索引
sudo apt-get update
# 2. 安装依赖
sudo apt-get install -y ca-certificates curl gnupg lsb-release
# 3. 添加 Docker 官方 GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 4. 设置稳定版仓库
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
# 5. 安装 Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 6. 验证安装
docker --version
docker run hello-world
2.2 配置免 sudo 运行
# 创建 docker 组(通常已存在)
sudo groupadd docker
# 将当前用户加入 docker 组
sudo usermod -aG docker $USER
# 重新登录或执行以下命令使生效
newgrp docker
# 验证
docker run hello-world
2.3 配置镜像加速器(国内必配)
编辑 /etc/docker/daemon.json:
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
# 重启 Docker 服务
sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证加速器是否生效
docker info | grep -A 10 "Registry Mirrors"
2.4 Docker 服务管理
# 启动 Docker
sudo systemctl start docker
# 设置开机自启
sudo systemctl enable docker
# 查看状态
sudo systemctl status docker
# 重启
sudo systemctl restart docker
3. 核心概念
3.1 镜像(Image)
- 镜像是一个只读的模板,包含运行应用所需的一切(代码、运行时、库、环境变量、配置文件)
- 镜像由多层(Layer)组成,每层对应 Dockerfile 中的一条指令
- 镜像层是只读的,容器启动时会在顶部添加一层可写层
- 镜像可以基于其他镜像构建(继承关系)
# 查看本地镜像
docker images
docker image ls
# 拉取镜像
docker pull nginx:latest
docker pull ubuntu:22.04
# 删除镜像
docker rmi nginx:latest
docker image rm nginx:latest
# 查看镜像详情
docker inspect nginx:latest
# 查看镜像历史(各层信息)
docker history nginx:latest
3.2 容器(Container)
- 容器是镜像的运行实例
- 容器之间相互隔离,有自己的文件系统、网络、进程空间
- 容器是临时的,删除容器后,容器内的数据也会丢失(除非挂载了数据卷)
# 创建并启动容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 常用选项:
# -d 后台运行(detached)
# -it 交互式运行(interactive + tty)
# --name 指定容器名称
# -p 端口映射 宿主机:容器
# -v 挂载数据卷 宿主机路径:容器路径
# -e 设置环境变量
# --rm 容器停止后自动删除
# --network 指定网络
3.3 仓库(Registry)
- 集中存储和分发镜像的地方
- Docker Hub 是官方公共仓库
- 可以搭建私有仓库(Harbor、Registry)
4. 常用命令速查
4.1 容器生命周期
# 启动容器
docker run -d --name mynginx -p 8080:80 nginx
# 启动已停止的容器
docker start mynginx
# 停止容器
docker stop mynginx
# 重启容器
docker restart mynginx
# 强制停止(发送 SIGKILL)
docker kill mynginx
# 删除容器(容器必须先停止)
docker rm mynginx
# 强制删除(包括运行中的容器)
docker rm -f mynginx
# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 查看容器详情
docker inspect mynginx
# 查看容器日志
docker logs mynginx
docker logs -f mynginx # 实时跟踪
docker logs --tail 100 mynginx # 最后100行
docker logs -t mynginx # 显示时间戳
# 查看容器内进程
docker top mynginx
# 查看容器资源使用情况
docker stats
docker stats mynginx
4.2 进入容器
# 进入运行中的容器(推荐)
docker exec -it mynginx /bin/bash
docker exec -it mynginx sh
# 以 root 用户进入
docker exec -it -u root mynginx bash
# 查看容器输出(不进入)
docker exec mynginx ls -la /
# 复制文件到容器
docker cp /local/path mynginx:/container/path
# 从容器复制文件到本地
docker cp mynginx:/container/path /local/path
4.3 镜像管理
# 构建镜像
docker build -t myapp:v1 .
docker build -t myapp:v1 -f Dockerfile.prod .
# 给镜像打标签
docker tag myapp:v1 myregistry.com/myapp:v1
# 推送镜像到仓库
docker push myregistry.com/myapp:v1
# 搜索镜像
docker search nginx
# 清理无用镜像
docker image prune # 清理悬空镜像(dangling)
docker image prune -a # 清理所有未使用的镜像
# 导出镜像为 tar
docker save -o myapp.tar myapp:v1
# 从 tar 导入镜像
docker load -i myapp.tar
4.4 系统清理
# 查看 Docker 占用空间
docker system df
# 清理所有未使用的资源(镜像、容器、网络、构建缓存)
docker system prune
# 更彻底的清理(包括未使用的卷)
docker system prune -a --volumes
# 清理构建缓存
docker builder prune
5. Dockerfile 详解
5.1 Dockerfile 指令一览
| 指令 | 说明 |
|---|---|
FROM | 指定基础镜像(必须是第一条指令) |
MAINTAINER | 维护者信息(已废弃,用 LABEL 替代) |
LABEL | 镜像元数据 |
RUN | 构建时执行命令 |
CMD | 容器启动时执行的默认命令 |
ENTRYPOINT | 容器启动时执行的入口命令 |
COPY | 复制文件到镜像 |
ADD | 复制文件(支持自动解压 tar、URL) |
WORKDIR | 设置工作目录 |
ENV | 设置环境变量 |
ARG | 构建时变量 |
EXPOSE | 声明容器监听的端口 |
VOLUME | 声明挂载点 |
USER | 指定运行用户 |
HEALTHCHECK | 健康检查 |
ONBUILD | 触发器,子镜像构建时执行 |
5.2 常用指令详解
FROM
# 基础镜像,尽量使用官方镜像和具体版本
FROM ubuntu:22.04
FROM node:18-alpine
FROM python:3.11-slim
RUN
# shell 形式
RUN apt-get update && apt-get install -y nginx
# exec 形式
RUN ["apt-get", "install", "-y", "nginx"]
# 最佳实践:多条命令合并,减少镜像层数
RUN apt-get update && \
apt-get install -y --no-install-recommends \
nginx \
curl \
vim && \
rm -rf /var/lib/apt/lists/*
CMD vs ENTRYPOINT
CMD:容器启动时的默认命令,可以被 docker run 后的参数覆盖。
# 三种形式
CMD ["executable","param1","param2"] # exec 形式(推荐)
CMD ["param1","param2"] # 作为 ENTRYPOINT 的参数
CMD command param1 param2 # shell 形式
ENTRYPOINT:容器启动时的入口命令,不会被 docker run 参数覆盖(参数会追加到 ENTRYPOINT 后)。
ENTRYPOINT ["nginx", "-g", "daemon off;"]
CMD + ENTRYPOINT 组合:
ENTRYPOINT ["java", "-jar", "app.jar"]
CMD ["--spring.profiles.active=prod"]
此时 docker run myapp 会执行 java -jar app.jar --spring.profiles.active=prod
docker run myapp --spring.profiles.active=dev 会执行 java -jar app.jar --spring.profiles.active=dev
COPY vs ADD
# COPY:简单复制(推荐优先使用)
COPY . /app
COPY package.json /app/
# ADD:支持自动解压 tar 文件和 URL(谨慎使用)
ADD app.tar.gz /app/
ADD https://example.com/file.txt /app/
WORKDIR
# 设置工作目录,后续 RUN/CMD/ENTRYPOINT/COPY/ADD 都在此目录下执行
WORKDIR /app
# 可以多次使用,相当于 cd
WORKDIR /app
WORKDIR src
# 最终工作目录为 /app/src
ENV
# 设置环境变量
ENV NODE_ENV=production
ENV APP_HOME=/app
ENV PATH="$PATH:/app/bin"
# 多个变量可以写一行
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk \
MAVEN_HOME=/usr/share/maven
ARG
# 构建时变量,仅在构建过程中可用
ARG VERSION=1.0.0
ARG BUILD_DATE
# 可以在 FROM 之前使用 ARG
ARG NODE_VERSION=18
FROM node:${NODE_VERSION}-alpine
构建时传入:
docker build --build-arg VERSION=2.0.0 -t myapp:v2 .
EXPOSE
# 声明容器监听的端口(仅作文档说明,不会自动映射)
EXPOSE 80
EXPOSE 443/tcp
EXPOSE 53/udp
USER
# 指定运行用户(安全最佳实践,不要用 root)
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser
HEALTHCHECK
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -f http://localhost:80/health || exit 1
5.3 完整 Dockerfile 示例
Node.js 应用
# 多阶段构建
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# 运行阶段
FROM node:18-alpine
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=3000
# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
# 从构建阶段复制
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json
USER nextjs
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1
CMD ["npm", "start"]
Python 应用
FROM python:3.11-slim
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
RUN apt-get update && \
apt-get install -y --no-install-recommends gcc && \
rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd -m appuser
USER appuser
EXPOSE 8000
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:8000"]
Java 应用
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
6. 镜像构建与优化
6.1 镜像分层原理
Docker 镜像由多层只读文件系统组成:
┌─────────────────────┐
│ 可写层(容器层) │ ← 容器运行时写入
├─────────────────────┤
│ Layer 3: CMD │
├─────────────────────┤
│ Layer 2: COPY app │
├─────────────────────┤
│ Layer 1: RUN apt │
├─────────────────────┤
│ Layer 0: 基础镜像 │
└─────────────────────┘
- 每条指令创建一层
- 相同的层可以被多个镜像共享
- 构建时使用缓存,未变化的层直接复用
6.2 构建缓存优化
利用缓存的原则:将变化频率低的指令放在前面,变化频率高的放在后面。
# ❌ 不好:每次代码变化都会导致 npm install 重新执行
COPY . .
RUN npm install
# ✅ 好:只有 package.json 变化时才重新安装依赖
COPY package*.json ./
RUN npm install
COPY . .
6.3 减小镜像体积
1. 使用轻量基础镜像
| 镜像 | 大小 | 说明 |
|---|---|---|
ubuntu:22.04 | ~77MB | 完整 Ubuntu |
debian:bookworm-slim | ~80MB | 精简 Debian |
alpine:3.18 | ~7MB | 超轻量 Alpine |
node:18 | ~990MB | 完整 Node.js |
node:18-slim | ~250MB | 精简 Node.js |
node:18-alpine | ~130MB | Alpine Node.js |
2. 多阶段构建(Multi-stage Build)
# 构建阶段
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp .
# 运行阶段(只包含编译后的二进制)
FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]
最终镜像只有几 MB,而不是几百 MB。
3. 清理包管理器缓存
# Debian/Ubuntu
RUN apt-get update && \
apt-get install -y --no-install-recommends package && \
rm -rf /var/lib/apt/lists/*
# Alpine
RUN apk add --no-cache package
# Python pip
RUN pip install --no-cache-dir -r requirements.txt
# npm
RUN npm ci --only=production && npm cache clean --force
4. 合并 RUN 指令
# ❌ 不好:产生 3 层
RUN apt-get update
RUN apt-get install -y nginx
RUN rm -rf /var/lib/apt/lists/*
# ✅ 好:只产生 1 层
RUN apt-get update && \
apt-get install -y --no-install-recommends nginx && \
rm -rf /var/lib/apt/lists/*
6.4 .dockerignore
类似 .gitignore,排除不需要复制到镜像中的文件:
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.env.local
dist
*.log
.DS_Store
7. 数据管理(Volume)
7.1 数据持久化的三种方式
| 方式 | 说明 | 适用场景 |
|---|---|---|
| Volumes | Docker 管理,存于宿主机 Docker 目录 | 推荐使用,数据持久化 |
| Bind Mounts | 挂载宿主机任意目录 | 开发环境、配置文件 |
| tmpfs | 挂载到内存,不持久化 | 敏感数据、临时文件 |
7.2 Volume 常用命令
# 创建卷
docker volume create mydata
# 查看卷列表
docker volume ls
# 查看卷详情
docker volume inspect mydata
# 删除卷
docker volume rm mydata
# 清理未使用的卷
docker volume prune
7.3 使用 Volume
# 命名卷
docker run -d --name db -v mydata:/var/lib/mysql mysql:8.0
# 匿名卷(Docker 自动生成名称)
docker run -d --name db -v /var/lib/mysql mysql:8.0
# 挂载宿主机目录(Bind Mount)
docker run -d --name nginx -v /host/path:/usr/share/nginx/html nginx
# 只读挂载
docker run -d --name nginx -v /host/path:/usr/share/nginx/html:ro nginx
7.4 数据卷容器
# 创建数据卷容器
docker create -v /data --name datastore busybox true
# 其他容器挂载数据卷容器的卷
docker run -d --volumes-from datastore --name app1 myapp
docker run -d --volumes-from datastore --name app2 myapp
7.5 数据备份与恢复
# 备份:启动临时容器挂载卷,打包输出到宿主机
docker run --rm -v mydata:/data -v $(pwd):/backup busybox \
tar czf /backup/mydata_backup.tar.gz -C /data .
# 恢复
docker run --rm -v mydata:/data -v $(pwd):/backup busybox \
tar xzf /backup/mydata_backup.tar.gz -C /data
8. Docker 网络
8.1 网络驱动类型
| 驱动 | 说明 |
|---|---|
bridge | 默认网络,桥接模式,容器间通过 IP 通信 |
host | 共享宿主机网络命名空间,性能最好 |
none | 无网络,完全隔离 |
overlay | 跨主机网络,用于 Swarm 模式 |
macvlan | 容器有独立 MAC 地址,像物理机一样 |
8.2 常用网络命令
# 查看网络列表
docker network ls
# 创建网络
docker network create mynetwork
docker network create --driver bridge mynetwork
# 查看网络详情
docker network inspect mynetwork
# 连接容器到网络
docker network connect mynetwork mycontainer
# 断开网络
docker network disconnect mynetwork mycontainer
# 删除网络
docker network rm mynetwork
# 清理未使用的网络
docker network prune
8.3 容器间通信
方式一:通过 IP 通信(不推荐,IP 会变)
# 查看容器 IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mycontainer
方式二:自定义网络 + 容器名(推荐)
# 创建自定义网络
docker network create app-net
# 启动容器并加入网络(使用 --name)
docker run -d --name db --network app-net mysql:8.0
docker run -d --name web --network app-net -p 8080:80 nginx
# 容器间可以直接用名称通信
docker exec web ping db
方式三:Link(已过时,不推荐)
docker run -d --name db mysql:8.0
docker run -d --name web --link db:db nginx
8.4 端口映射
# 映射指定端口
docker run -d -p 8080:80 nginx
# 映射到指定网卡
docker run -d -p 127.0.0.1:8080:80 nginx
# 随机映射宿主机端口
docker run -d -p 80 nginx
# 映射多个端口
docker run -d -p 80:80 -p 443:443 nginx
# 查看端口映射
docker port mycontainer
8.5 DNS 配置
# 指定 DNS
docker run -d --dns 8.8.8.8 nginx
# 添加 host 条目
docker run -d --add-host=host.docker.internal:host-gateway nginx
9. Docker Compose
9.1 简介
Docker Compose 是用于定义和运行多容器 Docker 应用的工具。通过 YAML 文件配置应用服务,然后一条命令启动所有服务。
9.2 安装
# Docker Desktop / Docker Engine 20.10+ 已内置 compose 插件
docker compose version
# 旧版独立安装(docker-compose)
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
9.3 Compose 文件结构
# docker-compose.yml
version: "3.8"
services:
web:
build: .
ports:
- "8080:80"
environment:
- NODE_ENV=production
depends_on:
- db
volumes:
- .:/app
networks:
- app-net
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: myapp
volumes:
- db-data:/var/lib/mysql
networks:
- app-net
volumes:
db-data:
networks:
app-net:
driver: bridge
9.4 常用命令
# 启动所有服务(前台)
docker compose up
# 后台启动
docker compose up -d
# 指定 compose 文件
docker compose -f docker-compose.prod.yml up -d
# 停止并删除容器、网络
docker compose down
# 停止并删除容器、网络、卷
docker compose down -v
# 查看服务状态
docker compose ps
# 查看日志
docker compose logs
docker compose logs -f web
docker compose logs --tail=100
# 进入服务容器
docker compose exec web bash
# 重启服务
docker compose restart web
# 重新构建镜像
docker compose build
docker compose up -d --build
# 拉取最新镜像
docker compose pull
# 查看配置(验证 compose 文件)
docker compose config
# 扩展服务实例
docker compose up -d --scale web=3
9.5 完整示例:LNMP 环境
version: "3.8"
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/ssl:/etc/nginx/ssl
- ./www:/var/www/html
depends_on:
- php
networks:
- frontend
- backend
php:
image: php:8.2-fpm-alpine
volumes:
- ./www:/var/www/html
- ./php/php.ini:/usr/local/etc/php/php.ini
depends_on:
- mysql
networks:
- backend
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: myapp
MYSQL_USER: myapp
MYSQL_PASSWORD: myapp123
volumes:
- mysql-data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
ports:
- "3306:3306"
networks:
- backend
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
networks:
- backend
volumes:
mysql-data:
redis-data:
networks:
frontend:
backend:
9.6 环境变量与 .env 文件
# .env 文件
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=myapp
TAG=v1.0.0
services:
db:
image: mysql:${TAG}
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
9.7 多环境配置
# docker-compose.yml(基础配置)
services:
web:
build: .
ports:
- "8080:80"
# docker-compose.override.yml(开发环境,自动加载)
services:
web:
volumes:
- .:/app
environment:
- NODE_ENV=development
# docker-compose.prod.yml(生产环境)
services:
web:
image: myregistry.com/myapp:latest
deploy:
replicas: 3
environment:
- NODE_ENV=production
# 开发环境(默认加载 docker-compose.yml + docker-compose.override.yml)
docker compose up -d
# 生产环境
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
10. 容器安全
10.1 安全最佳实践
1. 不要以 root 用户运行
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser
2. 使用官方镜像
- 优先使用 Docker Hub 官方镜像
- 验证镜像签名(Docker Content Trust)
- 定期扫描镜像漏洞
3. 最小化镜像
- 使用多阶段构建
- 只包含运行必需的文件
- 不安装不必要的工具
4. 限制容器资源
# 限制内存
docker run -d --memory="512m" --memory-swap="1g" nginx
# 限制 CPU
docker run -d --cpus="1.5" nginx
docker run -d --cpuset-cpus="0,1" nginx
5. 只读文件系统
docker run -d --read-only nginx
6. 禁用特权模式
# ❌ 不要用
docker run --privileged ...
# ✅ 按需添加特定能力
docker run --cap-add=NET_ADMIN ...
7. 安全扫描
# 扫描镜像漏洞
docker scan myapp:v1
# 使用 trivy
trivy image myapp:v1
10.2 敏感信息管理
# ❌ 不要在 Dockerfile 中硬编码
ENV PASSWORD=secret123
# ✅ 使用环境变量(运行时传入)
docker run -e DB_PASSWORD=secret myapp
# ✅ 使用 secrets(Swarm 模式)
docker secret create db_password ./password.txt
# ✅ 使用 .env 文件(开发环境)
# 注意:.env 不要提交到 Git
11. 最佳实践
11.1 Dockerfile 最佳实践
- 使用官方基础镜像:优先选择官方维护的镜像
- 固定版本标签:不要用
latest,用具体版本号如nginx:1.25-alpine - 最小化镜像层数:合并 RUN 指令
- 利用构建缓存:将变化少的指令放前面
- 使用 .dockerignore:排除不必要的文件
- 多阶段构建:编译和运行分离
- 非 root 用户:创建专用用户运行应用
- 一条容器一个进程:每个容器只跑一个主进程
- 健康检查:添加 HEALTHCHECK
- 清晰的注释:关键步骤添加注释
11.2 容器使用最佳实践
- 容器是临时的:随时可以销毁和重建
- 数据放卷里:重要数据用 Volume 持久化
- 日志输出到 stdout/stderr:不要写文件,用 docker logs 查看
- 配置通过环境变量传入:遵循 12-Factor 应用原则
- 使用自定义网络:不要用默认 bridge 网络
- 命名规范:容器、镜像、卷使用有意义的名称
11.3 生产环境最佳实践
- 使用编排工具:Kubernetes、Docker Swarm
- 资源限制:设置 CPU、内存限制
- 健康检查:配置就绪探针和存活探针
- 滚动更新:零停机部署
- 监控告警:Prometheus + Grafana
- 日志收集:ELK / Loki
- 自动扩缩容:根据负载自动调整实例数
- 安全扫描:CI/CD 中集成镜像漏洞扫描
12. 常见问题与排错
12.1 容器启动后立即退出
原因:容器没有前台进程在运行。
排查:
# 查看退出的容器日志
docker logs <container_id>
# 查看退出码
docker ps -a
解决:确保 CMD/ENTRYPOINT 启动的进程在前台运行。例如 Nginx 要用 daemon off;。
12.2 端口映射不生效
排查:
# 查看端口映射
docker port <container>
# 查看容器是否在监听
docker exec <container> netstat -tlnp
# 检查宿主机防火墙
sudo ufw status
sudo iptables -L
12.3 容器间无法通信
排查:
# 确认在同一网络
docker inspect <container> | grep NetworkMode
# 测试网络连通性
docker exec <container1> ping <container2>
docker exec <container1> curl http://<container2>:port
解决:使用自定义网络,通过容器名通信。
12.4 镜像构建慢
优化方向:
- 配置国内镜像加速器
- 优化 Dockerfile 顺序,利用缓存
- 使用 .dockerignore 减少上下文
- 多阶段构建减小最终镜像
12.5 磁盘空间不足
# 查看占用
docker system df
# 清理
docker system prune -a --volumes
# 清理日志
truncate -s 0 /var/lib/docker/containers/*/*-json.log
12.6 权限问题(Permission denied)
常见场景:挂载宿主机目录后,容器内进程无写入权限。
解决:
# 方式一:修改宿主机目录权限
chmod 777 /host/path
# 方式二:容器内使用与宿主机相同 UID/GID 的用户
docker run -u $(id -u):$(id -g) myapp
# 方式三:Dockerfile 中指定 UID
RUN usermod -u 1000 appuser
12.7 常用排错命令
# 查看容器详细信息
docker inspect <container>
# 查看容器进程
docker top <container>
# 查看资源使用
docker stats
# 实时查看事件
docker events
# 查看 Docker 守护进程日志
sudo journalctl -u docker -f
# 进入容器网络命名空间调试
docker run --rm --net container:<target> nicolaka/netshoot bash
附录:常用命令速查表
容器管理
docker run # 创建并启动容器
docker start # 启动已停止的容器
docker stop # 停止容器
docker restart # 重启容器
docker rm # 删除容器
docker ps # 列出容器
docker inspect # 查看详情
docker logs # 查看日志
docker exec # 在容器中执行命令
docker cp # 复制文件
docker stats # 资源统计
镜像管理
docker build # 构建镜像
docker pull # 拉取镜像
docker push # 推送镜像
docker images # 列出镜像
docker rmi # 删除镜像
docker tag # 打标签
docker save # 导出镜像
docker load # 导入镜像
docker history # 查看镜像历史
数据卷与网络
docker volume create # 创建卷
docker volume ls # 列出卷
docker volume rm # 删除卷
docker network create # 创建网络
docker network ls # 列出网络
docker network connect # 连接网络
Compose
docker compose up # 启动服务
docker compose down # 停止并删除
docker compose ps # 查看状态
docker compose logs # 查看日志
docker compose exec # 执行命令
docker compose build # 构建镜像
学习建议:
- 先理解核心概念(镜像、容器、仓库)
- 动手实践常用命令
- 学习 Dockerfile 编写和镜像优化
- 掌握数据卷和网络配置
- 学习 Docker Compose 编排多容器应用
- 了解容器安全和最佳实践
- 进阶学习 Kubernetes 等编排工具
更多推荐

所有评论(0)