Admin panel
The panel is on by default and runs on port 9091. It talks to the backend inside the
container: the browser needs only the panel’s address — neither CORS nor separate access to
/admin is required.
What it can do
A summary across all buckets: used space, files, traffic.
Folders, search, uploads with image processing, renaming and moving.
Issuing, rotating, disabling tokens and their expiry.
Temporary links of a bucket: issuing, revoking one at a time or all at once.
Traffic per day: egress, ingress and request counts.
The Cache-Control policy for the bucket and for each folder.
How the panel connects to the service
browser ──► :9091 panel ──► 127.0.0.1:9090/admin (inside the container)
clients ──► :9090 API /v1, delivery /o /p /tThe panel is a separate process in the same container. It serves the web app to the browser
and forwards its /api/… requests to the admin API at 127.0.0.1:9090/admin/…. Therefore:
- the browser needs no access to port
9090or to the/adminpath; - the admin API can stay closed from outside — and by default it does;
- a panel crash does not affect the API and delivery, and the supervisor restarts the panel.
Variables
| Variable | Default | Description |
|---|---|---|
ADMIN_LOGIN |
— | Login. Without it, signing in is closed. |
ADMIN_PASSWORD |
— | Password. Without it, signing in is closed. |
ADMIN_UI |
true |
Whether to run the panel. |
ADMIN_API |
(from ADMIN_UI) |
Where the admin API is accepted from: local or public. |
TRUSTED_PROXIES |
private |
Which proxies to believe in X-Forwarded-For. |
ADMIN_LOGIN and ADMIN_PASSWORD
What they do. Define the panel’s only account. There are no users, roles or sign-up: access to the panel is full access to the storage.
If not set (either of them). Signing in is closed for everyone: every attempt is refused. This is deliberate — a panel without credentials opens for no one rather than for everyone. The storage itself keeps working as usual.
If the password is changed. After the container is recreated, every open session stops working at once — a session is bound to the login and the password. Only the new credentials let you in.
Password
The examples use change-me. In a production deployment set a long random password and pass
it as a secret — through a .env file that never gets into the repository, or through your
platform’s secrets mechanism.
ADMIN_UI
true (default) — the panel starts and listens on 9091.
false — no panel: the process does not start, nothing listens on 9091, and it need not
be published. The container only stores and delivers files. In this mode buckets and tokens
are created through requests to the admin API — which is why it becomes open by default (see
below).
ADMIN_API
Decides where the admin API /admin/… on port 9090 accepts requests from.
local— only from the loopback address inside the container, that is, from the panel itself. Any other address gets404, as if the API did not exist.public— from anywhere. Needed by automation scripts that create buckets and tokens.
If not set (or set to any other value) — derived from ADMIN_UI: with the panel — local,
without it — public.
| How it runs | Panel | /admin from outside |
|---|---|---|
| default | ✅ | 404 |
ADMIN_API=public |
✅ | ✅ |
ADMIN_UI=false |
— | ✅ |
ADMIN_UI=false, ADMIN_API=local |
— | 404 — management only from inside the container |
network_mode: host
“Local” means the connection comes from 127.0.0.1. On a regular docker network nothing from
outside can arrive that way. But with network_mode: host the container shares the host’s
network, and the admin API becomes reachable by any process on that host.
Admin API exposed
With ADMIN_API=public or ADMIN_UI=false the management API is reachable by anyone who can
get to port 9090. Its requests require signing in, just like the panel, but the /admin path
should still be closed at the proxy or the network for everyone except the automation
addresses.
TRUSTED_PROXIES
Why. The password brute-force lockout is counted per client address. Behind a proxy the
connection address is the proxy’s, and the real client address arrives in X-Forwarded-For.
But anyone can send that header, so it can be believed only when it comes from your own
proxy.
How it works. If the request came from a trusted address, the service reads
X-Forwarded-For from right to left and takes the first address that is not trusted. If the
request did not come from a trusted address, the header is ignored. Loopback is always
trusted — that is the panel itself.
Values:
private(default) — private networks:10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,fc00::/7. Any docker network falls into these, so nginx-proxy-manager, traefik and the like work with no configuration.- A comma-separated list of IPs or CIDRs —
10.0.0.5,192.168.1.0/24. Can be mixed with the wordprivate. none— trust no one except loopback.
When to change it. If containers you do not trust run on the same docker network: with
private they can put any address into X-Forwarded-For and bypass the lockout. Then list
only your proxy’s address.
Sign-in and sessions
- A session lives 24 hours from sign-in; after that you sign in again.
- The session is kept in the
s5w_admincookie with theHttpOnlyandSameSite=Strictflags. - The session is signed with
WINTER_KEY. Changing the key or the password ends every session. - Signing out deletes the cookie in this browser.
Brute-force lockout
Five failed sign-ins from one address within 15 minutes lock that address for 5 minutes. During
that time sign-in answers 429 Too Many Requests with a Retry-After header — even with the
correct password. After that the counter starts over.
The counter lives in the application’s memory: restarting the container resets it.
Without the panel
docker run -d --name s5w -p 9090:9090 \
-e ADMIN_UI=false \
-e ADMIN_LOGIN=admin -e ADMIN_PASSWORD="$S5W_ADMIN_PASSWORD" \
-v s5w_data:/var/lib/s5w \
--stop-timeout 45 --restart unless-stopped \
flytachi/s5w:latestIn this mode the admin API is open on 9090 (/admin/…), and the login and password are
needed to sign in to it.
Panel security
- The panel’s domain is worth closing further at the proxy: an IP access list or basic auth.
- Behind a proxy the panel must run over HTTPS: otherwise the session cookie travels in the clear.
- More on the access model — Security.