Deployment · s5w

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.

Port 9091Account one, from the environmentSession 24 hoursLanguages English, Russian

What it can do

Overview

A summary across all buckets: used space, files, traffic.

Files

Folders, search, uploads with image processing, renaming and moving.

Tokens

Issuing, rotating, disabling tokens and their expiry.

Links

Temporary links of a bucket: issuing, revoking one at a time or all at once.

Statistics

Traffic per day: egress, ingress and request counts.

Cache

The Cache-Control policy for the bucket and for each folder.

How the panel connects to the service

text
browser ──► :9091  panel ──► 127.0.0.1:9090/admin  (inside the container)
clients ──► :9090  API /v1, delivery /o /p /t

The 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 9090 or to the /admin path;
  • 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 gets 404, 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 word private.
  • 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_admin cookie with the HttpOnly and SameSite=Strict flags.
  • 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

bash
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:latest

In 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.