本文按「基础安装→核心操作→数据管理→网络互联→镜像构建→编排部署」的逻辑分层讲解,每个模块包含概念 + 命令 + 实战案例 + 实用技巧,既是入门教程也是日常速查手册。
模块一:Docker 基础(安装 + 核心概念)
一、Docker 安装(主流系统,补充二进制安装)
Docker 分为 CE(社区版,免费)和 EE(企业版),日常使用 CE 即可。
1. Linux 安装(CentOS 7/8 为例)
方式 1:YUM 安装(推荐,自动处理依赖)
# 1. 卸载旧版本(如有)
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2. 安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 3. 添加 Docker 源(官方源/阿里云源二选一)
# 官方源
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 阿里云源(国内更快)
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 4. 安装 Docker CE(指定版本更稳定,如 24.0.7)
sudo yum install -y docker-ce-24.0.7 docker-ce-cli-24.0.7 containerd.io
# 5. 启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
# 6. 验证安装(输出版本即成功)
docker --version
方式 2:二进制文件安装(适合无网络 / 定制化场景)
# 1. 下载二进制包(替换为对应版本,官网:https://download.docker.com/linux/static/stable/x86_64/)
wget https://download.docker.com/linux/static/stable/x86_64/docker-24.0.7.tgz
# 2. 解压包
tar -zxvf docker-24.0.7.tgz
# 3. 将二进制文件复制到系统 PATH 目录
sudo cp docker/* /usr/bin/
# 4. 创建 systemd 服务文件(实现开机自启/进程管理)
sudo vim /usr/lib/systemd/system/docker.service
docker.service 内容:
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service containerd.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
[Install]
WantedBy=multi-user.target
# 5. 启动 Docker 服务
sudo systemctl daemon-reload # 重载 systemd 配置
sudo systemctl start docker
sudo systemctl enable docker
# 6. 验证安装
docker --version
2. Windows/Mac 安装
直接下载「Docker Desktop」:
- Windows:https://www.docker.com/products/docker-desktop/(需开启 Hyper-V 或 WSL2,Win10/11 专业版推荐 Hyper-V,家庭版用 WSL2)
- Mac:https://www.docker.com/products/docker-desktop/(Intel/M1/M2 均支持)安装后启动,终端输入
docker --version验证。
3. 权限配置(避免每次用 sudo)
sudo usermod -aG docker $USER # 将当前用户加入 docker 组
newgrp docker # 立即生效(无需重启)
# 验证:重启终端后执行 docker ps,无权限报错即成功
二、Docker 核心概念
| 概念 | 通俗解释 | 核心特点 |
|---|---|---|
| 镜像(Image) | 容器的「模板」,包含运行应用所需的代码、依赖、配置(如 nginx 镜像) | 只读、分层存储、可复用 |
| 容器(Container) | 镜像的「运行实例」,是独立的运行环境(启动镜像即创建容器) | 可读写、独立隔离、生命周期可控 |
| 数据卷(Volume) | 用于容器数据持久化的目录,独立于容器生命周期 | 持久化、可共享、跨容器使用 |
| 仓库(Registry) | 存储镜像的仓库(如 Docker Hub 公有仓库,Harbor 私有仓库) | 拉取 / 推送镜像、私有 / 公有部署 |
| Dockerfile | 构建自定义镜像的「脚本文件」,定义镜像的构建步骤 | 代码化构建、可版本控制、可复用 |
| Docker Compose | 多容器编排工具,通过 yaml 文件管理多个关联容器(如前端 + 后端 + 数据库) | 一键启停、统一配置、依赖管理 |
模块二:Docker 核心基础操作(细化版)
一、镜像操作(核心命令 + 实用技巧)
| 命令 | 作用 | 示例 | 注意事项 |
|---|---|---|---|
docker pull 镜像名:标签 |
拉取镜像(默认从 Docker Hub) | docker pull nginx:1.24 |
标签省略默认拉取 latest(不稳定),建议指定版本 |
docker images |
查看本地所有镜像 | docker images |
加 -q 只显示镜像 ID:docker images -q |
docker rmi 镜像ID/镜像名 |
删除镜像(需先删依赖容器) | docker rmi nginx:1.24 |
强制删除:docker rmi -f 镜像ID(谨慎,避免删错) |
docker save -o 文件名.tar 镜像 |
导出镜像为压缩包 | docker save -o nginx.tar nginx:1.24 |
可批量导出:docker save -o apps.tar nginx:1.24 mysql:8.0 |
docker load -i 文件名.tar |
导入本地镜像包 | docker load -i nginx.tar |
导入后自动保留原标签,无需重新打标签 |
docker search 镜像名 |
搜索 Docker Hub 镜像 | docker search mysql |
加 --filter=stars=1000 筛选高星镜像:docker search --filter=stars=1000 mysql |
docker tag 原镜像 新镜像:标签 |
给镜像打新标签(用于推送私有仓库) | docker tag nginx:1.24 my-registry/nginx:1.24 |
推送前必须打仓库地址标签 |
docker push 镜像名:标签 |
推送镜像到仓库 | docker push my-registry/nginx:1.24 |
需先登录仓库:docker login 仓库地址 |
实用技巧:清理无用镜像
# 清理悬空镜像(无标签的镜像)
docker rmi $(docker images -f "dangling=true" -q)
# 清理所有未使用的镜像(谨慎)
docker image prune -a
二、容器操作(核心命令 + 实战场景)
1. 基础操作(高频)
| 命令 | 作用 | 示例 | 扩展说明 |
|---|---|---|---|
docker run [参数] 镜像 |
创建并启动容器 | docker run -d -p 80:80 --name nginx nginx |
核心参数见下表 |
docker ps |
查看运行中的容器 | docker ps |
加 -a 查看所有容器(含停止的);加 -q 只显示 ID |
docker start/stop/restart 容器ID/名 |
启动 / 停止 / 重启容器 | docker restart nginx |
批量操作:docker start $(docker ps -aq)(启动所有容器) |
docker rm 容器ID/名 |
删除容器(需先停止) | docker rm nginx |
强制删除运行中容器:docker rm -f nginx |
docker exec -it 容器ID/名 命令 |
进入容器执行命令(交互模式) | docker exec -it nginx /bin/bash |
非交互执行:docker exec nginx ls /usr/share/nginx/html |
docker logs -f 容器ID/名 |
实时查看容器日志 | docker logs -f nginx |
加 --tail=100 只看最后 100 行:docker logs --tail=100 -f nginx |
docker inspect 容器ID/名 |
查看容器详细信息(IP、挂载等) | docker inspect nginx |
过滤查看 IP:docker inspect -f '{``{.NetworkSettings.IPAddress}}' nginx |
docker rename 旧名 新名 |
容器重命名 | docker rename nginx nginx-proxy |
重命名不影响容器运行 |
docker cp 主机路径 容器ID:容器路径 |
主机→容器拷贝文件 | docker cp index.html nginx:/usr/share/nginx/html |
反向拷贝(容器→主机):docker cp nginx:/usr/share/nginx/html/index.html ./ |
docker export 容器ID -o 文件名.tar |
导出容器为镜像包(仅含文件系统) | docker export nginx -o nginx-container.tar |
与 save 区别:save 存镜像(分层),export 存容器(扁平) |
docker import 文件名.tar 新镜像:标签 |
导入容器包为镜像 | docker import nginx-container.tar my-nginx:1.0 |
导入后需重新指定启动命令 |
2. docker run 核心参数(细化说明)
| 参数 | 作用 | 示例 | 实用场景 |
|---|---|---|---|
-d |
后台运行容器(守护进程模式) | -d |
生产环境必加,避免终端关闭容器停止 |
-p |
端口映射(主机:容器) | -p 8080:8080 |
多个端口映射:-p 80:80 -p 443:443 |
-P |
随机映射容器暴露的所有端口 | -P |
测试场景,无需手动指定端口 |
--name |
指定容器名称(唯一) | --name tomcat-demo |
便于管理,避免默认随机名称 |
-e |
设置环境变量 | -e MYSQL_ROOT_PASSWORD=123456 |
多个变量:-e KEY1=VAL1 -e KEY2=VAL2 |
-v |
挂载数据卷 / 目录 | -v nginx-vol:/usr/share/nginx/html |
权限控制::ro 只读,:rw 读写(默认) |
--network |
指定容器网络 | --network my-net |
自定义网络实现容器名互通 |
--restart |
容器重启策略 | --restart always |
可选值:always(始终重启)、on-failure(失败时重启)、no(不重启) |
--memory |
限制容器内存 | --memory 1G |
防止容器占用过多主机资源 |
--cpus |
限制容器 CPU 核心数 | --cpus 2 |
限制使用 2 个核心,小数也可:--cpus 1.5 |
--privileged |
赋予容器主机特权(慎用) | --privileged |
需访问主机硬件 / 内核时使用 |
3. 实战场景:容器操作高频需求
场景 1:进入容器(不同系统终端适配)
# 大部分Linux镜像(debian/ubuntu/centos)
docker exec -it 容器ID /bin/bash
# 轻量镜像(alpine)无bash,用sh
docker exec -it 容器ID /bin/sh
# Windows容器
docker exec -it 容器ID powershell
场景 2:限制容器资源(避免资源耗尽)
# 启动Tomcat,限制1G内存、1个CPU核心
docker run -d \
--name tomcat-limited \
-p 8080:8080 \
--memory 1G \
--cpus 1 \
tomcat:9.0
场景 3:批量管理容器
# 停止所有运行中的容器
docker stop $(docker ps -q)
# 删除所有停止的容器
docker rm $(docker ps -aq --filter "status=exited")
# 清理所有容器(停止+删除,谨慎)
docker rm -f $(docker ps -aq)
模块三:Docker 数据管理
一、核心挂载方式(3 种,对比 + 实战)
| 方式 | 语法 | 存储路径(Linux) | 适用场景 | 优势 | 劣势 |
|---|---|---|---|---|---|
| 数据卷(Volume) | -v 卷名:容器路径[:权限] |
/var/lib/docker/volumes/卷名/_data |
核心数据(MySQL 数据、Redis 持久化) | Docker 统一管理,跨平台,不易误删,支持备份 | 主机路径隐藏,修改文件需找对应目录 |
| 绑定挂载(Bind) | -v 主机绝对路径:容器路径[:权限] |
自定义主机路径(如 /docker/nginx/conf) |
配置文件、自定义代码(Nginx 配置) | 直接修改主机目录,直观便捷,可自定义路径 | 跨平台路径格式不同(Win D:\ vs Linux /) |
| 临时挂载(tmpfs) | --tmpfs 容器路径 |
主机内存(无实际路径) | 临时 / 敏感数据(缓存、会话) | 数据存内存,容器停止即删,性能高 | 数据不持久化,重启容器丢失 |
二、数据卷核心操作(+ 备份 / 恢复)
# 1. 创建数据卷(命名卷)
docker volume create mysql-data
# 2. 查看数据卷列表(加 -q 只看ID)
docker volume ls
# 3. 查看数据卷详情(含实际存储路径、挂载容器)
docker volume inspect mysql-data
# 4. 数据卷备份(将卷内容打包到主机)
# 原理:启动临时容器挂载数据卷,拷贝内容到主机
docker run --rm -v mysql-data:/data -v $(pwd):/backup alpine tar -zcvf /backup/mysql-data.tar.gz /data
# 5. 数据卷恢复(从备份包恢复到数据卷)
docker run --rm -v mysql-data:/data -v $(pwd):/backup alpine sh -c "tar -zxvf /backup/mysql-data.tar.gz -C / && rm -rf /data/* && mv /data/* /data/"
# 6. 删除数据卷(需先解除挂载)
docker volume rm mysql-data
# 7. 清理所有未使用的数据卷(谨慎,会删匿名卷)
docker volume prune
三、绑定挂载(实用技巧 + 权限问题解决)
1. 基础实战:Nginx 配置挂载
# 1. 主机创建自定义目录(规范命名,便于管理)
mkdir -p /docker/nginx/{conf,html,logs}
# 2. 复制容器默认配置到主机(避免配置缺失)
# --rm:容器执行完命令自动删除
docker run --rm nginx cp /etc/nginx/nginx.conf /docker/nginx/conf/
docker run --rm nginx cp /etc/nginx/conf.d/default.conf /docker/nginx/conf/
# 3. 启动容器,绑定挂载(加 :ro 设为只读,提高安全性)
docker run -d \
--name nginx-bind \
-p 80:80 \
-v /docker/nginx/conf:/etc/nginx:ro \ # 配置目录只读
-v /docker/nginx/html:/usr/share/nginx/html:rw \ # 页面目录可写
-v /docker/nginx/logs:/var/log/nginx:rw \ # 日志目录可写
nginx:1.24
2. 权限问题解决(常见报错)
问题 :容器启动后提示「Permission denied」,无法读写挂载目录。原因 :容器内进程(如 nginx 用 nginx 用户,MySQL 用 mysql 用户)无主机目录权限。解决方法:
# 方法 1:修改主机目录权限(最简单)
chmod 777 /docker/nginx/html # 测试场景可用,生产不推荐
# 方法 2:指定容器用户(推荐)
# 查看容器内进程UID:docker exec -it nginx id nginx → 通常 uid=101(nginx)
# 主机目录赋权给对应UID
chown -R 101:101 /docker/nginx/html
# 方法 3:启动容器时指定用户
docker run -d \
--name nginx-bind \
-p 80:80 \
-v /docker/nginx/html:/usr/share/nginx/html \
--user 101:101 \ # 指定nginx用户
nginx:1.24
四、匿名卷 vs 命名卷(区别 + 使用场景)
| 类型 | 语法 | 特点 | 适用场景 |
|---|---|---|---|
| 命名卷 | -v 卷名:容器路径 |
有明确名称,易管理、可备份 | 生产环境核心数据 |
| 匿名卷 | -v 容器路径 |
无名称(随机 ID),难管理、易误删 | 临时测试、容器内临时数据 |
# 匿名卷示例(不推荐生产用)
docker run -d --name nginx-anon -p 80:80 -v /usr/share/nginx/html nginx
# 查看匿名卷:名称为随机字符串
docker volume ls
模块四:Docker 网络与容器互联
一、Docker 网络模式(4 种,实战示例)
| 模式 | 语法(run 参数) | 网络特点 | 实战示例 |
|---|---|---|---|
| bridge(默认) | --network bridge(可省略) |
容器有独立 IP,通过 docker0 网桥与主机通信 | 单机多容器互联(如 Nginx+Tomcat) |
| host | --network host |
容器共享主机网络,无端口映射,IP = 主机 IP | 高性能场景(如大数据处理) |
| none | --network none |
容器仅回环地址(127.0.0.1),无外部网络 | 离线数据处理、无需网络的任务 |
| overlay | --network overlay |
跨主机容器互联(需 Swarm 集群) | 多主机集群部署 |
实战 1:host 网络模式(Nginx 示例)
# 启动 Nginx,使用 host 网络(无需 -p 映射,容器80端口=主机80端口)
docker run -d \
--name nginx-host \
--network host \
nginx:1.24
# 验证:访问主机80端口,直接访问到容器 Nginx
实战 2:none 网络模式(离线处理示例)
# 启动容器,无网络,仅处理本地文件
docker run -it --rm --network none alpine sh
# 验证:ping 百度失败,仅能访问 127.0.0.1
ping www.baidu.com # 报错
二、自定义网络(核心实战,替代默认 bridge)
默认 bridge 网络的问题:
- 容器间只能通过 IP 互通,无法用容器名;
- 网络隔离性差,所有容器默认在一个网桥。
自定义网络优势:
- 支持容器名 / 服务名互通;
- 可创建多个网络,实现容器分组隔离;
- 支持自定义网段、网关。
核心操作 + 实战:多容器互联
# 1. 创建自定义桥接网络(指定网段和网关,可选)
docker network create \
--driver bridge \ # 网络驱动
--subnet=172.30.0.0/16 \ # 自定义网段
--gateway=172.30.0.1 \ # 网关
app-network # 网络名称
# 2. 查看网络列表(确认创建成功)
docker network ls
# 3. 启动 MySQL 容器,加入自定义网络
docker run -d \
--name mysql-db \
--network app-network \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0
# 4. 启动 Tomcat 容器,加入同一网络
docker run -d \
--name tomcat-app \
--network app-network \
tomcat:9.0
# 5. 测试容器互联(Tomcat 访问 MySQL)
# 进入 Tomcat 容器,ping MySQL 容器名(能通则成功)
docker exec -it tomcat-app ping mysql-db
# 验证 MySQL 连接(需安装 mysql 客户端)
docker exec -it tomcat-app apt update && apt install -y mysql-client
docker exec -it tomcat-app mysql -h mysql-db -uroot -p123456 # 成功连接
# 6. 将现有容器加入自定义网络(无需重启容器)
docker run -d --name nginx-proxy -p 80:80 nginx:1.24 # 先启动容器
docker network connect app-network nginx-proxy # 加入网络
# 7. 将容器移出网络
docker network disconnect app-network nginx-proxy
# 8. 删除自定义网络(需先移除所有容器)
docker network rm app-network
三、容器网络故障排查
# 1. 查看容器 IP 地址
docker inspect -f '{{.NetworkSettings.IPAddress}}' 容器ID
# 2. 查看容器网络端口映射
docker port 容器ID
# 3. 测试容器网络连通性(用 alpine 镜像,自带 ping/curl)
docker run --rm --network app-network alpine ping tomcat-app
docker run --rm --network app-network alpine curl http://tomcat-app:8080
# 4. 查看 Docker 网桥信息
ip addr show docker0 # 默认网桥
ip addr show br-xxxx # 自定义网桥(xxxx 为网络ID前几位)
模块五:自定义镜像(Dockerfile 详解 + 实战)
一、Dockerfile 核心指令(细化说明 + 示例)
| 指令 | 作用 | 示例 | 注意事项 |
|---|---|---|---|
FROM |
指定基础镜像(必选,第一行) | FROM centos:7/FROM alpine:3.18 |
优先选轻量镜像(alpine < 10MB),减少体积 |
RUN |
构建时执行命令(分层构建) | RUN yum install -y nginx |
多命令合并用 &&,减少分层:RUN yum update && yum install -y nginx && yum clean all |
COPY |
复制主机文件到容器(本地→容器) | COPY index.html /usr/share/nginx/html |
支持通配符:COPY *.jar /app/;路径必须是构建上下文内的文件 |
ADD |
复制文件(支持解压、URL) | ADD app.tar.gz /usr/local/ |
慎用 URL 下载(增加镜像体积),建议用 RUN wget |
WORKDIR |
设置工作目录(后续指令的默认目录) | WORKDIR /app |
自动创建不存在的目录,推荐用绝对路径 |
ENV |
设置环境变量(构建 / 运行时均生效) | ENV JAVA_HOME /usr/local/jdk8 |
引用变量:ENV PATH $JAVA_HOME/bin:$PATH |
EXPOSE |
声明容器端口(仅说明,无映射) | EXPOSE 8080 |
仅为文档说明,运行时仍需 -p 映射 |
CMD |
容器启动时执行命令(可被覆盖) | CMD ["nginx", "-g", "daemon off;"] |
仅最后一个 CMD 生效;运行时可覆盖:docker run 镜像 自定义命令 |
ENTRYPOINT |
容器启动时执行命令(不可被覆盖) | ENTRYPOINT ["java", "-jar"] |
结合 CMD 传参:ENTRYPOINT ["java", "-jar"] + CMD ["app.jar"] |
VOLUME |
声明数据卷(建议运行时再挂载) | VOLUME ["/data"] |
运行时可通过 -v 覆盖:docker run -v 卷名:/data 镜像 |
USER |
指定容器运行用户 | USER nginx |
需先在镜像中创建用户:RUN useradd -m nginx |
二、Dockerfile 最佳实践(减少体积 + 提高效率)
- 合并 RUN 指令:减少镜像分层,降低体积;
- 清理缓存:安装依赖后清理 yum/apk/apt 缓存;
- 使用多阶段构建:分离构建环境和运行环境,大幅减少体积;
- 避免无用文件 :用
.dockerignore排除无关文件(如.git、node_modules)。
实战 1:基础镜像构建(Nginx 自定义首页)
# 1. 创建构建目录
mkdir -p /docker/nginx-build
cd /docker/nginx-build
# 2. 编写 .dockerignore(排除无用文件)
echo "*.log
.git
.DS_Store" > .dockerignore
# 3. 编写 Dockerfile
vim Dockerfile
Dockerfile 内容:
# 基础镜像(轻量 alpine 版本)
FROM nginx:1.24-alpine
# 维护者信息(可选)
LABEL maintainer="your-name@example.com"
# 设置工作目录
WORKDIR /usr/share/nginx/html
# 复制自定义首页(构建上下文内的 index.html)
COPY index.html .
# 声明端口
EXPOSE 80
# 启动命令(前台运行,避免容器退出)
CMD ["nginx", "-g", "daemon off;"]
# 4. 编写自定义首页
echo "<h1>Built by Dockerfile</h1>" > index.html
# 5. 构建镜像(-t 打标签,. 表示构建上下文为当前目录)
docker build -t my-nginx:1.0 .
# 6. 启动容器测试
docker run -d -p 8080:80 --name my-nginx my-nginx:1.0
# 验证:访问 http://主机IP:8080,看到自定义首页
实战 2:多阶段构建(Spring Boot 应用,减少镜像体积)
问题 :构建 Spring Boot 应用需 JDK(大体积),运行仅需 JRE(小体积)。解决:多阶段构建,第一阶段用 JDK 打包,第二阶段用 JRE 运行。
# 1. 创建构建目录
mkdir -p /docker/springboot-build
cd /docker/springboot-build
# 2. 准备 Spring Boot 源码(或 jar 包)
# 假设已有 app.jar 放在当前目录
# 3. 编写 Dockerfile
vim Dockerfile
Dockerfile 内容:
# 阶段 1:构建阶段(用 JDK 打包,可省略 if 已有 jar 包)
FROM maven:3.8.5-openjdk-8 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
# 打包应用(跳过测试,加快构建)
RUN mvn clean package -DskipTests
# 阶段 2:运行阶段(用轻量 JRE)
FROM openjdk:8-jre-alpine
WORKDIR /app
# 从构建阶段复制 jar 包到运行阶段
COPY --from=builder /app/target/*.jar app.jar
# 设置环境变量
ENV JAVA_OPTS="-Xms512m -Xmx1024m"
# 声明端口
EXPOSE 8080
# 启动命令(优雅退出)
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
# 4. 构建镜像
docker build -t my-springboot:1.0 .
# 5. 启动容器
docker run -d -p 8080:8080 --name my-springboot my-springboot:1.0
三、Dockerfile 常见错误及解决
| 错误现象 | 原因 | 解决方法 |
|---|---|---|
COPY failed: no source files |
构建上下文无指定文件,或路径错误 | 检查文件路径,确保在构建上下文内 |
| 容器启动后立即退出 | CMD 命令后台运行(如 nginx 不加 -g daemon off;) |
改为前台运行命令 |
| 镜像体积过大 | 未清理缓存、多阶段构建未使用 | 合并 RUN 指令,清理缓存,用多阶段构建 |
| 容器内无权限执行命令 | USER 指令指定的用户无权限 | 提前创建用户并赋权,或使用 root 用户(测试) |
模块六:容器编排(Docker Compose 详解 + 实战)
一、Docker Compose 安装
1. Linux 安装(手动下载,解决网络问题)
# 方法 1:官方源(国内慢,可换阿里云镜像)
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 方法 2:阿里云镜像(国内快)
sudo curl -L "https://mirrors.aliyun.com/docker-toolbox/linux/compose/latest/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 创建软链接(避免路径问题)
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 验证安装
docker-compose --version
2. Windows/Mac 安装
Docker Desktop 自带 Compose,安装后终端输入 docker-compose --version 验证。
二、Compose 核心概念 + 配置文件规范
1. 核心概念
| 概念 | 说明 | 对应配置项 |
|---|---|---|
services |
定义多个容器(如 web、db、redis) | 顶级配置项 services |
networks |
定义自定义网络(容器互联) | 顶级配置项 networks |
volumes |
定义数据卷(数据持久化) | 顶级配置项 volumes |
env_file |
环境变量文件(统一管理变量) | services.xxx.env_file |
2. Compose 文件规范
- 文件名:默认
docker-compose.yml或docker-compose.yaml; - 版本:推荐
3.8(兼容 Docker 20.10+),写在文件第一行version: '3.8'; - 语法:YAML 格式,缩进用 2 个空格(禁止 tab),键值对冒号后加空格。
三、Compose 核心命令(细化 + 场景)
| 命令 | 作用 | 示例 | 扩展说明 |
|---|---|---|---|
docker-compose up |
创建并启动所有容器(前台) | docker-compose up |
加 -d 后台运行:docker-compose up -d |
docker-compose up -d --build |
构建镜像并启动容器 | docker-compose up -d --build |
镜像有更新时强制重新构建 |
docker-compose down |
停止并删除容器、网络(保留数据卷) | docker-compose down |
加 -v 删除数据卷:docker-compose down -v(谨慎) |
docker-compose ps |
查看 Compose 管理的容器 | docker-compose ps |
加 -a 查看所有(含停止的) |
docker-compose logs |
查看容器日志 | docker-compose logs nginx |
加 -f 实时查看:docker-compose logs -f tomcat |
docker-compose restart |
重启指定 / 所有容器 | docker-compose restart mysql |
重启所有:docker-compose restart |
docker-compose stop/start |
停止 / 启动容器 | docker-compose stop |
仅停止容器,不删除 |
docker-compose exec |
进入指定容器 | docker-compose exec nginx bash |
等同于 docker exec,无需记容器名 |
docker-compose build |
构建指定 / 所有镜像 | docker-compose build tomcat |
加 --no-cache 无缓存构建:docker-compose build --no-cache |
四、实战:Compose 部署「Nginx + Tomcat + MySQL」(细化版)
1. 目录结构(规范命名)
/docker/compose-demo/
├── docker-compose.yml # Compose 配置文件
├── .env # 环境变量文件
├── mysql/
│ └── conf/ # MySQL 配置目录
│ └── my.cnf # MySQL 自定义配置
├── tomcat/
│ └── webapps/ # Tomcat 应用目录
└── nginx/
├── conf/ # Nginx 配置目录
│ └── default.conf # 反向代理配置
└── html/ # Nginx 页面目录
└── index.html # 自定义首页
2. 编写环境变量文件(.env)
# MySQL 配置
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=app_db
MYSQL_USER=app_user
MYSQL_PASSWORD=app_pass
# 端口配置
NGINX_PORT=80
TOMCAT_PORT=8080
MYSQL_PORT=3306
3. 编写 docker-compose.yml
version: '3.8'
# 定义数据卷(全局,可被所有服务使用)
volumes:
mysql-data: # MySQL 数据卷(持久化核心数据)
tomcat-webapps: # Tomcat 应用卷
# 定义自定义网络
networks:
app-network:
driver: bridge
ipam:
config:
- subnet: 172.40.0.0/16 # 自定义网段
# 定义服务
services:
# MySQL 服务
mysql:
image: mysql:8.0
container_name: mysql-db
ports:
- "${MYSQL_PORT}:3306" # 引用 .env 中的变量
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
volumes:
- mysql-data:/var/lib/mysql # 挂载全局数据卷
- ./mysql/conf:/etc/mysql/conf.d:ro # 绑定挂载配置(只读)
networks:
- app-network
restart: always # 异常退出自动重启
healthcheck: # 健康检查,确保 MySQL 启动成功
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 3
# Tomcat 服务
tomcat:
image: tomcat:9.0-alpine
container_name: tomcat-app
ports:
- "${TOMCAT_PORT}:8080"
volumes:
- tomcat-webapps:/usr/local/tomcat/webapps
- ./tomcat/conf:/usr/local/tomcat/conf:ro
networks:
- app-network
depends_on:
mysql:
condition: service_healthy # 等待 MySQL 健康检查通过再启动
restart: always
# 资源限制
deploy:
resources:
limits:
cpus: '1'
memory: 1G
# Nginx 服务
nginx:
image: nginx:1.24-alpine
container_name: nginx-proxy
ports:
- "${NGINX_PORT}:80"
volumes:
- ./nginx/conf:/etc/nginx/conf.d:ro
- ./nginx/html:/usr/share/nginx/html:rw
- ./nginx/logs:/var/log/nginx:rw
networks:
- app-network
depends_on:
- tomcat # 依赖 Tomcat,先启动 Tomcat
restart: always
# 日志配置(自定义格式)
logging:
driver: "json-file"
options:
max-size: "100m" # 单个日志文件最大 100M
max-file: "3" # 最多保留 3 个文件
4. 准备配套配置文件
# 1. 创建目录
mkdir -p ./mysql/conf ./tomcat/conf ./nginx/conf ./nginx/html ./nginx/logs
# 2. MySQL 配置(解决中文乱码)
echo -e "[mysqld]\ncharacter-set-server=utf8mb4\ncollation-server=utf8mb4_unicode_ci\n[client]\ndefault-character-set=utf8mb4" > ./mysql/conf/my.cnf
# 3. Nginx 反向代理配置
echo '
server {
listen 80;
server_name localhost;
# 代理 Tomcat
location / {
proxy_pass http://tomcat-app:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 静态页面
location /static {
root /usr/share/nginx/html;
expires 1d; # 缓存 1 天
}
}
' > ./nginx/conf/default.conf
# 4. Nginx 自定义首页
echo "<h1>Compose Demo - $(date)</h1>" > ./nginx/html/index.html
5. 启动与管理服务
# 1. 进入目录
cd /docker/compose-demo
# 2. 后台启动所有服务(首次启动建议不加 -d,查看日志是否有报错)
docker-compose up -d
# 3. 查看服务状态
docker-compose ps
# 4. 查看 MySQL 健康检查状态
docker inspect -f '{{.State.Health.Status}}' mysql-db
# 5. 进入 Nginx 容器修改配置
docker-compose exec nginx vi /etc/nginx/conf.d/default.conf
# 6. 重启 Nginx 服务
docker-compose restart nginx
# 7. 停止服务(保留数据卷)
docker-compose down
# 8. 重新启动(复用数据卷,数据不丢失)
docker-compose up -d
6. Compose 扩展技巧
技巧 1:使用 override.yml 覆盖配置
创建 docker-compose.override.yml,自动合并到主配置,用于开发 / 测试环境:
version: '3.8'
services:
nginx:
ports:
- "8080:80" # 覆盖主配置的 80 端口
volumes:
- ./nginx/dev-conf:/etc/nginx/conf.d # 覆盖配置目录
技巧 2:指定配置文件启动
# 启动生产环境配置
docker-compose -f docker-compose-prod.yml up -d
# 同时使用多个配置文件(后面的覆盖前面的)
docker-compose -f docker-compose.yml -f docker-compose-dev.yml up -d
总结
核心知识点回顾
- 安装与基础 :Linux 支持 YUM / 二进制安装,权限配置需将用户加入 docker 组;
docker run核心参数(-d/-p/-v/-e/--name)需熟练掌握。 - 数据管理:核心数据用「命名数据卷」(易备份、跨平台),配置文件用「绑定挂载」(易修改);数据卷备份可通过临时容器实现。
- 网络互联:自定义网络替代默认 bridge,支持容器名互通;host 模式适合高性能场景,none 模式适合离线任务。
- 镜像构建:Dockerfile 遵循「轻量、分层、缓存清理」原则;多阶段构建可大幅减少镜像体积,解决构建 / 运行环境分离问题。
- 编排部署 :Docker Compose 是单机多容器部署首选,通过 YAML 统一管理服务依赖、网络、数据卷;
.env文件统一管理环境变量,提高配置复用性。