Skip to main content

Infrastructure adapters

Infrastructure adapters

info

Most teams use the default Install Compose stack and never touch adapter settings. This page is for higher-scale or custom deployments, external object storage, a CDN in front of downloads, or splitting the API and worker.

Patch is an integrated product, not a plugin marketplace. Under the hood it has two fixed integration points, storage adapters and delivery adapters, that let you swap backends without changing the CLI, dashboard, or SDK.

See How it works for the end-to-end flow. This page explains what you can configure on the server side.

Two layers​

LayerQuestion it answersEnv var
Storage adapterWhere are bundles and manifests stored?STORAGE_ADAPTER
Delivery adapterWhat public URLs do clients download from, and how is the cache invalidated?DELIVERY_ADAPTER

The API and worker read and write artifacts through the storage adapter. When a release is published, the delivery adapter resolves stable public URLs (embedded in manifests) and optionally purges a CDN cache.

The server never serves OTA artifacts from the API domain; clients fetch from your download base URL. See How delivery works.

Defaults (self-host installer)​

scripts/selfhost/install.sh sets up:

  • STORAGE_ADAPTER=s3 with bundled MinIO
  • DELIVERY_ADAPTER=base-url: clients fetch directly from PUBLIC_BASE_URL
  • PUBLIC_BASE_URL on your storage domain, e.g. https://storage-updates.example.com/codemagic-patch
  • Compose hardcodes MODE=all (API and release worker in one process)

The cmpatch selfhost install wizard can prepare R2, S3 or GCS storage automatically or guide you through console setup, including the selected CDN. Splitting MODE=api / MODE=worker still requires a custom deployment; the supported Compose topology runs MODE=all.

Storage adapter​

Controls where release artifacts live.

ValueTypical use
s3Default. MinIO in the Compose stack, or any S3-compatible store (AWS S3, Cloudflare R2, etc.) in a custom deployment
gcsGoogle Cloud Storage with separate public and internal buckets (custom deployment)
memoryLocal development and tests only, not for production

S3-compatible storage​

Used by the default self-host stack (MinIO) and for external object storage at scale.

Key variables (full list in Configuration reference):

VariableRole
S3_BUCKETPublic bucket name (required when STORAGE_ADAPTER=s3)
S3_INTERNAL_BUCKETOptional distinct private bucket for _internal/ keys, including copy source and destination; unset retains one-bucket routing
S3_ENDPOINTCustom endpoint for MinIO or S3-compatible services
S3_FORCE_PATH_STYLEtrue for MinIO; often false for AWS
S3_REGIONAWS region (default us-east-1)
S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEYCredentials, or omit both to use the host's default credential chain

PUBLIC_BASE_URL must point at the publicly readable viewer URL for artifacts: the storage domain in a default install, or the CDN domain when fronted.

Choose S3/R2 in cmpatch selfhost install, or pass a complete runtime configuration with --storage-mode s3|r2. New wizard installs require distinct public and internal buckets; unset S3_INTERNAL_BUCKET preserves legacy one-bucket server routing. Changing only STORAGE_ADAPTER in an existing .env.selfhost is not a migration and does not move stored objects.

On AWS, the wizard's runtime credentials are a dedicated bucket-scoped IAM user key, not an SSO or STS session. It changes only the buckets it creates. It does not turn off account-wide Block Public Access.

Google Cloud Storage​

Set STORAGE_ADAPTER=gcs with:

  • GCS_PUBLIC_BUCKET: artifacts clients download
  • GCS_INTERNAL_BUCKET: staged uploads (_internal/*); must be a different bucket

Select GCS in cmpatch selfhost install with automatic or guided setup, or pass --storage-mode gcs with a complete two-bucket runtime configuration. The Compose path mounts the service-account JSON supplied with --gcs-credentials-file. Runtime access is granted on those two buckets, not the project. Public Access Prevention must allow anonymous reads on the public bucket, and the project must allow service-account key creation.

Delivery adapter​

Controls how storage keys become client-facing download URLs and whether the server purges an edge cache after each release.

ValueTypical use
base-urlDefault. URLs are PUBLIC_BASE_URL + storage key. No CDN integration.
cloudflareStorage domain is proxied through Cloudflare; server calls the Cache Purge API after releases
cloudfrontCloudFront serves PUBLIC_BASE_URL; server submits scoped invalidations after releases and wildcard invalidation on deployment deletion

With base-url, clients hit your storage domain directly (Caddy → MinIO in the default stack).

With cloudflare, manifest URLs still use PUBLIC_BASE_URL, which should be the Cloudflare-fronted storage domain, and Patch purges cached manifest URLs after releases, promotions, rollbacks, and related deployment changes. Setup: Cloudflare setup.

With cloudfront, bundled MinIO uses a separate header-protected origin hostname while the viewer storage hostname remains PUBLIC_BASE_URL. External S3/GCS uses the bucket endpoint directly. Setup: CloudFront setup.

Purge is best-effort: a failed purge does not roll back a release, but you may see stale bundles at the edge until the cache expires.

When adapters matter​

You usually need to think about adapters when:

  • Download volume or geographic reach outgrows a single origin: add Cloudflare (Cloudflare setup) or CloudFront (CloudFront setup)
  • You want managed object storage instead of bundled MinIO: choose external S3-compatible storage or GCS during the first install

You usually do not need to change adapters when:

  • You are evaluating Patch or running a single Docker host
  • You publish through cmpatch and the dashboard on the default installer layout

The server accepts MODE=api and MODE=worker, but the self-host Compose topology is MODE=all only. Caddy does not expose /worker/* publicly. Split API/worker is not a turnkey self-host option.

Client config stays the same​

Adapter changes are server-side. Apps still need two URLs:

App configPoints at
CodemagicPatchApiUrlAPI / control plane (metrics, auth)
CodemagicPatchDownloadBaseUrlPUBLIC_BASE_URL, storage domain or CDN-fronted equivalent

If you add a CDN, CodemagicPatchDownloadBaseUrl should match the CDN-facing base URL clients actually fetch from, not the raw MinIO origin.