Docker 入门学习笔记 04:环境变量到底在做什么,为什么很多容器都依赖它
Docker 入门学习笔记 04:环境变量到底在做什么,为什么很多容器都依赖它
本专栏文章导航
- 第 01 篇:Docker 入门学习笔记 01:它到底解决了什么问题,镜像和容器又是什么
- 第 02 篇:Docker 入门学习笔记 02:基础命令、前后台运行,以及 attach、logs、exec 的区别
- 第 03 篇:Docker 入门学习笔记 03:端口映射到底是什么,为什么容器启动了却访问不到
- 第 04 篇:Docker 入门学习笔记 04:环境变量到底在做什么,为什么很多容器都依赖它
- 第 05 篇:Docker 入门学习笔记 05:卷到底是什么,为什么容器删了数据却还能保留
- 第 06 篇:Docker 入门学习笔记 06:用一个可复现的 Python 项目真正理解 Dockerfile
- 第 07 篇:Docker 入门学习笔记 07:用一个多服务案例真正理解 Docker Compose
这一篇开始进入 Docker 运行配置里非常重要的一部分:
环境变量
如果前面端口映射解决的是“服务怎么暴露出来”,那么环境变量解决的就是:
服务运行时需要的配置,怎么传进去?
这个问题会一直贯穿后面的学习,包括:
Docker Compose- 数据库和缓存镜像的启动参数
- 应用服务的运行模式
Kubernetes ConfigMapKubernetes Secret
所以环境变量不是一个小参数,而是容器运行时配置的核心方式之一。
一、为什么需要环境变量
同一个应用,在不同环境中通常需要不同配置。
例如:
- 开发环境和生产环境的数据库地址不同
- 服务监听端口不同
- 日志级别不同
- 是否开启调试模式不同
- 第三方服务地址不同
如果把这些配置都写死在代码里,会带来很多问题:
- 切换环境需要改代码
- 容易把错误配置提交进仓库
- 同一个镜像不方便复用
所以更合理的方式是:
镜像尽量保持通用,配置在容器启动时动态传入。
二、什么是环境变量
环境变量可以先理解成:
程序启动时能够读取的一组键值对配置。
例如:
APP_ENV=prod
APP_PORT=8088
DB_HOST=mysql
程序运行时可以读取这些值,然后决定:
- 自己监听哪个端口
- 连接哪个数据库
- 使用什么运行模式
所以环境变量并不是 Docker 发明的。
它本来就是操作系统和程序运行时里非常常见的一种配置方式。
Docker 做的事情只是:
在启动容器时,把这些变量传给容器里的进程。
三、Docker 里怎么传环境变量
最常见的方式是:
-e 变量名=值
例如:
docker run -e APP_ENV=dev -e APP_PORT=3000 my-app
这表示:
- 给容器传一个
APP_ENV=dev - 再传一个
APP_PORT=3000
所以 -e 的本质就是:
把运行时配置传给容器里的程序。
四、先用最小实验验证:变量是否真的传进去了
理解环境变量时,最直接的实验方式之一是让容器把自己收到的变量直接打印出来。
例如:
docker run --rm -e APP_ENV=dev -e APP_PORT=3000 ubuntu env
这里可以顺手认识几个点:
--rm:容器退出后自动删除-e:传入环境变量ubuntu:使用 ubuntu 镜像env:在容器里打印当前环境变量
如果运行成功,输出里通常能看到类似:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=b3a3d7eb4625
APP_ENV=dev
APP_PORT=3000
HOME=/root
这个实验说明了一件事:
环境变量确实已经被传进了容器。
五、再进一步验证:程序能不能真正读取这些变量
只看到变量被打印出来,还不够说明问题。
更关键的是:
容器里的程序会不会真正读取并使用这些变量?
可以用下面这个更贴近真实行为的实验:
docker run --rm -e APP_ENV=prod -e APP_PORT=8088 ubuntu bash -c 'echo APP_ENV=$APP_ENV; echo APP_PORT=$APP_PORT'
如果运行成功,会看到类似输出:
APP_ENV=prod
APP_PORT=8088
这一步比单纯执行 env 更重要,因为它证明了:
- 变量不只是“存在于容器里”
- 容器里的程序也确实能读取这些值
这才更接近真实应用的行为。
六、env 和 bash -c 两种方式有什么区别
这两个实验都能帮助理解环境变量,但它们关注的重点不同。
1. env
例如:
docker run --rm -e APP_ENV=dev -e APP_PORT=3000 ubuntu env
它关注的是:
容器当前有哪些环境变量
这是在验证:
变量有没有被传进去
2. bash -c
例如:
docker run --rm -e APP_ENV=prod -e APP_PORT=8088 ubuntu bash -c 'echo APP_ENV=$APP_ENV; echo APP_PORT=$APP_PORT'
它关注的是:
容器里的程序能不能主动读取并使用这些变量
这是在验证:
变量能不能真正被程序消费
所以可以这样记:
env:看变量有没有进来bash -c 'echo ...':看程序能不能读到它
七、--rm 在这里为什么很适合
在这类短平快的实验中,--rm 非常合适。
例如:
docker run --rm -e APP_ENV=prod ubuntu env
它表示:
容器执行完命令后,自动删除这个容器对象。
这样做的好处是:
- 不会在
docker ps -a里留下大量临时容器 - 不会占用多余的容器名字
- 非常适合验证型实验
这里也要注意一个边界:
--rm 删除的是容器,不是镜像。`
也就是说:
- 容器会被清理掉
- 镜像仍然保留在本地
八、环境变量这一块最容易混淆的地方
1. 环境变量不是 Docker 独有概念
Docker 只是把它带到了容器启动流程里。
它本质上还是程序运行时配置的一种常见方式。
2. 环境变量不会修改镜像本身
环境变量作用在容器运行时。
它不会直接把配置写回镜像。
也就是说:
- 同一个镜像
- 可以因为传入不同环境变量
- 跑出不同配置效果
3. 环境变量不只是简单参数
很多真实应用都严重依赖环境变量,例如:
- 数据库地址
- 用户名和密码
- 端口
- 运行环境
- 调试开关
- 第三方服务地址
所以环境变量不是可有可无的补充,而是容器运行配置的重要入口。
九、这一部分学完后应该掌握什么
如果这一部分真正掌握了,应该能清楚表达这些内容:
- 环境变量用于在容器启动时传递动态配置
-e 变量名=值是最常见的传递方式env能验证变量是否传进了容器bash -c 'echo ...'能验证程序是否真的读取了变量--rm适合这类一次性实验,因为它会在容器退出后自动删除容器对象- 环境变量作用在运行时,不会直接修改镜像
十、这一部分最值得记住的一句话
如果只记一句话,最值得记住的是:
环境变量的关键不只是“传进去”,而是“容器里的程序会读取它”。
十一、下一步要学什么
环境变量讲清楚之后,下一步最自然的延伸就是:
数据卷
因为接下来会遇到另一个非常关键的问题:
如果容器删掉了,数据为什么会丢?
而这正是学习卷、持久化和后续数据库容器时必须理解的起点。
本专栏文章导航
- 第 01 篇:Docker 入门学习笔记 01:它到底解决了什么问题,镜像和容器又是什么
- 第 02 篇:Docker 入门学习笔记 02:基础命令、前后台运行,以及 attach、logs、exec 的区别
- 第 03 篇:Docker 入门学习笔记 03:端口映射到底是什么,为什么容器启动了却访问不到
- 第 04 篇:Docker 入门学习笔记 04:环境变量到底在做什么,为什么很多容器都依赖它
- 第 05 篇:Docker 入门学习笔记 05:卷到底是什么,为什么容器删了数据却还能保留
- 第 06 篇:Docker 入门学习笔记 06:用一个可复现的 Python 项目真正理解 Dockerfile
- 第 07 篇:Docker 入门学习笔记 07:用一个多服务案例真正理解 Docker Compose
更多推荐




所有评论(0)