
第一部分:Docker 基础概念
1.1 什么是 Docker?
Docker 是一个开源的容器化平台,它可以将应用程序及其依赖项打包到一个轻量级、可移植的容器中,从而实现"一次构建,到处运行"。
核心价值

三大核心价值:
1.一致性:消除"在我机器上能运行"的问题
2.快速交付:秒级启动,快速部署和扩展
3.资源高效:相比虚拟机,占用更少资源
1.2 容器 vs 虚拟机


1.3 Docker 核心组件

组件详解
1.Docker Client(客户端)
·用户与 Docker 交互的主要界面
·通过 CLI 或 API 发送命令
2.Docker Daemon(守护进程)
·监听 API 请求并管理 Docker 对象
·负责构建、运行和分发容器
3.Docker Image(镜像)
·只读模板,包含运行应用所需的一切
·分层存储,联合文件系统(UnionFS)
4.Docker Container(容器)
·镜像的运行实例
·可读可写层
5.Docker Registry(仓库)
·存储 and 分发镜像的服务
·Docker Hub 是最大的公共仓库
1.4 Docker 技术原理
联合文件系统(UnionFS)

分层机制的优势:
1.共享基础层:多个镜像可共享相同的基础层
2.快速构建:只传输变更的层
3.节省空间:相同的层只存储一次
命名空间(Namespace)隔离


第二部分:Docker 安装与配置
2.1 Linux 系统安装
Ubuntu/Debian 系统
java
# 1. 更新包索引
sudo apt-get update
# 2. 安装依赖包
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# 3. 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 4. 设置稳定版仓库
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.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
# 6. 验证安装
sudo docker run hello-world
CentOS/RHEL 系统
java
# 1. 安装依赖包
sudo yum install -y yum-utils
# 2. 添加 Docker 仓库
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 3. 安装 Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
# 4. 启动 Docker
sudo systemctl start docker
sudo systemctl enable docker
# 5. 验证安装
sudo docker run hello-world
2.2 配置镜像加速器

配置方法
java
# 创建或编辑 Docker 配置文件
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"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"
}
}
EOF
# 重启 Docker 服务
sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证配置
sudo docker info | grep -A 10 "Registry Mirrors"
2.3 用户权限配置
java
# 将当前用户添加到 docker 组
sudo usermod -aG docker $USER
# 刷新用户组(需要重新登录或执行)
newgrp docker
# 验证(不需要 sudo)
docker run hello-world
第三部分:Docker 核心操作
3.1 镜像管理
镜像操作流程图

常用命令详解
java
# ============ 搜索镜像 ============
# 在 Docker Hub 搜索镜像
docker search nginx
docker search python --filter=stars=100# 只显示星数超过100的
# ============ 拉取镜像 ============
# 拉取最新版镜像
docker pull nginx
# 拉取指定版本
docker pull nginx:1.24
docker pull nginx:alpine
docker pull nginx@sha256:abc123...# 拉取特定摘要的镜像
# ============ 查看镜像 ============
# 列出本地所有镜像
docker images
docker image ls
# 查看镜像详细信息
docker inspect nginx:latest
# 查看镜像历史(分层信息)
docker history nginx:latest
# ============ 删除镜像 ============
# 删除单个镜像
docker rmi nginx:latest
# 强制删除(即使有容器在使用)
docker rmi -f nginx:latest
# 删除所有悬虚镜像(dangling images)
docker image prune
# 删除所有未使用的镜像
docker image prune -a
# ============ 构建镜像 ============
# 从 Dockerfile 构建镜像
docker build -t myapp:v1.0 .
# 使用 Dockerfile 并指定构建参数
docker build \
--build-arg VERSION=1.0 \
--build-arg ENV=production \
-t myapp:v1.0 .
# ============ 标记和推送镜像 ============
# 为镜像打标签
docker tag myapp:v1.0 username/myapp:v1.0
docker tag myapp:v1.0 registry.example.com/myapp:v1.0
# 推送到 Docker Hub
docker push username/myapp:v1.0
# 推送到私有仓库
docker push registry.example.com/myapp:v1.0
# ============ 导出和导入镜像 ============
# 导出镜像到 tar 文件
docker save -o nginx.tar nginx:latest
docker save nginx:latest > nginx.tar
# 从 tar 文件导入镜像
docker load -i nginx.tar
docker load < nginx.tar
# ============ 镜像历史和清理 ============
# 查看镜像构建历史
docker history nginx:latest --no-trunc
# 清理所有未使用的镜像、容器、网络、构建缓存
docker system prune -a --volumes
3.2 容器管理
容器生命周期

容器管理命令大全
java
# ============ 创建和运行容器 ============
# 运行容器(最常用)
docker run nginx:latest
# 运行容器(后台模式)
docker run -d nginx:latest
# 运行容器(指定端口映射)
docker run -d -p 8080:80 nginx:latest
# 运行容器(指定名称)
docker run -d --name mynginx nginx:latest
# 运行容器(挂载卷)
docker run -d -v /host/path:/container/path nginx:latest
# 运行容器(环境变量)
docker run -d -e APP_ENV=production -e DB_HOST=mysql nginx:latest
# 运行容器(交互式)
docker run -it ubuntu:latest bash
# 运行容器(自动删除)
docker run --rm nginx:latest
# 创建但不启动容器
docker create --name mynginx nginx:latest
# ============ 查看容器 ============
# 列出运行中的容器
docker ps
# 列出所有容器(包括停止的)
docker ps -a
# 查看容器详细信息
docker inspect mynginx
# 查看容器日志
docker logs mynginx
# 实时查看日志
docker logs -f mynginx
# 查看最后100行日志
docker logs --tail 100 mynginx
# 查看带时间戳的日志
docker logs -t mynginx
# 查看容器内进程
docker top mynginx
# 查看容器资源使用
docker stats mynginx
# 查看所有容器的资源使用
docker stats
# ============ 容器控制 ============
# 启动容器
docker start mynginx
# 停止容器
docker stop mynginx
# 强制停止容器
docker kill mynginx
# 重启容器
docker restart mynginx
# 暂停容器
docker pause mynginx
# 恢复暂停的容器
docker unpause mynginx
# ============ 容器操作 ============
# 进入运行中的容器(推荐方式)
docker exec -it mynginx bash
docker exec -it mynginx /bin/sh
# 在容器中执行命令
docker exec mynginx nginx -v
# 从容器复制文件到主机
docker cp mynginx:/etc/nginx/nginx.conf ./nginx.conf
# 从主机复制文件到容器
docker cp ./nginx.conf mynginx:/etc/nginx/nginx.conf
# 查看容器文件系统变更
docker diff mynginx
# ============ 删除容器 ============
# 删除已停止的容器
docker rm mynginx
# 强制删除运行中的容器
docker rm -f mynginx
# 删除所有已停止的容器
docker container prune
# 删除所有容器(包括运行中的)
docker rm -f $(docker ps -aq)
# ============ 容器导出和导入 ============
# 导出容器为镜像
docker commit mynginx mynginx:new-image
# 导出容器为 tar 文件
docker export mynginx > mynginx.tar
# 从 tar 文件导入为镜像
docker import mynginx.tar mynginx:imported
# ============ 容器更新 ============
# 更新容器重启策略
docker update --restart=always mynginx
# 更新容器资源限制
docker update --memory="512m" --cpus=2 mynginx
# ============ 重启策略 ============
# no: 不自动重启(默认)
docker run --restart=no myapp
# on-failure: 只有在非正常退出时重启
docker run --restart=on-failure:5 myapp# 最多重启5次
# always: 总是重启
docker run --restart=always myapp
# unless-stopped: 总是重启,除非手动停止
docker run --restart=unless-stopped myapp
3.3 Docker 网络管理
网络模式

网络操作命令
java
# ============ 查看网络 ============
# 列出所有网络
docker network ls
# 查看网络详细信息
docker network inspect bridge
# ============ 创建网络 ============
# 创建 bridge 网络
docker network create mynetwork
# 创建指定子网的网络
docker network create \
--driver=bridge \
--subnet=172.20.0.0/16 \
--gateway=172.20.0.1 \
mynetwork
# 创建 overlay 网络(用于 Swarm)
docker network create --driver=overlay --attachable my-overlay
# ============ 连接容器到网络 ============
# 运行容器时指定网络
docker run --network=mynetwork --name container1 nginx
# 将已有容器连接到网络
docker network connect mynetwork existing_container
# 断开容器连接
docker network disconnect mynetwork existing_container
# ============ 端口映射 ============
# 映射单个端口
docker run -p 8080:80 nginx
# 映射多个端口
docker run -p 8080:80 -p 8443:443 nginx
# 绑定到特定接口
docker run -p 127.0.0.1:8080:80 nginx
# 随机端口映射
docker run -P nginx
# ============ 删除网络 ============
# 删除网络
docker network rm mynetwork
# 删除所有未使用的网络
docker network prune
网络模式详解
java
# ============ bridge 模式(默认)============
docker run --network=bridge nginx
# 特点:
# - 容器拥有独立 IP
# - 通过 NAT 访问外网
# - 端口映射才能从外部访问
# ============ host 模式 ============
docker run --network=host nginx
# 特点:
# - 共享主机网络栈
# - 无端口映射,直接使用主机端口
# - 网络性能最好
# 注意:Windows/Mac 不支持此模式
# ============ container 模式 ============
docker run --network=container:container1 nginx
# 特点:
# - 共享另一个容器的网络命名空间
# - localhost 可以访问共享容器的服务
# ============ none 模式 ============
docker run --network=none nginx
# 特点:
# - 完全网络隔离
# - 只有 lo 接口
# - 适合高度安全的场景
3.4 数据持久化

Volume 操作
java
# ============ 创建卷 ============
# 创建命名卷
docker volume create mydata
# 列出所有卷
docker volume ls
# 查看卷详细信息
docker volume inspect mydata
# ============ 使用卷 ============
# 运行容器并挂载卷
docker run -d -v mydata:/data nginx
# 运行容器并挂载到多个卷
docker run -d \
-v mydata1:/data1 \
-v mydata2:/data2 \
nginx
# 只读挂载
docker run -d -v mydata:/data:ro nginx
# ============ 清理卷 ============
# 删除卷
docker volume rm mydata
# 删除所有未使用的卷
docker volume prune
# 查看卷占用空间
docker system df -v
Bind Mount 操作
java
# ============ 绝对路径挂载 ============
docker run -d -v /host/path:/container/path nginx
# ============ 相对路径挂载(不推荐)============
docker run -d -v ./data:/data nginx
# ============ 只读挂载 ============
docker run -d -v /host/path:/container/path:ro nginx
# ============ 挂载单个文件 ============
docker run -d -v /host/nginx.conf:/etc/nginx/nginx.conf:ro nginx
# ============ macOS/Windows 特殊注意事项 ============
# Docker Desktop 需要在设置中授权目录访问
# 推荐使用 /Users/username (macOS) 或 C:\Users\username (Windows)
第四部分:Dockerfile 完全指南
4.1 Dockerfile 基础
Dockerfile 指令大全
java
# ============ 基础指令 ============
# FROM: 指定基础镜像
FROM ubuntu:22.04
FROM alpine:3.18
FROM scratch# 空白镜像,用于构建最小镜像
# LABEL: 添加元数据
LABEL maintainer="your-email@example.com"
LABEL version="1.0"
LABEL description="This is a sample image"
# RUN: 执行命令
RUN apt-get update && apt-get install -y \
curl \
vim \
&& rm -rf /var/lib/apt/lists/*
#-------------------------------------------------------------------------------===
# CMD: 容器启动时的默认命令
CMD ["nginx", "-g", "daemon off;"]
CMD ["python", "app.py"]
CMD echo "Hello World"
# ENTRYPOINT: 容器启动时的入口点
ENTRYPOINT ["python", "app.py"]
ENTRYPOINT ["nginx"]
# ============ 文件操作 ============
# COPY: 从主机复制文件到镜像
COPY app.py /app/
COPY . /app/
COPY --from=builder /app/build /app/
# ADD: 类似 COPY,但支持 URL 和自动解压
ADD https://example.com/file.tar.gz /tmp/
ADD archive.tar.gz /usr/local/# 自动解压
# ============ 环境和配置 ============
# ENV: 设置环境变量
ENV APP_ENV=production
ENV PATH="/app/bin:${PATH}"
ENV \
APP_VERSION=1.0 \
APP_ENV=production
# ARG: 构建时的参数
ARG VERSION=1.0
ARG BASE_IMAGE=ubuntu:22.04
FROM ${BASE_IMAGE}
# WORKDIR: 设置工作目录
WORKDIR /app
WORKDIR /var/www/html
# ============ 端口和用户 ============
# EXPOSE: 声明容器监听的端口
EXPOSE 80 443
EXPOSE 3000
# USER: 指定运行用户
USER nginx
USER 1000:1000
# ============ 卷和触发器 ============
# VOLUME: 创建挂载点
VOLUME ["/data"]
VOLUME ["/var/log/app", "/var/lib/app"]
# ONBUILD: 在子镜像构建时执行
ONBUILD COPY . /app/
ONBUILD RUN pip install -r requirements.txt
# ============ 健康检查 ============
# HEALTHCHECK: 健康检查指令
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
HEALTHCHECK NONE# 禁用基础镜像的健康检查
# ============ Shell 和信号 ============
# SHELL: 覆盖默认 shell
SHELL ["/bin/bash", "-c"]
# STOPSIGNAL: 设置停止信号
STOPSIGNAL SIGTERM
STOPSIGNAL 9
4.2 Dockerfile 最佳实践
1.最小化镜像层数
java
# ❌ 不推荐:多层 RUN
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y vim
RUN rm -rf /var/lib/apt/lists/*
# ✅ 推荐:合并 RUN 指令
RUN apt-get update && apt-get install -y \
curl \
vim \
&& rm -rf /var/lib/apt/lists/*
2.使用 .dockerignore
java
# .dockerignore 文件示例
.git
.gitignore
node_modules
npm-debug.log
.env
__pycache__
*.pyc
.vscode
.DS_Store
*.md
tests/
*.test.js
coverage/
3.优化缓存利用
java
# ✅ 推荐:将变化少的指令放在前面
FROM node:18-alpine
WORKDIR /app
# 先复制依赖文件(变化少)
COPY package*.json ./
RUN npm ci --only=production
# 再复制源代码(变化多)
COPY . .
CMD ["node", "app.js"]
4.多阶段构建
java
# ========== 构建阶段 ==========
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# ========== 生产阶段 ==========
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["node", "dist/app.js"]
5.使用非 root 用户
java
FROM alpine:3.18
# 安装必要的工具
RUN apk add --no-cache curl
# 创建用户
RUN addgroup -g 1000 appuser && \
adduser -D -u 1000 -G appuser appuser
# 设置工作目录并设置权限
WORKDIR /app
COPY --chown=appuser:appuser . .
# 切换到非 root 用户
USER appuser
CMD ["python", "app.py"]
4.3 实战 Dockerfile 示例
示例 1: Node.js 应用
java
# 多阶段构建
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
# 从构建阶段复制
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
# 创建非 root 用户
RUN addgroup -g 1000 node && \
adduser -D -u 1000 -G node node
# 设置权限
RUN chown -R node:node /app
USER node
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
CMD ["node", "dist/app.js"]
示例 2: Python 应用
java
FROM python:3.11-slim
# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
# 安装 Python 依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 创建非 root 用户
RUN useradd -m -u 1000 appuser && \
chown -R appuser:appuser /app
USER appuser
EXPOSE 8000
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
示例 3: Nginx 静态网站
java
FROM nginx:alpine
# 删除默认配置
RUN rm /etc/nginx/conf.d/default.conf
# 复制自定义配置
COPY nginx.conf /etc/nginx/nginx.conf
COPY conf.d/ /etc/nginx/conf.d/
# 复制静态文件
COPY html/ /usr/share/nginx/html/
# 创建 nginx 用户
RUN addgroup -g 1000 nginx && \
adduser -D -u 1000 -G nginx nginx
# 创建必要的目录并设置权限
RUN mkdir -p /var/cache/nginx /var/log/nginx && \
chown -R nginx:nginx /var/cache/nginx /var/log/nginx && \
chown -R nginx:nginx /usr/share/nginx/html
USER nginx
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
第五部分:Docker Compose
5.1 Compose 基础

docker-compose.yml 结构
java
version: '3.8' # Compose 文件版本
services:# 定义服务
web:# 服务名称
image: nginx:latest# 使用镜像
build: .# 或从 Dockerfile 构建
ports:# 端口映射
- "8080:80"
environment:# 环境变量
- NODE_ENV=production
volumes:# 卷挂载
- ./data:/data
depends_on:# 依赖关系
- db
networks:# 网络
- frontend
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: example
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
networks:# 定义网络
frontend:
backend:
volumes:# 定义卷
db-data:
5.2 Compose 常用命令
java
# ============ 启动和管理服务 ============
# 启动服务(后台运行)
docker-compose up -d
# 启动服务(前台运行,查看日志)
docker-compose up
# 强制重新构建镜像
docker-compose up -d --build
# 创建并启动服务(不使用缓存)
docker-compose build --no-cache
docker-compose up -d
# 停止服务
docker-compose stop
# 停止并删除容器、网络
docker-compose down
# 停止并删除容器、网络、卷
docker-compose down -v
# 重启服务
docker-compose restart
# 重启单个服务
docker-compose restart web
# ============ 查看服务状态 ============
# 查看运行中的服务
docker-compose ps
# 查看服务日志
docker-compose logs
# 查看特定服务日志
docker-compose logs web
# 实时查看日志
docker-compose logs -f
# 查看最后100行日志
docker-compose logs --tail=100 web
# ============ 构建和管理镜像 ============
# 构建镜像
docker-compose build
# 构建特定服务
docker-compose build web
# 构建时不使用缓存
docker-compose build --no-cache
# 查看服务使用的镜像
docker-compose images
# ============ 执行命令 ============
# 在运行的容器中执行命令
docker-compose exec web bash
# 在新容器中运行一次性命令
docker-compose run web python manage.py migrate
# 运行命令并自动删除容器
docker-compose run --rm web python manage.py shell
# ============ 扩展服务 ============
# 扩展服务实例数量
docker-compose up -d --scale web=3
# ============ 其他命令 ============
# 暂停服务
docker-compose pause
# 恢复服务
docker-compose unpause
# 查看服务之间的端口映射
docker-compose port web 80
# 列出所有容器(包括停止的)
docker-compose ps -a
# 验证 Compose 文件
docker-compose config
# 查看最终配置(合并环境变量后)
docker-compose config --resolve-image-digests
5.3 实战 Compose 配置
完整的 Web 应用栈
java
version: '3.8'
services:
# ========== Nginx 反向代理 ==========
nginx:
image: nginx:alpine
container_name: app_nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./ssl:/etc/nginx/ssl:ro
- static_files:/app/static:ro
- media_files:/app/media:ro
depends_on:
- web
networks:
- frontend
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost/health"]
interval: 30s
timeout: 5s
retries: 3
# ========== Web 应用 ==========
web:
build:
context: .
dockerfile: Dockerfile
args:
- BUILD_ENV=production
container_name: app_web
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_files:/app/static
- media_files:/app/media
env_file:
- .env.production
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/appdb
- REDIS_URL=redis://redis:6379/0
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- frontend
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health/"]
interval: 30s
timeout: 5s
retries: 3
start_period: 40s
# ========== PostgreSQL 数据库 ==========
db:
image: postgres:15-alpine
container_name: app_db
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=appdb
- PGDATA=/var/lib/postgresql/data/pgdata
networks:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
shm_size: 128mb
# ========== Redis 缓存 ==========
redis:
image: redis:7-alpine
container_name: app_redis
command: redis-server --appendonly yes --requirepass redispassword
volumes:
- redis_data:/data
networks:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
# ========== Celery Worker ==========
celery_worker:
build:
context: .
dockerfile: Dockerfile
container_name: app_celery_worker
command: celery -A config worker -l info
volumes:
- static_files:/app/static
- media_files:/app/media
env_file:
- .env.production
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/appdb
- REDIS_URL=redis://redis:6379/0
depends_on:
- db
- redis
networks:
- backend
restart: unless-stopped
# ========== Celery Beat ==========
celery_beat:
build:
context: .
dockerfile: Dockerfile
container_name: app_celery_beat
command: celery -A config beat -l info
volumes:
- ./celerybeat-schedule:/app/celerybeat-schedule
env_file:
- .env.production
environment:
- REDIS_URL=redis://redis:6379/0
depends_on:
- redis
networks:
- backend
restart: unless-stopped
# ========== Flower 监控 ==========
flower:
build:
context: .
dockerfile: Dockerfile
container_name: app_flower
command: celery -A config flower --port=5555
ports:
- "5555:5555"
environment:
- REDIS_URL=redis://redis:6379/0
- FLOWER_BASIC_AUTH=admin:admin123
depends_on:
- redis
networks:
- backend
restart: unless-stopped
networks:
frontend:
driver: bridge
backend:
driver: bridge
volumes:
postgres_data:
driver: local
redis_data:
driver: local
static_files:
driver: local
media_files:
driver: local
环境变量文件 (.env.production)
java
# .env.production
DATABASE_URL=postgresql://postgres:password@db:5432/appdb
REDIS_URL=redis://redis:6379/0
SECRET_KEY=your-secret-key-here
DEBUG=False
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_S3_BUCKET=your-bucket-name
第六部分:Docker 安全与优化
6.1 安全最佳实践

1.镜像安全扫描
java
# 使用 Trivy 扫描镜像
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image nginx:latest
# 扫描并显示漏洞详情
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image --severity HIGH,CRITICAL nginx:latest
# 生成 HTML 报告
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image --format template --template "@contrib/html.tpl" \
-o report.html nginx:latest
2.安全运行配置
java
# ============ 用户权限 ============
# 使用非 root 用户运行
docker run --user 1000:1000 nginx
# 使用用户命名空间(需要配置)
docker run --userns myuserns nginx
# ============ 只读文件系统 ============
docker run --read-only --tmpfs /tmp nginx
# ============ 资源限制 ============
# 限制内存使用
docker run -m 512m nginx
# 限制 CPU 使用
docker run --cpus="1.5" nginx
# 限制 CPU 核心使用
docker run --cpuset-cpus="0,1" nginx
# ============ 安全选项 ============
# 禁用特权模式
docker run --security-opt=no-new-privileges nginx
# 使用 AppArmor 配置文件
docker run --security-opt apparmor=docker-default nginx
# 使用 SELinux 标签
docker run --security-opt label=level:s0:c100,c200 nginx
# ============ 能力(Capabilities)管理 ============
# 删除所有能力
docker run --cap-drop=all nginx
# 添加特定能力
docker run --cap-drop=all --cap-add=NET_BIND_SERVICE nginx
# ============ 禁用特权容器 ============
# ❌ 危险:不要使用特权模式
docker run --privileged nginx# 不要这样做!
# ✅ 仅在必要时添加特定能力
docker run --cap-add=SYS_TIME nginx
3.安全 Dockerfile 实践
java
# 使用特定版本标签,不用 latest
FROM python:3.11.2-slim
# 使用非 root 用户
RUN groupadd -r appuser && useradd -r -g appuser appuser
# 设置工作目录
WORKDIR /app
# 只复制必要的文件
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY --chown=appuser:appuser . .
# 切换到非 root 用户
USER appuser
# 只读根文件系统
# 运行时使用:docker run --read-only --tmpfs /tmp --tmpfs /var/run app
# 健康检查
HEALTHCHECK CMD curl -f http://localhost/health || exit 1
# 限制信号
STOPSIGNAL SIGTERM
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
6.2 性能优化
1.镜像优化
java
# ✅ 使用 alpine 基础镜像
FROM node:18-alpine# 120MB
# FROM node:18 # 900MB
# ✅ 多阶段构建
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o app
FROM alpine:3.18
COPY --from=builder /app/app /usr/local/bin/app
CMD ["app"]
# ✅ 合并 RUN 指令
RUN apt-get update && \
apt-get install -y curl vim && \
rm -rf /var/lib/apt/lists/*
# ✅ 利用构建缓存
COPY package*.json ./
RUN npm ci
COPY . .
# ✅ 清理不必要的文件
RUN apt-get update && \
apt-get install -y package && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
2.运行时优化
java
# ============ 内存优化 ============
# 限制容器内存
docker run -m 512m --memory-swap 1g nginx
# 禁用内存 swap
docker run -m 512m --memory-swap 512m nginx
# ============ CPU 优化 ============
# 限制 CPU 使用
docker run --cpus=2 nginx
# 设置 CPU 权重(1024 默认)
docker run --cpu-shares=512 nginx
# 绑定到特定 CPU 核心
docker run --cpuset-cpus="0-2" nginx
# ============ IO 优化 ============
# 限制磁盘 IO
docker run --device-read-bps /dev/sda:1mb nginx
docker run --device-write-bps /dev/sda:1mb nginx
# ============ 网络优化 ============
# 使用 host 网络模式(性能最好)
docker run --network=host nginx
# 禁用容器网络(安全场景)
docker run --network=none app
# ============ 存储优化 ============
# 使用 tmpfs 挂载临时文件
docker run --tmpfs /tmp:rw,size=100m nginx
# 使用 volume 而不是 bind mount(性能更好)
docker run -v myvolume:/data nginx
3.Docker Daemon 优化
java
// /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn"
],
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 5,
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2",
"live-restore": true,
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 64000,
"Soft": 64000
}
},
"metrics-addr": "127.0.0.1:9323",
"experimental": true
}
6.3 故障排查
1.常见问题诊断
java
# ============ 查看容器日志 ============
# 查看容器日志
docker logs container_name
# 实时查看日志
docker logs -f container_name
# 查看最后 100 行
docker logs --tail 100 container_name
# 查看带时间戳的日志
docker logs -t container_name
# ============ 检查容器状态 ============
# 查看容器详细信息
docker inspect container_name
# 查看容器进程
docker top container_name
# 查看容器端口映射
docker port container_name
# 查看容器资源使用
docker stats container_name
# ============ 进入容器调试 ============
# 进入容器
docker exec -it container_name bash
# 查看容器环境变量
docker exec container_name env
# 查看容器内文件
docker exec container_name cat /etc/os-release
# ============ 网络排查 ============
# 测试容器网络连通性
docker exec container_name ping -c 3 google.com
# 查看容器网络配置
docker exec container_name ip addr
# 查看容器路由表
docker exec container_name ip route
# 查看容器网络命名空间
docker inspect container_name | grep -A 20 NetworkSettings
# ============ 磁盘和存储 ============
# 查看磁盘使用
docker system df
# 查看容器文件系统变更
docker diff container_name
# 查看挂载点
docker inspect container_name | grep -A 10 Mounts
# ============ 清理资源 ============
# 清理所有未使用的镜像、容器、网络
docker system prune -a --volumes
# 清理构建缓存
docker builder prune
# 查看磁盘使用详情
docker system df -v
2.性能监控
java
# 实时查看容器资源使用
docker stats
# 查看指定容器
docker stats container1 container2
# 格式化输出
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# 只显示一次
docker stats --no-stream
# 持续监控并保存到文件
docker stats --no-stream >> stats.log
3.调试技巧
java
# 在 Dockerfile 中添加调试工具
FROM alpine:3.18
# 安装调试工具
RUN apk add --no-cache \
curl \
wget \
tcpdump \
strace \
ltrace \
gdb \
vim \
bash
# 设置调试环境变量
ENV DEBUG=1
ENV LOG_LEVEL=debug
# 保持容器运行(用于调试)
CMD ["tail", "-f", "/dev/null"]
第七部分:生产环境最佳实践
7.1 CI/CD 集成

GitHub Actions 示例
java
# .github/workflows/docker-build.yml
name: Docker Build and Push
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout 代码
uses: actions/checkout@v4
- name: 设置 Docker Buildx
uses: docker/setup-buildx-action@v3
- name: 登录到 Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: 提取元数据
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-
- name: 构建并推送镜像
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
BUILD_DATE=${{ github.event.head_commit.timestamp }}
VCS_REF=${{ github.sha }}
- name: 镜像漏洞扫描
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
format: 'sarif'
output: 'trivy-results.sarif'
- name: 上传扫描结果
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: 'trivy-results.sarif'
7.2 日志管理
java
# docker-compose.yml
version: '3.8'
services:
app:
image: myapp:latest
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "3"
labels: "production,app"
tag: "{{.Name}}/{{.ID}}"
ELK Stack 集成
java
version: '3.8'
services:
elasticsearch:
image: elasticsearch:8.11.0
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes:
- es_data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
networks:
- elk
logstash:
image: logstash:8.11.0
volumes:
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
- ./logstash/pipeline:/usr/share/logstash/pipeline:ro
ports:
- "5044:5044"
networks:
- elk
depends_on:
- elasticsearch
kibana:
image: kibana:8.11.0
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
networks:
- elk
depends_on:
- elasticsearch
networks:
elk:
driver: bridge
volumes:
es_data:
7.3 监控和告警
java
version: '3.8'
services:
# ========== Prometheus ==========
prometheus:
image: prom/prometheus:latest
container_name: prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=200h'
- '--web.enable-lifecycle'
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
ports:
- "9090:9090"
networks:
- monitoring
restart: unless-stopped
# ========== Grafana ==========
grafana:
image: grafana/grafana:latest
container_name: grafana
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning:ro
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin123
- GF_USERS_ALLOW_SIGN_UP=false
ports:
- "3000:3000"
networks:
- monitoring
restart: unless-stopped
depends_on:
- prometheus
# ========== cAdvisor ==========
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
ports:
- "8080:8080"
networks:
- monitoring
restart: unless-stopped
privileged: true
# ========== Node Exporter ==========
node_exporter:
image: prom/node-exporter:latest
container_name: node_exporter
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
ports:
- "9100:9100"
networks:
- monitoring
restart: unless-stopped
# ========== Alertmanager ==========
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
command:
- '--config.file=/etc/alertmanager/alertmanager.yml'
- '--storage.path=/alertmanager'
volumes:
- ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
- alertmanager_data:/alertmanager
ports:
- "9093:9093"
networks:
- monitoring
restart: unless-stopped
networks:
monitoring:
driver: bridge
volumes:
prometheus_data:
grafana_data:
alertmanager_data:
第八部分:Docker 高级应用
8.1 Docker Swarm 集群

Swarm 初始化
java
# ========== 初始化集群 ==========
# 在第一个管理节点上初始化集群
docker swarm init --advertise-addr
# 查看加入集群的命令
docker swarm join-token worker
docker swarm join-token manager
# 在其他节点上加入集群
docker swarm join --token:2377
# ========== 节点管理 ==========
# 查看节点
docker node ls
# 查看节点详情
docker node inspect node1
# 更新节点可用性
docker node update --availability drain node1
# 提升节点为管理节点
docker node promote node1
# 降级节点为工作节点
docker node demote node1
# ========== 服务部署 ==========
# 部署服务
docker service create --name web --replicas 3 -p 80:80 nginx
# 查看服务
docker service ls
# 查看服务详情
docker service ps web
# 扩展服务
docker service scale web=5
# 更新服务
docker service update --image nginx:1.24 web
# 回滚服务
docker service rollback web
# 删除服务
docker service rm web
Swarm Stack
java
# docker-stack.yml
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
resources:
limits:
cpus: '0.50'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
networks:
- webnet
visualizer:
image: dockersamples/visualizer:latest
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints:
- node.role == manager
networks:
- webnet
networks:
webnet:
driver: overlay
# 部署 Stack
docker stack deploy -c docker-stack.yml myapp
# 查看 stacks
docker stack ls
# 查看服务
docker stack services myapp
# 删除 Stack
docker stack rm myapp
8.2 Docker 私有仓库
搭建私有仓库
java
version: '3.8'
services:
registry:
image: registry:2
container_name: docker-registry
ports:
- "5000:5000"
environment:
- REGISTRY_STORAGE_DELETE_ENABLED=true
volumes:
- registry_data:/var/lib/registry
- ./registry/config.yml:/etc/docker/registry/config.yml:ro
restart: unless-stopped
registry-ui:
image: joxit/docker-registry-ui:latest
container_name: registry-ui
ports:
- "8080:80"
environment:
- SINGLE_REGISTRY=true
- REGISTRY_TITLE=My Docker Registry
- DELETE_IMAGES=true
- SHOW_CONTENT_DIGEST=true
- NGINX_PROXY_PASS_URL=http://registry:5000
- SHOW_CATALOG_NB_TAGS=true
- CATALOG_MIN_BRANCHES=1
- CATALOG_MAX_BRANCHES=1
- TAGLIST_PAGE_SIZE=100
- REGISTRY_SECURED=false
- CATALOG_ELEMENTS_LIMIT=1000
depends_on:
- registry
restart: unless-stopped
volumes:
registry_data:
# 启动仓库
docker-compose up -d
# 推送镜像到私有仓库
docker tag myapp:latest localhost:5000/myapp:latest
docker push localhost:5000/myapp:latest
# 拉取镜像
docker pull localhost:5000/myapp:latest
# 删除镜像
DELETE /v2//manifests/
8.3 容器编排工具对比

附录:Docker 命令速查表
镜像命令
java
docker search <镜像名> # 搜索镜像
docker pull <镜像名> # 拉取镜像
docker images # 列出镜像
docker rmi <镜像ID> # 删除镜像
docker tag <镜像ID> <新标签> # 标记镜像
docker push <镜像名> # 推送镜像
docker build -t <标签> . # 构建镜像
docker history <镜像名> # 查看镜像历史
docker inspect <镜像名> # 查看镜像详情
docker save -o file.tar <镜像> # 导出镜像
docker load -i file.tar # 导入镜像
容器命令
java
docker run <镜像> # 运行容器
docker ps # 列出运行中的容器
docker ps -a # 列出所有容器
docker stop <容器ID> # 停止容器
docker start <容器ID> # 启动容器
docker restart <容器ID> # 重启容器
docker rm <容器ID> # 删除容器
docker exec -it <容器ID> bash # 进入容器
docker logs <容器ID> # 查看日志
docker inspect <容器ID> # 查看详情
docker stats <容器ID> # 查看资源使用
docker cp <文件> <容器>:<路径> # 复制文件到容器
docker commit <容器ID> <新镜像> # 容器提交为镜像
网络命令
java
docker network ls # 列出网络
docker network create <网络名> # 创建网络
docker network inspect <网络名> # 查看网络详情
docker network rm <网络名> # 删除网络
docker network connect <网络> <容器> # 连接容器到网络
docker network disconnect <网络> <容器> # 断开连接
卷命令
java
docker volume ls # 列出卷
docker volume create <卷名> # 创建卷
docker volume inspect <卷名> # 查看卷详情
docker volume rm <卷名> # 删除卷
docker volume prune # 删除未使用的卷
系统命令
java
docker info # 查看系统信息
docker version # 查看版本
docker system df # 查看磁盘使用
docker system prune # 清理未使用的资源
docker system prune -a --volumes # 完全清理
