Deployment · s5w

Behind a reverse proxy

The recommended layout for a production server: two domains, not a single published port. The proxy and S5W live on a shared docker network, and the proxy does TLS.

Layout

Domain Points to What Who needs it
s5.example.com s5w:9090 API and file delivery your applications and their users
s5w.example.com s5w:9091 admin panel administrators

The panel talks to the API inside the container, so its domain needs no access to the API domain — and vice versa. If the panel is not needed from outside at all, you can skip the second domain and open it through an SSH tunnel.

What to configure in any case

  1. A shared network with the proxy

    Attach the S5W container to the docker network the proxy runs in. Ports need not be published then: the proxy reaches the container by its service name (s5w).

  2. PUBLIC_BASE_URL — the API domain's address

    PUBLIC_BASE_URL=https://s5.example.com. Without it, file addresses are built from the request, and in the panel from the panel’s domain — that is, they point to the wrong place. The panel shows a warning.

  3. Request body size — at least 32 MiB

    Details are below.

  4. TRUSTED_PROXIES — nothing needed by default

    A proxy on a docker network falls into the private ranges and is already trusted: the real client address is taken from X-Forwarded-For. Change it only if containers you do not trust share that network, see TRUSTED_PROXIES.

docker compose for S5W

docker-compose.yml
services:
  s5w:
    image: flytachi/s5w:latest
    environment:
      ADMIN_LOGIN: admin
      ADMIN_PASSWORD: ${S5W_ADMIN_PASSWORD}
      PUBLIC_BASE_URL: https://s5.example.com   # links point to the API domain
    volumes:
      - s5w_data:/var/lib/s5w
    networks: [proxy]
    stop_grace_period: 45s
    restart: unless-stopped

volumes:
  s5w_data:

networks:
  proxy:
    external: true   # the network the proxy lives in

nginx-proxy-manager

Create two Proxy Hosts:

Field API Panel
Domain Names s5.example.com s5w.example.com
Scheme http http
Forward Hostname / IP s5w s5w
Forward Port 9090 9091
Block Common Exploits can be on can be on
Websockets Support not needed not needed
SSL certificate, Force SSL certificate, Force SSL
  • Body size in nginx-proxy-manager is 2000 MB by default — no need to change it.
  • Close the panel. For the panel host create an Access List — by IP or with a login and password — and select it in the host’s settings.

traefik

docker-compose.yml
services:
  s5w:
    image: flytachi/s5w:latest
    environment:
      ADMIN_LOGIN: admin
      ADMIN_PASSWORD: ${S5W_ADMIN_PASSWORD}
      PUBLIC_BASE_URL: https://s5.example.com
    volumes:
      - s5w_data:/var/lib/s5w
    networks: [proxy]
    stop_grace_period: 45s
    restart: unless-stopped
    labels:
      - traefik.enable=true
      # API and delivery
      - traefik.http.routers.s5w-api.rule=Host(`s5.example.com`)
      - traefik.http.routers.s5w-api.entrypoints=websecure
      - traefik.http.routers.s5w-api.tls.certresolver=le
      - traefik.http.routers.s5w-api.service=s5w-api
      - traefik.http.services.s5w-api.loadbalancer.server.port=9090
      # admin panel
      - traefik.http.routers.s5w-ui.rule=Host(`s5w.example.com`)
      - traefik.http.routers.s5w-ui.entrypoints=websecure
      - traefik.http.routers.s5w-ui.tls.certresolver=le
      - traefik.http.routers.s5w-ui.service=s5w-ui
      - traefik.http.services.s5w-ui.loadbalancer.server.port=9091

volumes:
  s5w_data:

networks:
  proxy:
    external: true

websecure and le are the entry point and the certificate resolver from your traefik configuration. traefik has no body size limit by default. To close the panel, add a basicAuth or ipAllowList middleware to the s5w-ui router.

nginx

/etc/nginx/conf.d/s5w.conf
# API and delivery
server {
    listen 443 ssl;
    http2 on;
    server_name s5.example.com;
    # ssl_certificate / ssl_certificate_key …

    client_max_body_size 32m;

    location / {
        proxy_pass http://s5w:9090;
        proxy_set_header Host              $host;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# admin panel
server {
    listen 443 ssl;
    http2 on;
    server_name s5w.example.com;
    # ssl_certificate / ssl_certificate_key …

    client_max_body_size 32m;

    location / {
        proxy_pass http://s5w:9091;
        proxy_set_header Host              $host;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

http://s5w:9090 works if nginx is on the same docker network. If nginx runs on the host, publish the ports on loopback only (127.0.0.1:9090:9090, 127.0.0.1:9091:9091) and proxy to http://127.0.0.1:9090.

Request body size

The application accepts a request body of up to 32 MiB. The proxy must not let through less:

Proxy Default What to do
nginx-proxy-manager 2000 MB nothing
traefik no limit nothing
nginx 1 MB client_max_body_size 32m;

Why 32 MiB is enough for files of any size: the panel uploads files over 16 MiB in chunks of 8 MiB, and API clients should do the same — a single POST /v1/files request accepts a file of up to 32 MiB, anything larger goes through chunked upload.

How to tell who rejected a request: a 413 with an HTML page comes from the proxy, a 413 with JSON ({"code": 413, …}) comes from S5W (the bucket quota or the size limit).

Downloading large files

Delivery is streamed, and Range allows resumed downloads. Proxies with default settings cope with this. If files are very large and clients’ connections are slow, check the read timeouts on the proxy — for example, proxy_read_timeout in nginx: the connection must not drop while data is still flowing.