Dockerfile 和 Docker Compose 的区别与使用指南

前言

在实际项目中,我们经常需要部署包含多个组件的复杂应用,如 WordPress(需要 PHP 和 MySQL)、微服务架构等。如果使用原生的 docker run 命令逐个启动容器,不仅命令冗长,而且难以管理容器间的依赖关系和网络连接。更棘手的是,时间一久就会忘记每个容器的具体配置:映射了哪些目录、暴露了哪些端口、设置了哪些环境变量。虽然可以通过 docker inspect 查询单个容器的配置,但当容器数量增多时,这种方式效率低下,容易出错,特别是在项目迁移或团队协作时。Dockerfile 和 Docker Compose 正是为了解决这些问题而生的工具,它们让容器化应用的构建、部署和管理变得更加规范化和可维护。

Dockerfile 和 Docker Compose 的核心区别

简单来说,Dockerfile 用于定义镜像内容,而 Docker Compose 用于编排容器运行。下面是两者的详细对比:

维度 Dockerfile Docker Compose
定位 镜像构建脚本(定义如何构建镜像) 容器编排工具(定义如何运行多个容器)
作用 定义镜像内应该安装什么软件、如何配置环境 定义多个容器如何启动、互联、协作
输出 生成一个镜像文件(.tar 格式) 启动一组运行中的容器(服务栈)
文件格式 Dockerfile(纯文本指令文件) docker-compose.yml(YAML 格式配置文件)
类比 菜谱(教你如何做一道菜) 宴席订单(安排多道菜的上菜顺序和搭配)

Dockerfile:定义”一个镜像”的内容

Dockerfile 的核心就是构建镜像。它是一系列指令的集合,告诉 Docker 如何从基础镜像(如 ubuntu:22.04)开始,一步步安装依赖、复制代码、配置环境,最终生成一个可重用的镜像。

关键点:它只负责生产出静态的”安装包”(镜像),不负责运行。

Dockerfile 是一个文本文件,包含一系列指令,用于指导 Docker 如何从基础镜像开始,逐步构建出符合需求的新镜像。

核心职责

  1. 指定基础镜像(FROM)
  2. 安装软件和依赖(RUN)
  3. 复制文件(COPY/ADD)
  4. 配置环境变量(ENV)
  5. 暴露端口(EXPOSE)
  6. 定义启动命令(CMD/ENTRYPOINT)

示例:定制 WordPress 镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 基于官方 WordPress 镜像
FROM wordpress:6.6-apache

# 安装系统工具
RUN apt-get update && apt-get install -y \
vim \
curl \
&& rm -rf /var/lib/apt/lists/*

# 复制自定义配置文件
COPY wp-config.php /var/www/html/

# 设置环境变量
ENV WORDPRESS_DEBUG=false

# 暴露 80 端口
EXPOSE 80

构建镜像

1
docker build -t my-wordpress:1.0 .

Docker Compose:编排”多个容器”的协作

Docker Compose 不构建镜像(除非你指定 build: 指令),它的核心是定义服务栈。它解决的是”如何让多个容器协同工作”的问题:

  • 批量操作:一条命令启动/停止所有容器(WordPress + MySQL + Redis)
  • 网络互联:自动创建网络,让容器间通过服务名直接通信(如 WordPress 直接连 mysql 主机)
  • 依赖管理:控制启动顺序(先启动数据库,再启动应用)

Docker Compose 通过一个 YAML 文件定义多容器应用的整个服务栈,包括服务间的依赖、网络、存储等配置。

示例:WordPress + MySQL 完整环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
version: '3.8'

services:
wordpress:
image: my-wordpress:1.0
ports:
- "8080:80"
environment:
- WORDPRESS_DB_HOST=mysql
- WORDPRESS_DB_USER=wpuser
volumes:
- wordpress_data:/var/www/html
depends_on:
- mysql
networks:
- app-network

mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=wordpress
volumes:
- mysql_data:/var/lib/mysql
networks:
- app-network

volumes:
wordpress_data:
mysql_data:

networks:
app-network:
driver: bridge

启动与管理

1
2
3
4
5
6
7
8
9
10
11
# 一键启动所有服务
docker-compose up -d

# 查看本项目的容器状态
docker-compose ps

# 查看日志
docker-compose logs -f

# 停止并清理
docker-compose down

典型工作流程

在实际项目中,Dockerfile 和 Docker Compose 通常配合使用,形成完整的容器化部署流程:

1
2
3
4
5
# 1. 使用 Dockerfile 构建定制化镜像
docker build -t my-app:latest .

# 2. 使用 Docker Compose 编排多容器环境
docker-compose up -d

项目结构示例

1
2
3
4
5
6
7
my-project/
├── Dockerfile # 定义应用镜像
├── docker-compose.yml # 定义服务编排
├── src/ # 应用源代码
├── config/
│ └── wp-config.php # 配置文件
└── README.md

在这种结构中:

  • Dockerfile 确保应用能在任何地方以相同的方式运行
  • docker-compose.yml 确保多个服务能正确协同工作

常见误区澄清

  1. “Docker Compose 可以替代 Dockerfile”
    错误。Docker Compose 可以引用现有镜像,但不能定义镜像的内部构建步骤。它们解决的是不同层次的问题。

  2. “Dockerfile 也能启动多个容器”
    错误。Dockerfile 一次只构建一个镜像,不具备编排多容器的能力。启动多个容器需要多次 docker run 或使用编排工具。

  3. “必须两者都用”
    不一定。如果只运行简单的官方镜像(如单个 nginx),可以直接用 docker run,不需要 Dockerfile 或 Docker Compose。

  4. “Docker Compose 只用于开发环境”
    不完全正确。虽然 Docker Compose 在开发环境中非常方便,但它同样适用于简单的生产部署场景。对于更复杂的生产环境,通常会使用 Kubernetes 等更强大的编排工具。

如何选择?

场景 推荐方案
定制镜像需求(需安装特定软件、修改配置) 必须使用 Dockerfile
单容器运行(如简单的 Nginx 服务) 直接使用 docker run
多容器应用(如 WordPress + MySQL + Redis) 必须使用 Docker Compose
开发环境搭建(需快速启停整套服务) 强烈推荐 Docker Compose
复杂生产环境(需要高可用、自动伸缩) 考虑 Kubernetes 等高级编排工具

总结

  • Dockerfile 关注镜像内部的环境一致性,解决”这个镜像里应该装什么、怎么配置”的问题。
  • Docker Compose 关注容器之间的协作关系,解决”这些容器如何一起工作、如何通信、如何存储”的问题。

用软件开发做个类比:

  • Dockerfile ≈ 编写类的定义(Class)
  • Docker Compose ≈ 编写程序的 Main 函数,将多个类实例化并组织起来工作

理解这两者的区别和适用场景,是掌握 Docker 容器化技术的关键。在实际项目中,通常先使用 Dockerfile 定义各个服务的镜像,再通过 Docker Compose 将它们组合成一个完整的应用系统。这种分工协作的模式,让 Docker 在开发、测试、部署的全流程中都能发挥最大价值,真正实现”一次构建,到处运行”的承诺。

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

0%