Skip to main content

File Storage

SolidPing stores a handful of binary blobs outside the database: organization logos, status-page brand assets (logo and favicon), and incident screenshots captured by browser checks. This is what "file storage" configures — it never holds check data, incidents, or any other row data. Metadata for each blob (name, size, MIME type, checksum) always lives in the database files table; only the bytes move between backends.

Backends​

Two backends are supported, selected by SP_FILESTORAGE_TYPE:

TypeSP_FILESTORAGE_TYPEStorage
Local filesystem (default)localA directory on the machine running SolidPing
S3-compatible object storages3AWS S3, or any S3-compatible store — MinIO, OVHcloud, Garage, Ceph/RGW, R2, Backblaze B2, …

local (default)​

VariableDefaultNotes
SP_FILESTORAGE_TYPElocal
SP_FILESTORAGE_LOCAL_ROOT./data/filesRoot directory for blobs. Relative to the process's working directory — see the warning below.

The ./data/files default above is the bare-binary default — running solidping directly, outside Docker. The published Docker image overrides SP_FILESTORAGE_LOCAL_ROOT to /data/files and declares /data as a VOLUME, so a plain docker run -v solidping-data:/data ... already persists uploads correctly.

Running the bare binary, or overriding the path yourself: this must be a mounted volume

./data/files (or whatever SP_FILESTORAGE_LOCAL_ROOT resolves to) is relative to the process's working directory. In a container, if that path — or any relative path you set explicitly — is not backed by a mounted volume, every upload lives on the container's ephemeral writable layer and is destroyed the next time the container is recreated — a restart, a rollout, a redeploy — silently. Nothing fails at write time: the upload succeeds and the dashboard shows it. The loss only surfaces later, when a read returns 500 read file: file not found in storage.

Either mount a volume at SP_FILESTORAGE_LOCAL_ROOT (set it to an absolute path, e.g. /data/files, to remove any working-directory ambiguity), or use the s3 backend below. See the worked volume setups in the installation guides: Kubernetes, Docker, and Docker Compose.

s3​

VariableRequiredNotes
SP_FILESTORAGE_S3_BUCKETyesBucket name
SP_FILESTORAGE_S3_REGIONyesRequired by the AWS SDK even for stores that ignore it (MinIO, Garage, …) — pick any value if the provider doesn't care
SP_FILESTORAGE_S3_PREFIXnoOptional key prefix — lets several SolidPing deployments share one bucket
SP_FILESTORAGE_S3_ENDPOINTnoCustom endpoint. Empty = AWS S3. Set it for MinIO, Garage, Ceph/RGW, R2, Backblaze B2, OVHcloud, etc.
SP_FILESTORAGE_S3_USE_PATH_STYLEnotrue / false. Path-style addressing never needs per-bucket DNS, so it's the safe choice when unsure — required by MinIO/Garage/Ceph, optional elsewhere
SP_FILESTORAGE_S3_ACCESS_KEYnoStatic access key. Secret — never logged
SP_FILESTORAGE_S3_SECRET_KEYnoStatic secret key. Secret — never logged

Credentials​

Leave SP_FILESTORAGE_S3_ACCESS_KEY and SP_FILESTORAGE_S3_SECRET_KEY both empty to use the standard AWS credential chain (environment, IAM role, shared config) — this is what you want on EKS or an EC2 instance with an attached role. Set both to pin static credentials, which is what any S3-compatible store that isn't AWS itself needs.

Worked examples​

MinIO (self-hosted, e.g. alongside SolidPing in Docker Compose):

SP_FILESTORAGE_TYPE=s3
SP_FILESTORAGE_S3_BUCKET=solidping
SP_FILESTORAGE_S3_REGION=us-east-1
SP_FILESTORAGE_S3_ENDPOINT=http://localhost:9000
SP_FILESTORAGE_S3_USE_PATH_STYLE=true
SP_FILESTORAGE_S3_ACCESS_KEY=minioadmin
SP_FILESTORAGE_S3_SECRET_KEY=minioadmin

OVHcloud Object Storage:

SP_FILESTORAGE_TYPE=s3
SP_FILESTORAGE_S3_BUCKET=solidping
SP_FILESTORAGE_S3_REGION=gra
SP_FILESTORAGE_S3_ENDPOINT=https://s3.gra.io.cloud.ovh.net
SP_FILESTORAGE_S3_USE_PATH_STYLE=true
SP_FILESTORAGE_S3_ACCESS_KEY=your-access-key
SP_FILESTORAGE_S3_SECRET_KEY=your-secret-key

Plain AWS S3 (IAM role, no static credentials):

SP_FILESTORAGE_TYPE=s3
SP_FILESTORAGE_S3_BUCKET=solidping-prod
SP_FILESTORAGE_S3_REGION=eu-west-1

Switching backends​

Each blob's URI records the scheme it was written under (file:// for the local backend, s3:// for S3), and a read always resolves through that recorded scheme rather than through the currently configured SP_FILESTORAGE_TYPE. So flipping SP_FILESTORAGE_TYPE from local to s3 (or back) only changes where new uploads land — it does not orphan what is already stored.

The old backend must stay reachable

An existing blob keeps resolving through its original backend for as long as that backend's configuration and storage remain in place. If you switch from local to s3 and later remove the local volume (or stop mounting it), every blob still recorded as file:// becomes unreadable. Migrating existing blobs to the new backend is not automated today — keep the old backend reachable until you've migrated (or accepted the loss of) anything written before the switch.

Next steps​