.env 文件零基础完整教程(开发→打包→部署全链路)
什么是.env、语法、python-dotenv使用、git规范、打包分发、容器部署、生产安全规范全覆盖
目录
一、什么是 .env 文件,解决什么核心问题
.env 全称 environment(环境变量文件),是纯文本无后缀隐藏文件,专门存放程序环境变量。
❌ 硬编码(致命错误)
# db.py DB_HOST = "127.0.0.1" DB_USER = "root" DB_PWD = "123456" # 密码明文写代码 API_KEY = "sk-xxx密钥"
上传代码到Git会泄露账号密钥,开发/生产环境切换需要改代码、重新打包。
✅ 使用 .env 规范方案
# .env
DB_HOST=127.0.0.1
DB_USER=root
DB_PWD=123456
API_KEY=sk-xxx密钥
# db.py 从环境读取,无明文密码
import os
DB_PWD = os.getenv("DB_PWD")
配置与代码完全分离,切换环境仅替换.env,密钥不会提交代码仓库。
.env 四大核心价值
安全隔离 数据库密码、API密钥、token不存入代码仓库
多环境切换 dev/test/prod三套配置一键切换
统一标准 Python/JS/Go/Docker全生态通用
部署兼容 本地开发、服务器、容器共用一套变量名
二、.env 基础语法与文件规范
2.1 标准 .env 示例
# 数据库配置 DB_HOST=127.0.0.1 DB_PORT=3306 DB_USER=root DB_PASSWORD=Root@123456 # 布尔/数字 DEBUG=true SERVER_PORT=8000 TIMEOUT=30 # 带空格字符串必须双引号 APP_NAME="后端演示服务" # 空变量 REDIS_PASSWORD= # 多值数组(逗号分隔,代码自行拆分) ALLOW_ORIGIN="http://localhost:3000,https://prod.com"
2.2 配套模板文件 .env.example
核心规范:.env 禁止上传Git,必须提供模板 .env.example,仅保留变量名,删除真实密钥。
# .env.example(可提交git) DB_HOST=填写数据库地址 DB_PORT=3306 DB_USER=root DB_PASSWORD=请填写数据库密码 API_KEY=第三方密钥留空待填充
2.3 多环境文件命名规范
- .env.dev 本地开发环境
- .env.test 测试服务器环境
- .env.prod 生产服务器环境
- .env 兜底默认配置
三、Python读取.env:python-dotenv完整使用
Python原生os只能读取系统环境变量,读取本地.env文件需要第三方库 python-dotenv
安装依赖
基础加载 .env
指定环境文件
3.1 最简读取代码
# config.py 全局配置文件
from dotenv import load_dotenv
import os
# 加载根目录.env,会把变量注入系统环境
load_dotenv()
# 读取环境变量,第二个参数为默认值
DB_HOST = os.getenv("DB_HOST", "127.0.0.1")
DB_PORT = int(os.getenv("DB_PORT", 3306))
DEBUG = os.getenv("DEBUG", "false") == "true"
API_KEY = os.getenv("API_KEY")
# 缺失密钥直接抛出异常,阻断程序启动
if not API_KEY:
raise ValueError("缺少API_KEY环境变量,请检查.env文件")
3.2 多环境动态加载(开发常用)
from dotenv import load_dotenv
import os
# 通过环境变量区分当前环境,本地/CI/服务器通用
env_mode = os.getenv("ENV_MODE", "dev")
env_file = f".env.{env_mode}"
load_dotenv(env_file)
print(f"当前加载环境配置:{env_file}")
本地启动命令:ENV_MODE=dev python main.py
四、开发阶段完整流程
- 项目根目录新建
.env.example模板,所有变量名齐全,无真实密码 - 复制模板为
.env.dev,填充本地数据库、测试密钥 - .gitignore 写入 .env* 屏蔽所有环境文件,仅放行 .env.example
- 代码统一通过 config.py 读取环境变量,全程无硬编码
- 切换环境只需修改启动时 ENV_MODE 参数,不用改代码
.gitignore 标准配置
# 屏蔽所有真实环境文件 .env .env.dev .env.test .env.prod # 仅保留模板文件不屏蔽 !.env.example
五、Git仓库管理规范(安全核心)
Git三条铁律
1. 所有 .env、.env.* 禁止提交到远程仓库
2. 必须提交 .env.example 模板,保证新人拉取项目可直接复制使用
3. 任何密码、token、私钥绝不写入代码、注释、提交记录
六、项目打包环节处理 .env
场景1:源码打包(sdist/uv build)
打包工具默认不会打包 .env 文件,只会打包代码与pyproject.toml,不会泄露本地密钥;分发源码包给他人,对方复制.env.example使用。
场景2:exe打包(PyInstaller)
- 打包时不要将本地.env打进exe,避免本机密码随程序分发
- 程序运行目录外置.env,由使用者自行填写配置
- 打包脚本排除.env文件:–exclude .env
pyinstaller main.py --exclude .env
场景3:Docker镜像打包
Dockerfile中绝对不能COPY .env进入镜像,镜像推送仓库会泄露密钥;两种标准方案:
- 方案1:运行容器时通过 -e / –env-file 外部传入.env
- 方案2:生产使用K8s ConfigMap/Secret管理环境变量
七、部署全链路完整方案(本地→服务器→Docker→K8s)
7.1 本地开发(电脑)
使用.env.dev,load_dotenv自动加载,所有配置本地存储,不上传Git
7.2 物理云服务器部署
- 服务器项目目录新建 .env.prod,填入线上数据库、生产密钥
- 设置文件权限:chmod 600 .env.prod 仅root可读,防止其他用户读取密钥
- 启动脚本指定加载生产环境:ENV_MODE=prod python main.py
- 服务器不提交.env到代码仓库,单独运维保管
7.3 Docker 容器部署
错误写法(密钥打进镜像)
# Dockerfile 禁止这么写 COPY .env .
正确运行方式(外部注入)
# 外部传入环境文件,镜像不含密钥 docker run --env-file .env.prod -p 8000:8000 app:latest # 单独传入单个变量 docker run -e DB_HOST=10.0.0.1 app:latest
7.4 Kubernetes 生产集群
生产禁止使用.env文件,统一使用K8s Secret存储密钥、ConfigMap存储普通配置,集群自动注入容器环境变量,密钥加密存储,不落地文件。
八、生产环境安全红线
绝对禁止操作
❌ 代码、注释、提交记录写数据库密码、API密钥
❌ 将.env打包进exe、Docker镜像、源码包
❌ .env提交到Git/Gitee/GitHub远程仓库
❌ 生产服务器.env文件权限开放给所有用户
❌ 线上容器镜像内置.env配置文件
推荐安全规范
✅ 开发本地使用.env,生产使用系统/容器原生环境变量
✅ 密钥统一轮换机制,一旦泄露立刻重置
✅ 服务器.env权限chmod 600,仅所有者读写
✅ 集群环境使用Secret加密存储敏感信息
九、高频踩坑与解决方案
| 问题现象 | 原因 | 解决方案 |
|---|---|---|
| load_dotenv读不到变量 | 1.文件名错误 2.等号两侧有空格 3.文件不在项目根目录 | 文件放根目录,key=value无空格,指定文件路径load_dotenv(“.env.dev”) |
| 数字读取出来是字符串 | .env所有值默认字符串 | int(os.getenv(“PORT”, 8000))强制转换 |
| Git提交把.env上传了 | .gitignore未配置,新用户复制遗漏 | 立即轮换所有密钥,清理git历史,完善.gitignore与模板 |
| Docker镜像内置.env泄露密钥 | Dockerfile COPY .env | 删除COPY .env,运行时–env-file外部传入 |
| 多人开发配置冲突 | 共用.env,本地数据库不同 | 每人使用独立.env.dev,统一.env.example模板 |
| 生产.env被其他用户读取 | 文件权限755/644 | chmod 600 .env.prod,仅管理员可读 |
十、全流程标准落地模板
1. 项目目录结构
project/ ├── .gitignore # 屏蔽.env系列 ├── .env.example # 模板,可提交git ├── .env.dev # 本地开发(不上传) ├── config.py # 统一读取环境变量 ├── pyproject.toml # 依赖含python-dotenv ├── main.py # 程序入口 └── Dockerfile # 打包不复制.env
2. .gitignore 标准内容
.env .env.* !.env.example __pycache__ *.pyc dist build
3. pyproject.toml 依赖配置
[project.optional-dependencies] dev = [ "python-dotenv>=1.0.0" ]
4. config.py 通用加载代码
from dotenv import load_dotenv
import os
# 识别环境
env_mode = os.getenv("ENV_MODE", "dev")
env_path = f".env.{env_mode}"
load_dotenv(env_path)
# 基础配置
DEBUG = os.getenv("DEBUG", "false") == "true"
SERVER_PORT = int(os.getenv("8000"))
DB_HOST = os.getenv("DB_HOST")
DB_USER = os.getenv("DB_USER")
DB_PWD = os.getenv("DB_PASSWORD")
# 强制校验核心密钥
required_vars = ["DB_HOST", "DB_PASSWORD"]
for var in required_vars:
if not os.getenv(var):
raise RuntimeError(f"环境变量 {var} 未配置,请检查 {env_path} 文件")
.env File Full Guide (Dev → Build → Deploy)
What is .env, syntax, python-dotenv, git rules, packaging, Docker/K8s deployment security
Table of Contents
1 What is .env File & Core Purpose
.env = environment file, stores environment variables, separates sensitive credentials from source code.
Never hardcode DB password, API key inside your Python scripts.
2 Syntax & Template .env.example
Syntax: KEY=VALUE, no space around =, # for comment.
.env.example: commit to git with placeholder values, real .env files ignored by gitignore.
3 python-dotenv Usage
pip install python-dotenv
from dotenv import load_dotenv
import os
load_dotenv(".env.dev")
db_pwd = os.getenv("DB_PASSWORD")
4 Multi Environment Separation
- .env.dev local dev
- .env.test staging
- .env.prod production
Launch command: ENV_MODE=prod python main.py
5 Git Ignore Rule
# .gitignore .env .env.* !.env.example
Never push real .env to remote repo, risk credential leak.
6 Packaging Rules
- Source dist: .env excluded by default
- PyInstaller: exclude .env from binary
- Docker: Do NOT COPY .env into image
7 Full Deployment Flow
Local PC: .env.dev
VM Server: .env.prod with chmod 600 permission
Docker: pass env via –env-file at runtime
docker run --env-file .env.prod app
K8s: Use Secret for secrets, ConfigMap for plain config (no .env file)
8 Production Security Rules
- No credentials in source code / git history
- No .env inside docker images / executable packages
- Restrict file permission chmod 600 on server .env
- Rotate keys immediately after credential leak
- Cluster use encrypted Secret instead of local .env file
Common Errors
- Spaces around KEY=VALUE cause read failure
- All values read as string, cast int/bool manually
- Accidentally commit .env → rotate all secrets
Standard Project Structure
project/ ├── .gitignore ├── .env.example ├── .env.dev ├── config.py ├── pyproject.toml ├── main.py └── Dockerfile
