Skip to content

Docker 入门到项目实战

1. Docker 核心概念与快速入门

1.1 为什么需要 Docker?

传统部署痛点:

  • 环境差异:开发、测试、生产环境不一致
  • 配置复杂:依赖安装、环境变量配置繁琐
  • 部署困难:手动部署容易出错,回滚困难
  • 资源浪费:虚拟机资源利用率低

Docker 解决方案:

  • 环境一致性:镜像包含完整运行环境
  • 快速部署:秒级启动,一键部署
  • 资源高效:容器共享内核,轻量级虚拟化
  • 版本控制:镜像版本化管理

1.2 Docker 核心概念

概念说明类比
镜像(Image)只读模板,包含应用运行环境软件安装包
容器(Container)镜像的运行实例安装好的软件
仓库(Repository)镜像存储和分发中心应用商店
数据卷(Volume)数据持久化存储U 盘/移动硬盘

1.3 Docker vs 虚拟机

核心差异:

  • 启动速度:容器秒级 vs 虚拟机分钟级
  • 资源占用:容器共享内核 vs 虚拟机独立 OS
  • 性能损耗:容器几乎无损耗 vs 虚拟机有明显损耗

1.4 快速入门:部署 MySQL

传统方式(复杂):

bash
# 下载安装包 → 配置环境 → 编译安装 → 配置服务

Docker 方式(简单):

bash
docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  mysql:8.0

命令解读:

  • -d:后台运行
  • --name:容器名称
  • -p:端口映射(宿主机:容器)
  • -e:环境变量设置
  • mysql:8.0:镜像名称和版本

2. Docker 安装与配置

2.1 环境要求与安装

系统要求:

  • CentOS 7+ / Ubuntu 16.04+
  • 内核版本 3.10+
  • 64 位操作系统

安装步骤:

bash
# 卸载旧版本
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine

# 安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

# 配置阿里云镜像源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安装Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io

# 启动服务
sudo systemctl start docker
sudo systemctl enable docker

2.2 配置镜像加速器

bash
# 创建配置目录
sudo mkdir -p /etc/docker

# 配置镜像加速器
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://registry.dockermirror.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}
EOF

# 重启服务
sudo systemctl daemon-reload
sudo systemctl restart docker

2.3 验证安装

bash
# 查看版本
docker --version

# 运行测试容器
docker run hello-world

# 查看服务状态
systemctl status docker

3. Docker 核心命令详解

3.1 镜像管理命令

命令说明示例
docker search搜索镜像docker search redis
docker pull拉取镜像docker pull redis:7.0
docker images查看镜像docker images
docker rmi删除镜像docker rmi redis
docker build构建镜像docker build -t myapp .

实用技巧:

bash
# 仅显示镜像ID
docker images -q

# 删除所有镜像
docker rmi -f $(docker images -q)

# 查看镜像历史
docker history image_name

3.2 容器管理命令

命令说明示例
docker run创建容器docker run -d nginx
docker ps查看容器docker ps -a
docker start/stop启停容器docker stop mynginx
docker rm删除容器docker rm -f mynginx
docker exec进入容器docker exec -it mynginx bash

容器类型:

bash
# 交互式容器(临时调试)
docker run -it --name=mycentos centos:7 /bin/bash

# 守护式容器(服务部署)
docker run -d --name=mynginx nginx:latest

3.3 实用命令别名

bash
# 添加到 ~/.bashrc
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
alias dis='docker images'
alias dc='docker compose'

# 生效配置
source ~/.bashrc

4. 数据卷与持久化存储

4.1 数据卷核心概念

为什么需要数据卷?

  • 容器数据持久化
  • 容器间数据共享
  • 备份和迁移

4.2 数据卷操作

bash
# 创建数据卷
docker volume create mydata

# 查看数据卷
docker volume ls

# 查看详情
docker volume inspect mydata

# 删除数据卷
docker volume rm mydata
docker volume prune  # 清理未使用数据卷

4.3 挂载方式

1. 数据卷挂载:

bash
docker run -d --name=redis \
  -v redis-data:/data \
  redis:7.0

2. 目录挂载:

bash
docker run -d --name=nginx \
  -v /host/nginx.conf:/etc/nginx/nginx.conf \
  -v /host/html:/usr/share/nginx/html \
  nginx:latest

3. 匿名卷挂载:

bash
docker run -d --name=mysql \
  -v /var/lib/mysql \
  mysql:8.0

4.4 MySQL 数据持久化实战

bash
# 创建目录结构
mkdir -p ~/mysql/{data,conf,init}

# 运行MySQL容器
docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v ~/mysql/data:/var/lib/mysql \
  -v ~/mysql/conf:/etc/mysql/conf.d \
  -v ~/mysql/init:/docker-entrypoint-initdb.d \
  mysql:8.0

5. 自定义镜像与 Dockerfile

5.1 镜像分层结构

优势:

  • 层复用,减少存储空间
  • 构建缓存,加速镜像构建
  • 版本管理,易于回滚

5.2 Dockerfile 核心指令

指令说明示例
FROM基础镜像FROM openjdk:11-jre
WORKDIR工作目录WORKDIR /app
COPY复制文件COPY target/app.jar app.jar
RUN执行命令RUN apt-get update
EXPOSE暴露端口EXPOSE 8080
ENV环境变量ENV JAVA_OPTS=""
ENTRYPOINT启动命令ENTRYPOINT ["java","-jar","app.jar"]

5.3 Spring Boot 应用 Dockerfile

dockerfile
# 多阶段构建,减小镜像体积
FROM maven:3.8-openjdk-11 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

FROM openjdk:11-jre-slim
WORKDIR /app

# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 复制应用
COPY --from=builder /app/target/*.jar app.jar

# 安全配置
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

5.4 镜像构建与推送

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

# 测试运行
docker run -d -p 8080:8080 myapp:1.0

# 推送到镜像仓库
docker tag myapp:1.0 registry.example.com/myapp:1.0
docker push registry.example.com/myapp:1.0

6. Docker 网络管理

6.1 网络类型

网络类型说明适用场景
bridge默认网络,NAT 模式单机容器通信
host共享宿主机网络高性能需求
none无网络安全隔离
overlay跨主机网络集群部署

6.2 网络操作命令

bash
# 查看网络
docker network ls

# 创建网络
docker network create mynet

# 查看网络详情
docker network inspect mynet

# 连接容器到网络
docker network connect mynet myapp

# 断开网络连接
docker network disconnect mynet myapp

6.3 自定义网络实战

bash
# 创建自定义网络
docker network create app-network

# 运行MySQL加入网络
docker run -d --name mysql --network app-network \
  -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0

# 运行应用加入网络
docker run -d --name myapp --network app-network \
  -p 8080:8080 myapp:1.0

优势:

  • 容器间通过名称直接通信
  • 网络隔离更安全
  • DNS 自动服务发现

7. 项目部署实战

7.1 后端应用部署

1. 准备应用镜像:

dockerfile
FROM openjdk:11-jre-slim
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY target/mall-service.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

2. 构建与运行:

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

# 运行容器
docker run -d --name mall \
  --network mall-net \
  -p 8080:8080 \
  mall:1.0

7.2 前端应用部署

Nginx 配置:

nginx
server {
    listen 18080;
    server_name localhost;

    location / {
        root /usr/share/nginx/html/mall-portal;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
}

server {
    listen 18081;
    server_name localhost;

    location / {
        root /usr/share/nginx/html/mall-admin;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
}

运行 Nginx:

bash
docker run -d --name nginx \
  -p 18080:18080 \
  -p 18081:18081 \
  -v /path/to/nginx.conf:/etc/nginx/nginx.conf \
  -v /path/to/html:/usr/share/nginx/html \
  nginx:latest

8. Docker Compose 应用编排

8.1 核心概念

解决的问题:

  • 多服务依赖管理
  • 服务启动顺序控制
  • 统一配置管理
  • 一键部署

8.2 安装 Docker Compose

bash
# 下载最新版本
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

# 验证安装
docker compose version

8.3 docker-compose.yml 详解

yaml
version: "3.8"

services:
  mysql:
    image: mysql:8.0
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      TZ: Asia/Shanghai
    volumes:
      - mysql-data:/var/lib/mysql
      - ./mysql/conf:/etc/mysql/conf.d
    networks:
      - app-net

  redis:
    image: redis:7.0
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    networks:
      - app-net

  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: mall-app
    ports:
      - "8080:8080"
    environment:
      SPRING_PROFILES_ACTIVE: prod
    depends_on:
      - mysql
      - redis
    networks:
      - app-net

  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./html:/usr/share/nginx/html
    depends_on:
      - app
    networks:
      - app-net

volumes:
  mysql-data:
  redis-data:

networks:
  app-net:
    driver: bridge

8.4 Compose 常用命令

bash
# 启动所有服务
docker compose up -d

# 停止所有服务
docker compose down

# 查看服务状态
docker compose ps

# 查看服务日志
docker compose logs -f app

# 重启特定服务
docker compose restart app

# 扩展服务实例
docker compose up -d --scale app=3

9. 生产环境最佳实践

9.1 安全最佳实践

1. 使用非 root 用户:

dockerfile
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser

2. 镜像安全扫描:

bash
docker scan myapp:1.0

3. 资源限制:

yaml
services:
  app:
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "1.0"

9.2 性能优化

1. 镜像优化:

  • 使用多阶段构建减小镜像体积
  • 合并 RUN 指令减少镜像层
  • 使用.dockerignore 排除无用文件

2. 容器配置:

yaml
services:
  app:
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

9.3 监控与日志

日志管理:

bash
# 查看实时日志
docker compose logs -f

# 查看特定服务日志
docker logs -f --tail 100 container_name

# 日志驱动配置
docker run --log-driver=json-file --log-opt max-size=10m app

10. 常见问题与解决方案

10.1 容器连接问题

问题: 容器间网络不通 解决: 使用自定义网络,确保容器在同一网络

bash
# 创建网络
docker network create myapp-network

# 运行容器时指定网络
docker run -d --name app --network myapp-network myapp

10.2 数据持久化问题

问题: 容器重启后数据丢失 解决: 使用数据卷或目录挂载

bash
docker run -d --name mysql \
  -v mysql-data:/var/lib/mysql \
  mysql:8.0

10.3 资源限制问题

问题: 容器占用过多资源 解决: 设置资源限制

bash
docker run -d --name app \
  --memory=512m \
  --cpus=1.0 \
  myapp