2026 开发必备 Docker 实战:从本地环境到 CI/CD 交付指南
Docker 实战案例分享|2026最新版
前言:为什么 2026 年依然要认真学习 Docker?
进入 2026 年,云原生、微服务、DevOps、AI 工程化、边缘计算等技术已经非常成熟,但 Docker 依然是开发、测试、交付和部署环节中最基础、最常用、最值得掌握的工具之一。
很多人第一次接触 Docker 时,会把它简单理解为“一个轻量级虚拟机”。这种理解虽然便于入门,但并不准确。Docker 的核心价值并不是“模拟一台服务器”,而是通过容器技术,把应用程序及其运行依赖打包成一个标准化单元,使应用可以在不同环境中保持一致的运行表现。
在实际项目中,Docker 最常见的价值包括:
- 解决“我本地能跑,线上跑不了”的环境一致性问题;
- 快速搭建开发、测试、演示环境;
- 简化中间件部署,例如 MySQL、Redis、Nginx、RabbitMQ;
- 支持微服务项目的本地联调;
- 配合 CI/CD 实现自动构建、自动测试和自动发布;
- 为 Kubernetes、云原生部署打好基础。
本文将围绕真实开发场景,分享多个 Docker 实战案例,帮助你从“会写命令”提升到“能在项目中真正用好 Docker”。
一、案例一:使用 Docker 快速启动 MySQL 数据库
在传统开发模式中,如果要在本地安装 MySQL,通常需要下载安装包、配置端口、设置密码、调整字符集,还可能遇到版本冲突问题。使用 Docker 后,我们可以用一条命令快速启动一个独立的 MySQL 实例。
docker run -d \
--name mysql-demo \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=demo_db \
mysql:8.4
这条命令完成了几件事:
-d表示后台运行容器;--name mysql-demo为容器指定名称;-p 3306:3306将宿主机 3306 端口映射到容器内 3306 端口;MYSQL_ROOT_PASSWORD设置 root 用户密码;MYSQL_DATABASE在启动时自动创建数据库;mysql:8.4指定使用 MySQL 8.4 镜像。
启动后,可以通过以下命令查看容器状态:
docker ps
如果容器正常运行,开发工具就可以连接 localhost:3306,用户名为 root,密码为 123456。
数据持久化问题
直接运行 MySQL 容器有一个隐患:如果容器被删除,数据库中的数据也可能丢失。因此在真实项目中,必须使用数据卷进行持久化。
docker run -d \
--name mysql-demo \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=demo_db \
-v mysql_data:/var/lib/mysql \
mysql:8.4
这里的 -v mysql_data:/var/lib/mysql 表示把 MySQL 的数据目录挂载到 Docker 数据卷中。即使容器删除,只要数据卷还在,数据就不会丢失。
查看数据卷:
docker volume ls
删除容器但保留数据:
docker rm -f mysql-demo
重新创建容器并挂载同一个数据卷后,历史数据仍然存在。
二、案例二:使用 Docker 部署 Redis 缓存服务
Redis 是后端项目中非常常见的中间件,常用于缓存、分布式锁、排行榜、验证码、会话存储等场景。使用 Docker 启动 Redis 非常简单。
docker run -d \
--name redis-demo \
-p 6379:6379 \
redis:7.4
如果需要设置密码,可以使用以下方式:
docker run -d \
--name redis-demo \
-p 6379:6379 \
redis:7.4 redis-server --requirepass 123456
进入容器测试 Redis:
docker exec -it redis-demo redis-cli
如果设置了密码,需要执行:
AUTH 123456
然后测试写入和读取:
SET username docker
GET username
Redis 配置文件挂载
在生产或准生产环境中,不建议把复杂配置写在命令行中。更推荐将配置文件挂载到容器内。
假设本地有一个 redis.conf 文件:
requirepass 123456
appendonly yes
启动命令如下:
docker run -d \
--name redis-demo \
-p 6379:6379 \
-v ./redis.conf:/usr/local/etc/redis/redis.conf \
-v redis_data:/data \
redis:7.4 redis-server /usr/local/etc/redis/redis.conf
其中:
appendonly yes开启 AOF 持久化;/data是 Redis 默认数据目录;redis_data用于保存持久化数据。
这个案例说明,Docker 不只是“快速启动服务”,更重要的是可以通过挂载配置文件和数据卷,实现接近真实环境的服务管理。
三、案例三:使用 Dockerfile 构建 Spring Boot 应用镜像
在企业项目中,我们通常不会只运行官方镜像,还需要把自己的业务应用构建成镜像。下面以 Spring Boot 项目为例。
假设项目打包后生成文件:
target/app.jar
可以编写一个简单的 Dockerfile:
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
构建镜像:
docker build -t springboot-demo:1.0 .
运行容器:
docker run -d \
--name springboot-demo \
-p 8080:8080 \
springboot-demo:1.0
访问接口:
curl http://localhost:8080
更推荐的多阶段构建
上面的方式要求你先在宿主机执行 Maven 打包。如果希望整个构建过程都在 Docker 中完成,可以使用多阶段构建。
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /build
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=builder /build/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
多阶段构建的好处是:
- 构建环境和运行环境分离;
- 最终镜像中不包含 Maven 和源码;
- 镜像体积更小;
- 构建流程更标准,适合 CI/CD。
对于 Java 项目来说,Dockerfile 的质量会直接影响构建速度、镜像大小和部署稳定性。实际工作中还可以进一步优化,例如利用依赖缓存、分层 Jar、JVM 参数配置等。
四、案例四:使用 Docker Compose 搭建本地开发环境
当项目只依赖一个数据库时,使用 docker run 足够。但真实项目往往同时依赖 MySQL、Redis、后端服务、前端服务、消息队列等多个组件。如果每个组件都手写命令启动,维护成本会很高。
这时可以使用 Docker Compose。
下面是一个典型的 docker-compose.yml 示例:
services:
mysql:
image: mysql:8.4
container_name: demo-mysql
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: demo_db
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:7.4
container_name: demo-redis
ports:
- "6379:6379"
app:
build: .
container_name: demo-app
ports:
- "8080:8080"
depends_on:
- mysql
- redis
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/demo_db
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 123456
SPRING_DATA_REDIS_HOST: redis
volumes:
mysql_data:
启动全部服务:
docker compose up -d
查看日志:
docker compose logs -f
停止服务:
docker compose down
如果需要连数据卷一起删除:
docker compose down -v
Compose 的核心价值
Docker Compose 最大的价值不是“少写几条命令”,而是把整个本地开发环境变成一个可描述、可复用、可版本管理的配置文件。
团队成员只需要拿到代码仓库,执行:
docker compose up -d
就能得到基本一致的运行环境。这对新员工入职、测试环境搭建、演示环境交付都非常有帮助。
五、案例五:使用 Nginx 容器部署前端项目
对于 Vue、React、Angular 等前端项目,常见部署方式是先构建静态文件,然后使用 Nginx 提供访问服务。
假设前端项目构建后生成 dist 目录,可以编写如下 Dockerfile:
FROM nginx:1.27-alpine
COPY dist /usr/share/nginx/html
EXPOSE 80
构建镜像:
docker build -t frontend-demo:1.0 .
运行容器:
docker run -d \
--name frontend-demo \
-p 8081:80 \
frontend-demo:1.0
访问:
http://localhost:8081
处理前端路由刷新 404
如果前端使用 History 模式,直接刷新二级路由时可能出现 404。此时需要自定义 Nginx 配置。
nginx.conf 示例:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:8080/;
}
}
对应 Dockerfile:
FROM nginx:1.27-alpine
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
这个配置不仅解决了前端路由问题,还可以通过 /api/ 代理后端服务,避免前端直接暴露后端地址。
六、案例六:优化镜像体积与构建速度
Docker 在项目中用得好不好,很大程度上取决于镜像构建是否合理。很多初学者写 Dockerfile 时,会不小心构建出几 GB 的镜像,导致构建慢、上传慢、部署慢。
选择更小的基础镜像
例如 Node.js 项目可以优先考虑:
FROM node:22-alpine
Java 项目可以选择 JRE 镜像,而不是完整 JDK 镜像:
FROM eclipse-temurin:21-jre
合理利用缓存
Docker 构建镜像时,每一行指令都会形成一层缓存。如果把变化频繁的代码复制放在依赖安装之前,就会导致每次修改代码都重新安装依赖。
Node.js 项目推荐写法:
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
这样只有 package.json 或 package-lock.json 变化时,才会重新执行 npm ci。
使用 .dockerignore
很多人会忽略 .dockerignore,导致 node_modules、日志文件、构建产物、Git 历史等无关内容被发送到 Docker 构建上下文中。
常见 .dockerignore 示例:
.git
node_modules
dist
target
logs
*.log
.env
.dockerignore 可以显著减少构建上下文大小,提高构建速度,同时降低敏感信息误打包进镜像的风险。
七、案例七:容器日志与问题排查
Docker 实战中,排查问题是必备能力。常用命令包括:
docker logs container_name
实时查看日志:
docker logs -f container_name
查看最近 100 行日志:
docker logs --tail=100 container_name
进入容器:
docker exec -it container_name sh
如果容器内有 Bash,也可以使用:
docker exec -it container_name bash
查看容器资源占用:
docker stats
查看容器详细信息:
docker inspect container_name
常见问题一:端口被占用
如果启动时报错端口占用,例如 bind: address already in use,说明宿主机端口已经被其他进程或容器使用。可以换一个宿主机端口:
docker run -p 8082:8080 app-demo
表示宿主机使用 8082,容器内部仍然使用 8080。
常见问题二:容器启动后马上退出
可以先查看日志:
docker logs container_name
常见原因包括:
- 配置文件错误;
- 环境变量缺失;
- 数据库连接失败;
- 启动命令写错;
- 应用端口冲突;
- 权限不足。
常见问题三:容器之间无法访问
在 Docker Compose 中,服务之间应该使用服务名访问,而不是 localhost。例如后端访问 MySQL,应使用:
jdbc:mysql://mysql:3306/demo_db
而不是:
jdbc:mysql://localhost:3306/demo_db
因为在容器内部,localhost 指的是当前容器本身,不是宿主机,也不是其他容器。
八、案例八:结合 CI/CD 自动构建 Docker 镜像
在现代软件交付流程中,Docker 常常与 CI/CD 平台结合使用。典型流程如下:
- 开发人员提交代码到 Git 仓库;
- CI 平台拉取代码;
- 执行单元测试和构建;
- 根据 Dockerfile 构建镜像;
- 推送镜像到镜像仓库;
- 部署平台拉取新镜像并更新服务。
以 GitHub Actions 为例,可以编写如下流程:
name: Build Docker Image
on:
push:
branches:
- main
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Login Registry
run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login registry.example.com -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin
- name: Build Image
run: docker build -t registry.example.com/demo/app:${{ github.sha }} .
- name: Push Image
run: docker push registry.example.com/demo/app:${{ github.sha }}
这里使用 github.sha 作为镜像标签,可以保证每次构建都有唯一版本,便于回滚和追踪。
在生产环境中,不建议只使用 latest 标签。latest 虽然方便,但不利于版本管理,一旦出现问题,很难准确判断当前运行的是哪一次构建产物。
九、Docker 实战中的安全建议
Docker 使用方便,但如果配置不当,也可能带来安全风险。
不要把敏感信息写进镜像
例如不要在 Dockerfile 中直接写:
ENV DB_PASSWORD=123456
更推荐通过环境变量、密钥管理服务或部署平台注入。
尽量不要使用 root 用户运行应用
很多基础镜像默认使用 root 用户。对于生产环境,可以创建普通用户运行应用。
RUN addgroup -S app && adduser -S app -G app
USER app
这样即使应用被攻击,攻击者拿到的权限也会受到限制。
定期更新基础镜像
基础镜像中可能包含系统库和运行时依赖,如果长期不更新,可能存在已知漏洞。因此建议定期重构镜像,并结合安全扫描工具检查漏洞。
控制容器权限
除非确有必要,不要随意使用:
--privileged
该参数会赋予容器非常高的权限,可能突破容器隔离边界。生产环境中应谨慎使用。
十、从 Docker 到 Kubernetes:下一步怎么走?
Docker 解决的是单个容器和本地环境标准化问题,而 Kubernetes 解决的是大规模容器编排问题。当应用从单体项目演进为多个服务后,就会面临服务发现、负载均衡、自动扩缩容、滚动更新、故障恢复、配置管理等问题。
这时 Kubernetes 就成为更合适的选择。
不过,学习 Kubernetes 之前,必须先掌握 Docker 的核心概念,包括:
- 镜像;
- 容器;
- 数据卷;
- 网络;
- Dockerfile;
- Docker Compose;
- 日志与排错;
- 镜像仓库;
- 环境变量与配置管理。
可以说,Docker 是云原生学习路线中的基础层。如果 Docker 没有掌握扎实,学习 Kubernetes 时会遇到大量理解障碍。
总结
Docker 在 2026 年依然是开发者必须掌握的核心技能之一。它不是一个过时工具,而是现代软件工程体系中的基础能力。无论你是后端开发、前端开发、测试工程师、运维工程师,还是正在学习云原生和 DevOps,Docker 都能显著提升你的开发效率和交付质量。
通过本文的实战案例,我们可以总结出几个关键经验:
- 使用 Docker 可以快速搭建 MySQL、Redis、Nginx 等常用服务;
- 使用数据卷可以解决容器数据持久化问题;
- 使用 Dockerfile 可以把业务应用标准化为镜像;
- 使用多阶段构建可以减小镜像体积,提高交付效率;
- 使用 Docker Compose 可以统一管理多服务开发环境;
- 使用
.dockerignore和缓存机制可以优化构建速度; - 使用日志、
inspect、exec、stats等命令可以高效排查问题; - 在生产环境中要重视镜像安全、权限控制和版本管理;
- Docker 是继续学习 Kubernetes 和云原生体系的重要基础。
真正掌握 Docker,不是记住几条命令,而是理解它如何融入项目开发、测试、部署和运维的完整链路。当你能用 Docker 快速复现环境、稳定交付应用、定位容器问题,并将它接入 CI/CD 流程时,Docker 才真正成为你的工程生产力工具。