---
description: 环境变量管理规范 — 新增/修改环境变量时需同步更新的文件清单和读取机制
alwaysApply: true
---

# 环境变量管理

## 读取机制

项目有两种读取方式，新增变量时必须选对：

| 方式 | 用法 | `.env` 文件生效？ | 场景 |
|------|------|-------------------|------|
| `config._env(key, default)` | 先读 `.env` 文件，再 `os.environ`，再 default | 是（直接解析） | **首选**，用于所有业务配置 |
| `os.environ.get(key, default)` | 仅读环境变量 | 仅通过 `start.sh`（`set -a; source .env`）或 `docker-compose env_file` 间接生效 | 仅用于基础设施级配置（如 `LOG_LEVEL`） |

**规则：新增环境变量优先使用 `config._env()`**，除非变量在 `config.py` 导入之前就需要读取（如 logging 初始化）。

## 新增/修改环境变量的检查清单

每次新增或修改环境变量时，必须同步更新以下文件：

1. **`.env.example`** — 添加变量和中文说明；敏感生产值只能作为本地 `.env` 配置，不能写入仓库
2. **`README.md` Configuration 表** — 添加变量、默认值、英文描述
3. **`backend/app/config.py`** — 使用 `_env()` 读取（如适用）

如果变量影响 Docker 部署：
4. **`docker-compose.yml`** — `environment` 或 `args` 中引用

## 当前变量全景

| 变量 | 读取位置 | 默认值 | 用途 |
|------|----------|--------|------|
| `DATABASE_URL` | config.py | 无代码默认；从 `.env` / 环境变量读取，`.env.example` 仅提供本地开发示例 | 数据库连接 |
| `DOCKER_HOST_ADDR` | config.py | `localhost` | 后端访问浏览器容器地址 |
| `API_BASE_URL` | config.py | `http://localhost:8000` | 内置存储文件 URL 前缀 |
| `PLATFORM_JWT_SECRET` | config.py | 降级为 `JWT_SECRET` | Platform 管理端独立 JWT 签名密钥 |
| `OPENAI_API_KEY` | auto_name.py | （空） | Session 自动命名 |
| `LOG_LEVEL` | logging_config.py | `INFO` | 日志级别 |
| `APP_TITLE` | config.py | `Browser Pilot` | 品牌名称 |
| `CLI_COMMAND_NAME` | config.py | `bpilot` | CLI 命令名 |
| `CLI_INSTALL_COMMAND` | config.py | `pip install bpilot-cli` | CLI 安装命令 |
| `CONTAINER_PREFIX` | config.py | `bp` | Docker 容器名前缀 |
| `SELENIUM_IMAGE_NAME` | config.py | `browser-pilot-selenium` | Selenium 镜像名 |
| `SELENIUM_BASE_IMAGE` | docker-compose.yml | `selenium/standalone-chrome:latest` | Selenium 基础镜像（构建参数） |
| `NETWORK_EGRESS_DOCKER_NETWORK` | config.py | `browser-pilot-net` | 浏览器容器和托管网络出口容器共用的 Docker 网络 |
| `NETWORK_EGRESS_CONFIG_DIR` | config.py | `data/network-egress` | 托管 Clash/OpenVPN 出口配置目录 |
| `NETWORK_EGRESS_CLASH_IMAGE` | config.py | `ghcr.io/metacubex/mihomo:latest` | 托管 Clash 出口镜像 |
| `NETWORK_EGRESS_CLASH_PROXY_PORT` | config.py | `7890` | 托管 Clash 内部代理端口 |
| `NETWORK_EGRESS_OPENVPN_IMAGE` | config.py | `browser-pilot-openvpn-egress:latest` | 托管 OpenVPN 出口镜像 |
| `NETWORK_EGRESS_OPENVPN_PROXY_PORT` | config.py | `8888` | 托管 OpenVPN 内部 HTTP 代理端口 |
| `POSTGRES_USER` | docker-compose.yml/start.sh | 无 Compose/start.sh 默认；从 `.env` / 环境变量读取，`.env.example` 仅提供本地开发示例 | PG 用户名 |
| `POSTGRES_PASSWORD` | docker-compose.yml/start.sh | 无 Compose/start.sh 默认；从 `.env` / 环境变量读取，`.env.example` 仅提供本地开发示例 | PG 密码 |
| `POSTGRES_DB` | docker-compose.yml/start.sh | 无 Compose/start.sh 默认；从 `.env` / 环境变量读取，`.env.example` 仅提供本地开发示例 | PG 数据库名 |
| `MINIO_STORAGE_BOOTSTRAP` | config.py/docker-compose.yml/start.sh | Docker Compose/start.sh 设为 `true` | 是否在首次 DB 初始化或旧空 S3 配置修复时预置内置 S3 兼容存储 |
| `MINIO_ROOT_USER` | config.py/docker-compose.yml/start.sh | 无 Compose/start.sh 默认；从 `.env` / 环境变量读取，`.env.example` 仅提供本地开发示例 | 内置 S3 兼容对象存储 root 用户名 |
| `MINIO_ROOT_PASSWORD` | config.py/docker-compose.yml/start.sh | 无 Compose/start.sh 默认；从 `.env` / 环境变量读取，`.env.example` 仅提供本地开发示例 | 内置 S3 兼容对象存储 root 密码 |
| `MINIO_BUCKET` | config.py/docker-compose.yml/start.sh | 无 Compose/start.sh 默认；从 `.env` / 环境变量读取，`.env.example` 仅提供本地开发示例 | 内置 S3 兼容对象存储默认 bucket |
| `MINIO_ENDPOINT` | config.py/docker-compose.yml/start.sh | 本地 `http://localhost:9000`；Docker Compose backend 覆盖为容器内对象存储地址 | 后端访问内置 S3 兼容对象存储的 endpoint |

## 数据库密码规则

- `backend/app/config.py` 和 `docker-compose.yml` 禁止硬编码数据库密码或含固定密码的 `DATABASE_URL`。
- 本地开发示例值只放在 `.env.example`；真实部署必须复制到 `.env` 后修改。
