Install
Storage

Storage overview

What Relic keeps in object storage, the buckets and permissions it needs, and what S3 services must support.

Relic keeps file content in object storage and everything else in the database. Object storage is an S3-compatible service (RELIC_OBJECT_STORAGE_TYPE=s3, the default), Azure Blob Storage (azure), Google Cloud Storage (gcs), or a local directory on a single node (filesystem).

What goes where

DatabaseObject storage
Repositories, items, properties, checksums, builds, users, tokens, permissions, scan results, the job queue.File content, stored once per SHA-256.

Buckets

BucketHoldsBehaviour
artifactsContent under sha256/<aa>/<bb>/<sha256>Objects never change. Identical files share one object. Garbage collection deletes an object once nothing has referenced it for RELIC_GARBAGE_COLLECTION_GRACE_PERIOD (default one hour).
temporaryUploads in progressNew content is copied server-side into artifacts, then deleted here. Garbage collection deletes objects older than a day.

artifacts also holds layout.json ({"version":1}). Relic refuses to start on a store that records another layout version. Keep the file in backups.

Clients never reach the storage: Relic reads every download from the bucket and sends it on. Only Relic needs network access to the storage, and with a cloud provider each download is a bucket read you pay for, so run Relic in the same region. The daily storage check adds a listing of artifacts and up to 10 GiB of reads to verify content.

Bucket requirements

  • Create both buckets yourself. Relic never creates buckets; only the Helm chart's bundled SeaweedFS and the Compose stack do.
  • Use two different buckets on the same endpoint, both readable and writable with one key pair.
  • On both buckets, expire incomplete multipart uploads after one day. Relic cannot see them.
  • Turn off versioning and object lock on artifacts, or expire noncurrent versions. Object lock makes deletes fail.
  • Keep both buckets private.
  • Unless RELIC_OBJECT_STORAGE_SSE is set, the bucket's default encryption applies.

Permissions

OperationBucketWhy
PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload, AbortMultipartUploadtemporaryStage uploads.
CopyObject, UploadPartCopy (over 5 GiB)temporary to artifactsMove an upload to its content address.
GetObject with byte ranges, HeadObjectbothDownloads, scanning, the readiness and storage checks.
ListObjectsV2bothGarbage collection and the storage check.
DeleteObjectbothClean up staged uploads; garbage collection.

The readiness check (/readyz) sends HeadObject for the missing key readyz/probe and expects "not found". An "access denied" answer keeps Relic unready. On Amazon S3 this happens when the key lacks s3:ListBucket.

Connection settings

VariableDefaultMeaning
RELIC_OBJECT_STORAGE_ENDPOINT(empty)The S3 API's base URL, with scheme. Empty means Amazon S3.
RELIC_OBJECT_STORAGE_REGIONus-east-1The region Relic signs requests for.
RELIC_OBJECT_STORAGE_ACCESS_KEY, RELIC_OBJECT_STORAGE_SECRET_KEY(empty)A static key pair. Without one, Relic uses the AWS default credential chain.
RELIC_OBJECT_STORAGE_ARTIFACTS_BUCKET, RELIC_OBJECT_STORAGE_TEMPORARY_BUCKETartifacts, temporaryBucket names. They must differ.

In the Helm chart, these are objectStorage.* values; the key pair is objectStorageAccessKey and objectStorageSecretKey in the Secret. See Helm.

What Relic does not support

No setting changes these.

  • Virtual-hosted-style URLs on a custom endpoint. With an endpoint set, Relic sends path-style requests (<endpoint>/<bucket>/<key>).
  • A session token setting. Without a static key pair, Relic uses the AWS default credential chain: AWS_* variables, shared credential files, IRSA, EKS Pod Identity and instance profiles.
  • TLS options. Relic verifies https:// endpoints against the system CA bundle, which SSL_CERT_FILE and SSL_CERT_DIR replace. The Helm chart has no value to mount such a file.
  • Signing options. Uploads carry the AWS SDK's CRC32 checksums. For a service that rejects them, set RELIC_OBJECT_STORAGE_CHECKSUM=when_required.
  • ACL headers. The bucket's defaults apply.

Sizes and throughput

  • A file can be up to 5 TiB with Content-Length, and up to 64 GiB without (a chunked transfer).
  • Uploads go in 5 MiB parts (larger above about 49 GiB), two in flight per upload, so memory stays bounded.
  • Objects up to 5 GiB move into artifacts with one CopyObject; larger ones with UploadPartCopy in 512 MiB parts.
  • Range requests pass straight through to GetObject.

Moving to another provider

Object keys are the same on every provider.

  1. Create the buckets on the new service.
  2. Copy artifacts with an S3 sync tool, such as rclone sync.
  3. Stop the server and the worker. Run the copy again. Point RELIC_OBJECT_STORAGE_* at the new service and start both.

You do not need to copy temporary.

Backups

Back up the database first, then copy artifacts. Backup explains why the order matters.