Docker 与 Docker Compose 到底差在哪?一篇搞懂用法和常用命令
Docker 和 Docker 的区别|附完整命令
说明:标题中的“Docker 和 Docker 的区别”看起来像是重复表述。实际技术场景中,大家常问的通常是 Docker 与 Docker Compose 的区别、Docker 与 Docker Engine 的区别、Docker 与虚拟机的区别,或者 Docker 命令与 Docker Compose 命令的区别。
本文将围绕最常见、最实用的场景展开:Docker 与 Docker Compose 的区别,并补充 Docker Engine、Docker Desktop、Docker CLI 等概念,最后附上常用完整命令,方便直接查阅和使用。
一、先理解 Docker 到底是什么
Docker 是一个开源的容器化平台,用于将应用程序及其运行环境打包成一个轻量级、可移植的容器。通过 Docker,开发者可以把应用、依赖、配置、运行时环境统一封装,做到“一次构建,到处运行”。
举个例子,一个 Java 项目可能依赖:
- JDK 17
- Maven
- MySQL
- Redis
- Nginx
- 特定的系统环境变量
- 特定版本的 Linux 运行环境
如果不用 Docker,在新服务器上部署时,需要手动安装这些环境,容易出现版本不一致、依赖缺失、配置错误等问题。
而使用 Docker 后,可以把这些环境写进 Dockerfile 或通过镜像直接拉取,部署时只需要运行容器即可。
二、Docker 的核心组成
很多人说“Docker”,其实可能指代不同的东西。严格来说,Docker 生态里包含多个组件。
1. Docker Engine
Docker Engine 是 Docker 的核心引擎,负责容器的创建、运行、停止、删除等操作。
它主要包括:
- Docker Daemon:后台服务进程,负责管理镜像、容器、网络、数据卷等。
- Docker CLI:命令行工具,也就是我们常用的
docker命令。 - REST API:用于让外部程序与 Docker Daemon 通信。
当你执行:
docker run nginx
实际上是 Docker CLI 把命令发送给 Docker Daemon,然后由 Docker Daemon 去拉取镜像、创建容器并运行。
2. Docker Image
Docker Image,也就是 Docker 镜像,是一个只读模板。
镜像里通常包含:
- 操作系统基础环境
- 应用程序
- 应用依赖
- 配置文件
- 启动命令
例如:
docker pull nginx
docker pull mysql:8.0
docker pull redis:7
这些命令就是从镜像仓库拉取镜像。
3. Docker Container
Docker Container,也就是 Docker 容器,是镜像运行后的实例。
可以这样理解:
- 镜像类似“类”
- 容器类似“对象”
- 一个镜像可以启动多个容器
例如:
docker run -d --name my-nginx nginx
这条命令会基于 nginx 镜像创建并运行一个名为 my-nginx 的容器。
4. Dockerfile
Dockerfile 是用于构建 Docker 镜像的脚本文件。
示例:
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/demo.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
然后执行:
docker build -t my-java-app:1.0 .
即可构建一个自定义镜像。
5. Docker Compose
Docker Compose 是用于定义和运行多容器 Docker 应用的工具。
它通过一个 docker-compose.yml 或 compose.yml 文件来描述多个服务,例如:
- Web 服务
- MySQL
- Redis
- Nginx
- 消息队列
- Elasticsearch
然后通过一条命令启动整个应用:
docker compose up -d
三、Docker 和 Docker Compose 的区别
这是实际开发中最常见的问题。
简单来说:
Docker 主要用于管理单个容器或镜像,Docker Compose 主要用于编排和管理多个容器。
四、Docker 与 Docker Compose 对比表
| 对比项 | Docker | Docker Compose |
|---|---|---|
| 主要作用 | 管理镜像、容器、网络、数据卷 | 编排多个容器服务 |
| 常用命令 | docker run、docker build、docker ps |
docker compose up、docker compose down |
| 配置方式 | 主要通过命令参数或 Dockerfile | 通过 YAML 文件集中配置 |
| 适用场景 | 单个服务、简单容器运行 | 多服务项目、本地开发环境、测试环境 |
| 是否需要配置文件 | 不一定需要 | 通常需要 compose.yml |
| 学习难度 | 基础必学 | 建议在掌握 Docker 后学习 |
| 可维护性 | 参数多时较难维护 | 配置清晰,易于复用 |
| 示例 | 启动一个 Nginx 容器 | 同时启动 Nginx、MySQL、Redis |
五、用 Docker 启动 MySQL 的方式
如果只用 Docker 命令启动 MySQL,可以这样写:
docker run -d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=testdb \
-v mysql_data:/var/lib/mysql \
mysql:8.0
这条命令的含义是:
-d:后台运行--name mysql8:容器名称为mysql8-p 3306:3306:映射端口-e MYSQL_ROOT_PASSWORD=123456:设置 root 密码-e MYSQL_DATABASE=testdb:初始化数据库-v mysql_data:/var/lib/mysql:挂载数据卷mysql:8.0:使用 MySQL 8.0 镜像
对于单个服务来说,这种方式很方便。
但是,如果项目还需要 Redis、Nginx、后端服务,就会出现很多长命令,维护起来比较麻烦。
六、用 Docker Compose 启动 MySQL 的方式
使用 Docker Compose,可以把配置写到 compose.yml 文件中:
services:
mysql:
image: mysql:8.0
container_name: mysql8
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: testdb
volumes:
- mysql_data:/var/lib/mysql
restart: unless-stopped
volumes:
mysql_data:
启动命令:
docker compose up -d
停止命令:
docker compose down
相比一长串 docker run 命令,Compose 文件更清晰、更适合团队协作,也更容易放进 Git 仓库进行版本管理。
七、Docker 适合什么场景
Docker 适合以下场景:
1. 快速启动单个服务
例如临时启动一个 Nginx:
docker run -d --name nginx-demo -p 8080:80 nginx
访问:
curl http://localhost:8080
2. 构建应用镜像
例如构建一个 Spring Boot 应用镜像:
docker build -t springboot-demo:1.0 .
运行:
docker run -d \
--name springboot-demo \
-p 8080:8080 \
springboot-demo:1.0
3. 管理镜像和容器
查看镜像:
docker images
查看运行中的容器:
docker ps
查看所有容器:
docker ps -a
停止容器:
docker stop springboot-demo
删除容器:
docker rm springboot-demo
删除镜像:
docker rmi springboot-demo:1.0
八、Docker Compose 适合什么场景
Docker Compose 更适合多服务项目,尤其是本地开发环境和测试环境。
例如一个典型的后端项目可能包含:
- Java 后端服务
- MySQL 数据库
- Redis 缓存
- Nginx 反向代理
如果只用 Docker 命令,需要分别执行多个 docker run,而且还要手动创建网络、挂载数据卷、配置环境变量。
使用 Compose 后,可以统一定义。
九、完整 Docker Compose 示例:Java + MySQL + Redis + Nginx
下面是一个较完整的 compose.yml 示例:
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: demo-app
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE: prod
MYSQL_HOST: mysql
MYSQL_PORT: 3306
MYSQL_DATABASE: demo
MYSQL_USERNAME: root
MYSQL_PASSWORD: 123456
REDIS_HOST: redis
REDIS_PORT: 6379
depends_on:
- mysql
- redis
networks:
- demo-net
restart: unless-stopped
mysql:
image: mysql:8.0
container_name: demo-mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: demo
volumes:
- mysql_data:/var/lib/mysql
networks:
- demo-net
restart: unless-stopped
redis:
image: redis:7
container_name: demo-redis
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- demo-net
restart: unless-stopped
nginx:
image: nginx:latest
container_name: demo-nginx
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- app
networks:
- demo-net
restart: unless-stopped
volumes:
mysql_data:
redis_data:
networks:
demo-net:
driver: bridge
启动整个项目:
docker compose up -d
查看服务状态:
docker compose ps
查看日志:
docker compose logs -f
查看某个服务日志:
docker compose logs -f app
停止并删除容器:
docker compose down
停止并删除容器、网络、数据卷:
docker compose down -v
重新构建并启动:
docker compose up -d --build
十、Docker 与 Docker Compose 命令区别
1. 启动服务
Docker:
docker run -d --name my-nginx -p 8080:80 nginx
Docker Compose:
docker compose up -d
2. 停止服务
Docker:
docker stop my-nginx
Docker Compose:
docker compose stop
3. 删除服务
Docker:
docker rm my-nginx
Docker Compose:
docker compose down
4. 查看日志
Docker:
docker logs -f my-nginx
Docker Compose:
docker compose logs -f
查看指定服务:
docker compose logs -f nginx
5. 进入容器
Docker:
docker exec -it my-nginx bash
如果容器没有 bash,可以使用 sh:
docker exec -it my-nginx sh
Docker Compose:
docker compose exec nginx bash
或:
docker compose exec nginx sh
6. 构建镜像
Docker:
docker build -t my-app:1.0 .
Docker Compose:
docker compose build
构建并启动:
docker compose up -d --build
十一、Docker 常用完整命令汇总
1. 查看 Docker 版本
docker version
docker info
2. 搜索镜像
docker search nginx
3. 拉取镜像
docker pull nginx
指定版本:
docker pull mysql:8.0
4. 查看本地镜像
docker images
5. 删除镜像
docker rmi nginx
强制删除:
docker rmi -f nginx
6. 启动容器
docker run -d --name nginx-demo -p 8080:80 nginx
7. 查看运行中的容器
docker ps
查看所有容器:
docker ps -a
8. 停止容器
docker stop nginx-demo
9. 启动已停止容器
docker start nginx-demo
10. 重启容器
docker restart nginx-demo
11. 删除容器
docker rm nginx-demo
强制删除运行中的容器:
docker rm -f nginx-demo
12. 查看容器日志
docker logs nginx-demo
实时查看:
docker logs -f nginx-demo
查看最近 100 行:
docker logs --tail=100 nginx-demo
13. 进入容器
docker exec -it nginx-demo bash
或:
docker exec -it nginx-demo sh
14. 查看容器详情
docker inspect nginx-demo
15. 查看容器资源占用
docker stats
16. 复制文件到容器
docker cp ./index.html nginx-demo:/usr/share/nginx/html/index.html
从容器复制到宿主机:
docker cp nginx-demo:/etc/nginx/nginx.conf ./nginx.conf
17. 创建网络
docker network create my-net
查看网络:
docker network ls
删除网络:
docker network rm my-net
18. 创建数据卷
docker volume create mysql_data
查看数据卷:
docker volume ls
删除数据卷:
docker volume rm mysql_data
19. 清理无用资源
清理停止的容器、无用网络、悬空镜像:
docker system prune
清理所有未使用镜像:
docker system prune -a
清理并包含数据卷:
docker system prune -a --volumes
注意:清理命令可能删除重要数据,生产环境请谨慎执行。
十二、Docker Compose 常用完整命令汇总
1. 启动服务
docker compose up
后台启动:
docker compose up -d
2. 停止并删除服务
docker compose down
删除数据卷:
docker compose down -v
3. 查看服务
docker compose ps
4. 查看日志
docker compose logs
实时日志:
docker compose logs -f
查看指定服务日志:
docker compose logs -f app
5. 构建服务
docker compose build
不使用缓存构建:
docker compose build --no-cache
构建并启动:
docker compose up -d --build
6. 停止服务但不删除容器
docker compose stop
7. 启动已停止服务
docker compose start
8. 重启服务
docker compose restart
重启指定服务:
docker compose restart app
9. 进入服务容器
docker compose exec app bash
或:
docker compose exec app sh
10. 执行一次性命令
docker compose run --rm app java -version
11. 拉取服务镜像
docker compose pull
12. 推送服务镜像
docker compose push
13. 查看 Compose 配置
docker compose config
十三、Dockerfile 常用指令说明
一个常见的 Dockerfile 如下:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
常用指令说明:
| 指令 | 作用 |
|---|---|
FROM |
指定基础镜像 |
WORKDIR |
设置工作目录 |
COPY |
复制文件到镜像 |
ADD |
复制文件,支持自动解压和 URL |
RUN |
构建镜像时执行命令 |
CMD |
容器启动时默认执行命令 |
ENTRYPOINT |
容器入口命令 |
EXPOSE |
声明容器端口 |
ENV |
设置环境变量 |
VOLUME |
声明数据卷 |
ARG |
构建参数 |
十四、Docker 和 Docker Compose 应该怎么选
如果你的场景是:
- 临时启动一个服务
- 测试某个镜像
- 构建单个镜像
- 管理单个容器
优先使用 Docker 命令。
例如:
docker run -d --name redis-demo -p 6379:6379 redis:7
如果你的场景是:
- 项目包含多个服务
- 本地开发环境需要统一启动
- 需要团队共享环境配置
- 需要管理网络、数据卷、依赖关系
- 希望一条命令启动完整系统
优先使用 Docker Compose。
例如:
docker compose up -d
十五、常见误区
误区一:Docker Compose 可以替代 Docker
不完全正确。
Docker Compose 是基于 Docker 的工具,它本身并不能脱离 Docker Engine 单独运行。Compose 的底层仍然依赖 Docker 来创建镜像、启动容器、管理网络和数据卷。
误区二:Docker 只能用于开发环境
不正确。
Docker 可以用于开发、测试、预生产和生产环境。只不过在生产环境中,通常会配合 Kubernetes、Docker Swarm、CI/CD、镜像仓库、日志监控系统等工具使用。
误区三:容器就是虚拟机
不正确。
容器和虚拟机都能提供隔离环境,但实现方式不同。
虚拟机包含完整操作系统,资源消耗较大;容器共享宿主机内核,启动速度更快,占用资源更少。
误区四:删除容器就等于删除数据
不一定。
如果数据保存在容器内部,删除容器后数据会丢失;如果数据挂载到了 volume 或宿主机目录,删除容器后数据仍然可以保留。
例如:
docker run -d \
--name mysql8 \
-v mysql_data:/var/lib/mysql \
mysql:8.0
这里的 MySQL 数据会保存在 mysql_data 数据卷中。
十六、总结
Docker 是容器化的基础工具,主要负责镜像和容器的构建、运行、停止、删除等操作;Docker Compose 是 Docker 生态中的编排工具,主要用于通过 YAML 文件统一管理多个容器服务。
一句话总结:
Docker 解决“如何运行一个容器”的问题,Docker Compose 解决“如何管理一组容器”的问题。
如果只是启动一个 Nginx、Redis、MySQL,直接使用 Docker 命令即可;如果是一个完整项目,包含应用服务、数据库、缓存、代理等多个组件,则推荐使用 Docker Compose。
实际开发中,最常见的组合方式是:
docker build -t my-app:1.0 .
docker compose up -d
掌握 Docker 命令可以帮助你理解容器的底层运行方式;掌握 Docker Compose 则可以大幅提升多服务项目的部署和维护效率。对于后端开发、运维、测试、前端工程化以及云原生方向来说,这两者都是非常重要的基础技能。