Each node in a cluster — the Portal and every instance — can serve static web content from a storage/web directory, on the same public URL as the application. This is useful for branded landing pages, welcome screens, help links, and lightweight status pages that should live next to a deployment. It complements the cluster theme, which restyles the app itself.

The overlay serves static files only. Dynamic requests, uploads, and API calls continue to be handled by the normal application routes.

How It Works

When a storage/web directory exists, PhotoPrism checks it for a matching file before returning the default login redirect or a 404:

  • / serves storage/web/index.html
  • /about/ serves storage/web/about/index.html
  • /img/logo.svg serves storage/web/img/logo.svg

So you can structure the directory like a small static website:

storage/
  web/
    index.html
    about/
      index.html
    css/
      site.css
    img/
      logo.svg

Behavior to keep in mind:

  • Static files are served only for GET and HEAD requests.
  • A path without a filename extension resolves to index.html inside the requested folder.
  • If no index.html exists at the overlay root, the server root keeps showing the usual sign-in page.
  • Missing files below other paths return the standard 404 response.

Supported Directories & File Names

The overlay mirrors whatever directory tree you place under storage/web, with no fixed set of folders — about/, css/, img/, help/, and so on are all served by their path. To keep secrets and configuration out of public reach, several names and types are never served, even if present:

  • Unsafe paths are rejected: //, parent-directory traversal, encoded dot/separator probes, and hidden or special segments such as ., @, _., and __.
  • Sensitive file names are denied even when they are not dotfiles — for example options.yml, config.yaml, id_rsa, client_secret, and anything under node/secrets/.
  • Sensitive extensions are denied — for example .pem, .key, .jwk, .sql, and .toml.
  • Symlinks are resolved before serving and must stay within the overlay root; targets that escape storage/web are blocked.

In practice, keep only public web assets in storage/web and continue storing keys, certificates, backups, and configuration elsewhere under storage.

Combining with the Path-Based Proxy

The overlay works together with path-based routing. On the Portal, a storage/web/index.html provides the landing page at the shared root; on an instance served under /i/<name>/, the overlay provides that tenant’s start page:

  • Root landing page: https://portal.example.com/
  • Tenant landing page: https://portal.example.com/i/acme/

When an instance is published below a path, set its PHOTOPRISM_SITE_URL to the same public base URL (including the trailing slash) so generated links, redirects, and browser storage stay scoped to the correct tenant. Requests to /i/acme are redirected to /i/acme/, while deeper paths are forwarded as-is so file access and WebDAV clients keep working.

Recommendations

  • Keep the public server URL (PHOTOPRISM_SITE_URL) configured correctly, especially behind a reverse proxy or on a Portal tenant path.
  • Use HTTPS so landing pages, sign-in flows, and linked assets are delivered securely.
  • Keep the overlay small and focused on static content.
  • Use folder-based routes such as /about/ and /help/ for clean URLs.

PhotoPrism® Documentation

For more information on specific features, services and related resources, please refer to the other documentation available in our Knowledge Base and User Guide: