百变环境—direnv 教你72变 !
笔者:何大
有任何疑问欢迎关注微信公众号:网易游戏运维平台。(长按识别上图二维码)
微信公众号原文链接:百变环境—direnv 教你72变 !
经常接触 linux 的同学,相信对环境变量并不陌生,我们执行命令需要环境变量、编译软件包需要环境变量、运行自己的代码有时候也会需要环境变量。
不知道你是否遇到过这样一种情况, 在某个目录下,执行一些命令的时候,需要提前加载一些环境变量,然而我们又不想每次都要 cd 进去,先 export 几个环境变量,然后再执行需要的命令,因为那样不仅操作起来麻烦,还有个可能因为 export 的环境变量没清理,导致影响到其他同一个 Shell 下的后续操作。
本文将介绍一个叫 direnv 的小工具,并以一个具体的开发环境部署场景作为实例,讲解如何进行环境分离,并结合 direnv 降低使用上的影响。
实际场景
最近由于项目的需求,需要在同一台机器上部署dev/test/stage 三个环境。这种多个环境共存的情况,不仅需要在代码启动时进行环境变量的分离,也需要在启动时通过环境变量来控制启动不同的环境。为此我的设计是这样的
- 代码的运行在 docker 环境下,方便系统层面的隔离
- 由于涉及到数据库以及 web api 等多个服务实例,因此使用 compose 来管理整个项目的 docker 实例
- 由于代码中使用了较多的环境变量,因此将环境变量剥离到单独的env文件中,并在 docker-compose.yml 中使用 env_file 配置项来import
- 不同的运行环境,使用不同的 docker-compose.yml 文件(
docker-compose-dev/test/stage.yml
),如下图: - 这里的 compose 文件里面用了一个 CODE_DIR 环境变量,因此每次在执行 docker-compose 命令之前,都需要先 export 一个CODE_DIR环境变量
- 同时为了不每次都敲很长的命令(docker-compose -f xxx.yml up xxx),我编写了一个 start.sh ,大概的内容如下图
在经过上述的设计之后,期待的效果是,在同一台机器上,以如下的目录结构,进入对应的目录运行对应环境的代码:
即cd code_dev -> export RUN_ENV & export CODE_DIR-> 执行 start.sh
即可以运行起一个开发环境,同理类推
至此,终于引出了 进入特定目录,就载入特定环境变量 的需求, 于是我找到了 direnv 这个工具。
具体配置
- direnv 这个工具,安装配置超级简单,直接通过 debian 8源里面就可以安装。
- 安装 direnv
# aptitude install direnv
- 修改~/.bashrc 增加 direnv 的 hook 到 bash 中(如果你用的是 zsh,请修改~/.zshrc)
#在最后加上一行
eval "$(direnv hook bash)"
- 在需要export 环境变量的目录下,编写一个名为
.envrc
的文件,内容为需要 export 的环境变量,例如:
export COMPOSE_HTTP_TIMEOUT=200
export CODE_DIR=/home/xiaomi/running/code_stage
export RUN_ENV=stage
- 在对应目录允许 direnv 加载环境变量
cd ~/running/code_stage
direnv allow .
-
在上述配置完成后,当你 cd 进入对应目录时,会自动加载
envrc
配置文件中定义的环境变量,并给出提示,如下图:
-
还可以通过
direnv status
命令查看当前加载的环境变量
####小提示
- 每次
.envrc
文件内容有更新,都需要执行一次direnv allow
命令重新加载 - 事实上 direnv 的原理是进入某个目录,就执行一次
.envrc
文件,因此还可以通过这种行为,做更多事情,发挥更大的作用哦,例如进入某个目录就执行某个命令,如下图: - 大家还想到可以在什么场景下用 direnv 呢,欢迎一起探讨!