跳至內容

伺服器

我們提供 Tuist 伺服器的自託管版本,供需要對基礎設施擁有更多控制權的組織使用。此版本允許你在自己的基礎設施上託管 Tuist,確保你的資料保持安全與私密。

需要授權

自託管 Tuist 需要具備法律效力的付費授權。Tuist 的內部部署版本僅提供給採用 Enterprise 方案的組織。如果你對此版本有興趣,請聯絡 [email protected]。

舊版快取服務

舊有的自託管快取節點技術已不建議用於新安裝。請參閱自託管快取指南以取得目前自託管快取基礎設施的資訊。

現有部署仍可透過 GitHub 的 Markdown 檢視器參考舊版原始文件:快取節點與快取架構。

發布節奏#

Tuist 伺服器與 Kura 快取伺服器透過三個 GHCR 映像檔管道交付:canary(每次提交至 main)、release candidate(每週一發布,測試一週)以及 stable(隔週一提升為穩定版)。只有穩定版會移動 :latest 並預設解析;canary 與 release candidate 屬於 GitHub 預發布版本,需固定其標籤才能選用。伺服器與 Kura 遵循相同的每週發布列車,並與 Tuist CLI 的發布時程同步。

我們遵循 語義化版本 以確保版本可預測且相容。主要版本用於標示 Tuist 伺服器中需要與自託管使用者協調的重大變更;你不應預期我們會經常使用主要版本,若確實需要,我們會協助你順利完成轉換。

請參閱 發布管道 頁面,了解各管道的發布方式、如何在部署中固定特定版本,以及建議的策略:讓生產環境停留在變動較少的穩定線,同時讓暫存環境先行測試即將推出的版本。

瀏覽器工作階段升級#

若在 15 分鐘內沒有經過驗證的頁面請求或 LiveView 互動,瀏覽器工作階段將會過期,且最遲不會超過驗證後的八小時。「記住我」會恢復相同的伺服器端工作階段,但無法延長任一期限。活動每分鐘記錄一次檢查點,因此閒置的工作階段可能提前最多 59 秒過期。WebSocket 心跳、自動重新連線與背景更新不會刷新活動狀態。這些期限不會改變機器憑證或 API 權杖的有效時間。

在啟動升級後的應用程式程序之前,先執行附加的 users_tokens 遷移。現有的資料列不會回填:其建立時間會限制閒置與絕對過期時間,且在存取強制 SSO 的組織前必須重新驗證。回呼的提供者、發行者或已驗證的工作區,以及自訂 SSO 連線會儲存在伺服器端,並與組織目前的設定進行比對。已連結的帳號並非工作階段驗證的證明。

在將政策視為強制生效前,請升級每個提供服務的網頁複本。較舊的二進位檔仍可能接受原先的 60 天工作階段,且不會強制執行新的 LiveView 邊界;混合版本在結構描述上相容,但在政策上並不等同。預期使用者需要再次登入。回退至較舊的二進位檔會削弱這些控制措施;若需要結構描述回退,請在移除新欄位前停止所有讀取該欄位的二進位檔。切勿延長舊工作階段或推斷來源以避免重新驗證。

驗證器應用程式 MFA#

伺服器內建原生驗證器應用程式(TOTP)雙因素驗證。儀表板尚未提供連結;後續版本將加入設定入口。它不需要啟用旗標、託管服務相依性或身分提供者憑證:只需 PostgreSQL、下方的遷移、TOTP 驗證器,以及所有服務複本共用的穩定加密金鑰(TUIST_SECRET_KEY_ENCRYPTION,備用為 TUIST_SECRET_KEY_BASE)。請保持伺服器與驗證器的時鐘同步。MFA 驗證及其每五分鐘五次失敗代碼的共用配額使用 PostgreSQL 資料列鎖定,而非 Redis。

設定需要在最近五分鐘內登入、將設定金鑰輸入 TOTP 驗證器應用程式,並確認應用程式產生的代碼。系統會顯示十個一次性復原代碼,僅顯示一次;請妥善儲存。停用該因素也需要近期登入以及未使用的驗證器或復原代碼。變更因素會撤銷其他瀏覽器工作階段。重設密碼不會移除 MFA,且此實作不提供僅限電子郵件或管理員繞過遺失因素的機制。

一旦註冊,每次新的瀏覽器登入(包含聯合登入)在取得工作階段或完成基於瀏覽器的 CLI/裝置授權前,都需要原生第二因素。直接密碼與 Apple API 登入會拒絕已註冊的使用者,並指示他們使用瀏覽器登入。已註冊使用者的新電子郵件代理聲明需要經過 MFA 驗證的瀏覽器工作階段;僅限信箱的舊式聲明會被拒絕。現有的 API 權杖、機器憑證、工作負載身分及其續約規則維持不變。這是針對個別使用者的選用支援,並非組織範圍的 MFA 強制要求,也不是對身分提供者自身 MFA 政策的驗證。組織 SSO 除了原生因素外,仍需正確設定的提供者/發行者。

註冊、登入、使用復原代碼或停用 MFA 都不需要提供電子郵件。因素變更通知為尽力而為;傳送失敗不會撤銷已完成的變更。

在新版二進位檔之前,執行獨立的累加式 user_mfa/users_tokens.mfa_verified_at 遷移。TOTP 秘密金鑰使用現有的 Vault 加密金鑰;請保留該金鑰及其備份。在允許 MFA 註冊前,請完成 所有提供驗證服務的複本 的升級。舊版二進位檔可以繞過原生 MFA,因此在註冊後,它們不是符合政策要求的回滾目標。刪除 MFA 結構描述會破壞註冊和復原狀態;請先停止讀取器並保留加密備份。混合版本結構描述的相容性並非 MFA 或瀏覽器工作階段控制已強制執行的證據。

OAuth 升級與回滾邊界#

移除 OAuth 實體快取需要對現有安裝進行分階段升級。在部署停止 OAuth 快取失效的版本之前,請先將來自 #14040 的權威讀取相容版本部署到 每個 OAuth 讀取器和寫入器。此相容階段首次出現在 1.355 發行系列中:ghcr.io/tuist/tuist:1.355.0-rc.1 包含它;一旦提升為穩定版,生產環境部署應使用穩定的 1.355.x 版本。安裝在 1.354 或更早版本的系統必須在完成此階段後,才能升級到包含移除功能的後續版本。保持 1.355 系列僅用於相容性:不要將失效移除功能回溯移植到該系列中。

原始相容性提交也可作為 ghcr.io/tuist/tuist:sha-c8e54471a425 取得。另一個映像檔僅在保留權威讀取 並保留舊式失效 且舊消費者仍然存在時,才適合作為相容階段。在提供流量服務之前,請執行該階段的常規資料庫遷移,包括重新整理權杖查詢索引。

檢查每個環境中的所有 Web 複本、背景工作器、排程工作以及單獨固定的處理器映像檔。等待相容性推出完成,並在移除失效之前驗證沒有剩餘的快取讀取二進位檔。不要在自動升級期間讓浮動映像標籤跳過此階段。沒有舊消費者的全新安裝不需要中間部署。

保留權威讀取的回滾目標

移除失效後,常規的滾動回滾必須針對 #14040 或另一個權威讀取版本。即使每個無失效程序都已停止,保留的 OAuth 快取條目仍可能過時,並且重新啟動的快取讀取複本可以從對等節點匯入它們。

進一步回滾需要停止並排空 所有 無失效 OAuth 消費者,然後在啟動任何快取讀取消費者之前清除或替換 每個 保留的 Boruta 快取參與者。防止保留的參與者重新加入。僅排空入口或僅重新啟動 Web 複本是不夠的;請與您的 Tuist 支援聯絡人協調此恢復過程,而不是自動清除快取或回滾資料庫遷移。

多複本叢集#

支援的多複本 Web 部署需要 Erlang 叢集來實現跨複本的 Phoenix PubSub 和 Oban PG 通知,而非作為驗證授權機構。當 server.cluster.enabled 為 false 時,Chart 會拒絕多個複本,包括可以增長超過一個複本的自動縮放器。先前接受的未叢集部署必須規劃此升級,而不是繞過防護。在變更成員資格之前,請完成 OAuth 升級序列,包括移除失效。

使用您的秘密管理器在發布命名空間中建立私有 Cookie Secret,然後設定其名稱和金鑰:

yaml
server:
replicaCount: 2
cluster:
enabled: true
distributionPort: 9100
cookieExistingSecret: tuist-server-cluster
cookieExistingSecretKey: release-cookie

Cookie 必須具有高熵並由所有參與的 Web 複本共用。切勿使用嵌入在已發布映像檔中的 Cookie:擁有分發 Cookie 即授予在其節點上遠端執行的權限。分散式發布啟動現在會拒絕缺少的私有 RELEASE_COOKIE 或無效的連接埠,包括明確設定的 RELEASE_DISTRIBUTION=name 或 sname 而無需 DNS 發現。非 Chart 部署也必須一致地設定 TUIST_CLUSTER_DNS_SERVICE、TUIST_CLUSTER_APP_NAME 以及 Pod IP/節點名稱。發現目前使用 IPv4 A 記錄。

透過常規伺服器連接的 helm upgrade,將 cookieExistingSecret 留空會建立 Cookie Secret,並在後續升級中重複使用其當前值。離線 helm template、Argo CD 和其他沒有即時 Secret 查詢的 GitOps 轉譯器無法保留該生成的值;它們必須使用由單獨管理的穩定 Secret 支援的 cookieExistingSecret。不要更改 Cookie 金鑰以隱式輪換活躍叢集。Cookie 輪換需要協調每個參與者的遷移/重新啟動;僅更新 Secret 不會更新現有程序。

從映像檔內建 Cookie 的首次推出會形成單獨的新舊成員島嶼,直到所有 Web 複本都使用私有 Secret。為即時更新規劃遷移視窗。後續的滾動部署會形成混合版本叢集,因此請根據實際的新舊版本限定 PubSub、Oban 通知和對等節點替換。這些通知不是持久的交付保證。在回滾相容版本時,請保留權威讀取的回滾映像檔並保持相同的私有 Cookie。

僅允許受信任的伺服器對等節點之間使用 EPMD(TCP 4369)和設定的分發連接埠,絕不允許來自租戶工作負載或公共網路。驗證您環境中的實際入口/出口隔離;轉譯 NetworkPolicy 並不能證明強制執行或後端可達性。兩複本金絲雀在持續負載下必須通過加入、滾動替換和故障/恢復測試才能提升。DNS 用於發現對等節點,而不是在瞬態失敗或部分回應時斷開健康節點的連線;真實節點丟失和 OTP 分割預防仍然適用。libcluster 可能仍會為保留回調記錄成功的「斷開」操作而不關閉連線;請從節點上線/下線事件或 Node.list() 建立實際成員資格,而不僅依賴該日誌行。

持續部署#

我們建議將生產環境鎖定在穩定的次要版本線(例如 ghcr.io/tuist/tuist:1.351),以便日常升級僅包含回溯移植的修復程式。穩定版本線會在候選發布通道上經過一週的浸泡測試後,於每週一 UTC 06:00 提升;在 canary 或當前候選發布標籤上的暫存環境可以在問題影響使用者之前捕捉回歸錯誤。請參閱 Release channels 以了解建議的鎖定策略。

如果您希望在不修改清單檔案的情況下吸收新功能,請鎖定 :latest。該標籤每週一早上更新一次,因此請相應安排您的部署視窗。以下是一個 GitHub Actions 工作流程範例,它會按照此頻率檢查並部署最新的穩定映像檔:

yaml
name: Update Tuist Server
on:
schedule:
- cron: '0 8 * * 1' # Mondays 08:00 UTC, after the weekly stable promote
workflow_dispatch: # Allow manual runs
jobs:
update:
runs-on: ubuntu-latest
steps:
- name: Check and deploy latest version
run: |
# Your deployment commands here
# Example: docker pull ghcr.io/tuist/tuist:latest
# Deploy to your infrastructure

網路信任存取#

自託管安裝可以允許受信任網路上的開發人員在不登入的情況下提交洞察報告、使用快取,或兩者皆可。儀表板和管理功能仍然需要驗證。

僅啟用您需要的功能:

伺服器環境變數允許無需登入
TUIST_NETWORK_TRUSTED_INSIGHTS_ACCESS=true提交建置和測試洞察報告
TUIST_NETWORK_TRUSTED_CACHE_ACCESS=true讀取和寫入快取的二進位輸出

這兩項設定預設均為 關閉,彼此獨立,並適用於所有帳戶和專案(包括私有專案)的整個實例。它們在託管的 Tuist 上不可用,也不能取代自託管授權。

當未設定 TUIST_NETWORK_TRUSTED_INSIGHTS_ACCESS 時,舊的 TUIST_NETWORK_TRUSTED_REPORT_PUBLISHING 名稱仍作為相容性備援。

Warning

僅在強制執行的辦公網路或 VPN 邊界後方啟用這些設定。任何能夠存取已啟用端點的人都可以提交報告,或者在啟用快取存取時讀取和覆寫快取輸出。這可能導致偽造的遙測資料、快取污染和容量耗盡。報告回應也可能洩露私有專案的控制代碼和建置系統。Tuist 不會驗證 VPN 成員資格,也不會信任轉發的 IP 標頭作為成員資格的證明。

設定實例#

  1. 使用防火牆或私有入口,將 Tuist 伺服器、每個 Kura HTTP/gRPC 監聽器以及任何 Bazel BES 入口限制在您的受信任網路內。
  2. 在升級用戶端之前,先升級每個伺服器和 Kura 複本。保持 Kura 驗證啟用狀態,並使用 KURA_AUTH_TUIST_URL 及其控制平面憑證;停用它會繞過這些限制。請使用 self-hosted cache guide 設定您的快取端點。
  3. 在每個相關的 Tuist 伺服器複本上設定上述所需的變數,然後重新啟動或重新部署它們。只有確切的值 true 才能啟用設定。儀表板上沒有切換開關,也沒有單獨的 Kura 旗標。

設定用戶端#

在每個相容的用戶端上設定最終的自託管伺服器 URL 和專案。當缺少憑證時,用戶端會自動發現哪些功能已啟用;無需用戶端選擇加入。探索不會遵循重新導向。現有憑證會繼續使用,而無效或刷新失敗的憑證會導致錯誤,而不是匿名回退。請重新登入或明確登出以恢復。

在啟用洞察存取之前,請將所有共用憑證的工具升級到能夠保留損壞或被拒絕的憑證、拒絕無法讀取的憑證目錄,並在未簽署的報告中省略 Git 來源的版本。較舊的工具可能會刪除憑證並意外允許匿名回退;僅升級伺服器無法解決此問題。如果伺服器缺乏探索支援或回滾到較舊版本,用戶端必須進行驗證。舊的 TUIST_NETWORK_TRUSTED_PUBLISHING 用戶端設定不再適用。

  • 洞察: 僅提交已完成的 Xcode、Gradle、Elixir/Mix 和 Bazel 報告,不包含封存、附件、涵蓋率、分片規劃或現有報告存取。參與者聲明未經驗證;未簽署的遙測資料不會驅動受信任的測試證據或自動化。請參閱 Xcode、Gradle 和 Elixir 指南以了解用戶端設定和隱私權詳細資訊。
  • 快取: 支援 CLI 編譯/模組快取、Bazel 快取和 Gradle 任務快取。快取清除和遠端資產下載仍然需要憑證。不支援的用戶端必須繼續進行驗證。
  • Bazel: 報告需要明確的 TUIST_BAZEL_BES_BACKEND 和相容的 Kura。快取和報告選項是獨立啟用的。在更改憑證或任一設定後,請重新執行 tuist bazel setup;對於編譯快取設定變更,請重新執行 tuist cache config。

報告請求限制為每個專案每次 8 MB、每分鐘 60 次請求和每天 10,000 次請求。為具有多個複本的部署範圍配額設定共用的 Valkey;否則限制是按程序計算。如果設定的共用配額後端不可用,則會拒絕未簽署的報告。同時添加入口連線、主體和速率限制。

停用網路信任存取#

將相關變數設定為 false,然後重新啟動 每個相關的伺服器複本。舊複本在被替換之前可以繼續接受無需憑證的請求。在最後一個複本切換後的 60 秒內,新請求的快取存取將停止;進行中的傳輸不會被取消。如果需要立即撤銷,請先在入口處封鎖流量。現有報告保留其常規的可見性和保留策略,且經過驗證的用戶端繼續正常工作。

執行階段需求#

本節概述了在您的基礎設施上託管 Tuist 伺服器的需求。

相容性矩陣#

Tuist 伺服器已通過測試,並與以下最低版本相容:

元件最低版本備註
PostgreSQL15
ClickHouse25分析功能所需

執行 Docker 虛擬化映像檔#

我們透過 GitHub’s Container Registry 以 Docker 映像檔的形式分發伺服器。

要執行它,您的基礎設施必須支援執行 Docker 映像檔。請注意,大多數基礎設施供應商都支援它,因為它已成為在生產環境中分發和執行軟體的標準容器。

Postgres 資料庫#

除了執行 Docker 映像檔外,您還需要一個 Postgres 資料庫 來儲存關聯式資料。大多數基礎設施供應商在其服務中都包含 Postgres 資料庫(例如 AWS 和 Google Cloud)。

遷移

Docker 映像檔的進入點會在啟動服務前自動執行任何待處理的結構描述遷移。

ClickHouse 資料庫#

Tuist 使用 ClickHouse 來儲存和查詢大量分析資料。ClickHouse 是建置洞察等功能的 必要條件。您可以選擇自行託管 ClickHouse 或使用其託管服務。

遷移

Docker 映像檔的進入點會在啟動服務前自動執行任何待處理的 ClickHouse 結構描述遷移。

內建的 Docker Compose 和 Helm 嵌入式 ClickHouse 設定會將 ClickHouse 文字記錄層級從映像檔預設的 trace 降低至 information,這是 system.text_log 容量的主要來源。兩者也可以限制 ClickHouse 自身的 system.* 作業記錄表,這些表否則會是無限制的,但此功能預設為關閉 — 請參閱下文。外部 ClickHouse 部署應在其 ClickHouse 服務中直接設定這些作業記錄。

ClickHouse 複寫拓撲#

Tuist 後方的多複本 ClickHouse 僅在 ClickHouse Cloud 上支援。自行管理的 ClickHouse 為單複本。

匯入遷移會發出普通的 MergeTree 引擎。在 Cloud 上,這會透明地變為 SharedMergeTree,因此寫入會落入共用的物件儲存空間,且任何複本數量皆可運作。在自行管理的 ClickHouse 上,MergeTree 僅寫入單一複本的本地磁碟;多複本設定要么會靜默地在複本間分割匯入,要么會以 UNKNOWN_STORAGE: Only tables with a Replicated engine or tables which do not store data on disk are allowed in a Replicated database. 拒絕 CREATE,具體取決於連接使用者如何設定 database_replicated_allow_only_replicated_engine。

在自行管理的 ClickHouse 上執行一個具有一個複本的分片,並定期備份 ClickHouse 資料目錄。如果節點遺失,沒有第二個複本可以回退。

限制作業記錄保留期#

保留期可應用於 system.text_log、system.query_log、system.query_thread_log、system.query_views_log、system.trace_log、system.metric_log、system.asynchronous_metric_log 和 system.part_log。

在已有資料的實例上開啟此功能是一次性且不可逆的步驟,這就是為什麼兩個套件都不會為您執行此操作。任何保留視窗都會導致這些表定義不再符合其設定,因此 ClickHouse 會將每個表重新命名並啟動一個新表,如 被取代的記錄表 中所述。留下的世代持有迄今為止累積的所有內容,且自身不帶有任何保留期,因此除非您在同一步驟中回收它,否則它將永久保留在磁碟上,而新視窗僅限制從那時起寫入的列。同時啟用兩者:

yaml
clickhouse:
embedded:
systemLogs:
ttlDays: 14
supersededTables: delete

該單一的 helm upgrade 是自包含的,因為將 ttlDays 從空白改為設定值會新增掛載並滾動更新 ClickHouse Pod:它會重新啟動、取代表,然後升級後作業會刪除它們。使用 helm upgrade --wait 進行部署,以便在作業執行前先滾動更新 Pod;否則世代會在作業檢查後出現,而下一次 helm upgrade 則會回收它們。

使用 Docker Compose 時,取消註解 docker-compose.yml 中 clickhouse 服務上的 clickhouse-log-ttl.xml 卷,並在 .env 中設定這兩個變數:

bash
CLICKHOUSE_SYSTEM_LOG_TTL_DAYS=14
CLICKHOUSE_SUPERSEDED_LOG_TABLES=delete

一旦空間被回收,您可以將 supersededTables/CLICKHOUSE_SUPERSEDED_LOG_TABLES 改回 ignore,這樣後續的 ClickHouse 升級就不會自行丟棄歷史記錄。

被取代的記錄表#

ClickHouse 在啟動時檢查每個系統記錄表是否仍符合其設定。當不符合時,它會將現有表重新命名為 system.<name>_0,然後是 _1、_2 等,並啟動一個新表。這發生在您更改保留視窗時,以及任何更改系統記錄結構描述的 ClickHouse 升級時。

重新命名表不會複製其資料,因此這不會消耗額外的磁碟空間。被取代的表之後會發生什麼取決於它來自哪個表,因為它保留了被取代時活動表所擁有的任何保留期。第一次啟用保留期時,被取代的表沒有任何保留期,因此它會持有迄今為止累積的所有歷史記錄並無限期保留。隨後對視窗的更改會取代已帶有 TTL 的表,因此這些表會自行過期並留下一個空表。ClickHouse 從不刪除表本身,因此在長期運行的實例上,它們無論如何都會累積。

預設情況下會保留被取代的表,這樣升級就不會自行丟棄作業歷史記錄。將策略設定為 delete 以改為刪除它們,這發生在 docker compose up 和每次 helm upgrade 時:

bash
CLICKHOUSE_SUPERSEDED_LOG_TABLES=delete

使用 Helm chart 時,將相同的策略設定為值:

yaml
clickhouse:
embedded:
systemLogs:
supersededTables: delete

刪除被取代的表會回收其磁碟空間。活動表從未被觸及,自被取代以來寫入的列也未受影響。

若要在不更改策略的情況下一次性回收空間,請手動刪除表:

sql
SELECT name FROM system.tables WHERE database = 'system' AND match(name, '_log_[0-9]+$');
DROP TABLE IF EXISTS system.text_log_0 SYNC;

system 資料庫使用 Atomic 引擎,這會將普通的 DROP TABLE 延遲 database_atomic_delay_before_drop_table_sec(預設為八分鐘)。SYNC 會立即刪除資料,這正是您在因磁碟已滿而刪除這些表時所需要的。

儲存空間#

您還需要一個解決方案來儲存檔案(例如框架和函式庫二進位檔)。Tuist 伺服器支援 S3 相容儲存空間和 Azure Blob Storage,用於伺服器拥有的工件。

最佳化快取

如果您的主要目標是減少快取延遲,您可能不需要自行託管整個伺服器。您可以在靠近您的 CI 或開發者網路的位置部署自行託管的 Kura 節點,並將它們連接到託管的 Tuist 伺服器或您的自行託管伺服器。

請參閱 自行託管快取指南。

自行託管的 Kura 節點#

若要將自行託管的 Kura 節點與自行託管的 Tuist 伺服器一起使用:

  1. 在 Tuist 伺服器上設定 KURA_CONTROL_PLANE_CLIENT_ID 和 KURA_CONTROL_PLANE_CLIENT_SECRET。用戶端 ID 必須是 UUID。使用 自行託管快取指南 中的命令產生 UUID 和隨機密鑰,並將它們儲存在您的部署密鑰中。
  2. 按照 自行託管快取指南 部署 Kura 節點,使用相同的控制平面憑證。
  3. 使用 KURA_REGISTRATION_URL 和 KURA_ADVERTISED_HTTP_URL 設定每個 Kura 節點。註冊心跳會告知伺服器哪些已就緒且面向客戶端的 Kura 端點可以向 CLI 公告。

設定#

服務的設定是在執行階段透過環境變數完成。鑑於這些變數的敏感性,我們建議將其加密並儲存在安全的密碼管理解決方案中。請放心,Tuist 會極其謹慎地處理這些變數,確保它們絕不會顯示在日誌中。

啟動檢查

必要的變數會在啟動時進行驗證。如果缺少任何變數,啟動將會失敗,且錯誤訊息會詳細說明缺少的變數。

授權設定#

作為本地部署使用者,您將收到一個需要公開為環境變數的授權。該授權用於驗證部署,並確保服務在協議條款範圍內運行。

環境變數描述必要預設值範例
TUIST_LICENSE簽署服務等級協議後提供的授權。接受標準授權金鑰,或用於無法聯絡外部服務的隔離環境中的 base64 編碼憑證。是******
到期日

授權具有到期日。如果授權在 30 天內到期,使用者在使用與伺服器互動的 Tuist 命令時會收到警告。如果您有興趣續訂授權,請聯絡 [email protected]。

基礎環境設定#

環境變數描述必要預設值範例
TUIST_APP_URL從網際網路存取執行個體的基礎 URL是https://tuist.dev
TUIST_SECRET_KEY_BASE用於加密資訊的金鑰(例如 cookie 中的工作階段)是c5786d9f869239cbddeca645575349a570ffebb332b64400c37256e1c9cb7ec831345d03dc0188edd129d09580d8cbf3ceaf17768e2048c037d9c31da5dcacfa
TUIST_SECRET_KEY_PASSWORD用於產生雜湊密碼的鹽值否$TUIST_SECRET_KEY_BASE
TUIST_SECRET_KEY_TOKENS用於產生隨機權杖的密鑰否$TUIST_SECRET_KEY_BASE
TUIST_SECRET_KEY_ENCRYPTION用於 AES-GCM 加密敏感資料的 32 位元組金鑰否$TUIST_SECRET_KEY_BASE
TUIST_USE_IPV6當為 1 時,它會將應用程式設定為使用 IPv6 位址否01
TUIST_LOG_LEVEL應用程式使用的日誌層級否info日誌層級
TUIST_GITHUB_APP_NAME您的 GitHub 應用程式的 slug,取自 https://github.com/apps/<slug>。安裝應用程式時需要。請參閱 GitHub否my-app
TUIST_GITHUB_APP_PRIVATE_KEY_BASE64用於 GitHub 應用程式的 base64 編碼私鑰,以解鎖額外功能,例如自動發布 PR 評論否LS0tLS1CRUdJTiBSU0EgUFJJVkFUR...
TUIST_GITHUB_APP_PRIVATE_KEY用於 GitHub 應用程式的私鑰,以解鎖額外功能,例如自動發布 PR 評論。我們建議改用 base64 編碼版本,以避免特殊字元問題否-----BEGIN RSA...
TUIST_OPERATOR_EMAIL_DOMAIN電子郵件地址以 @<this-domain> 結尾的已確認使用者可以存取營運 URL(/ops/*)否tuist.devexample.com
TUIST_SERVER_VERSION_IDENTIFIER在儀表板導覽列中顯示為徽章的標籤,用於識別伺服器執行個體(例如版本號或分支名稱)否開發環境中的 Git 分支v1.2.3
TUIST_WEB啟用網頁伺服器端點否11 或 0
TUIST_NETWORK_TRUSTED_INSIGHTS_ACCESS允許在未登入的情況下提交建置和測試見解。請參閱 網路信任存取 以了解設定和安全要求。否falsetrue
TUIST_NETWORK_TRUSTED_CACHE_ACCESS允許在未登入的情況下讀取和寫入快取。請參閱 網路信任存取 以了解設定和安全要求。否falsetrue
TUIST_OTEL_EXPORTER_OTLP_ENDPOINTOpenTelemetry Collector 的 gRPC 端點,用於傳送追蹤資料否http://localhost:4317
TUIST_LOKI_URLLoki 相容端點的基礎 URL,用於推送日誌(例如 Grafana Alloy 或 Loki)否http://localhost:3100
透過 HTTPS 提供應用程式服務

工作階段 Cookie 標記為 Secure,因此瀏覽器會在純文字 http:// 連線中丟棄它們,導致使用者無法登入。請在伺服器前方終止 TLS(使用內部 CA 簽發憑證的反向代理即可),並將 TUIST_APP_URL 設定為 https:// URL,即使是內部或僅限 VPN 的部署也是如此。

資料庫設定#

下列環境變數用於設定資料庫連線:

環境變數描述必要預設值範例
DATABASE_URL存取 Postgres 資料庫的 URL。請注意,URL 應包含驗證資訊是postgres://username:[email protected]/production
TUIST_DATABASE_SCHEMATuist 應用程式資料表使用的 PostgreSQL 結構描述。當您的資料庫政策不允許使用 public 結構描述時,請設定此項。結構描述名稱必須是未加引號的 PostgreSQL 識別碼。否publictuist
TUIST_MIGRATION_DATABASE_URL僅由 Tuist.Release.migrate 使用的選用 Postgres URL。當 DATABASE_URL 指向權限較窄的執行階段角色時,請將其設定為擁有者角色 URL。否DATABASE_URLpostgres://owner:[email protected]/production
TUIST_DATABASE_RUNTIME_ROLE遷移完成後應授予應用程式資料表權限的執行階段 Postgres 角色。當網頁伺服器不應以結構描述擁有者身分連線時,請將此項與 TUIST_MIGRATION_DATABASE_URL 搭配使用。否tuist_web
TUIST_CLICKHOUSE_URL存取 ClickHouse 資料庫的 URL。請注意,URL 應包含驗證資訊否http://username:[email protected]/production
TUIST_USE_SSL_FOR_DATABASE當為 true 時,它會使用 SSL 連線至資料庫否11
TUIST_DATABASE_POOL_SIZE連線池中保持開啟的連線數量否1010
TUIST_DATABASE_QUEUE_TARGET檢查從池中取出的所有連線是否耗時超過佇列間隔的時間(以毫秒為單位)(更多資訊)否300300
TUIST_DATABASE_QUEUE_INTERVAL佇列中的閾值時間(以毫秒為單位),池使用此時間來決定是否開始丟棄新連線(更多資訊)否10001000
TUIST_CLICKHOUSE_FLUSH_INTERVAL_MSClickHouse 緩衝區重新整理之間的時間間隔(以毫秒為單位)否50005000
TUIST_CLICKHOUSE_MAX_BUFFER_SIZE強制重新整理前的最大 ClickHouse 緩衝區大小(以位元組為單位)否10000001000000
TUIST_CLICKHOUSE_BUFFER_POOL_SIZE要執行的 ClickHouse 緩衝區處理序數量否55

當 TUIST_DATABASE_SCHEMA 不是 public 時,若結構描述尚不存在,發布遷移會在執行 Ecto 遷移鏈之前建立該結構描述。如果遷移角色無法建立結構描述,請預先建立結構描述並將遷移角色設為其擁有者。

Tuist 透過設定工作階段 search_path 將連線指向自訂結構描述。某些共用或代理的 Postgres 設定(例如 PgBouncer,或限制啟動參數的受管資料庫)不會套用此設定,導致工作階段回退至 public,這在遷移期間會顯示為 permission denied for schema public。透過此類設定連線時,請將結構描述固定在角色本身,以便每個工作階段無論代理為何都從該結構描述開始:

sql
CREATE SCHEMA IF NOT EXISTS tuist AUTHORIZATION <migration_role>;
ALTER ROLE <migration_role> IN DATABASE <database> SET search_path = tuist;
-- If the web server connects as a separate runtime role (TUIST_DATABASE_RUNTIME_ROLE):
ALTER ROLE <runtime_role> IN DATABASE <database> SET search_path = tuist;

驗證環境設定#

我們透過 身分提供者 (IdP) 促進驗證。若要使用此功能,請確保所選提供者的所有必要環境變數都存在於伺服器環境中。缺少變數 將導致 Tuist 略過該提供者。

電子郵件和密碼#

電子郵件和密碼登入以及自助註冊是內建功能且預設啟用。在需要要求身分提供者(例如強制使用 SSO)的執行個體上,您可以完全關閉它們。這會從登入體驗中移除電子郵件/密碼表單、註冊連結和密碼重設流程,並關閉每個對應的伺服器端端點,包括 CLI 使用的電子郵件/密碼端點(tuist auth)。

環境變數描述必要預設值範例
TUIST_EMAIL_AUTH_ENABLED是否可以使用電子郵件和密碼進行登入和註冊。設定為 0 可從登入頁面移除電子郵件/密碼表單、註冊連結和密碼重設流程,並關閉對應的伺服器端端點否10

停用已設定的身分提供者#

預設情況下,只要設定了提供者,它就會顯示為登入選項。若要保留提供者設定(其憑證保持設定狀態)同時將其從登入和註冊頁面中移除,請將對應的開關設為 0。對於 GitHub、Google 和 Apple,這也會關閉登入回呼,因此該方法將完全無法使用。

環境變數描述必要預設值範例
TUIST_GITHUB_AUTH_ENABLED是否可以使用 GitHub 進行登入(請參閱 GitHub 章節,了解為何應用程式與登入共用其憑證)否10
TUIST_GOOGLE_AUTH_ENABLED是否可以使用 Google 進行登入否10
TUIST_OKTA_AUTH_ENABLED已設定的 Okta 提供者是否顯示為登入選項否10
TUIST_APPLE_AUTH_ENABLED是否可以使用 Apple 進行登入否10

GitHub#

我們建議使用 GitHub App 進行驗證,但您也可以使用 OAuth App。請確保伺服器環境中包含 GitHub 指定的所有必要環境變數。缺少變數將導致 Tuist 略過 GitHub 驗證。若要正確設定 GitHub 應用程式:

  • 在 GitHub 應用程式的一般設定中:
    • 複製 Client ID 並將其設定為 TUIST_GITHUB_APP_CLIENT_ID
    • 建立並複製新的 client secret,然後將其設定為 TUIST_GITHUB_APP_CLIENT_SECRET
    • 將 Callback URL 設定為 http://YOUR_APP_URL/users/auth/github/callback。YOUR_APP_URL 也可以是您伺服器的 IP 位址。
  • 需要以下權限:
    • 儲存庫:
      • 拉取請求:讀寫
    • 帳戶:
      • 電子郵件地址:唯讀

在 Permissions and events 的 Account permissions 區段中,將 Email addresses 權限設定為 Read-only。

接著,您需要在 Tuist 伺服器執行的環境中公開下列環境變數:

環境變數描述必要預設值範例
TUIST_GITHUB_APP_CLIENT_IDGitHub 應用程式的用戶端 ID是Iv1.a629723000043722
TUIST_GITHUB_APP_CLIENT_SECRET應用程式的用戶端密碼是232f972951033b89799b0fd24566a04d83f44ccc
TUIST_GITHUB_AUTH_ENABLED是否可以使用 GitHub 進行登入。您為平台整合(PR 評論等)設定的 GitHub App 會與登入共用其用戶端憑證,因此它會顯示為登入選項。設定為 0 可保留應用程式同時從登入頁面移除 GitHub否10

Google#

您可以使用 OAuth 2 設定 Google 驗證。為此,您需要建立類型為 OAuth 用戶端 ID 的新憑證。建立憑證時,選擇「Web Application」作為應用程式類型,將其命名為 Tuist,並將重新導向 URI 設定為 {base_url}/users/auth/google/callback,其中 base_url 是您託管服務運行的 URL。建立應用程式後,複製用戶端 ID 和密碼,並分別將它們設定為環境變數 GOOGLE_CLIENT_ID 和 GOOGLE_CLIENT_SECRET。

同意畫面範圍

您可能需要建立同意畫面。建立時,請務必新增 userinfo.email 和 openid 範圍,並將應用程式標記為內部。

Okta#

您可以透過 OAuth 2.0 協定啟用 Okta 驗證。您必須按照 這些說明 在 Okta 上 建立應用程式。

在設定 Okta 應用程式期間取得用戶端 ID 和密碼後,您需要設定下列環境變數:

環境變數描述必要預設值範例
TUIST_OKTA_1_CLIENT_ID用於向 Okta 驗證的用戶端 ID。數字應為您的組織 ID是
TUIST_OKTA_1_CLIENT_SECRET用於向 Okta 驗證的用戶端密碼是

數字 1 需要替換為您的組織 ID。這通常為 1,但請檢查您的資料庫。

儲存環境設定#

Tuist 需要儲存空間來存放透過 API 上傳的成品。為了讓 Tuist 有效運作,必須設定其中一種支援的儲存解決方案。

設定 TUIST_OBJECT_STORAGE_PROVIDER 以選擇伺服器成品後端:

環境變數描述必要預設值範例
TUIST_OBJECT_STORAGE_PROVIDER伺服器成品儲存後端。對於 S3 相容儲存使用 s3,對於 Azure Blob Storage 使用 azure_blob否s3azure_blob

S3 相容儲存#

您可以使用任何 S3 相容的儲存提供者來儲存成品。下列環境變數是驗證和設定與儲存提供者整合所必需的:

環境變數描述必要預設值範例
TUIST_S3_ACCESS_KEY_ID 或 AWS_ACCESS_KEY_ID用於向儲存提供者驗證的存取金鑰 ID是AKIAIOSFOD
TUIST_S3_SECRET_ACCESS_KEY 或 AWS_SECRET_ACCESS_KEY用於向儲存提供者驗證的秘密存取金鑰是wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
TUIST_S3_REGION 或 AWS_REGION儲存桶所在的區域否autous-west-2
TUIST_S3_ENDPOINT 或 AWS_ENDPOINT儲存提供者的端點是https://s3.us-west-2.amazonaws.com
TUIST_S3_BUCKET_NAME將儲存成品的儲存桶名稱是tuist-artifacts
TUIST_S3_CA_CERT_PEMPEM 編碼的 CA 憑證,用於驗證 S3 HTTPS 連線。適用於具有自簽名憑證或內部憑證授權單位的隔離環境。否系統 CA 捆綁包-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----
TUIST_S3_CONNECT_TIMEOUT建立與儲存提供者連線的逾時時間(毫秒)否30003000
TUIST_S3_RECEIVE_TIMEOUT從儲存提供者接收資料的逾時時間(毫秒)否50005000
TUIST_S3_POOL_TIMEOUT連線池與儲存提供者之間連線的逾時時間(毫秒)。使用 infinity 表示無逾時否50005000
TUIST_S3_POOL_MAX_IDLE_TIME連線池中連線的最大閒置時間(毫秒)。使用 infinity 以無限期保持連線活躍否infinity60000
TUIST_S3_POOL_SIZE每個連線池的最大連線數否500500
TUIST_S3_POOL_COUNT要使用的連線池數量否系統排程器數量4
TUIST_S3_PROTOCOL連線至儲存提供者時使用的協定(http1 或 http2)否http1http1
TUIST_S3_VIRTUAL_HOST是否應將儲存桶名稱作為子網域(虛擬主機)來建構 URL否false1
使用環境變數中的 Web Identity Token 進行 AWS 驗證

如果您的儲存提供者是 AWS,且您希望使用 Web Identity Token 進行驗證,您可以將環境變數 TUIST_S3_AUTHENTICATION_METHOD 設定為 aws_web_identity_token_from_env_vars,Tuist 將會使用該方法並搭配慣用的 AWS 環境變數。

Google Cloud Storage#

對於 Google Cloud Storage,請遵循 這些文件 取得 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 配對。AWS_ENDPOINT 應設定為 https://storage.googleapis.com。其他環境變數與任何其他 S3 相容儲存相同。

Azure Blob Storage#

對於 Azure Blob Storage,請設定 TUIST_OBJECT_STORAGE_PROVIDER=azure_blob 並設定 Azure 儲存帳戶憑證:

環境變數描述必要預設值範例
TUIST_AZURE_STORAGE_ACCOUNT_NAMEAzure 儲存帳戶名稱是tuiststorage
TUIST_AZURE_STORAGE_ACCOUNT_KEY用於簽署 Azure Blob REST 請求和 SAS URL 的儲存帳戶存取金鑰是******
TUIST_AZURE_BLOB_CONTAINER_NAME儲存伺服器成品的容器是tuist-artifacts
TUIST_AZURE_BLOB_ENDPOINTBlob 服務端點。省略則使用 https://<account>.blob.core.windows.net否衍生自帳戶名稱https://tuiststorage.blob.core.windows.net
TUIST_AZURE_BLOB_SERVICE_VERSION用於簽署請求和 SAS URL 的 Azure Blob REST API 版本否2020-12-062020-12-06

使用 Helm chart 時,請設定 server.storage.provider=azure_blob 並填寫 server.azureBlob.*。chart 的頂層 objectStorage 設定仍保持 S3 相容,因為可選的快取和 registry-mirror 工作負載仍預期使用 S3 相容儲存。如果停用這些工作負載且伺服器使用 Azure Blob,請設定 objectStorage.mode=external 並將外部物件儲存端點和憑證留空,以避免部署內嵌的 MinIO 服務。

成品保留#

在自託管實例中,成品清理預設為停用。每種支援的成品類型都有其專屬的環境變數。將變數設定為正整數的天數,即可啟用該成品類型的清理。將變數留空或不設定,則僅停用該成品類型的清理。

bash
TUIST_CACHE_ARTIFACT_RETENTION_DAYS=30
TUIST_APP_PREVIEW_RETENTION_DAYS=30
TUIST_BUILD_ARCHIVE_RETENTION_DAYS=60
TUIST_RUN_ARTIFACT_RETENTION_DAYS=30
TUIST_TEST_ATTACHMENT_RETENTION_DAYS=30
TUIST_SHARD_BUNDLE_RETENTION_DAYS=14

使用 Helm chart 時,請將相同的視窗設定為映射:

yaml
server:
artifactRetentionDays:
cacheArtifacts: 30
appPreviews: 30
buildArchives: 60
runArtifacts: 30
testAttachments: 30
shardBundles: 14

所有六個鍵都是可選的。此範例啟用了每種支援的成品類型,並具有獨立的保留視窗。省略某個鍵或將其值留空,以保持該成品類型的清理停用。自託管保留視窗沒有 30 天的上限。若設定的值不是正整數,會導致伺服器在啟動時失敗。

變更保留變數後請重新啟動伺服器。每個排入佇列的自託管清理批次在刪除檔案前都會檢查目前設定,因此取消設定或清空變數,或是延長其視窗,也能在重新啟動後保護檔案不受待處理作業影響。

環境變數從物件儲存中移除的成品檔案
TUIST_CACHE_ARTIFACT_RETENTION_DAYSXcode 快取、舊版內容定址儲存快取、模組快取,以及 Gradle 快取檔案
TUIST_APP_PREVIEW_RETENTION_DAYSApp 預覽建置與圖示
TUIST_BUILD_ARCHIVE_RETENTION_DAYS目前與舊版建置封存檔
TUIST_RUN_ARTIFACT_RETENTION_DAYS儲存在已過期執行之成品前綴下的所有物件,包括結果套件、叫用記錄與工作階段封存檔
TUIST_TEST_ATTACHMENT_RETENTION_DAYS測試執行附件
TUIST_SHARD_BUNDLE_RETENTION_DAYS測試分片套件

排程清理僅移除成品 Blob。它會保留對應的 PostgreSQL 與 ClickHouse 資料列,因此在下載過期後,建置、測試、執行、預覽與分片中繼資料仍可在儀表板中顯示。此設定不會改變 ClickHouse 資料表的保留規則。

電子郵件設定#

Tuist 需要電子郵件功能以進行使用者驗證與交易通知(例如重設密碼、帳戶通知)。目前,僅支援 Mailgun 作為電子郵件提供者。

環境變數描述必要預設值範例
TUIST_MAILGUN_API_KEY用於向 Mailgun 驗證的 API 金鑰是*key-1234567890abcdef
TUIST_MAILING_DOMAIN發送電子郵件的網域是*mg.tuist.io
TUIST_MAILING_FROM_ADDRESS將出現在「寄件者」欄位的電子郵件地址是*[email protected]
TUIST_MAILING_REPLY_TO_ADDRESS用於使用者回覆的選擇性回覆地址否[email protected]
TUIST_SKIP_EMAIL_CONFIRMATION略過新使用者註冊的電子郵件確認。啟用時,使用者會自動獲得確認,並可在註冊後立即登入否若未設定電子郵件則為 true,若已設定電子郵件則為 falsetrue, false, 1, 0

* 僅在您希望發送電子郵件時才需要電子郵件設定變數。若未設定,系統會自動略過電子郵件確認

SMTP 支援

目前不提供通用 SMTP 支援。若您需要在本機部署中使用 SMTP 支援,請聯絡 [email protected] 討論您的需求。

隔離網路部署

對於沒有網際網路存取權限或未設定電子郵件提供者的本機安裝,預設會自動略過電子郵件確認。使用者可在註冊後立即登入。若您已設定電子郵件但仍希望略過確認,請設定 TUIST_SKIP_EMAIL_CONFIRMATION=true。若要在已設定電子郵件時要求電子郵件確認,請設定 TUIST_SKIP_EMAIL_CONFIRMATION=false。

電子郵件配額與密碼重設連結

設定電子郵件後,邀請電子郵件(建立、大量或重新發送)限制為每位收件者每五分鐘一封,且每次突發上限為 50 封,以每組織、每邀請者每小時 50 封的速度補充。取消邀請不會恢復配額,而邀請 API 會在配額耗盡時回應 429 與 Retry-After。若有多個複本,請設定共用的 Valkey 以實現整個部署的配額;若已設定但無法使用,邀請電子郵件將被拒絕。密碼重設連結在 15 分鐘後過期。

Git 平台設定#

Tuist 可以 與 Git 平台整合,提供額外功能,例如自動在您的拉取請求中張貼評論。

GitHub#

自託管的 Tuist 伺服器無法安裝在 https://tuist.dev 上執行的 GitHub App。GitHub App 綁定於註冊它們的伺服器,因此您的部署需要在 github.com 上擁有自己的 App。

註冊 App

建立 GitHub App,並由您的 GitHub 組織擁有。您可以重複使用為驗證建立的 App,除非您建立的是 OAuth App。請使用以下設定進行設定,並將 YOUR_APP_URL 替換為 TUIST_APP_URL 的值:

設定值
回呼 URLYOUR_APP_URL/users/auth/github/callback 與 YOUR_APP_URL/integrations/github/authorize
設定 URLYOUR_APP_URL/integrations/github/setup
更新時重新導向已啟用
Webhook URLYOUR_APP_URL/webhooks/github
Webhook 密鑰任意隨機字串。您將把它設定為 TUIST_GITHUB_APP_WEBHOOK_SECRET

授予下列儲存庫權限:

權限存取權
內容唯讀
中繼資料唯讀
議題讀寫
拉取請求讀寫
檢查讀寫

同時授予 成員:唯讀 的組織權限。在 github.com 設定期間,Tuist 會檢查連線組織安裝的人員是否為有效的 GitHub 組織擁有者,而不只是擁有其中一個儲存庫存取權的人。

讓 App 訂閱 Check run、Pull request 和 Issue comment 事件。

保持 安裝期間要求使用者授權 (OAuth) 為停用狀態,以便 GitHub 將安裝程式傳送至設定 URL。Tuist 會使用額外的 /integrations/github/authorize 回呼啟動獨立的授權步驟,以驗證安裝擁有權。當在 GitHub 上開始安裝時,安裝程式會選擇 Tuist 組織;在 Tuist 中開始的安裝會保留其組織。

設定伺服器

設定下列環境變數,然後重新啟動伺服器:

環境變數說明必要預設值範例
TUIST_GITHUB_APP_NAMEApp 的 slug,即其公開頁面 URL https://github.com/apps/<slug> 的最後路徑元件是my-company-tuist
TUIST_GITHUB_APP_ID數字 App ID,用於驗證安裝擁有權是123456
TUIST_GITHUB_APP_CLIENT_IDGitHub 應用程式的客戶端 ID是Iv1.a629723000043722
TUIST_GITHUB_APP_CLIENT_SECRET應用程式的客戶端密鑰是232f972951033b89799b0fd24566a04d83f44ccc
TUIST_GITHUB_APP_PRIVATE_KEY_BASE64GitHub 應用程式的 Base64 編碼私鑰。優先於 TUIST_GITHUB_APP_PRIVATE_KEY,因為後者對平台處理換行符號的方式較為敏感是LS0tLS1CRUdJTiBSU0EgUFJJVkFUR...
TUIST_GITHUB_APP_WEBHOOK_SECRET在 GitHub 應用程式上設定的 Webhook 密鑰否a4c1e0f2b8d6...
設定所有必要的 App 憑證

組織整合頁面上的 安裝 GitHub App 按鈕會保持停用狀態,直到設定了 TUIST_GITHUB_APP_NAME、TUIST_GITHUB_APP_CLIENT_ID、TUIST_GITHUB_APP_CLIENT_SECRET 以及私鑰為止。也需要數字 TUIST_GITHUB_APP_ID 來驗證安裝擁有權。安裝 URL 內嵌了 App slug,因此若缺少 TUIST_GITHUB_APP_NAME,特別是會產生 GitHub 回應 404 的連結。

伺服器重新啟動後,組織管理員會依照 GitHub 整合指南 安裝 App 並將儲存庫連線至專案。

OIDC 驗證取決於此

OIDC 驗證 會根據與您專案連線的儲存庫,解析 CI 權杖中的儲存庫聲明,且只能透過已安裝的 GitHub App 建立連線。在您的 CI 工作流程執行不含權杖的 tuist auth login 之前,請先完成上述設定。

您的 Tuist 伺服器也需要出站存取權以連接到 CI 供應商的 OIDC 發行者,以便取得其簽署金鑰:

CI 供應商主機
GitHub Actionstoken.actions.githubusercontent.com
CircleCIoidc.circleci.com
Bitrisetoken.builds.bitrise.io
GitHub Enterprise Server

上述環境變數僅設定 Tuist 的 github.com App。若要改為將 Tuist 與 GitHub Enterprise Server (GHES) 執行個體整合,組織管理員需切換至整合頁面上的 企業伺服器 分頁並輸入 GHES 基礎 URL — Tuist 會引導他們透過 GitHub 的 App 清單流程,在其 GHES 執行個體上註冊全新的 Tuist App。新 App 的憑證會依安裝進行加密儲存;不需要額外的 TUIST_GITHUB_APP_* 環境變數。

Origin#

自託管的 Tuist 伺服器需要自己的 Origin app,並使用您部署的 URL 和簽署金鑰進行設定。為每個 Tuist 環境註冊獨立的 app,以使安裝和憑證保持獨立。

註冊 App
  1. 使用支援 Ed25519 的 OpenSSL 產生 Ed25519 簽署金鑰組:

    bash
    umask 077
    openssl genpkey -algorithm ED25519 -out origin-app-private.pem
    openssl pkey -in origin-app-private.pem -pubout -out origin-app-public.pem
  2. 在 Origin app 設定 中建立 app。將 origin-app-public.pem 的內容註冊為其公開簽署金鑰。請保密 origin-app-private.pem;您需要將其提供給 Tuist 伺服器,而不是上傳到 Cursor。

  3. 設定下列設定,將 YOUR_APP_URL 替換為您 Tuist 部署的 HTTPS 基礎 URL:

    設定值
    首頁 URLYOUR_APP_URL
    重新導向 URIYOUR_APP_URL/integrations/origin/setup
    Webhook URLYOUR_APP_URL/webhooks/origin
  4. 複製註冊的 App ID,其開頭為 app_。

Tuist 在安裝期間要求下列權限:

範圍用途
repository:pull_requests:read尋找拉取請求及其目前的 head commit。
repository:pull_requests:reviews:write讀取、張貼和更新報告評論。Origin 包含對應的審查讀取權限。
repository:metadata:read探索儲存庫並讀取其預設分支。由 Origin 自動授予。

不要選取可選的儲存庫 Webhook 事件。安裝生命週期通知已足夠;不需要原始碼存取、合併權限和檢查執行權限。

設定伺服器

設定下列環境變數,然後重新啟動伺服器:

環境變數說明必要預設值範例
TUIST_ORIGIN_APP_ID從 Origin app 設定複製的 App ID。是app_...
TUIST_ORIGIN_APP_PRIVATE_KEYorigin-app-private.pem 的完整內容,包括 BEGIN PRIVATE KEY 和 END PRIVATE KEY 行以及所有換行符號。是-----BEGIN PRIVATE KEY-----...

將私密金鑰儲存在您部署的密鑰管理器中。保留其多行 PEM 格式;此設定不接受 base64 編碼的替代項目。切勿將金鑰提交至原始碼控制或在記錄中公開。兩個變數必須屬於同一個註冊的 app。

您的 Tuist 伺服器需要對 api.cursor.com 具有出站 HTTPS 存取權限。Cursor 必須能夠將請求傳送至 Webhook URL,且管理員必須能夠在瀏覽器中返回重新導向 URI。兩個註冊的 URL 都必須與您部署的 HTTPS 基礎 URL 相符。

安裝 App

伺服器重新啟動後,管理員開啟 設定 → 整合,在 Origin 下方選擇 連接,並核准 app 對適當 Origin 帳戶和儲存庫的存取權限。整個流程會保留 Tuist 組織。若直接從 Origin 啟動安裝,則會提示管理員登入並選取要連接的 Tuist 組織。接著他們選擇 新增專案連接,將 Tuist 專案連結至原生儲存庫。

請參閱 Origin 整合指南 以了解專案連接和結果上傳需求。安裝 app 不會啟動建置或測試工作流程;這些工作流程會繼續向您的 Tuist 伺服器回報結果。

在本機測試#

我們提供完整的 Docker Compose 設定,其中包含在您本機電腦上測試 Tuist 伺服器所需的所有相依性,然後再部署到您的基礎設施:

  • PostgreSQL 15
  • 用於分析的 ClickHouse 26.5
  • 用於協調的 ClickHouse Keeper
  • 用於 S3 相容儲存的 MinIO
  • 用於本機自託管快取測試的 Kura
  • 用於資料庫管理的 pgweb
需要授權

執行 Tuist 伺服器(包括本機開發執行個體)依法需要有效的 TUIST_LICENSE 環境變數。如果您需要授權,請聯絡 [email protected]。

快速入門:

  1. 下載設定檔:

    bash
    curl -O https://docs.tuist.io/server/self-host/docker-compose.yml
    curl -O https://docs.tuist.io/server/self-host/clickhouse-config.xml
    curl -O https://docs.tuist.io/server/self-host/clickhouse-log-level.xml
    curl -O https://docs.tuist.io/server/self-host/clickhouse-log-ttl.xml
    curl -O https://docs.tuist.io/server/self-host/clickhouse-keeper-config.xml
    curl -O https://docs.tuist.io/server/self-host/.env.example
  2. 設定環境變數:

    bash
    cp .env.example .env
    # Edit .env and add your TUIST_LICENSE, TUIST_SECRET_KEY_BASE, and authentication credentials

    內建的 ClickHouse 服務接受下列可選的操作記錄控制項:

    環境變數說明預設值範例
    CLICKHOUSE_SYSTEM_LOG_TTL_DAYSClickHouse system.* 記錄表(例如 text_log、query_log、trace_log、metric_log 和 part_log)的保留期限(天)147
    CLICKHOUSE_TEXT_LOG_LEVELClickHouse 伺服器記錄器和 system.text_log 層級informationwarning
    CLICKHOUSE_SUPERSEDED_LOG_TABLES當 ClickHouse 取代系統記錄表時,如何處理其留下的 <name>_N 表。ignore 會保留它們,delete 會刪除它們ignoredelete
  3. 啟動所有服務:

    bash
    docker compose up -d
    # or with podman:
    podman compose up -d

    在 Apple Silicon 上,Docker Desktop 會自動拉取 Tuist 和相依性映像的 linux/arm64 變體。若要強制使用 amd64 模擬進行偵錯,請使用 DOCKER_DEFAULT_PLATFORM=linux/amd64 執行 Compose。

    內建的 compose 檔案使用具名 Docker 磁碟區來儲存持久化資料。若您將其替換為主機繫結掛載,請先建立主機目錄,並使其可被容器使用者寫入,特別是 ClickHouse 和 ClickHouse Keeper 資料目錄。

  4. 在 http://localhost:8080 存取伺服器

服務端點:

常見指令:

檢查服務狀態:

bash
docker compose ps
# or: podman compose ps

檢視記錄:

bash
docker compose logs -f tuist

停止服務:

bash
docker compose down

重置所有內容(刪除所有資料):

bash
docker compose down -v

設定檔:

使用 Helm 部署至 Kubernetes#

Tuist 提供官方的 Helm chart,用於在 Kubernetes 上進行部署。該 chart 封裝了 Tuist 伺服器和快取服務,以及內建的基礎設施相依性,您可以視需要將其替換為外部供應商。

安裝 chart#

bash
helm install tuist oci://ghcr.io/tuist/charts/tuist \
--set server.license.key="YOUR_LICENSE_KEY"

若要鎖定特定的 chart 版本:

bash
helm install tuist oci://ghcr.io/tuist/charts/tuist \
--set server.license.key="YOUR_LICENSE_KEY" \
--version 0.1.0

授權#

server.license.key 值同時接受標準授權金鑰,以及針對隔離環境安裝的 Base64 編碼授權憑證;伺服器會自動偵測是哪一種。

使用 --set 傳遞授權適合快速安裝。若您將值儲存在版本控制中,請將授權儲存在由 Helm 外部管理的 Kubernetes Secret 中(例如使用 Vault、Sealed Secrets 或 SOPS),並將 chart 指向該 Secret:

yaml
# values.yaml
server:
license:
existingSecret: tuist-license
existingSecretKeys:
key: TUIST_LICENSE
certificateBase64: ""

existingSecretKeys.key 下方的項目命名了您的 Secret 中持有授權值的欄位,該值可以是授權金鑰,或是針對隔離環境安裝的 Base64 編碼授權憑證。existingSecretKeys 下方的每個項目預設為 chart 自身的金鑰名稱,因此請將您的 Secret 中不包含的項目設為空字串,如上方的 certificateBase64 所示。否則,Pod 會參考不存在的金鑰而無法啟動。請在安装或升級 chart 之前,在發行版命名空間中建立該 Secret。

僅透過單一來源設定授權:server.license.key 或 server.license.existingSecret。若未設定任何來源或混合使用來源,chart 將無法渲染。透過 server.extraEnv 傳遞的授權不被視為來源,因此請改用 existingSecret。

基礎設施相依性#

該 chart 管理三個基礎設施相依性:postgresql、clickhouse 和 objectStorage。每個相依性預設為 內建 模式,表示 chart 會將它們部署在叢集內部。若要改為指向您自己的外部執行個體,請將相依性的 mode 設為 external,並在您的 values.yaml 中填寫連線詳細資訊。例如,若要使用外部 PostgreSQL 資料庫:

yaml
# values.yaml
postgresql:
mode: external
external:
host: your-db-host
port: 5432
database: tuist
username: tuist
password: your-password

若您在 Helm 外部管理 PostgreSQL 憑證,請將 chart 指向現有的 Kubernetes Secret:

yaml
# values.yaml
postgresql:
mode: external
external:
port: 5432
database: tuist
existingSecret: tuist-postgresql
existingSecretKeys:
host: host
username: username
password: password

Chart 會從 Secret 讀取主機、使用者名稱和密碼,並透過 Kubernetes 環境變數替換組成 DATABASE_URL,因此密碼不會被渲染到 Helm manifest 中。Secret 的密碼值應符合 URL 安全規範,因為它會被插入到資料庫 URL 中。

相同的模式也適用於 clickhouse 和 objectStorage。請參閱 chart 的 values.yaml 中各章節下的 external 區塊,以取得可設定欄位的完整清單。

共用排程與標籤#

該 chart 在 global 下公開一組共用的 Pod 設定,讓營運人員可以調整部署以適應其叢集,而無需為每個工作負載重複相同的值:

yaml
global:
podLabels:
environment: production
imagePullSecrets:
- name: ghcr-pull-secret
nodeSelector:
nodepool: apps
tolerations:
- key: dedicated
operator: Equal
value: apps
effect: NoSchedule

當您需要執行以下操作時,請使用這些設定:

  • 為每個 Pod 新增叢集專屬標籤
  • 從私人註冊表拉取鏡像映像
  • 指定專用的節點池
  • 允許 Pod 调度到保留給 Tuist 工作負載的污點節點

工作負載身分與服務帳戶#

該 chart 依應用程式工作負載範圍劃分服務帳戶,以便僅在需要的地方授予身分:

  • server.serviceAccount 適用於 Tuist 伺服器部署與遷移作業
  • cache.serviceAccount 適用於快取部署

例如,當快取在 EKS 上使用外部 S3 儲存貯體時,您可以為快取工作負載啟用 IRSA,而無需將相同的 IAM 角色附加到內建資料庫:

yaml
cache:
serviceAccount:
create: true
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/tuist-cache

相容性覆寫#

該 chart 將儲存與服務網格專屬的微調設為選擇性啟用,以保持預設值的可移植性:

yaml
cache:
podSecurityContext:
fsGroup: 990
clickhouse:
embedded:
service:
nativePort: 9100
systemLogs:
ttlDays: 7
supersededTables: delete
level: warning

僅在您的叢集需要時才使用這些覆寫:

  • cache.podSecurityContext 預設為空。若您的儲存類別或 CSI 驅動程式需要在掛載的磁碟區上共用群組擁有權,請設定 fsGroup。
  • clickhouse.embedded.service.nativePort 預設為 ClickHouse 的標準 9000 原生服務埠,當服務網格或平台保留與該埠衝突時可以變更。
  • clickhouse.embedded.systemLogs.ttlDays 預設為空,讓 ClickHouse 對內建內部日誌表(例如 system.text_log、system.query_log、system.trace_log、system.metric_log 和 system.part_log)保持無限制的保留期。設定它會一次性取代這些表格,因此請搭配 supersededTables: delete 一起採用 — 請參閱 限制營運日誌保留期。
  • clickhouse.embedded.systemLogs.level 針對內建 ClickHouse 伺服器記錄器和 system.text_log 預設為 information。與 ttlDays 不同,它不屬於任何表格定義的一部分,因此變更它絕不會取代表格。
  • clickhouse.embedded.systemLogs.supersededTables 預設為 ignore,並決定當 ClickHouse 取代系統日誌表時,<name>_N 表格的處理方式。將其設為 delete 以在每次 helm upgrade 時刪除它們。
  • 對 ttlDays 和 level 的編輯會在 ClickHouse Pod 下次重新啟動時生效,因為兩者都是 subPath 掛載,且當其 ConfigMap 變更時,chart 不會滾動更新 StatefulSet。

可觀測性#

該 chart 包含一個選擇性的可觀測性堆疊(OpenTelemetry Collector、Prometheus、Grafana、Loki 和 Tempo)。它預設為 停用。若要在您的 values.yaml 中啟用它:

yaml
# values.yaml
observability:
enabled: true

啟用後,Grafana 即可使用,並已預先設定好日誌、追蹤和指標的下鑽功能。對於外部可觀測性,請保持此功能停用,並透過 server.extraEnv 設定端點:

yaml
# values.yaml
server:
extraEnv:
- name: TUIST_OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://your-otel-collector:4317"
- name: TUIST_LOKI_URL
value: "http://your-loki:3100"

數值參考#

如需可設定數值的完整清單,請參閱 chart 的 values.yaml。

部署#

官方 Tuist Docker 映像位於:

yaml
ghcr.io/tuist/tuist

發布的映像包含用於 .xcactivitylog 歸檔的內建 Linux 建置處理功能,因此自託管部署可以在不執行任何其他服務的情況下處理建置 — ProcessBuildWorker Oban 作業在每個伺服器 Pod 的程序內執行。若您想將建置處理卸載到專用的複本集(例如,為了獨立於網頁層擴展解析吞吐量),請在 Helm chart 中設定 processor.enabled: true:chart 會將同一個映像部署為僅限佇列的消費者(TUIST_PROCESSOR_MODE=true)。請參閱 values.yaml 以取得完整的控制項清單。

Note

.xcresult 解析依賴 Xcode 中的 xcresulttool,因此只能在 macOS 上執行。CLI 會透明地處理自託管部署的這種情況:tuist test 針對任何非 tuist.dev 伺服器預設為 本機 處理模式,在開發者機器上解析 xcresult(該機器已具備用於建置本身的 Xcode)並上傳結構化結果。測試結果可在無需任何額外基礎設施的情況下被攝取。

拉取 Docker 映像#

您可以執行以下命令來取得映像:

bash
docker pull ghcr.io/tuist/tuist:latest

該映像同時發布了 linux/amd64 和 linux/arm64 版本,因此 Docker 會自動為主機選取原生的 Linux 架構。

或拉取特定版本:

bash
docker pull ghcr.io/tuist/tuist:0.1.0

部署 Docker 映像#

Docker 映像的部署流程會因您選擇的雲端供應商和您組織的持續部署方法而異。由於大多數雲端解決方案和工具(如 Kubernetes)都使用 Docker 映像作為基本單位,因此本節中的範例應能與您現有的設定良好配合。

Warning

若您的部署管道需要驗證伺服器是否已啟動並運行,您可以向 /ready 發送 GET HTTP 請求,並斷言回應中的狀態碼為 200。

Fly#

若要在 Fly 上部署應用程式,您需要一個 fly.toml 設定檔。建議在您的持續部署 (CD) 管道中動態產生它。以下是供您參考的範例:

toml
app = "tuist"
primary_region = "fra"
kill_signal = "SIGINT"
kill_timeout = "5s"
[experimental]
auto_rollback = true
[env]
# Your environment configuration goes here
# Or exposed through Fly secrets
[processes]
app = "/usr/local/bin/hivemind /app/Procfile"
[[services]]
protocol = "tcp"
internal_port = 8080
auto_stop_machines = false
auto_start_machines = false
processes = ["app"]
http_options = { h2_backend = true }
[[services.ports]]
port = 80
handlers = ["http"]
force_https = true
[[services.ports]]
port = 443
handlers = ["tls", "http"]
[services.concurrency]
type = "connections"
hard_limit = 100
soft_limit = 80
[[services.http_checks]]
interval = 10000
grace_period = "10s"
method = "get"
path = "/ready"
protocol = "http"
timeout = 2000
tls_skip_verify = false
[services.http_checks.headers]
[[statics]]
guest_path = "/app/public"
url_prefix = "/"

接著您可以執行 fly launch --local-only --no-deploy 來啟動應用程式。在後續部署中,您不需要執行 fly launch --local-only,而是需要執行 fly deploy --local-only。Fly.io 不允許拉取私人 Docker 映像,這就是我們需要使用 --local-only 旗標的原因。

Prometheus 指標#

Tuist 在 /metrics 公開 Prometheus 指標,以協助您監控自託管執行個體。這些指標包括:

Finch HTTP 用戶端指標#

Tuist 使用 Finch 作為其 HTTP 用戶端,並公開關於 HTTP 請求的詳細指標:

請求指標#

  • tuist_prom_ex_finch_request_count_total - Finch 請求總數(計數器)
    • 標籤:finch_name、method、scheme、host、port、status
  • tuist_prom_ex_finch_request_duration_milliseconds - HTTP 請求持續時間(直方圖)
    • 標籤:finch_name、method、scheme、host、port、status
    • 區間:10ms、50ms、100ms、250ms、500ms、1s、2.5s、5s、10s
  • tuist_prom_ex_finch_request_exception_count_total - Finch 請求例外總數(計數器)
    • 標籤:finch_name、method、scheme、host、port、kind、reason

連線池佇列指標#

  • tuist_prom_ex_finch_queue_duration_milliseconds - 在連線池佇列中等待的時間(直方圖)
    • 標籤:finch_name、scheme、host、port、pool
    • 區間:1ms、5ms、10ms、25ms、50ms、100ms、250ms、500ms、1s
  • tuist_prom_ex_finch_queue_idle_time_milliseconds - 連線在使用前閒置的時間(直方圖)
    • 標籤:finch_name、scheme、host、port、pool
    • 區間:10ms、50ms、100ms、250ms、500ms、1s、5s、10s
  • tuist_prom_ex_finch_queue_exception_count_total - Finch 佇列例外總數(計數器)
    • 標籤:finch_name、scheme、host、port、kind、reason

連線指標#

  • tuist_prom_ex_finch_connect_duration_milliseconds - 建立連線所花的時間(直方圖)
    • 標籤:finch_name、scheme、host、port、error
    • 區間:10ms、50ms、100ms、250ms、500ms、1s、2.5s、5s
  • tuist_prom_ex_finch_connect_count_total - 連線嘗試總數(計數器)
    • 標籤:finch_name、scheme、host、port

傳送指標#

  • tuist_prom_ex_finch_send_duration_milliseconds - 傳送請求所花的時間(直方圖)
    • 標籤:finch_name、method、scheme、host、port、error
    • 區間:1ms、5ms、10ms、25ms、50ms、100ms、250ms、500ms、1s
  • tuist_prom_ex_finch_send_idle_time_milliseconds - 連線在傳送前閒置的時間(直方圖)
    • 標籤:finch_name、method、scheme、host、port、error
    • 區間:1ms、5ms、10ms、25ms、50ms、100ms、250ms、500ms

所有直方圖指標都提供 _bucket、_sum 和 _count 變體,以便進行詳細分析。

其他指標#

除了 Finch 指標外,Tuist 還公開以下指標:

  • BEAM 虛擬機器效能
  • 自訂業務邏輯指標(儲存、帳號、專案等)
  • 資料庫效能(使用 Tuist 託管基礎設施時)

營運#

Tuist 在 /ops/ 下提供一組工具程式,可用於管理您的執行個體。

授權

只有電子郵件網域符合 TUIST_OPERATOR_EMAIL_DOMAIN(預設為 tuist.dev)的已確認使用者才能存取 /ops/ 端點。

  • 錯誤(/ops/errors): 您可以檢視應用程式中發生的非預期錯誤。這有助於除錯並了解問題所在;若您遇到問題,我們可能會請您與我們分享此資訊。
  • 儀表板(/ops/dashboard): 您可以檢視提供應用程式效能與健康狀況洞察的儀表板(例如記憶體消耗、執行中的程序、請求數量)。此儀表板對於判斷您使用的硬體是否足以處理負載相當有用。