1. 前言
在现代软件开发中,Docker 已经成为一项极为重要的技术,而 Makefile 则是构建和自动化流程的有力工具。将 Docker 和 Makefile 结合起来,可以显著简化应用程序的构建、测试和部署流程,提高开发效率和可维护性。
2. Docker简介
Docker 是一种容器化技术,允许开发者将应用程序及其依赖项打包成一个独立的容器。这个容器包含了运行应用所需的所有组件,包括操作系统、库、环境变量等。这使得应用在不同的环境中能够一致地运行,避免了“在我的机器上能运行”的问题。
Docker 的主要概念包括镜像(Image)和容器(Container):
镜像:一个镜像是一个只读的模板,包含了运行应用所需的文件系统、代码和配置。镜像是构建容器的基础。
容器:容器是基于镜像创建的一个运行实例,它隔离了应用及其依赖项,使得应用可以在一个隔离的环境中运行。
3. Makefile简介
Makefile 是一个文本文件,其中定义了一系列规则,用于自动化构建过程。通过 Makefile,开发者可以定义源代码的依赖关系,以及如何编译、链接和构建最终的应用程序。
Makefile 的基本结构如下:
1 | target: prerequisites |
- 目标(Target):表示要生成的文件或执行的操作。
- 依赖项(Prerequisites):指定目标所依赖的文件或其他目标。
- 命令(Recipe):在目标和依赖项之间,定义了如何生成目标的操作。
以下是一个简单的示例 Makefile,用于编译一个包含两个源文件的 C 程序:
1 | CC = gcc |
在这个示例中,有三个目标:
- all:默认目标,运行 myprogram 目标,生成最终的可执行文件。
- myprogram:生成可执行文件 myprogram,依赖于 main.o 和 utils.o。
- clean:删除生成的目标文件和可执行文件。
通过在命令行中运行 make 命令,Make 工具会查找当前目录下的 Makefile 文件,并根据定义的规则执行构建操作。例如,运行 make 将会编译源文件并生成可执行文件。
.PHONY
是一个特殊的目标,用于声明一组伪目标(Phony Targets)。伪目标是那些并不代表真实文件的目标,而是代表一些操作或动作。使用 .PHONY 可以告诉 Make 工具,这些目标不应该被当作文件名进行比较,而是始终会执行对应的命令,无论文件是否已经存在。
带有 .PHONY
的示例 Makefile:
1 | .PHONY: clean build run |
在这个示例中,.PHONY
声明了三个伪目标:clean, build, 和 run。当你运行 make clean
,make build
,或 make run
时,Make 工具将会执行与这些目标关联的命令,而不会考虑文件名的存在与否。
Makefile 可以更加复杂,支持条件语句、循环、变量等功能,使其能够适应各种项目的构建需求。使用 Makefile 可以提高开发效率,确保代码在不同环境下能够正确地构建。
4. Docker和Makefile结合示例
参考项目:github - voidking/python-wechaty-template
项目中Makefile内容为:
1 | P=$(shell pwd) |
项目中Dockerfile内容为:
1 | FROM python:3.9 |
宿主机上执行 make bot
,调用流程如下:
1、从Makefile中找到目标bot对应的命令,执行
1 | make build |
2、从Makefile中找到build和dockerrun对应的命令,执行
1 | docker build -t py-wechaty-template-bot:latest . |
3、执行docker build
时,当前目录中的Makefile和其他文件一起被拷贝到了容器中
4、执行docker build
中的make install
时,从Makefile中找到install对应的命令,容器中执行
1 | pip install -r requirements.txt |
5、执行docker build
结束时,指定镜像的启动命令为make run
,从Makefile中找到run对应的命令为python bot.py
6、执行docker run
时,因为没有指定启动命令,所以执行默认启动命令
1 | python bot.py |
5. 优势和总结
将 Docker 和 Makefile 结合,为开发者带来了许多优势:
- 自动化流程:通过 Makefile,可以定义一系列自动化的构建、测试和部署流程,减少手动操作的需要。
- 一致性:Docker 容器保证了应用在不同环境中的一致运行,而 Makefile 确保了构建过程的一致性。
- 可维护性:将构建和部署步骤定义在 Makefile 中,使得团队成员可以轻松了解和执行这些操作。
综上所述,结合 Docker 和 Makefile 可以使得容器化应用的构建和部署变得更加高效、可靠,并且易于维护。这种结合为现代软件开发提供了一种强大的工具,能够帮助开发者更好地管理复杂的构建流程。