一、Docker 是什么?为什么需要它?
1.1 诞生的背景
在没有Docker之前,开发和运维面临一个经典难题:环境不一致。
- 开发在自己电脑上跑得好好的,一放到测试/生产环境就报错
- 换一台服务器,就要重新装系统、装依赖、配配置,步骤繁琐又容易出错
- 项目版本一多,环境差异、依赖冲突、兼容性问题层出不穷
Docker正是为了解决这个痛点而诞生的------它提供了一套标准化的环境打包与运行方案,把代码、依赖、配置、系统环境全部打包在一起,形成一个可移植的容器。
1.2 Docker 的定义
Docker是一个开源的应用容器引擎,基于Go语言开发。它可以让开发者打包应用及其依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上。
核心目标 :Build, Ship and Run Any App, Anywhere ------ 一次封装,到处运行。
1.3 Docker vs 虚拟机
| 对比维度 | 虚拟机(VM) | Docker 容器 |
|---|---|---|
| 隔离级别 | 硬件级虚拟化,隔离更彻底 | 进程级隔离,共享宿主机内核 |
| 启动速度 | 分钟级 | 秒级(数量级差距) |
| 资源利用率 | 较低(每个VM独占OS) | 高(共享内核,轻量级) |
| 体积 | GB级别 | MB级别 |
| 性能开销 | 大 | 极低 |
1.4 Docker 的五大优势
- 轻量级 ------ 共享内核,启动快,资源占用少
- 可移植性 ------ 跨平台运行,无需关注底层OS差异
- 快速部署 ------ 简单打包、分发、部署
- 弹性扩展 ------ 快速创建/启停容器实例,实现负载均衡
- 环境隔离 ------ 容器间相互独立,安全稳定
二、Docker 核心架构与概念
2.1 C/S 架构
Docker是一个客户端-服务器(C/S)架构程序:
- Docker Client:用户界面,接受命令并与Daemon通信
- Docker Daemon:运行在宿主机的后台守护进程,完成所有工作
- RESTful API:客户端和守护进程之间的通信协议
2.2 四大核心概念
| 概念 | 类比 | 说明 |
|---|---|---|
| 镜像(Image) | 软件安装包 | 只读模板,包含运行应用所需的全部环境 |
| 容器(Container) | 已安装好的软件 | 镜像的运行实例,可启动、停止、删除 |
| 仓库(Registry) | 手机应用商店 | 存放和下载镜像的平台(如Docker Hub) |
| 数据卷(Volume) | 电脑的D盘 | 持久化数据的工具,容器删除后数据不丢失 |
镜像与容器的关系 :类似面向对象中类与对象的关系。一个镜像可以创建多个容器。
2.3 两个核心工具
- Dockerfile ------ 自定义镜像的"构建脚本",纯文本文件,包含一系列构建指令
- Docker Compose ------ 多容器的"一键管理工具",通过YAML配置文件定义多个关联容器
三、Docker 安装
3.1 CentOS 安装
要求内核版本高于3.10,安装步骤:
bash
# 1. 卸载旧版本
sudo yum remove docker docker-client docker-client-latest \
docker-common docker-latest docker-latest-logrotate \
docker-logrotate docker-engine
# 2. 安装yum-utils并设置阿里云yum源
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 3. 安装Docker CE
sudo yum install -y docker-ce docker-ce-cli containerd.io
# 4. 启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
3.2 Win11 安装(依赖WSL2)
Win11下运行Docker需依赖WSL2,安装前准备:
-
开启虚拟化:任务管理器 → 性能 → 查看虚拟化是否已启用(未启用需进入BIOS开启)
-
启用WSL和虚拟机平台 :
powershelldism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart -
更新WSL内核 :从 GitHub WSL Releases 下载最新版本安装
-
安装Docker Desktop:从官网下载安装包,默认安装即可
3.3 Ubuntu 安装
bash
# 卸载旧版本
sudo apt remove -y docker docker-engine docker.io containerd runc
# 按照Docker官方文档安装最新版本
# https://docs.docker.com/engine/install/ubuntu/
# 免sudo运行
sudo usermod -aG docker $USER
# 注意:执行后需重新登录
3.4 镜像加速器配置(必须配置)
国内下载Docker Hub镜像速度慢,需配置镜像加速器:
Linux(修改 /etc/docker/daemon.json):
json
{
"registry-mirrors": [
"https://docker.xuanyuan.me",
"https://docker.1ms.run",
"https://docker.m.daocloud.io"
]
}
Win11(Docker Desktop) :设置 → Docker Engine → 添加 registry-mirrors 配置 → Apply & Restart
四、Docker 常用命令速查
4.1 镜像管理
| 命令 | 作用 | 示例 |
|---|---|---|
docker pull <镜像名:版本> |
拉取镜像 | docker pull mysql:8.0.45 |
docker images |
查看本地所有镜像 | docker images |
docker rmi <镜像ID/名> |
删除单个镜像 | docker rmi mysql:8.0.45 |
docker search <关键词> |
搜索Docker Hub镜像 | docker search mysql |
docker build -t <名:版本> . |
基于Dockerfile构建镜像 | docker build -t my-app:1.0 . |
docker save -o <文件.tar> <镜像> |
导出镜像为压缩包 | docker save -o mysql8.tar mysql:8.0.45 |
docker load -i <压缩包.tar> |
导入镜像压缩包 | docker load -i mysql8.tar |
4.2 容器管理
| 命令 | 作用 | 示例 |
|---|---|---|
docker run [参数] <镜像> |
创建并启动容器 | docker run -d --name mysql-db -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.45 |
docker ps |
查看运行中的容器 | docker ps |
docker ps -a |
查看所有容器(含已停止) | docker ps -a |
docker start <容器名> |
启动已停止的容器 | docker start mysql-db |
docker stop <容器名> |
停止容器 | docker stop mysql-db |
docker restart <容器名> |
重启容器 | docker restart mysql-db |
docker rm <容器名> |
删除已停止的容器 | docker rm mysql-db |
docker rm -f <容器名> |
强制删除运行中的容器 | docker rm -f mysql-db |
docker exec -it <容器名> bash |
进入容器交互终端 | docker exec -it mysql-db bash |
docker logs <容器名> |
查看容器日志 | docker logs -f mysql-db |
docker inspect <容器名> |
查看容器详细信息 | docker inspect mysql-db |
docker cp <容器:路径> <宿主路径> |
容器与宿主机互相复制文件 | docker cp mysql-db:/etc/mysql my-local-dir |
docker run 常用参数说明:
| 参数 | 说明 |
|---|---|
-d |
后台运行(detach) |
--name |
给容器命名 |
-p 宿主端口:容器端口 |
端口映射 |
-e KEY=VALUE |
设置环境变量 |
-v 宿主路径:容器路径 |
数据卷挂载 |
--net |
网络模式(bridge/host/none/container) |
--restart always |
容器自动重启策略 |
4.3 Docker Compose 常用命令
| 命令 | 作用 |
|---|---|
docker compose up -d |
后台启动所有服务 |
docker compose up -d --build |
强制重建镜像并启动 |
docker compose stop |
停止所有服务(保留容器) |
docker compose down |
停止并删除容器+网络(保留数据卷) |
docker compose down -v |
停止并删除容器+网络+数据卷 |
docker compose ps |
查看运行状态 |
docker compose logs <服务名> |
查看服务日志 |
docker compose exec <服务名> <命令> |
在运行中的容器执行命令 |
docker compose build <服务名> |
仅构建镜像 |
五、Dockerfile 构建镜像
5.1 常用指令一览
| 指令 | 用途 | 说明 |
|---|---|---|
FROM |
指定基础镜像 | 必须是第一条指令 |
RUN |
构建阶段执行命令 | 结果打包进镜像 |
ADD |
添加文件 | 支持URL和自动解压 |
COPY |
拷贝文件 | 不支持URL和自动解压 |
CMD |
容器启动后执行命令 | 仅最后一个有效 |
ENTRYPOINT |
容器入口点 | 与CMD配合使用 |
EXPOSE |
声明对外服务端口 | |
WORKDIR |
指定工作路径 | |
ENV |
设置环境变量 | |
VOLUME |
指定持久化存储挂载点 | |
USER |
设置启动用户 |
关键区别 :RUN 在构建阶段执行,结果打包进镜像;CMD 在容器启动后执行。一个Dockerfile可有多个RUN但仅一个CMD。
5.2 微服务镜像构建实战
以Java微服务为例:
dockerfile
# 基础镜像
FROM java:8
# 添加应用jar包
ADD tulingmall-member-0.0.5.jar /tulingmall-member-0.0.5.jar
# 暴露端口
EXPOSE 8877
# 入口点,支持JVM参数
ENTRYPOINT java ${JAVA_OPTS} -jar /tulingmall-member-0.0.5.jar
以Python应用为例:
dockerfile
# 指定基础镜像
FROM python:3.12
# 设置工作目录
WORKDIR /app
# 复制项目文件
COPY . /app
# 安装依赖
RUN pip install pymysql cryptography
# 启动命令
CMD ["python", "test_mysql1.py"]
5.3 启动容器时传递参数
bash
docker run -d -p 8877:8877 \
-e SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=192.168.65.174:8848 \
-e JAVA_OPTS='-Xmx1g -Xms1g -XX:MaxMetaspaceSize=512m' \
--cap-add=SYS_PTRACE \
tulingmall-member:0.0.5
六、Docker Compose 编排详解
6.1 为什么需要 Compose?
Docker解决了服务打包安装问题,但服务数量增多后带来三大痛点:
- 多次使用Dockerfile、Build、Image命令或从DockerHub拉取镜像
- 需要创建多个Container,多次编写启动命令
- Container之间互相依赖的管理和编排困难
Compose 通过一个YAML配置文件定义所有服务,一条命令即可创建并启动全部服务。
6.2 三层管理结构
- 工程(Project):运行目录下所有文件组成一个工程
- 服务(Service):一个工程包含多个服务,每个服务定义了容器运行的配置
- 容器(Container):一个服务可包括多个容器实例
服务间通信 :同一Compose内部容器之间可以用服务名相互访问(服务名相当于hostname)。服务扩容后,Docker底层通过LVS等技术实现负载均衡。
6.3 docker-compose.yml 常用指令
| 指令 | 功能 | 关键要点 |
|---|---|---|
image |
指定镜像 | 本地不存在时自动pull |
build |
指定Dockerfile路径 | 支持context、dockerfile、args子参数 |
command |
覆盖容器启动命令 | 支持字符串和list格式 |
links |
链接到其他服务容器 | 格式:SERVICE:ALIAS |
external_links |
链接到Compose外部容器 | 用于共享容器或公共服务 |
ports |
暴露端口到宿主机 | 格式:宿主端口:容器端口 |
expose |
仅向连接服务暴露端口 | 不暴露给宿主机 |
volumes |
卷挂载路径 | 支持绝对路径、相对路径、命名卷、只读(ro) |
volumes_from |
从其他服务挂载卷 | 可指定只读(ro)或读写(rw) |
environment |
设置环境变量 | 支持数组和字典格式 |
env_file |
从文件获取环境变量 | 与environment冲突时以environment为准 |
extends |
继承另一个服务 | 基于已有服务扩展 |
depends_on |
服务依赖 | 控制启动顺序,支持健康检查条件 |
restart |
重启策略 | always/on-failure/no |
healthcheck |
健康检查 | 确保服务真正就绪 |
networks |
网络配置 | 自定义bridge网络实现容器互通 |
6.4 实战:Python + MySQL 多容器编排
yaml
services:
# MySQL 服务容器
mysql-db:
image: mysql:8.0.45
restart: always
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_DATABASE: "test_db"
MYSQL_INITDB_ARGS: "--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci"
ports:
- "9999:3306"
volumes:
- D:/mysql-data:/var/lib/mysql
networks:
- app-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p123456"]
interval: 3s
timeout: 3s
retries: 10
start_period: 5s
# Python 应用容器
python-app:
build: .
depends_on:
mysql-db:
condition: service_healthy # 等待MySQL健康检查通过后再启动
environment:
MYSQL_HOST: "mysql-db" # 容器间用服务名通信
MYSQL_PORT: "3306"
MYSQL_USER: "root"
MYSQL_PASSWORD: "123456"
MYSQL_DB: "test_db"
networks:
- app-network
networks:
app-network:
driver: bridge
关键技术点:
depends_on+condition: service_healthy:确保MySQL完全就绪后再启动Python容器healthcheck:通过mysqladmin ping检测MySQL是否真正可用networks:自定义bridge网络,容器间通过服务名互通volumes:数据持久化,容器删除后数据不丢失
七、Docker Compose 编排电商微服务项目
7.1 基础设施编排(Nacos + MySQL)
首先编排基础设施环境:
yaml
version: '3'
services:
mysql:
image: mysql:8.0
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
- /data/mysql-data:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
nacos:
image: nacos/nacos-server:v2.1.0
ports:
- 8848:8848
- 9848:9848
- 9555:9555
environment:
MODE: standalone
SPRING_DATASOURCE_PLATFORM: mysql
MYSQL_SERVICE_HOST: mysql
MYSQL_SERVICE_DB_NAME: nacos_config
MYSQL_SERVICE_USER: root
MYSQL_SERVICE_PASSWORD: root
depends_on:
- mysql
restart: always
启动命令:
bash
docker compose -f docker-compose-env.yml up -d
7.2 微服务应用编排
编排电商微服务的完整配置模式:
yaml
services:
tulingmall-authcenter:
image: tulingmall-authcenter:0.0.5
ports:
- 9999:9999
volumes:
- /etc/localtime:/etc/localtime:ro # 同步宿主机时间
- /skywalking-agent:/skywalking-agent # 挂载链路追踪Agent
environment:
SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR: 192.168.65.174:8848
JAVA_TOOL_OPTIONS: "-Xmx1g -Xms1g -XX:MaxMetaspaceSize=512m -javaagent:/skywalking-agent/skywalking-agent.jar"
cap_add: SYS_PTRACE # 支持JDK诊断命令
restart: always
tulingmall-gateway:
image: tulingmall-gateway:0.0.5
ports:
- 8888:8888
depends_on:
- tulingmall-authcenter # 网关依赖认证中心
volumes:
- /etc/localtime:/etc/localtime:ro
- /skywalking-agent:/skywalking-agent
environment:
SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR: 192.168.65.174:8848
JAVA_TOOL_OPTIONS: "-Xmx1g -Xms1g -XX:MaxMetaspaceSize=512m -javaagent:/skywalking-agent/skywalking-agent.jar"
cap_add: SYS_PTRACE
restart: always
# ... 其他微服务(member、product、order、cart等)配置类似
7.3 编排的微服务清单
| 微服务 | 端口 | 说明 |
|---|---|---|
| tulingmall-authcenter | 9999 | 认证中心 |
| tulingmall-gateway | 8888 | API网关 |
| tulingmall-member | 8877 | 会员服务 |
| tulingmall-product | 8866 | 商品服务 |
| tulingmall-order-curr | 8844 | 订单服务 |
| tulingmall-cart | 8855 | 购物车服务 |
| tulingmall-unqid | 8833 | 唯一ID生成服务 |
| tulingmall-search | 8054 | 搜索服务 |
7.4 每个微服务的共同配置模式
- volumes:同步宿主机时间 + 挂载SkyWalking Agent
- environment:Nacos配置中心地址 + JVM参数 + SkyWalking链路追踪
- cap_add: SYS_PTRACE:使容器内支持jinfo、jmap等JDK诊断命令
- depends_on:控制服务启动顺序(如gateway依赖authcenter)
八、镜像仓库管理
8.1 阿里云远程仓库
bash
# 1. 登录阿里云镜像仓库
docker login --username=你的用户名 registry.cn-hangzhou.aliyuncs.com
# 2. 给镜像打标签
docker tag tulingmall-member:0.0.5 registry.cn-hangzhou.aliyuncs.com/命名空间/仓库名:标签
# 3. 推送镜像
docker push registry.cn-hangzhou.aliyuncs.com/命名空间/仓库名:标签
8.2 私有镜像仓库搭建
使用Docker Compose搭建私有仓库:
yaml
version: '3'
services:
registry:
container_name: docker-registry
image: registry:2
ports:
- 5000:5000
volumes:
- /data/docker-registry:/var/lib/registry
bash
# 启动私有仓库
docker compose up -d
# 配置daemon.json允许HTTP访问
# /etc/docker/daemon.json 中添加:
{
"insecure-registries": ["你的仓库地址:5000"]
}
# 验证镜像是否推送成功
curl -X GET http://仓库地址:5000/v2/_catalog
九、环境移植:从Win11到Ubuntu
9.1 在线下载式(推荐)
bash
# 1. 上传docker-compose.yml到Ubuntu
scp docker-compose.yml user@ubuntu-ip:/home/user/docker-python-mysql/
# 2. 修改volumes路径适配Ubuntu
# 将 D:/mysql-data 改为 /home/user/mysql-data
# 3. 一键启动
cd /home/user/docker-python-mysql
docker compose up -d
# 4. 验证
docker compose logs python-app
9.2 离线同步式(无网络环境)
bash
# === Win11 上操作 ===
# 打包镜像
docker save mysql:8.0.45 -o ./mysql-8.0.45.tar
docker save docker-python-mysql-python-app:latest -o ./python-app.tar
# 上传 tar 文件和 docker-compose.yml 到 Ubuntu
# === Ubuntu 上操作 ===
# 导入镜像
docker load -i ./mysql-8.0.45.tar
docker load -i ./python-app.tar
# 修改 docker-compose.yml:将 build: . 替换为 image: docker-python-mysql-python-app:latest
# 修改 volumes 路径
# 启动(全程离线)
docker compose up -d
十、常见问题排查
| 问题 | 解决方案 |
|---|---|
| Win11启动Docker失败,提示"WSL2未配置" | 确保虚拟化开启、WSL2功能和内核已安装,重启电脑 |
| Python连接MySQL失败,"Connection refused" | 检查MySQL容器是否启动(docker ps),确认端口映射正确 |
| docker-compose.yml格式错误 | 检查缩进(必须用空格不能用Tab),冒号后加空格,引号为英文引号 |
| Ubuntu下docker命令"权限不足" | 执行 sudo usermod -aG docker $USER,重新登录 |
| 容器启动后立即退出 | 使用 docker logs <容器名> 查看日志排查原因 |
| 端口冲突 | 修改 -p 参数的宿主机端口,或先停止占用端口的服务 |
十一、总结
本文系统梳理了Docker从入门到实战的完整知识链路:
- 基础篇:Docker核心概念(镜像、容器、仓库、数据卷)、C/S架构、与虚拟机的区别
- 安装篇:CentOS、Win11(WSL2)、Ubuntu三种平台的安装与卸载
- 命令篇:镜像管理、容器管理、Docker Compose命令速查
- 构建篇:Dockerfile指令详解、Java/Python微服务镜像构建实战
- 编排篇:Docker Compose YAML指令详解、电商微服务项目完整编排
- 仓库篇:阿里云远程仓库和私有仓库的搭建与使用
- 移植篇:在线下载式和离线同步式两种环境移植方案
- 排障篇:常见问题与解决方案
Docker的核心价值在于**"一次封装,到处运行"**,配合Docker Compose可以实现多容器的一键编排和管理。在实际的微服务项目中,Docker已经成为不可或缺的基础设施工具。