Running SwiftFS
A SwiftFS deployment is one stateless process, one data directory and one PostgreSQL database. Object bytes live on the data directory's filesystem; everything else (buckets, keys, metadata, usage) lives in PostgreSQL.
Availability
SwiftFS Core's source and container image are published together with its open-source license. This guide describes running it once you have them.
Requirements
- PostgreSQL 15 or later, UTF-8 encoding.
- A filesystem for the data directory with working
fsyncand atomicrename: ext4 or XFS on Linux. Avoid network filesystems. - A 32-byte encryption key, which protects access-key secrets at rest:
openssl rand -base64 32Back the key up somewhere safe and separate: without it, every existing access key stops working.
The container
docker run -d --name swiftfs \
-p 9000:9000 -p 127.0.0.1:9100:9100 \
-v swiftfs-data:/data \
-e SWIFTFS_DATABASE_URL='postgres://swiftfs:…@db:5432/swiftfs' \
-e SWIFTFS_ENCRYPTION_KEY='…' \
-e SWIFTFS_PUBLIC_ENDPOINT='https://s3.example.com' \
swiftfs- Port 9000 is the S3 API. Port 9100 serves health checks and Prometheus metrics: keep it private.
- The image is a small distroless image running as a non-root user.
- Database migrations run at start-up. To run them as a separate step, set
SWIFTFS_AUTO_MIGRATE=falseand runswiftfs migrate. Concurrent migrations are serialized, so several instances can start together. - Invalid configuration is reported in full at start-up, before anything listens.
The first account and key
SwiftFS is multi-tenant: accounts own buckets and access keys. Create one for each application or customer:
docker exec swiftfs swiftfs admin account create acme
docker exec swiftfs swiftfs admin key create --account acme --description "web app"
docker exec swiftfs swiftfs admin account limits acme --storage 50GiB --buckets 20The key's secret is printed once. Then use any S3 client with
https://s3.example.com as the endpoint (see SDKs and tools).
More commands are in administration.
Behind a proxy or load balancer
Terminate TLS in front of SwiftFS. The proxy must:
- pass the original
Hostheader through: it is part of every signature; - leave the path exactly as sent (
//,%2F,..); - not buffer request bodies, and allow large ones;
- pass
OPTIONSrequests through (browsers' CORS preflights); - set
X-Forwarded-For, with the proxy listed inSWIFTFS_TRUSTED_PROXIES.
location / {
proxy_pass http://swiftfs:9000;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_request_buffering off;
proxy_buffering off;
client_max_body_size 0;
proxy_http_version 1.1;
}Use /health/ready on the ops port for health checks. It fails as soon as
shutdown starts, so traffic drains first; in-flight requests get
SWIFTFS_SHUTDOWN_TIMEOUT to finish.
Backups
Back up PostgreSQL and the data directory as a pair, in this order:
- Back up PostgreSQL (
pg_dumpworks from a consistent snapshot). - Then snapshot the data directory, starting within
SWIFTFS_GC_GRACE(5 minutes by default) of step 1. RaiseSWIFTFS_GC_GRACEif your snapshots can't start that soon.
Every object in the database backup then has its data in the snapshot. Data written in between becomes unreferenced after a restore and is cleaned up automatically. Back up the encryption key separately.
Monitoring
- Metrics: scrape
/metricson the ops port with Prometheus. Alert on 5xx rates, failing background jobs, and above allswiftfs_corrupt_blobs > 0: stored data no longer matches its checksum, and the named objects must be restored from backup. - Status at a glance:
swiftfs admin statusshows health, disk use, stored totals, and every background job's last run. - Logs are JSON by default. A
DATA LOSSline means a stored object's data is missing.
Upgrading
Stop the old version (or let your orchestrator replace it), start the new one; migrations apply at start-up. The on-disk format is versioned, and SwiftFS refuses to use a data directory it doesn't recognize.