cache/README.md
A lightweight Elixir/Phoenix service for handling Tuist cache operations, including Xcode compilation cache and key-value storage.
This service provides:
PUT /api/cache/keyvalue/:cas_id - Retrieve key-value entries (requires account_handle and project_handle query params)PUT /api/cache/keyvalue - Store key-value entries (requires account_handle and project_handle query params)GET /api/cache/cas/:id - Retrieve Xcode cache artifact (nginx serves directly after auth)POST /api/cache/cas/:id - Store Xcode cache artifact (requires account_handle and project_handle query params)GET /up - Health check endpoint (returns 200 when healthy, 503 otherwise)Install dependencies:
mix deps.get
Configure environment variables:
SECRET_KEY_BASE - Phoenix secret key base (generate with mix phx.gen.secret)PUBLIC_HOST - Hostname for the service (release entrypoint sets $(cat /etc/host_hostname).tuist.dev)PORT - Port to run on (default: 4000)SERVER_URL - URL of the main Tuist server for authenticationSTORAGE_DIR - Directory for artifact storage (default: /storage)DISK_HIGH_WATERMARK_PERCENT - Optional high watermark (%) that triggers disk eviction (default: 75)DISK_TARGET_PERCENT - Optional target usage (%) the eviction job aims for after cleanup (default: 60)S3_BUCKET - S3 bucket for module and Gradle cache artifactsS3_XCODE_CACHE_BUCKET - Optional dedicated S3 bucket for Xcode cache artifacts (defaults to S3_BUCKET). When set to a different value, Xcode cache reads and writes use this bucket directly.S3_REGISTRY_BUCKET - S3 bucket for Swift package registryKEY_VALUE_READ_BUSY_TIMEOUT_MS - Optional SQLite contention budget for KV read-through requests (default: 2000)Start the server:
mix phx.server
Run tests with:
mix test
The service uses a checkout-local suffix in development mode through the shared mise shell env. Each checkout persists that suffix through Git metadata when available, while keeping the existing root .tuist-dev-instance file as a compatibility fallback. That suffix scopes the cache port and the main server URL it talks to, so developers can choose either multiple clones or linked worktrees and still run their own paired server/ and cache/ instances without colliding.
/api/projects endpointThe service is designed to work with nginx for optimal performance:
auth_request to validate access via Phoenix, then serves files directly from disk/_auth endpoint for nginx subrequestsSee platform/nginx.nix for the complete nginx configuration.
The cache service is optimized for the read path, specifically for handling thousands of small files in bursts:
account/project/xcode/ structure/storage directory mounted for persistent storageS3_XCODE_CACHE_BUCKET), module/Gradle cache (S3_BUCKET), and Swift package registry (S3_REGISTRY_BUCKET). When S3_XCODE_CACHE_BUCKET is unset, Xcode cache artifacts continue using S3_BUCKET. When S3_XCODE_CACHE_BUCKET points to a different bucket, Xcode cache reads and writes use that bucket directly. Project cleanup still runs both Xcode cache and general cache deletion passes, so duplicate cleanup work in logs is expected when both artifact types resolve to the same bucket.The service is deployed via Kamal to NixOS servers:
config/deploy.yml and config/deploy.staging.yml)platform/ directory:
platform/nginx.nix/storage directory for persistent artifact storageDeploy with:
kamal deploy -c config/deploy.yml # Production
kamal deploy -c config/deploy.staging.yml # Staging