记一次对Makefile的重构
2023-04-18 14:52:18 时间
如果你不了解 Makefile 的话,那么推荐看看阮一峰的文章「Make 命令教程」。本文通过一个重构的例子带你写出味道更好的 Makefile,让我们开始吧!
假设有一个名为 foo 的项目,用 golang 开发,在 docker 上部署,其 Makefile 如下:
APP = $(shell basename ${CURDIR})
TAG = $(shell git log --pretty=format:"%cd.%h" --date=short -1)
.PHONY: build
build:
go build -ldflags "-X 'main.version=${TAG}'" -o ./tmp/${APP} .
.PHONY: docker-config
docker-config: env
TAG=${TAG} docker-compose config
.PHONY: docker-build
docker-build: env
TAG=${TAG} docker-compose build
.PHONY: docker-push
docker-push: env
TAG=${TAG} docker-compose push
.PHONY: docker-up
docker-up: env
TAG=${TAG} docker-compose up
.PHONY: docker-down
docker-down:
TAG=${TAG} docker-compose down
看上去很简洁,唯一需要说明的是在操作 docker-compose 的时候,传递了一个名为 TAG 的环境变量,表示项目当前所属的标签,看一下对应的 docker-compose.yml 文件:
version: "3.0"
services:
server:
image: docker.domain.com/foo:${TAG}
build:
context: .
dockerfile: build/docker/Dockerfile
ports:
- "9090:9090"
- "6060:6060"
此时出现了一个有待改进的地方:ports 信息重复,看一下对应的 config.toml 文件:
[rpc]
port = 9090
[debug]
port = 6060
其中,rpc 端口 9090,debug 端口 6060 最初是在 config.toml 文件里配置的,但是在 docker-compose.yml 文件又重复了一次,假设要修改的话,就需要修改多个地方。
此时我们很容易想到的解决方案是把端口信息也通过环境变量传递,就像 TAG 变量那样,确定了解决方案,让我们再看一下对应的 docker-compose.yml 文件:
version: "3.0"
services:
server:
image: docker.domain.com/${APP}:${TAG}
build:
context: .
dockerfile: build/docker/Dockerfile
ports:
- "${RPC_PORT}:${RPC_PORT}"
- "${DEBUG_PORT}:${DEBUG_PORT}"
让我们再看看对应的 Makefile 文件,其中用 dasel 来解析配置文件:
APP = $(shell basename ${CURDIR})
TAG = $(shell git log --pretty=format:"%cd.%h" --date=short -1)
RPC_PORT = $(shell dasel -f configs/production.toml rpc.port)
DEBUG_PORT = $(shell dasel -f configs/production.toml debug.port)
.PHONY: build
build:
go build -ldflags "-X 'main.version=${TAG}'" -o ./tmp/${APP} .
.PHONY: docker-config
docker-config: env
APP=${APP} TAG=${TAG} RPC_PORT=${RPC_PORT} DEBUG_PORT=${DEBUG_PORT} docker-compose config
.PHONY: docker-build
docker-build: env
APP=${APP} TAG=${TAG} RPC_PORT=${RPC_PORT} DEBUG_PORT=${DEBUG_PORT} docker-compose build
.PHONY: docker-push
docker-push: env
APP=${APP} TAG=${TAG} RPC_PORT=${RPC_PORT} DEBUG_PORT=${DEBUG_PORT} docker-compose push
.PHONY: docker-up
docker-up: env
APP=${APP} TAG=${TAG} RPC_PORT=${RPC_PORT} DEBUG_PORT=${DEBUG_PORT} docker-compose up
.PHONY: docker-down
docker-down:
APP=${APP} TAG=${TAG} RPC_PORT=${RPC_PORT} DEBUG_PORT=${DEBUG_PORT} docker-compose down
不得不说,长长的环境变量实在是太丑了,好在 docker-compose 支持 .env 文件,于是我们可以把环境变量写入 .env 文件,然后让 docker-compose 命令从其中取数据:
APP = $(shell basename ${CURDIR})
TAG = $(shell git log --pretty=format:"%cd.%h" --date=short -1)
RPC_PORT = $(shell dasel -f configs/production.toml rpc.port)
DEBUG_PORT = $(shell dasel -f configs/production.toml debug.port)
.PHONY: env
env: build
echo "APP=${APP}" > .env;
echo "TAG=${TAG}" >> .env;
echo "RPC_PORT=${RPC_PORT}" >> .env;
echo "DEBUG_PORT=${DEBUG_PORT}" >> .env
.PHONY: build
build:
go build -ldflags "-X 'main.version=${TAG}'" -o ./tmp/${APP} .
.PHONY: docker-config
docker-config: env
docker-compose config
.PHONY: docker-build
docker-build: env
docker-compose build
.PHONY: docker-push
docker-push: env
docker-compose push
.PHONY: docker-up
docker-up: env
docker-compose up
.PHONY: docker-down
docker-down: env
docker-compose down
在 Makefile 里,我们定义了一个 env 操作,并把它作为所有 docker-compose 操作的前置操作来执行,终于不用再写长长的环境变量了,不过记得把 .env 写到 .gitignore 里!
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击