Skip to content

Latest commit

 

History

History
147 lines (99 loc) · 7.67 KB

deployment.md

File metadata and controls

147 lines (99 loc) · 7.67 KB

Deployment Guide

This page covers Docker setup, prebuilt binaries, cloud storage backends, and production deployment considerations for truss.

Prebuilt Binaries

Download a prebuilt binary from the GitHub Releases page. Archives and SHA256 checksums are published for each release, along with release-manifest.json; see Downloading release binaries from a program for reading it from code.

Homebrew

Homebrew installs are published to nao1215/tap:

brew install nao1215/tap/truss
Target Archive
Linux x86_64 truss-v*-x86_64-unknown-linux-gnu.tar.gz
Linux aarch64 truss-v*-aarch64-unknown-linux-gnu.tar.gz
macOS x86_64 truss-v*-x86_64-apple-darwin.tar.gz
macOS aarch64 (Apple Silicon) truss-v*-aarch64-apple-darwin.tar.gz
Windows x86_64 truss-v*-x86_64-pc-windows-msvc.zip

Example (Linux x86_64):

tar xzf truss-v*.tar.gz
sudo mv truss /usr/local/bin/

Docker

Docker Compose

docker compose up

This starts the server from compose.yml. The default configuration mounts ./images as the storage root.

Building and Running Directly

docker build -t truss .
docker run -p 8080:8080 \
  -e TRUSS_BIND_ADDR=0.0.0.0:8080 \
  -e TRUSS_BEARER_TOKEN=changeme \
  -v ./images:/data:ro \
  -e TRUSS_STORAGE_ROOT=/data \
  truss

Prebuilt Container Images

Prebuilt container images are published to GHCR:

docker pull ghcr.io/nao1215/truss:latest

Storage Backends

truss supports multiple storage backends. The backend is selected via TRUSS_STORAGE_BACKEND. Only one backend can be active at a time. See the Configuration Reference for all storage-related environment variables.

Installing with Storage Backend Support

# S3
cargo install truss-image --features s3

# Google Cloud Storage
cargo install truss-image --features gcs

# Azure Blob Storage
cargo install truss-image --features azure

# All storage backends
cargo install truss-image --features "s3,gcs,azure"

S3

Set TRUSS_STORAGE_BACKEND=s3 and configure:

Variable Description
TRUSS_S3_BUCKET Default S3 bucket name (required)
TRUSS_S3_FORCE_PATH_STYLE Use path-style addressing (true/1; required for MinIO, LocalStack, etc.)
AWS_REGION AWS region (e.g. us-east-1)
AWS_ACCESS_KEY_ID AWS access key
AWS_SECRET_ACCESS_KEY AWS secret key
AWS_ENDPOINT_URL Custom S3-compatible endpoint (e.g. http://minio:9000)

GCS

Set TRUSS_STORAGE_BACKEND=gcs and configure:

Variable Description
TRUSS_GCS_BUCKET Default GCS bucket name (required)
TRUSS_GCS_ENDPOINT Custom endpoint (e.g. http://fake-gcs:4443)
GOOGLE_APPLICATION_CREDENTIALS Path to service account JSON key file
GOOGLE_APPLICATION_CREDENTIALS_JSON Inline service account JSON (alternative to file path)

Azure Blob Storage

Set TRUSS_STORAGE_BACKEND=azure and configure:

Variable Description
TRUSS_AZURE_CONTAINER Default container name (required)
TRUSS_AZURE_ENDPOINT Custom endpoint (e.g. http://azurite:10000/devstoreaccount1)
AZURE_STORAGE_ACCOUNT_NAME Storage account name (3-24 lowercase alphanumeric)

By default, truss uses anonymous access, which works for public containers and Azurite local development. For private containers, append a SAS token to TRUSS_AZURE_ENDPOINT. On Azure-hosted compute (App Service, AKS, VMs), managed identity is used automatically when no explicit credentials are provided.

CDN / Reverse-Proxy Integration

In production, place a CDN such as CloudFront (or a reverse proxy like nginx / Envoy) in front of truss so that transformed images are cached at the edge. See the API Reference for detailed CDN configuration guidance, including cache key setup and public vs. private endpoint visibility.

Graceful Shutdown

truss supports graceful shutdown for zero-downtime deployments. The TRUSS_SHUTDOWN_DRAIN_SECS variable controls the drain period (default: 10 seconds). During this period the server keeps accepting and answering requests, and /health/ready returns 503 to every probe so that load balancers stop sending new traffic while in-flight requests complete. The listener is closed as soon as the drain period ends, before in-flight requests are given their remaining time, so a connection attempted after it is refused rather than left waiting.

On Kubernetes, set terminationGracePeriodSeconds >= drain + 20 (e.g. 35 for the default 10 s drain).

The drain is started by SIGTERM or SIGINT on Unix. On Windows it is started by a console control event, which is what the operating system delivers in place of the signals it does not raise: Ctrl+C, Ctrl+Break, the console window being closed, the user logging off, and the system shutting down. Windows still never raises SIGTERM, so nothing depends on it. The last three of those five are terminating events, where the operating system kills the process as soon as the handler returns and allows only a few seconds before it stops asking — about five, set by the HungAppTimeout and WaitToKillServiceTimeout registry values — so truss holds the process open for up to four seconds waiting for the drain and the drain there is best effort. Ctrl+C and Ctrl+Break are not terminating, so the full TRUSS_SHUTDOWN_DRAIN_SECS window applies to them as it does on Unix. The published container image is Linux.

Rate Limiting

Per-client rate limiting is off by default. Set TRUSS_RATE_LIMIT_RPS to a positive value to enable it; each client IP then gets a token bucket refilling at that rate, with a capacity of TRUSS_RATE_LIMIT_BURST (defaulting to the same value), and requests that find an empty bucket receive 429.

Behind a CDN or reverse proxy every connection arrives from the proxy, so without further configuration all traffic shares one bucket and the limit applies to the whole site at once rather than per client. Set TRUSS_TRUSTED_PROXIES to the proxy addresses or CIDR ranges to fix this: when a connection comes from one of them, the client IP is taken from X-Forwarded-For (rightmost entry that is not itself a trusted proxy) or X-Real-IP. Only list addresses you control, because trusting an address means trusting whatever it puts in those headers.

The limit applies to the image routes -- /images/by-path, /images/by-url, /images:transform and /images -- and to a path truss does not serve. /health, /health/live, /health/ready and /metrics are outside it: a liveness probe answered 429 is a failed probe, and an orchestrator that fails enough of them restarts the process, which is the opposite of what shedding load is for. Use TRUSS_METRICS_TOKEN and TRUSS_HEALTH_TOKEN to control access to those endpoints.

Health Checks

Endpoint Purpose
GET, HEAD /health/live Liveness probe (always returns 200)
GET, HEAD /health/ready Readiness probe (returns 503 when draining, when the storage or cache root is unreachable, when the cache disk is below its minimum free bytes, or when RSS is over its limit). Transform capacity is reported in the transformCapacity check but does not withdraw readiness: a server with every slot busy is answering what it accepted, and a request that finds no free slot is shed on its own with 503 and a Retry-After

Configure health thresholds with:

  • TRUSS_HEALTH_CACHE_MIN_FREE_BYTES -- minimum free bytes on cache disk
  • TRUSS_HEALTH_MAX_MEMORY_BYTES -- maximum process RSS (Linux only)