# AgentLab 一键部署的配置。改完运行 ./deploy.sh(已经在跑的,改完运行 ./deploy.sh install 让它生效)。 # # 写法(这个文件直接交给 docker run --env-file,规矩和 shell 不一样): # - 一行一个 KEY=VALUE,等号两边不要空格; # - 值不要加引号,引号会原样变成值的一部分; # - 注释只能单独成行,不能写在值后面。 # # 前四项(HOST_PORT、BIND_ADDR、DATA_DIR、CONTAINER_NAME)和 ENABLE_MICROVM、ENABLE_BWRAP 是给 deploy.sh 用的; # 其余的变量原样传进容器,给 AgentLab 自己用。 # ---- 访问 ---- # 宿主机上对外的端口。浏览器打开 http://<这台机器的地址>:HOST_PORT HOST_PORT=8080 # 监听哪个地址。0.0.0.0 表示所有网卡,同一网络里的电脑、手机都能打开。 # # 注意:默认不开登录(见下面的「登录」一节)。不开登录时,同一网络里打得开页面的人都能用它——跑工作流、 # 花你配的模型额度、读你接入的数据源、在沙箱里执行代码,审批记的是各自填的署名、未经核实。 # 这种情况下只在信得过的网络里开,并用防火墙限制来源;多人使用请开登录。只给本机用,改成 127.0.0.1。 BIND_ADDR=0.0.0.0 # ---- 登录(可选)---- # off(默认,不开登录)| local(账号密码)| oidc(通用 OIDC 单点登录)。设了这一项就以它为准,界面上「设置 → 身份」 # 不能再改登录方式。local:第一次打开登录页时建第一个管理员(只在还没有管理员时可用);oidc 的身份提供方地址、 # 客户端、管理员映射在「设置 → 身份」里配。忘了密码:docker exec -it agentlab python -m app.auth reset-admin # AGENTLAB_AUTH_MODE=local # 对外访问地址(在反向代理后面时填):通知和定时任务 Webhook 里的链接、OIDC 的回调地址都按它拼,非 GET 请求的 # Origin 核对也认它。设了这一项就以它为准,界面上「设置 → 通用」里的「对外访问地址」显示「由环境变量指定」、不能改; # 不设时用界面上填的那一项。写错了(没有 http:// 或 https://、带 ? 或 #)服务启动时报错 # AGENTLAB_PUBLIC_URL=https://agentlab.example.internal # 会话:闲置多少小时、最长多少天过期 # AGENTLAB_AUTH_SESSION_IDLE_HOURS=12 # AGENTLAB_AUTH_SESSION_MAX_DAYS=7 # 会话 cookie 是否带 Secure:留空按请求是不是 https 决定;反向代理终结了 https 时填 true # AGENTLAB_AUTH_COOKIE_SECURE= # ---- 嵌入(可选)---- # 默认只有 AgentLab 自己能把页面放进 iframe(响应头 Content-Security-Policy: frame-ancestors 'self',另加 # X-Frame-Options: SAMEORIGIN),别的站点嵌进去会被浏览器拦下,防点击劫持。HSTS 不在这里加,交给终结 https 的反向代理。 # 同站的门户(和 AgentLab 在同一个可注册域名下,比如 portal.example.internal 和 agentlab.example.internal)要嵌整站时, # 把门户的地址写在下面,逗号分隔,只写 协议://主机[:端口],主机可以写 *.example.internal。填了之后只发 # frame-ancestors、不再发 X-Frame-Options。同站时登录用的会话 cookie(SameSite=Lax)会随 iframe 里的请求带上,看的人在 # 门户里照常登录、单点登录照常;嵌进去的就是整站,权限和直接打开一样。 # 跨站的门户(不在同一个可注册域名下)嵌整站不支持:浏览器不把会话 cookie 带进跨站的 iframe,登录不了;为此把 cookie # 改成 SameSite=None 会削弱整站防跨站请求伪造的那一层,Safari、Firefox 默认还是会拦。跨站要嵌,请用下面的分享链接。 # 写错了(带路径、没写协议、只写 *)服务启动时报错。 # AGENTLAB_FRAME_ANCESTORS=https://portal.example.internal # 分享页(/s,分享链接打开的只读页面)允许被哪些站点嵌,写法同上。分享页只认这一项、不认上面那一项;不填时只有 AgentLab # 自己的页面能嵌。分享链接要管理员在「设置 → 偏好设置」的「应用」一节里打开「允许建分享链接」,再由管理应用的人在 # 应用编辑的「岗位与授权」里建(必设到期、最长 90 天,可撤销);建的时候没勾「允许嵌入」的那一条,在别的页面的 iframe 里 # 不显示内容。分享页另带 Referrer-Policy: no-referrer # AGENTLAB_EMBED_ORIGINS=https://bi.example.internal # ---- 数据 ---- # 数据目录:数据库、执行断点、上传的文件、沙箱工作区,还有加密密钥 .secret_key 都在这里。 # 要备份的就是这个目录(丢了 .secret_key,存进去的 API Key 就解不开了)。 # 相对路径以 deploy.sh 所在的目录为准。升级时解到新目录的,记得指回原来的数据目录(写绝对路径最稳)。 # deploy.sh 会把它的属主改成容器里的用户(uid 10001),备份和删除要用 sudo。 DATA_DIR=~/agentlab_data # ---- 容器 ---- CONTAINER_NAME=agentlab # ---- 模型接入(可选)---- # 填了的话,第一次启动时(库里还没有任何模型接入)自动导入成模型接入。之后再改这里不会更新已导入的, # 要到界面「设置 → 模型接入」里改。也可以都留空,启动后在「设置 → 模型接入」里配,Key 加密存进数据目录。 # 不配也能用:内置的演示模型不需要 Key,编排链路能完整走一遍。 # ANTHROPIC_API_KEY= # 用中转网关时填这两个(以 Authorization: Bearer 发送),这时不填 ANTHROPIC_API_KEY # ANTHROPIC_BASE_URL= # ANTHROPIC_AUTH_TOKEN= # OPENAI_API_KEY= # 配了就用 Tavily 做网页搜索,否则退回 DuckDuckGo # TAVILY_API_KEY= # ---- 代理(可选)---- # 机器要经代理才能访问模型接口时填。NO_PROXY 里的地址不走代理。 # HTTPS_PROXY=http://proxy.example.internal:3128 # NO_PROXY=localhost,127.0.0.1 # ---- 代码沙箱 ---- # auto:按 microvm → bubblewrap → local 挑第一个能用的。可选值 auto | microvm | bubblewrap | local | off # microvm 每段代码在独立内核的虚拟机里执行,看不到容器里的数据目录、密钥和别的进程,内存上限真正生效。 # 隔离最强,但要宿主机有 KVM,见下面的 ENABLE_MICROVM。 # bubblewrap 共享内核的隔离环境:看不到数据目录和别的进程,默认断网。要额外的容器权限,见下面的 ENABLE_BWRAP。 # local 前两种都用不了时的退路:在容器里起一个普通子进程执行代码。隔离的边界只有容器本身, # 代码伤不到宿主机,但和 AgentLab 在同一个容器、同一个用户下,读得到数据目录里的数据库和 # 加密密钥、读得到传进容器的 API Key、能联网。只运行你信得过的工作流。 # off 不执行代码。 # 实际用的是哪一种,deploy.sh 部署完会打印出来,./deploy.sh status 和界面「设置 → 运行环境」里也看得到。 AGENTLAB_SANDBOX_BACKEND=auto # # microVM 要宿主机是支持 KVM 的 Linux:物理机、树莓派 5 这类 64 位 ARM 单板机、开了嵌套虚拟化的云主机。 # Mac、Windows 上的 Docker Desktop 和多数云主机没有 KVM,用不了。 # auto 本机有 /dev/kvm 时,先用一个临时容器试着启动一台 microVM,起得来才启用;起不来照常部署, # 只是不用 microVM(默认) # 1 必须启用,启动不了就报错停下 # 0 不启用 # 启用后 deploy.sh 给容器加上 --device /dev/kvm,以及 /dev/kvm 所属的组(容器里的服务以 uid 10001 运行, # 要靠这个组读写 /dev/kvm)。运行时和沙箱镜像(python:3.12-slim)已经打在镜像里,部署时不用联网。 # 已知缺口:代码节点关掉网络时,HTTP/HTTPS 和域名解析都会断,但 UDP/53 仍然放行,存在经 DNS 外泄数据的可能。 ENABLE_MICROVM=auto # # 想让代码在 bubblewrap 里执行,把下面改成 1,然后运行 ./deploy.sh install。microVM 已经启用时用不上它。 # 容器里实测(Docker 默认权限):bubblewrap 无法创建命名空间,所以 deploy.sh 要给容器加三项权限: # --security-opt seccomp=unconfined 放开 Docker 默认的系统调用过滤,才能创建命名空间 # --security-opt systempaths=unconfined 取消对 /proc、/sys 部分路径的遮蔽,才能在沙箱里挂载 /proc # --security-opt apparmor=unconfined Ubuntu 上 Docker 默认的 AppArmor 配置不允许沙箱里的挂载 # 代价:整个容器少了系统调用过滤和这几处遮蔽,内核暴露给容器的面变大。AgentLab 自己仍以非 root 运行。 # 实测在 Docker Desktop(arm64)上生效,沙箱类型显示为 bubblewrap。Ubuntu 24.04 默认还限制非特权 # user namespace,开了之后「设置 → 运行环境」里仍显示 local 的话,要在宿主机上执行 # sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0 # 这一步会放宽整台机器的限制,自行权衡。 ENABLE_BWRAP=0 # ---- 内置 PostgreSQL(可选)---- # 缺省库是数据目录里的 SQLite。新部署要用内置的 PostgreSQL 运行 ./deploy.sh install --postgres,已经在用 SQLite 的运行 # ./deploy.sh migrate-to-postgres(见 README.md「用 PostgreSQL」)。密码自动生成在数据目录的 .postgres/ 里,这里不用填。 # 和外接 PostgreSQL(AGENTLAB_DATABASE_URL)只能选一种。下面几项是给 deploy.sh 用的,都有缺省值,一般不用改;要改去掉 # 行首的 # 再 ./deploy.sh install。 # # 库的镜像(小版本固定;离线包里带着同一个标签的 postgres-image.tar) POSTGRES_IMAGE=postgres:16.15 # 库的容器名,缺省 -postgres POSTGRES_CONTAINER=agentlab-postgres # 两个容器共用的 docker 网络,缺省 -net(库的端口不对外,只在这个网络里可见) DOCKER_NETWORK=agentlab-net # 库的数据放在这个 docker 数据卷里,缺省 -pgdata(卸载不删) POSTGRES_VOLUME=agentlab-pgdata # upgrade 前自动备份库(SQLite 拷到 backups/sqlite/,内置 PostgreSQL 用 pg_dump 存到 backups/postgres/),只留最近几份 BACKUP_KEEP=5 # ---- 外接 PostgreSQL 与多进程(可选)---- # 库放在你自己的 PostgreSQL 上(库要先建好):去掉 AGENTLAB_DATABASE_URL 行首的 # 填好地址,再 ./deploy.sh install。 # 和上面的内置 PostgreSQL 只能选一种:两个都用时 deploy.sh 照实报错、不起容器。容器里的 127.0.0.1 是容器自己:库就在这台机器上时 # 写宿主机在 docker 网桥上的地址(一般是 172.17.0.1),并让 PostgreSQL 监听这个地址、pg_hba.conf 放行容器的网段(一般是 # 172.17.0.0/16);库在别的机器上就写那台的地址。下面这些 AGENTLAB_* 都原样传进容器(docker run --env-file 这个文件) # AGENTLAB_DATABASE_URL=postgresql+asyncpg://agentlab:密码@172.17.0.1:5432/agentlab # 断点放另一个库时才设(不设就和应用库同一个库) # AGENTLAB_CHECKPOINT_URL=postgresql://agentlab:密码@172.17.0.1:5432/agentlab_checkpoints # 前面有 PgBouncer 的事务模式时:AGENTLAB_DB_PGBOUNCER 设成 1,并另给直连 PostgreSQL 的地址(会话模式、直连都不用这两项)。 # 内置 PostgreSQL 是直连,设了 deploy.sh 会拦下 # AGENTLAB_DB_PGBOUNCER=0 # AGENTLAB_DATABASE_DIRECT_URL=postgresql+asyncpg://agentlab:密码@172.17.0.1:5432/agentlab # 容器里起几个工作进程,缺省 1。只有用 PostgreSQL(内置或外接)时才能大于 1:SQLite 时 deploy.sh 先拦下 # AGENTLAB_WORKERS=1 # 工作进程在库里的租约多长、隔多久续一次(秒,缺省 30、5)。租约到期没续上算进程没了,别的进程接手它的活 # AGENTLAB_WORKER_LEASE_S=30 # AGENTLAB_WORKER_HEARTBEAT_S=5 # 连接池(每个工作进程一套):常驻几条、高峰再多开几条、等空闲连接最多几秒、一条连接用多久换新(缺省 10、20、30、1800 秒)。 # 进程多了连接数跟着乘,PostgreSQL 的 max_connections 要够(见 README「用 PostgreSQL」的连接数的账) # AGENTLAB_DB_POOL_SIZE=10 # AGENTLAB_DB_MAX_OVERFLOW=20 # AGENTLAB_DB_POOL_TIMEOUT=30 # AGENTLAB_DB_POOL_RECYCLE=1800 # 启动时库还没就绪最多等几秒(按退避重试,内置、外接都一样),缺省 90 # AGENTLAB_DB_STARTUP_TIMEOUT=90