環境變數對照表
本頁在建置時由 repo 根目錄的 .env.example 自動產生;說明欄是該檔案裡的註解原文。.env 由 Docker Compose 與後端的 app/core/config.py 共同讀取。「選填」表示該變數在範本中是註解掉的,有合理預設值。
完整說明見部署指南;只有少數值必須在第一次啟動前修改,見快速開始。
1. 必改 —— 身分與密鑰(正式對外務必修改)
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
SECRET_KEY | changethis | 有預設 | 產生:python -c "import secrets; print(secrets.token_urlsafe(32))" SECRET_KEY 必須設成固定值、至少 32 字元,backend 與 worker 共用同一把:它簽發 JWT, 也衍生加密資料庫內憑證(PVE/LDAP 密碼、TOTP 等)的金鑰。 ENVIRONMENT 不是 local 時,沒設或留空 backend 會拒絕啟動。 上線後要更換,必須跑 backend/scripts/rotate_secret_key.py 重新加密既有憑證, 直接改這一行會讓已加密的值全部解不開。 |
FIRST_SUPERUSER | [email protected] | 有預設 | 第一位管理員帳號(PVE 連線在初始化精靈或「PVE 連線」頁設定,連線資訊存資料庫) |
FIRST_SUPERUSER_PASSWORD | changethis | 有預設 | 第一位管理員帳號(PVE 連線在初始化精靈或「PVE 連線」頁設定,連線資訊存資料庫) |
LOGIN_RATE_LIMIT_PER_ACCOUNT | 10 | 選填 | 登入節流(每分鐘):同一帳號的嘗試上限,與同一來源 IP 的總上限。 整班從同一個 NAT 出口登入時 IP 上限要夠大,預設值通常不必改。 |
LOGIN_RATE_LIMIT_PER_IP | 300 | 選填 | 登入節流(每分鐘):同一帳號的嘗試上限,與同一來源 IP 的總上限。 整班從同一個 NAT 出口登入時 IP 上限要夠大,預設值通常不必改。 |
SIGNUP_RATE_LIMIT_PER_IP | 20 | 選填 | 公開註冊的每來源 IP 每分鐘上限,與 AI API 申請/輪替的每使用者上限。 |
SIGNUP_RATE_LIMIT_PER_SUBNET | 60 | 選填 | 公開註冊的每來源 IP 每分鐘上限,與 AI API 申請/輪替的每使用者上限。 |
SIGNUP_RATE_LIMIT_GLOBAL | 120 | 選填 | 公開註冊的每來源 IP 每分鐘上限,與 AI API 申請/輪替的每使用者上限。 |
AI_API_CONTROL_RATE_LIMIT_PER_USER | 10 | 選填 | 公開註冊的每來源 IP 每分鐘上限,與 AI API 申請/輪替的每使用者上限。 |
POSTGRES_PASSWORD | changethis | 有預設 | 資料庫密碼(容器內 PostgreSQL 會用這個值建立) |
2. 環境
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
ENVIRONMENT | local | 有預設 | local / staging / production。 設 production 時,上面三個密鑰若仍是 "changethis" 會直接啟動失敗(安全檢查)。 |
ENABLE_SIGNUP | true | 有預設 | 首次啟動時的公開註冊預設值;之後由管理員後台控制信箱註冊與 Google 首次登入自動建帳。 |
PROJECT_NAME | SkyLab | 有預設 | 首次啟動時的公開註冊預設值;之後由管理員後台控制信箱註冊與 Google 首次登入自動建帳。 |
FRONTEND_HOST | http://127.0.0.1:5173 | 有預設 | 後端寄信時產生的前端連結位址(沒用到 email 可不管;nginx 同源下前端會自動跟著訪問網址走) |
3. 資料庫(容器內 PostgreSQL,通常保持預設)
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
POSTGRES_SERVER | db | 有預設 | 容器內固定連服務名 db(docker-compose 會強制覆蓋為 db),請勿改成外部 IP Compose 會把 backend/worker 的 POSTGRES_SERVER 覆寫成 pgbouncer(prestart 直連 db);這個值只影響在容器外直接跑 fastapi dev 的情況。 |
POSTGRES_PORT | 5432 | 有預設 | 容器內固定連服務名 db(docker-compose 會強制覆蓋為 db),請勿改成外部 IP Compose 會把 backend/worker 的 POSTGRES_SERVER 覆寫成 pgbouncer(prestart 直連 db);這個值只影響在容器外直接跑 fastapi dev 的情況。 |
POSTGRES_HOST_PORT | 5433 | 有預設 | Host-only Compose mapping for the local db container; containers still use db:5432. Use a different value if 5433 is already occupied. |
NGINX_HOST_PORT | 8082 | 有預設 | Host port for the nginx entrypoint (frontend + /api + /ws). Defaults to 8082 because rootless Docker cannot bind privileged ports (< 1024). |
SKYLAB_TRUSTED_PROXY | 192.0.2.2 | 選填 | 主系統經 Gateway 的 nginx 對外(閘道頁「平台入口」)時,填 Gateway 連進來的 來源 IP 或 CIDR,內建 nginx 才會還原使用者真正的 IP 與 https。沒用平台入口 就維持預設(不信任任何外部代理)。詳見 website/guides/deployment.md「平台入口」。 |
POSTGRES_DB | app | 有預設 | 主系統經 Gateway 的 nginx 對外(閘道頁「平台入口」)時,填 Gateway 連進來的 來源 IP 或 CIDR,內建 nginx 才會還原使用者真正的 IP 與 https。沒用平台入口 就維持預設(不信任任何外部代理)。詳見 website/guides/deployment.md「平台入口」。 |
POSTGRES_USER | postgres | 有預設 | 主系統經 Gateway 的 nginx 對外(閘道頁「平台入口」)時,填 Gateway 連進來的 來源 IP 或 CIDR,內建 nginx 才會還原使用者真正的 IP 與 https。沒用平台入口 就維持預設(不信任任何外部代理)。詳見 website/guides/deployment.md「平台入口」。 |
4. Compose 內部用(保持預設即可)
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
DOMAIN | localhost | 有預設 | 後端不讀 DOMAIN / STACK_NAME,目前僅 docker-compose 殘留的標籤需要 |
STACK_NAME | SkyLab | 有預設 | 後端不讀 DOMAIN / STACK_NAME,目前僅 docker-compose 殘留的標籤需要 |
DOCKER_IMAGE_BACKEND | backend | 有預設 | 本地 build 的映像名稱 |
DOCKER_IMAGE_FRONTEND | frontend | 有預設 | 本地 build 的映像名稱 |
5. Redis(速率限制 / JTI 撤銷 / arq 任務佇列 / 監控快取)
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
REDIS_ENABLED | true | 有預設 | 容器部署建議 true;容器內 URL 用服務名 redis |
REDIS_URL | redis://redis:6379/0 | 有預設 | 容器部署建議 true;容器內 URL 用服務名 redis |
6. CORS(nginx 同源時可留空;前後端不同網域才需要列來源)
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
BACKEND_CORS_ORIGINS | 有預設 |
7. Proxmox 連線(不需在這裡設定)
| 變數 | 範本值 | 必填 | 說明 |
|---|
8. System AI / vLLM(選填;不用 AI 功能保持預設即可)
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
VLLM_BASE_URL | http://localhost:8000/v1 | 有預設 | |
VLLM_API_KEY | vllm-secret-key-change-me | 有預設 | |
VLLM_MODEL_NAME | gemma4-26b-a4b-it | 有預設 |
9. AI API LiteLLM 代理(選填)
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
AI_API_BASE_URL | http://litellm:4000 | 有預設 | |
AI_API_API_KEY | ai-api-secret-key-change-me | 有預設 | |
AI_API_TIMEOUT | 120 | 有預設 | |
AI_API_MAX_REQUEST_BODY_BYTES | 1048576 | 有預設 | |
AI_API_RATE_LIMIT_PER_MINUTE | 20 | 有預設 | |
AI_API_RATE_LIMIT_WINDOW_SECONDS | 60 | 有預設 | |
AI_API_PUBLIC_BASE_URL | http://localhost:8082 | 有預設 | 使用者看見的 Campus 對外根網址,不是 LiteLLM 位址;正式部署請填實際網域。 |
LITELLM_RUNTIME_BASE_URL | http://litellm:4000 | 有預設 | 主 Compose include vllm-service/litellm/docker-compose.yml;它的 master key、upstream key、DATABASE_URL、salt key 請只放在該目錄的 .env。此處僅 保留 Campus backend 連線使用的受限 service identity,絕不可填 master key。 |
LITELLM_RUNTIME_API_KEY | 選填 | 主機程序執行 backend 時同樣改用 http://127.0.0.1:4000。 與 AI_API_API_KEY 使用同一把受限 LiteLLM service key(--init-env 會自動填入)。 | |
LITELLM_SERVICE_API_KEY | # 同一把受限 service key;prepare script 可由 AI_API_API_KEY 取得 | 選填 | 主機程序執行 backend 時同樣改用 http://127.0.0.1:4000。 與 AI_API_API_KEY 使用同一把受限 LiteLLM service key(--init-env 會自動填入)。 |
BACKEND_HOST_PORT | 8000 | 有預設 | 若主機埠被其他服務占用,可調整;容器內連線埠不變。 |
REDIS_HOST_PORT | 6379 | 有預設 | 若主機埠被其他服務占用,可調整;容器內連線埠不變。 |
10. SSH 遠端執行 / PVE log collector(選填)
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
SSH_DEFAULT_USER | root | 有預設 | SSH host key 不再有開關:連線一律用自管的 known_hosts(首次連線 TOFU 記錄, 之後對不上就拒絕),所以沒有 SSH_INSECURE_HOST_KEY 這個設定。 |
SSH_TIMEOUT | 30 | 有預設 | SSH host key 不再有開關:連線一律用自管的 known_hosts(首次連線 TOFU 記錄, 之後對不上就拒絕),所以沒有 SSH_INSECURE_HOST_KEY 這個設定。 |
11. Email / SMTP(正式環境啟用註冊時必填;MailCatcher 僅供本機開發)
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
SMTP_HOST | 有預設 | ||
SMTP_USER | 有預設 | ||
SMTP_PASSWORD | 有預設 | ||
SMTP_PORT | 587 | 有預設 | |
SMTP_TLS | True | 有預設 | |
SMTP_SSL | False | 有預設 | |
EMAILS_FROM_EMAIL | 有預設 |
12. 其他選填
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
GOOGLE_CLIENT_ID | 有預設 | Google 登入使用 OAuth Client ID;後端驗證 ID token 的 aud 與 email_verified。可登入的 Google 帳號範圍由 Google Cloud 目標對象設定控制。 | |
ENABLE_SIGNUP | true 且非 local 環境時,兩個金鑰都是必填,否則 backend 會拒絕啟動。 | 選填 | Cloudflare Turnstile 機器人驗證(密碼/LDAP 登入與註冊頁的驗證框)。 |
TURNSTILE_SITE_KEY | 有預設 | 到 Cloudflare 後台 Turnstile 新增網站取得金鑰,網域要填使用者實際開啟 SkyLab 的網域(本機測試可用 localhost)。 啟用後直接呼叫 /login/access-token 的腳本(例如 vllm-service/tools 的整合測試)也要帶 X-Turnstile-Token 才過得了。 | |
TURNSTILE_SECRET_KEY | 有預設 | 到 Cloudflare 後台 Turnstile 新增網站取得金鑰,網域要填使用者實際開啟 SkyLab 的網域(本機測試可用 localhost)。 啟用後直接呼叫 /login/access-token 的腳本(例如 vllm-service/tools 的整合測試)也要帶 X-Turnstile-Token 才過得了。 | |
LDAP_CA_CERT_FILE | /app/certs/campus-ca.pem | 選填 | LDAP/AD 登入(連線設定在管理員的 LDAP 設定頁;這裡只放 CA 憑證路徑) ldaps:// 與 StartTLS 一律驗證伺服器憑證與主機名稱。網域控制站若用校內私有 CA 或自簽憑證,填該 CA 的 PEM 路徑,並把檔案掛進 backend 與 worker 容器(例如 volume); 留空=使用系統信任庫。升級注意:既有用私有 CA/自簽憑證的 AD,在設定這個值之前 會綁定失敗(錯誤顯示為 ldap.serverUnavailable)。 |
SENTRY_DSN | 有預設 | Sentry 錯誤追蹤(後端+worker);SENTRY_RELEASE 例如填 git commit,方便看哪一版開始出錯 | |
SENTRY_TRACES_SAMPLE_RATE | 0.1 | 選填 | Sentry 錯誤追蹤(後端+worker);SENTRY_RELEASE 例如填 git commit,方便看哪一版開始出錯 |
SENTRY_RELEASE | 選填 | Sentry 錯誤追蹤(後端+worker);SENTRY_RELEASE 例如填 git commit,方便看哪一版開始出錯 | |
VITE_SENTRY_DSN | 有預設 | 前端(瀏覽器)Sentry:建置 frontend 映像時帶入;建議在 Sentry 開一個獨立的 Browser 專案 | |
DESKTOP_CLIENT_DOWNLOAD_URL | https://github.com/1Ray0/SkyLab-Connect-Releases/releases/latest/download/SkyLab-Connect-Setup.exe | 有預設 | Desktop client / WireGuard tunnel |
WIREGUARD_ENDPOINT_HOST | 選填 | Desktop client / WireGuard tunnel | |
WIREGUARD_ENDPOINT_PORT | 51821 | 選填 | Desktop client / WireGuard tunnel |
WIREGUARD_INTERFACE | wg0 | 選填 | Desktop client / WireGuard tunnel |
WIREGUARD_CLIENT_SUBNET | 10.250.0.0/16 | 選填 | Desktop client / WireGuard tunnel |
WIREGUARD_VM_SUBNET | 10.10.0.0/16 | 選填 | Fallback used only before the platform IP-management subnet is configured. |
WIREGUARD_KEEPALIVE_SECONDS | 25 | 選填 | Fallback used only before the platform IP-management subnet is configured. |
WIREGUARD_SESSION_TTL_SECONDS | 28800 | 選填 | Fallback used only before the platform IP-management subnet is configured. |
WIREGUARD_RECONCILE_ENABLED | true | 選填 | Fallback used only before the platform IP-management subnet is configured. |
WIREGUARD_RECONCILE_INTERVAL_SECONDS | 60 | 選填 | Fallback used only before the platform IP-management subnet is configured. |
WIREGUARD_REVOKED_RETENTION_DAYS | 30 | 選填 | Fallback used only before the platform IP-management subnet is configured. |
WIREGUARD_ALLOW_INACTIVE_PEER_TRANSFER | false | 選填 | Fallback used only before the platform IP-management subnet is configured. |
LOG_LEVEL | INFO | 有預設 | Logging(容器建議 LOG_JSON=true;監控 stack 的 Loki 靠 JSON 解析 level/request_id) |
LOG_JSON | true | 有預設 | Logging(容器建議 LOG_JSON=true;監控 stack 的 Loki 靠 JSON 解析 level/request_id) |
LOG_FILE_ENABLED | true | 有預設 | Logging(容器建議 LOG_JSON=true;監控 stack 的 Loki 靠 JSON 解析 level/request_id) |
DOCKER_LOG_MAX_SIZE | 10m | 選填 | docker logs 輪替(每個容器最多 MAX_SIZE × MAX_FILE) |
DOCKER_LOG_MAX_FILE | 5 | 選填 | docker logs 輪替(每個容器最多 MAX_SIZE × MAX_FILE) |
13. 監控 stack(選用):docker compose --profile monitoring up -d
| 變數 | 範本值 | 必填 | 說明 |
|---|---|---|---|
COMPOSE_PROFILES | monitoring | 選填 | 設了這行之後,一般的 docker compose up -d(含 CI 部署 workflow)就會一起啟動監控 stack |
DOCKER_SOCKET | /run/user/<uid>/docker.sock | 選填 | rootless Docker(docker info 的 SecurityOptions 有 name=rootless)要改成使用者自己的路徑, 否則 Alloy 收不到日誌、cAdvisor 抓不到容器;<uid> 用 id -u 查,data-root 看 docker info 的 Docker Root Dir |
CONTAINERD_SOCKET | /run/user/<uid>/docker/containerd/containerd.sock | 選填 | rootless Docker(docker info 的 SecurityOptions 有 name=rootless)要改成使用者自己的路徑, 否則 Alloy 收不到日誌、cAdvisor 抓不到容器;<uid> 用 id -u 查,data-root 看 docker info 的 Docker Root Dir |
DOCKER_DATA_ROOT | /home/<user>/.local/share/docker | 選填 | rootless Docker(docker info 的 SecurityOptions 有 name=rootless)要改成使用者自己的路徑, 否則 Alloy 收不到日誌、cAdvisor 抓不到容器;<uid> 用 id -u 查,data-root 看 docker info 的 Docker Root Dir |
METRICS_TOKEN | 選填 | /metrics 的 Bearer token(留空=不驗證;/metrics 本來就只在內網,nginx 不轉發) 設了之後也要寫進 monitoring/prometheus/metrics_token 並打開 prometheus.yml 的 authorization | |
GRAFANA_ADMIN_PASSWORD | 有預設 | Grafana:經 nginx 的 /grafana/ 進入;GRAFANA_ROOT_URL 填對外網址(例如 https://skylab.example.edu/grafana/) Grafana 自己的帳密登入(登入表單、API basic auth)已關閉,只能以 SkyLab 管理員免密碼進入。 內建 admin 帳號的密碼:留空(或 changethis/admin)=第一次啟動時產生隨機密碼;之後要用時以 grafana cli 重設,見 website/guides/monitoring.md「Logging in to Grafana」 | |
GRAFANA_ROOT_URL | 選填 | Grafana:經 nginx 的 /grafana/ 進入;GRAFANA_ROOT_URL 填對外網址(例如 https://skylab.example.edu/grafana/) Grafana 自己的帳密登入(登入表單、API basic auth)已關閉,只能以 SkyLab 管理員免密碼進入。 內建 admin 帳號的密碼:留空(或 changethis/admin)=第一次啟動時產生隨機密碼;之後要用時以 grafana cli 重設,見 website/guides/monitoring.md「Logging in to Grafana」 | |
GRAFANA_AUTH_PROXY_ENABLED | true | 選填 | SkyLab 管理員免密碼進 Grafana(nginx auth_request + Grafana auth.proxy,見 website/guides/monitoring.md) |
GRAFANA_SESSION_EXPIRE_MINUTES | 480 | 選填 | SkyLab 管理員免密碼進 Grafana(nginx auth_request + Grafana auth.proxy,見 website/guides/monitoring.md) |
GRAFANA_AUTHPROXY_SUBNET | 172.30.253.0/28 | 選填 | nginx 與 Grafana 專用網段;和主機或其他 docker 網路衝突時三個一起改(nginx IP 要在網段內、ip_range 外) |
GRAFANA_AUTHPROXY_IP_RANGE | 172.30.253.8/29 | 選填 | nginx 與 Grafana 專用網段;和主機或其他 docker 網路衝突時三個一起改(nginx IP 要在網段內、ip_range 外) |
GRAFANA_AUTHPROXY_NGINX_IP | 172.30.253.2 | 選填 | nginx 與 Grafana 專用網段;和主機或其他 docker 網路衝突時三個一起改(nginx IP 要在網段內、ip_range 外) |
INFLUXDB_ADMIN_PASSWORD | changethis-influxdb | 有預設 | InfluxDB 2:接收 Proxmox VE 內建 Metric Server 推送的節點/VM 指標 PVE 節點要連得到,所以通常要把 INFLUXDB_BIND_ADDRESS 改成 SkyLab 主機的內網 IP(或 0.0.0.0) |
INFLUXDB_ADMIN_TOKEN | changethis-influxdb-token | 有預設 | InfluxDB 2:接收 Proxmox VE 內建 Metric Server 推送的節點/VM 指標 PVE 節點要連得到,所以通常要把 INFLUXDB_BIND_ADDRESS 改成 SkyLab 主機的內網 IP(或 0.0.0.0) |
INFLUXDB_ORG | skylab | 選填 | InfluxDB 2:接收 Proxmox VE 內建 Metric Server 推送的節點/VM 指標 PVE 節點要連得到,所以通常要把 INFLUXDB_BIND_ADDRESS 改成 SkyLab 主機的內網 IP(或 0.0.0.0) |
INFLUXDB_BUCKET | proxmox | 選填 | InfluxDB 2:接收 Proxmox VE 內建 Metric Server 推送的節點/VM 指標 PVE 節點要連得到,所以通常要把 INFLUXDB_BIND_ADDRESS 改成 SkyLab 主機的內網 IP(或 0.0.0.0) |
INFLUXDB_RETENTION | 30d | 選填 | InfluxDB 2:接收 Proxmox VE 內建 Metric Server 推送的節點/VM 指標 PVE 節點要連得到,所以通常要把 INFLUXDB_BIND_ADDRESS 改成 SkyLab 主機的內網 IP(或 0.0.0.0) |
INFLUXDB_BIND_ADDRESS | 127.0.0.1 | 選填 | InfluxDB 2:接收 Proxmox VE 內建 Metric Server 推送的節點/VM 指標 PVE 節點要連得到,所以通常要把 INFLUXDB_BIND_ADDRESS 改成 SkyLab 主機的內網 IP(或 0.0.0.0) |