环境变量注入是什么
systemd 启动服务时并不经过交互式 shell,所以 `export` 与环境脚本都不会自动生效。变量要通过单元里的 Environment= 内联声明,或 EnvironmentFile= 指定一个 KEY=VALUE 文件注入,也可以直接在 ExecStart 前面用 env 命令显式设置。这三种方式决定了服务进程能看到什么环境,是「本地跑得通、装上服务就报找不到配置」类问题的第一现场。
基本信息
| 适用平台 | Linux(systemd) |
|---|---|
| 写在哪个段 | [Service] 段 |
| 三种写法 | Environment=KEY=VALUE 内联;EnvironmentFile=/path 文件注入;ExecStart=/usr/bin/env KEY=VALUE 命令 |
| 文件格式 | 每行 KEY=VALUE,无 export、无引号、不支持行内注释、不做 shell 展开 |
| 可选文件 | 路径前加 - 表示文件不存在时忽略,不报错 |
| 权限要求 | env 文件常含凭据,建议 600 且属主 root;单元文件本身通常 644 |
典型使用场景
- 数据库连接串、密钥等敏感配置从单元文件里剥离,放独立文件便于单独控制权限
- 同一程序部署多实例:用不同 EnvironmentFile 区分端口、日志路径与租户
- 与环境变量式配置的应用对接(Spring Boot 的 SERVER_PORT、Node 的 NODE_ENV)
- 灰度与回滚:只切 env 文件内容,不改单元、不重装包
- 区分可选配置:用 - 前缀让可选文件缺失时不影响启动
单元中的三种写法
单元中的三种写法
[Service]
EnvironmentFile=/etc/myapp/env # 必选文件,缺失则启动失败
EnvironmentFile=-/etc/myapp/env.optional # 可选文件,缺失时忽略
Environment=LOG_LEVEL=info # 内联声明,简单值用这个
ExecStart=/usr/bin/env APP_MODE=prod /opt/app/bin/app # 只对这一次执行生效env 文件格式
env 文件格式
# /etc/myapp/env —— KEY=VALUE,每行一条,没有 export
db_host=127.0.0.1
db_port=5432
db_user=app
# 值里不要出现行内注释符号,它会被当成值的一部分
timeout=30三种注入方式对比
| 方式 | 绑定关系 | 适用与注意 |
|---|---|---|
| Environment= | 写死在单元里 | 值简单、不敏感时用;会出现在 systemctl show 输出中 |
| EnvironmentFile= | 指向外部文件 | 适合敏感值与多环境差异;改文件只需 restart 服务 |
| ExecStart 前置 env | 只影响该条命令 | 适合一次性覆盖;多个 ExecStart 要各自写 |
| $VAR 与 ${VAR} | 在 ExecStart 等指令里引用注入的变量 | 变量不存在时展开为空,注意别把路径写空 |
EnvironmentFile 由 root 读取后注入进程:文件权限设 600、属主 root,否则任何本地用户都能读到数据库口令。另外注入后的值会出现在 systemctl show 的输出里,敏感项要考虑这个展示面。
单元里用 Environment= 与多个 EnvironmentFile= 时按出现顺序生效,后面的覆盖前面的,所以可以把公共默认值放前面、环境专属覆盖放后面。改 env 文件内容后只需 restart 服务;只有改单元文件本身才需要先 daemon-reload。