Skip to content

环境变量与配置管理,一篇文章搞懂

前言

随着项目越来越大、依赖越来越多,配置管理将显得越来越重要。

服务应用的哪些应该是配置?哪些写死到代码中?

哪些配置打包到 Dockerfile 镜像中,哪些在容器启动时动态加载?

多环境dev、test、prod下环境变量如何管理?

环境变量的优先级?当环境变量发生变化时,如何做到最小化修改?

为了回答上述问题,我学习相关知识并记录到了本文中。

配置与环境变量

配置是一个广义的概念,指的是一切影响应用程序行为、但又不属于其核心逻辑代码的数据或设置。它回答了这些问题:

  • 数据库在哪台机器上?
  • 日志级别该多详细?
  • 功能A对用户开放吗?
  • 缓存多久失效?

让同一份应用程序代码,能在不同的环境(开发、测试、生产)、不同需求下,表现出不同的行为,而无需重新编写和编译代码。存在形式有多种:配置文件、数据库/配置中心、启动参数、环境变量等。

在容器化技术普遍流行的现代开发中,环境变量非常受宠,其与“不可变基础设施”理念契合:可以构建一个纯净的、不包含任何环境信息的 Docker 镜像。在启动容器时,通过环境变量将“它是生产环境”、“它的数据库连接串是XXX”这些信息“注入”进去。镜像不变,环境可变。

配置文件

什么是环境变量,什么是配置?

什么是配置,哪些写死的静态代码,哪些是作为配置?静态配置与动态配置?

云原生核心原则

12-Factor 原则说的那样:把配置彻底从代码里剥离出来。

在现代云原生开发中,遵循 12-Factor App 原则将配置与代码严格分离是构建可扩展、安全应用的基础。本文将探讨环境变量的核心原则、加载优先级以及在 Python 项目中的具体实践。

核心原则

  • 不提交敏感配置:.env 文件严禁提交至版本控制系统(Git)。必须在 .gitignore 中忽略,防止 API 密钥、数据库密码泄露。
  • 配置与镜像分离:不要将 .env 打包进 Docker 镜像。镜像应保持环境无关性,通过运行时的容器编排工具注入变量。
  • Fail-Fast(快速失败):程序启动时必须校验核心配置,若缺失或格式错误应立即报错退出,避免程序在不稳定的配置下运行。

环境变量加载优先级

为了兼顾开发便利性和生产安全性,建议采用以下加载顺序(由低到高,高优先级覆盖低优先级):

代码默认值:在配置类中定义的硬编码默认值(仅限非敏感项)。

.env 文件:本地开发环境的配置文件。

Shell 环境变量:如执行 export APP_PORT=8080。

Docker Compose:environment 块定义的变量。

集群管理工具:Kubernetes Secrets 或 ConfigMaps。

  1. Python 实践示例

在 Python 中,pydantic-settings 是目前管理配置的事实标准,它提供了自动类型转换、验证和敏感信息保护功能。

3.1 统一配置类

使用 Pydantic 定义配置模型,可以自动从环境变量中读取同名变量。

配置管理工具与编程实践

参考