S5W.
Your own file storage for your applications: it accepts files over an API, stores them and delivers them to users — with CDN headers, temporary links and an admin panel. It runs as a single container on your server.
What it is
S5W is a service your application hands files to for storage and later asks for links to them. User avatars, attachments, documents, images for a website, exports — anything an application would rather not keep on its own disk or in its database.
The application uploads a file with a single HTTP request and gets its address back. At that address the file is served to a browser, a mobile client or a CDN — fast, with support for resumed downloads and caching. Everything there is to manage — buckets, quotas, access, links — is visible in the web panel.
All of this runs on your side: on your server, inside your perimeter, with no external cloud and no paying a third party for traffic.
What problems it solves
The application no longer has to keep files itself, watch its disk or serve them with its own code. It stores only a short file id.
Data never leaves your server. A fit when cloud storage is ruled out by security, legal or contractual requirements.
Public files through an open link, private ones with a token, one-off sharing through a temporary link that expires by itself.
Retention, quotas, cleanup of abandoned uploads and space recalculation run by themselves, on a schedule.
Typical scenarios
- User uploads — avatars, photos, attachments to support tickets. Images can be shrunk
and converted to
webporavifright away. - Media for a website or an app — delivered through a CDN with a long cache and
ETag. - Sharing documents — a temporary link for a day with a download limit, without granting access to the whole storage.
- Temporary files — exports, reports, intermediate results in a folder with a retention period: after a week or a month they delete themselves.
- Several projects on one server — each in its own bucket, with its own quota and its own tokens.
Features
The database, the scheduler and the panel are already inside. No external dependencies, no connection settings.
Each bucket has its own quota and tokens; a folder has visibility, retention and a cache policy.
Public links, access with a token and signed temporary links with a download limit.
Identical files are stored once: a copy takes no disk space and uses no quota.
Chunked upload that resumes after a dropped connection.
Shrinking, EXIF rotation and re-encoding to webp, avif, jpeg, png at upload time.
Range, ETag, conditional requests and a configurable Cache-Control.
Egress, ingress and request counts — per bucket and per day.
A separate web app on its own port: responsive, light and dark themes, English and Russian.
How it works
Four parts run inside one container. Only two ports face the outside.
:9090The client API /v1/… for your applications and file delivery /o, /p, /t.
:9091The web management panel. Talks to the application inside the container. Can be turned off.
not exposedMetadata: buckets, files, tokens, links, statistics. Creates and migrates itself.
on a scheduleRetention, cleanup of abandoned uploads, space recalculation, statistics flush.
All data — the database, the files, the signing key — lives in one volume, /var/lib/s5w.
A backup or a move to another server is a copy of that volume. Details are in the
architecture.
When it fits and when it does not
| Fits | Better pick something else |
|---|---|
| You need your own storage inside your perimeter | You need an S3-compatible protocol: S5W speaks its own REST API |
| One server handles the volume and the load | You need replication and multiple nodes: S5W is one container on one volume |
| Simplicity matters: one command to start, no separate database | You need video processing: S5W processes images only |
| Files from kilobytes to gigabytes, chunked upload | The data is larger than one server’s disk can hold |
Fault tolerance
S5W runs on a single server. Protection against data loss is a backup of the volume (see operations), and the recovery time is the time it takes to start the container on a copy of the volume.
Limits in numbers
| What | Limit |
|---|---|
A file in one request, POST /v1/files |
up to 32 MiB |
| A file through chunked upload | no separate limit — up to the bucket quota and the disk space |
| A chunk in chunked upload | 4–16 MiB |
| An unfinished chunked upload | lives 24 hours after the last chunk |
| A temporary link | up to 30 days, up to 1000 downloads |
| An image for processing | up to 25 megapixels |
| Folder retention | from a day to a year, or forever |
| Default bucket quota | 100 MiB, changed in the panel |
Where to start
Start with one command, the first bucket, a token and an upload.
What it is made of, how files are stored, how space is counted.
Every environment variable: what it does, why, and what happens if it is not set.
Tokens, panel sign-in, file visibility, link signatures.
nginx-proxy-manager, traefik, nginx: two domains, no open ports.
Tokens, files, chunked upload, folders, temporary links.
A ready PHP client: resumable chunked upload, typed objects and errors.