Skip to content

星枢终端 Docker 环境变量配置

本文档整理可通过 Docker/Docker Compose 配置的环境变量。完整的变量参考请查看下方环境变量表格。

⚠️ .env 生效范围

.env 文件仅对 backend 容器生效(通过 env_file 加载)。Remote Gateway 的变量必须在 docker-compose.ymlenvironment 段中直接配置,或通过 ${VAR} 语法从 .env 引用(仅 REMOTE_GATEWAY_API_TOKEN 等少量变量支持此方式)。

⚠️ v1.5.1 环境变量变更

自 v1.5.1 起,以下环境变量默认值已变更

变量旧默认值新默认值
REMOTE_GATEWAY_WS_PORT80808081
REMOTE_GATEWAY_WS_URL_LOCALws://localhost:8080ws://localhost:8081
REMOTE_GATEWAY_WS_URL_DOCKERws://remote-gateway:8080ws://remote-gateway:8081

如果您的 .env 文件中显式设置了这些变量,请同步更新。


目录


1. Backend 服务变量

配置方式: 在 .env 文件中配置,docker-compose.yml 会自动加载

变量名默认值必填描述
DEPLOYMENT_MODEdocker部署模式: localdocker
NODE_ENVproduction运行环境: development/production/test
PORT3001后端服务端口
APP_NAMENexus Terminal应用名称

Passkey 认证配置

变量名默认值必填描述
RP_IDlocalhost否(Passkey 功能启用时必填)WebAuthn RP ID。可单值(跨域共享 Passkey 推荐)或多值(按顺序映射)
RP_ORIGINhttp://localhost:5173否(Passkey 功能启用时必填)WebAuthn RP Origin。支持逗号分隔多值(完整 URL)

若要实现“一个 Passkey 跨多个完全不同域名”,请使用单一 RP_ID + 多个 RP_ORIGIN,并确保 RP_ID 域名可访问 /.well-known/webauthn

远程网关地址配置

变量名默认值描述
REMOTE_GATEWAY_API_BASE_LOCALhttp://localhost:9090本地开发时远程网关 API 地址
REMOTE_GATEWAY_API_BASE_DOCKERhttp://remote-gateway:9090Docker 部署时远程网关 API 地址
REMOTE_GATEWAY_WS_URL_LOCALws://localhost:8081本地开发时远程网关 WebSocket 地址
REMOTE_GATEWAY_WS_URL_DOCKERws://remote-gateway:8081Docker 部署时远程网关 WebSocket 地址

REMOTE_GATEWAY_WS_URL_* 可包含反向代理路径;WebRTC 远程桌面桥接会保留该路径并追加连接参数。

Remote Gateway API 鉴权(推荐)

✅ 建议为远程网关 API 配置共享令牌,避免 token 生成接口在端口被误暴露时可被滥用。

变量名默认值描述
REMOTE_GATEWAY_API_TOKEN-共享令牌:backend 请求 Remote Gateway API 时会携带 X-Remote-Gateway-Token

安全相关(自动生成)

⚠️ 以下变量首次启动时会自动生成到挂载卷 ./data/.env(容器内路径为 /app/data/.env),不要手动配置

变量名格式描述
ENCRYPTION_KEY64字符 hex数据库敏感信息加密密钥
SESSION_SECRET128字符 hex会话密钥

可选配置

变量名默认值描述
ALLOWED_ORIGINS-额外允许的 CORS 来源(逗号分隔多个域名)
ALLOWED_WS_ORIGINS-额外允许的 WebSocket 来源(逗号分隔多个域名)
ENABLE_GEO_LOOKUPtrue登录事件 IP 地理位置查询开关。设为 false 可禁用(节省外部请求)。
GEO_PROVIDERip-apiIP 地理定位提供商:ip-api(默认,免费)、ipinfo(ipinfo.io)或 iplocate(iplocate.io)。
IPINFO_TOKEN-ipinfo.io API Token(可选,提升请求配额至 50k/月)。
IPLOCATE_TOKEN-iplocate.io API Key(可选,提升请求配额与速率限制)。
IP_API_USE_HTTPSfalseIP 地理定位 API 是否使用 HTTPS
HEARTBEAT_INTERVAL_DESKTOP30000桌面端心跳间隔(毫秒)
HEARTBEAT_INTERVAL_MOBILE12000移动端心跳间隔(毫秒)
MAX_MISSED_PONGS_DESKTOP1桌面端最大允许丢失 pong 次数,超过则断开连接
MAX_MISSED_PONGS_MOBILE3移动端最大允许丢失 pong 次数,超过则断开连接
ENABLE_MULTIPLEXfalseWebSocket 多路复用开关。设为 true 启用单连接多会话模式
TRUST_PROXY-是否信任代理 (true/false)
TRUST_PROXY_HOPS-信任的代理跳数
SHELL-终端默认 Shell(如 /bin/bash
METRICS_TOKEN-Prometheus 指标端点访问令牌(保护 /api/v1/metrics
LOG_LEVELinfo后端日志等级(debug/info/warn/error/silent
LOG_PRETTY-日志格式化开关。true=pino-pretty 彩色输出,false=JSON。dev 模式默认开启
LOG_REDACT-日志脱敏开关。设为 false 可关闭敏感信息脱敏(默认开启)
LOG_TZ-日志时间戳时区(优先级高于 TZ
ENABLE_REQUEST_LOGtrue启用请求访问日志。设为 false 可关闭"请求开始/完成"日志,减少容器日志量
ENABLE_HSTSfalse启用 HSTS 安全头(Strict-Transport-Security)。仅生产 HTTPS 环境开启,开发环境勿启用
BEHIND_REVERSE_PROXYfalse设为 true 跳过 Express 安全头设置,由 Nginx/Cloudflare 等反向代理统一管理
SESSION_COOKIE_SECUREauto会话 Cookie Secure 策略:auto 根据请求协议自动设置,true 强制 HTTPS Cookie,false 强制非 Secure Cookie
ENABLE_METRICSfalse设为 true 启用 Prometheus 指标端点 /api/v1/metrics,配合 METRICS_TOKEN 保护访问
API_RATE_LIMIT_WINDOW_MS900000API 通用限流窗口时间(毫秒),默认 15 分钟
API_RATE_LIMIT_MAX300API 通用限流窗口内最大请求数
SETTINGS_RATE_LIMIT_WINDOW_MS900000Settings API 限流窗口时间(毫秒),默认 15 分钟
SETTINGS_RATE_LIMIT_MAX500Settings API 限流窗口内最大请求数
TZUTC后端进程默认时区

NL2CMD 调试配置

变量名默认值范围描述
NL2CMD_TIMING_LOG00 / 1是否启用计时日志(开发模式自动启用)
NL2CMD_SLOW_THRESHOLD_MS30000-300000慢查询阈值(毫秒),超过会记录警告
NL2CMD_REQUEST_TIMEOUT_MS300001000-300000NL2CMD 上游 HTTP 请求超时(毫秒)

⚠️ 注意: NL2CMD 的 AI 配置(API Key、Provider、Model 等)存储在数据库中,通过前端设置页面 (/settings/ai) 或 API 配置。

WebRTC / STUN / TURN 配置

WebRTC 用于 RDP/VNC 远程桌面的 P2P 数据通道。STUN 服务器帮助 NAT 穿透发现公网地址,TURN 服务器在 P2P 失败时提供中继兜底。

变量名默认值描述
WEBRTC_STUN_URLS见下方表格STUN 服务器地址(逗号分隔)。用于 NAT 穿透发现公网 IP,多服务器提高成功率。
WEBRTC_TURN_URLS-TURN 中继服务器地址(逗号分隔)。NAT 穿透失败时的流量中继兜底,通常需要自建或购买商业服务。
WEBRTC_TURN_USERNAME-TURN 服务器认证用户名
WEBRTC_TURN_CREDENTIAL-TURN 服务器认证凭据

默认 STUN 服务器说明

服务器运营方区域说明
stun.l.google.com:19302Google国际WebRTC 最常用的公共 STUN
stun1.l.google.com:19302Google国际Google 备用节点
stun.cloudflare.com:3478Cloudflare国际全球 CDN 高可用,支持 TCP/UDP
stun.chat.bilibili.com:3478Bilibili国内阿里云部署,国内网络环境优选
stun.miwifi.com:3478小米国内中国联通北京,NAT 测试工具常用默认服务器

自定义示例

dotenv
# 覆盖默认 STUN(仅使用 Cloudflare + 国内)
WEBRTC_STUN_URLS=stun:stun.cloudflare.com:3478,stun:stun.chat.bilibili.com:3478

# 配置 TURN 中继(需自建 coturn 或使用 Twilio/Cloudflare 等商业服务)
WEBRTC_TURN_URLS=turn:turn.your-server.com:3478
WEBRTC_TURN_USERNAME=your-username
WEBRTC_TURN_CREDENTIAL=your-credential

2. Remote Gateway 服务变量

配置方式: 在 docker-compose.ymlremote-gateway 服务的 environment 中直接配置 ⚠️ 重要: Remote Gateway 不读取 .env 文件,仅 docker-compose.yml 中通过 ${VAR} 语法引用的变量会从 .env 解析。其他变量必须直接写在 environment 段中。

端口配置

变量名默认值描述
REMOTE_GATEWAY_API_PORT9090Remote Gateway API 端口(Docker 内部通信端口)
REMOTE_GATEWAY_WS_PORT8081Guacamole WebSocket 端口

Guacd 连接

变量名默认值描述
GUACD_HOSTlocalhostGuacd 服务地址(内嵌于同一容器,默认 localhost)
GUACD_PORT4822Guacd 服务端口

CORS 白名单

变量名默认值描述
FRONTEND_URLhttp://frontend前端 URL(始终加入 CORS 白名单)
MAIN_BACKEND_URLhttp://backend:3001后端 URL(始终加入 CORS 白名单)

代码默认值说明:Remote Gateway 代码中的默认值为 http://localhost:5173http://localhost:3001。Docker Compose 配置通过环境变量覆盖为容器服务名 http://frontendhttp://backend:3001,实现容器间通信。

API 鉴权

变量名默认值描述
REMOTE_GATEWAY_API_TOKEN-共享令牌。若配置,backend 的 .env 中也必须配置相同值

⚠️ 生产环境强烈推荐配置此令牌。未配置时,生产模式下会输出警告日志。

可选配置

变量名默认值描述
CORS_ALLOWED_ORIGINS-额外允许的 CORS 来源(逗号分隔多个域名)
CORS_ALLOW_ALLfalse是否允许所有来源(⚠️ 仅开发环境使用)
NODE_ENVproduction运行环境

3. 端口配置

docker-compose.yml 端口映射

服务外部端口容器端口描述
frontend181118080Web 应用访问端口
backend3001 (内部)3001API 服务端口
remote-gateway- (内部)8081Guacamole WebSocket 端口(backend 内部代理)
remote-gateway- (内部)9090API 服务端口
guacd- (内部)4822Guacamole 协议端口

外部访问端口

端口服务协议
18111frontendHTTP

安全提示

18111 是明文 HTTP 入口,仅适合内网学习、测试或首次验证。公网生产环境不要直接暴露该端口;请通过 HTTPS 反向代理访问,或将会话策略设置为 SESSION_COOKIE_SECURE=true 强制只允许 HTTPS 会话。


4. 完整配置示例

.env 文件示例

以下变量仅对 backend 容器生效。Remote Gateway 端口、Guacd 连接等变量需在 docker-compose.yml 中配置。

dotenv
# ===== 部署模式 =====
DEPLOYMENT_MODE=docker

# ===== Passkey 配置(生产环境必须修改)=====
# 单域名
RP_ID=yourdomain.com
RP_ORIGIN=https://yourdomain.com
# 一个 Passkey 跨多个独立域名(Related Origins)
# RP_ID=yourdomain.com
# RP_ORIGIN=https://yourdomain.com,https://another-domain.net
# 并确保 https://yourdomain.com/.well-known/webauthn 可访问

# ===== 远程网关地址(backend 连接 remote-gateway 用)=====
REMOTE_GATEWAY_API_BASE_LOCAL=http://localhost:9090
REMOTE_GATEWAY_API_BASE_DOCKER=http://remote-gateway:9090
REMOTE_GATEWAY_WS_URL_LOCAL=ws://localhost:8081
REMOTE_GATEWAY_WS_URL_DOCKER=ws://remote-gateway:8081

# ===== Remote Gateway API 鉴权 =====
# 共享令牌:backend 与 remote-gateway 必须使用相同值
# backend 通过 .env 读取,remote-gateway 通过 docker-compose.yml 的 ${REMOTE_GATEWAY_API_TOKEN} 引用
REMOTE_GATEWAY_API_TOKEN=

# ===== 代理配置(反向代理/Cloudflare 场景)=====
# TRUST_PROXY=true
# TRUST_PROXY_HOPS=1

# ===== Session Cookie =====
# 默认 auto:HTTP 直连可登录,HTTPS 反代时自动使用 Secure Cookie
# HTTP 直连仅适合内网学习、测试或首次验证;公网生产请使用 HTTPS 反代或设为 true
# SESSION_COOKIE_SECURE=auto

# ===== IP 地理位置查询 =====
# ENABLE_GEO_LOOKUP=true
# GEO_PROVIDER=ip-api
# IPINFO_TOKEN=
# IP_API_USE_HTTPS=false
# IP 地理位置数据由 IPLocate (https://iplocate.io) 提供

# ===== WebSocket 多路复用 =====
# ENABLE_MULTIPLEX=false

# ===== 心跳与连接保活 =====
# HEARTBEAT_INTERVAL_DESKTOP=30000
# HEARTBEAT_INTERVAL_MOBILE=12000
# MAX_MISSED_PONGS_DESKTOP=1
# MAX_MISSED_PONGS_MOBILE=3

# ===== CORS 额外白名单 =====
# ALLOWED_ORIGINS=https://yourdomain.com
# ALLOWED_WS_ORIGINS=https://yourdomain.com

# ===== 监控与日志 =====
# ENABLE_METRICS=false
# METRICS_TOKEN=
# LOG_LEVEL=info
# LOG_PRETTY=
# LOG_REDACT=
# LOG_TZ=
# ENABLE_REQUEST_LOG=true
# ENABLE_HSTS=false
# TZ=UTC

# ===== 终端配置 =====
# SHELL=/bin/bash

# ===== 前端构建时变量(可选,仅自构建 frontend 镜像时生效)=====
# VITE_NOTIFICATION_TIMEOUT_MS=3000
# VITE_API_BASE_URL=

# ===== Rate Limit(可选)=====
# API_RATE_LIMIT_WINDOW_MS=900000
# API_RATE_LIMIT_MAX=300
# SETTINGS_RATE_LIMIT_WINDOW_MS=900000
# SETTINGS_RATE_LIMIT_MAX=500

Rate Limit(后端限流)

后端使用 express-rate-limit 进行基础限流。默认值已经相对宽松,但在反向代理/Cloudflare 场景或前端多接口并发加载时,仍可能触发 429

可通过以下环境变量调节(单位:毫秒 ms;仅支持正整数,缺省或非法会回退默认值):

dotenv
# 通用 API(除 auth/AI 等特殊路由外)
API_RATE_LIMIT_WINDOW_MS=900000
API_RATE_LIMIT_MAX=300

# Settings API(/api/v1/settings/*)
SETTINGS_RATE_LIMIT_WINDOW_MS=900000
SETTINGS_RATE_LIMIT_MAX=500

docker-compose.yml 完整配置

yaml
services:
  frontend:
    image: ghcr.io/silentely/nexus-terminal-frontend:latest
    container_name: nexus-terminal-frontend
    ports:
      - '18111:8080'
    depends_on:
      backend:
        condition: service_healthy
      remote-gateway:
        condition: service_healthy
    networks:
      - nexus-terminal-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:8080/ > /dev/null 2>&1 || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3

  backend:
    image: ghcr.io/silentely/nexus-terminal-backend:latest
    container_name: nexus-terminal-backend
    env_file:
      - .env # ← 仅 backend 读取 .env
    environment:
      NODE_ENV: production
      PORT: 3001
    volumes:
      - ./data:/app/data
    networks:
      - nexus-terminal-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:3001/api/v1/health > /dev/null 2>&1 || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  # Remote Gateway:内嵌 guacd,guacd 进程与 Node.js 共享同一容器
  # RDP/VNC 连接由 backend 通过 /rdp-proxy WebSocket 内部代理,无需暴露端口
  remote-gateway:
    image: ghcr.io/silentely/nexus-terminal-remote-gateway:latest
    container_name: nexus-terminal-remote-gateway
    environment:
      # guacd 已内嵌于本容器,使用 localhost 连接
      GUACD_HOST: localhost
      GUACD_PORT: 4822
      REMOTE_GATEWAY_API_PORT: 9090
      REMOTE_GATEWAY_WS_PORT: 8081
      FRONTEND_URL: http://frontend
      MAIN_BACKEND_URL: http://backend:3001
      NODE_ENV: production
      # Remote Gateway API 访问令牌(可选但强烈推荐)
      # 若配置,则 backend(.env)与 remote-gateway 必须使用相同值
      REMOTE_GATEWAY_API_TOKEN: ${REMOTE_GATEWAY_API_TOKEN}
      # CORS 配置(可选)
      # CORS_ALLOWED_ORIGINS: https://yourdomain.com
      # CORS_ALLOW_ALL: false  # ⚠️ 仅开发环境使用
    networks:
      - nexus-terminal-network
    depends_on:
      backend:
        condition: service_healthy
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:9090/health > /dev/null 2>&1 || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3

networks:
  nexus-terminal-network:
    driver: bridge

公网部署

上面的端口映射会开放 HTTP 入口。若服务器在公网,请优先使用宿主机 Nginx/Caddy/Cloudflare Tunnel 等 HTTPS 反向代理;不需要直接公网访问 18111 时,可改为 127.0.0.1:18111:8080,仅允许本机反代访问。

启动顺序保障

depends_on 配合 condition: service_healthy 确保 Docker 等待后端健康检查通过后再启动前端容器,避免启动竞态条件导致 API 请求返回 503。

backend 的 start_period: 30s 给予后端足够的初始化时间(数据库迁移、会话存储创建等),在此期间健康检查失败不会计入重试次数。

前端构建时变量(可选)

⚠️ 与后端变量的区别:后端变量在进程启动时实时读取,改 .env 重启即生效。前端 VITE_* 变量是 Vite 构建时固化到 JS 产物中的,运行时无法更改。

  • 使用 ghcr.io/silentely/nexus-terminal-frontend:latest 预构建镜像时,这些变量已内置默认值,无法覆盖。
  • 如需自定义,必须自行构建 frontend 镜像,在构建阶段通过 build.args 传入。
  • 变量通过 import.meta.env.VITE_* 在前端代码中读取。
变量名默认值描述
VITE_NOTIFICATION_TIMEOUT_MS3000通知自动关闭时间(毫秒),仅支持正整数,缺省或非法值回退默认值
VITE_API_BASE_URL-拼接后端静态资源地址的基础 URL(如背景图),留空则使用当前页面 origin

WebSocket 多路复用(前后端协同)

多路复用将多个 SSH 会话共享在一条物理 WebSocket 连接上,减少连接数和资源消耗。只需在后端设置 ENABLE_MULTIPLEX=true,前端启动时自动从 /auth/init 接口读取该配置,无需额外操作。

关闭(默认)开启
前端行为每个 SSH 会话独立建立一条 WebSocket全局共享 1 条 WebSocket,每个会话创建逻辑通道(按 sid 路由)
后端行为每条 WebSocket 绑定单个 SSH 会话在 1 条 WebSocket 上管理多个逻辑通道,按消息中的 sid 字段分发
连接数N 个会话 = N 条 WebSocketN 个会话 = 1 条 WebSocket
yaml
# 开启示例:只需设置后端环境变量,前端自动跟随
services:
  backend:
    environment:
      ENABLE_MULTIPLEX: 'true'

构建参数示例

yaml
services:
  frontend:
    build:
      context: .
      dockerfile: packages/frontend/Dockerfile
      args:
        VITE_NOTIFICATION_TIMEOUT_MS: ${VITE_NOTIFICATION_TIMEOUT_MS:-3000}
        VITE_API_BASE_URL: ${VITE_API_BASE_URL:-}
    ports:
      - '18111:8080'
    depends_on:
      - backend
      - remote-gateway

快速配置清单

首次部署(生产环境)

  1. ✅ 修改 .env 中的 RP_IDRP_ORIGIN
  2. ✅ 若希望”一个 Passkey 跨多域名”,使用单一 RP_ID + 多个 RP_ORIGIN
  3. ✅ 确保 RP_ID 域名可访问 /.well-known/webauthn
  4. ✅ 确保 ALLOWED_ORIGINS / 反向代理 CORS 配置包含所有前端域名
  5. ✅ 公网访问使用 HTTPS 反向代理;如需强制只允许 HTTPS 会话,设置 SESSION_COOKIE_SECURE=true
  6. ✅ 启动服务:docker compose up -d

5. 内置安全特性

以下安全防护已在代码层面实现,无需额外配置。了解这些特性有助于排查问题。

SSRF 防护

以下模块已内置 SSRF 防护,DNS 解析后检查目标 IP 是否指向私网(127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 等),私网地址请求会被拒绝并返回错误信息:

  • 外观模块 — HTML 主题远程加载
  • AI 智能运维 — NL2CMD 的 URL 抓取功能
  • WebRTC 远程桌面桥接 — 使用服务端配置的 remote-gateway WebSocket 地址建立连接,并在外部地址场景下进行 SSRF 校验与 DNS 绑定
  • SSRF DNS 缓存 — 使用 ipaddr.js 检测 IP 地址格式,避免直接 IP 被误缓存为域名

无需配置,自动生效。

命令注入防护

Docker 容器管理和批量命令执行已内置命令注入防护:

  • 容器 ID 校验:仅允许字母、数字、连字符、下划线,非法输入直接拒绝
  • 批量命令校验:拒绝包含反引号、$()、分号、管道符等 shell 元字符的命令
  • 无需配置,自动生效

路径穿越防护

文件上传/下载路径已内置路径穿越校验:

  • 使用 path.resolve() + startsWith() 确保路径不会逃逸出允许的目录
  • 影响模块:外观设置(背景图上传)、终端主题(主题导入)、会话挂起(日志存储)
  • 无需配置,自动生效

文档生成时间:2025-12-26 | 最后更新:2026-05-08(新增内置安全特性说明)

IP 地理位置数据由 IPLocate 提供